Converting lat/lon numpy array(s) to geoarrow-rust objects? #643
-
Hello! I have a notebook that reads in weather radar data, does some coordinate transformation, and produces a numpy array of shape (366143, 4, 2), representing 300k polygons that have four corners (they're not quite square...) and each corner has latitude and longitude. To plot this data with lonboard, I'm creating The relevant lines of code below are the monstrosity that are my numpy string operations and the calls to geoarrow.pyarrow.as_geoarrow and geoarrow.pyarrow.to_geopandas... Minimal exampleimport numpy as np
import geoarrow.pyarrow as ga
import geopandas as gpd
# poly_coords is an array of shape (366143, 4, 2)
lon_lat_pairs = np.strings.add(np.strings.add(poly_coords[:, :, 0].astype(str), ' '), poly_coords[:, :, 1].astype(str))
polygon_strings = np.strings.add(np.strings.add(
np.strings.add(np.strings.add(
np.strings.add(np.strings.add(
np.strings.add(np.strings.add(
lon_lat_pairs[:, 0], ', '), lon_lat_pairs[:, 1]), ', '), lon_lat_pairs[:, 2]), ', '), lon_lat_pairs[:, 3]), ', '), lon_lat_pairs[:, 0])
polygon_strings = np.char.add(np.char.add('POLYGON ((', polygon_strings), '))')
geom_arrow = ga.as_geoarrow(polygon_strings)
geometry = gpd.GeoDataFrame(geometry=ga.to_geopandas(geom_arrow))
# Then I plot it as a SolidPolygonLayer... you get the idea However, I'd like to use this with upcoming versions of pyodide, geoarrow.pyarrow is not supported, but geoarrow-rust is! Is there a way to replace my calls to gearrow.pyarrow with geoarrow-rust to create a geopandas dataframe with the geometry of these points (quickly, without a python for loop)? And, I'm reaching here, is there a way to do this using just the original numpy array, without the intermediate WKT string representation? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
First, super cool to see weather (radar?) data visualized in this way: If you have an open, public-facing example, we should add it to our collection of user examples in the docs website. Otherwise, I have a few comments:
😬 that sounds like a mess 😅
As an aside, note that even with shapely you don't need a Python for loop here. You can use the I will admit that that constructor isn't the easiest to use. It always takes me some time to recall how to use it, but it is possible to use with direct numpy input. Still though, that gives you vectorized creation of shapely geometries, and lonboard would still need to convert those geometries to GeoArrow, so a GeoArrow-native approach would be faster.
To be clear, geoarrow-pyarrow can still be used in any normal Python environment outside of the browser. And pyarrow actually now works in pyarrow, the missing piece is just the
Well, with geoarrow-rust you need to work with Arrow tables, not GeoPandas GeoDataFrames. But in principle yes. The smallest change from your existing workflow is to create an Arrow string column from your numpy string data (e.g. with Dewey created geoarrow-pandas and geoarrow-pyarrow; geoarrow-pandas currently only works with geoarrow-pyarrow, not geoarrow-rust, so you can't use a GeoPandas GeoDataFrame with a geoarrow-rust column. It would be cool to implement support for geoarrow-rust as well, but I don't have time for that right now.
Yeah you really don't want to go through WKT. I haven't implemented native constructors in geoarrow-rs like the You can still do this today in an "advanced" way with a bit of knowledge of the GeoArrow format. Assuming that you have a numpy array of shape Then reshape your data to a flat array of all coordinates ordered as Then construct an offsets buffer for each ring. Since every ring has exactly 5 coordinates, this is just Then construct an offsets buffer for each geometry. Since every polygon has exactly 1 ring, this is just Then you can construct a geoarrow array as such: lonboard/lonboard/_geoarrow/extension_types.py Lines 225 to 237 in 7562834 (You can look back in that file's history if you want to see how to do it with pyarrow) I hope this is somewhat easy to follow! |
Beta Was this translation helpful? Give feedback.
-
continuing discussion for weather radar viz at ARM-DOE/pyart#1653 |
Beta Was this translation helpful? Give feedback.
You missed the
* 5
in the second arg, so you're not creating the right length of offsets array.You also need to pass in a table, not just a geometry to the layer class, because most of the time you have some attribute per geometry. This is something maybe we could relax in the future.
See repro notebook here: https://github.com/kylebarron/lonboard-radar-example/blob/d372b6526d6fd766e6767c80ccbfea27914590b2/radar-viz-lonboard.ipynb. That repo also has a pixi env file if you want to reproduce it.