@@ -46,6 +46,11 @@ class GeoInterfaceProtocol(Protocol):
4646 @property
4747 def __geo_interface__ (self ) -> dict : ...
4848
49+ class ArrowArrayExportable (Protocol ):
50+ def __arrow_c_array__ (
51+ self , requested_schema : object | None = None
52+ ) -> Tuple [object , object ]: ...
53+
4954 class ArrowStreamExportable (Protocol ):
5055 def __arrow_c_stream__ (
5156 self , requested_schema : object | None = None
@@ -187,6 +192,11 @@ def create_layer_from_data_input(
187192 if isinstance (data , shapely .geometry .base .BaseGeometry ):
188193 return _viz_shapely_scalar (data , ** kwargs )
189194
195+ # Anything with __arrow_c_array__
196+ if hasattr (data , "__arrow_c_array__" ):
197+ data = cast ("ArrowArrayExportable" , data )
198+ return _viz_geoarrow_array (data , ** kwargs )
199+
190200 # Anything with __arrow_c_stream__
191201 if hasattr (data , "__arrow_c_stream__" ):
192202 data = cast ("ArrowStreamExportable" , data )
@@ -296,6 +306,52 @@ def _viz_geo_interface(
296306 raise ValueError (f"type '{ geo_interface_type } ' not supported." )
297307
298308
309+ def _viz_geoarrow_array (
310+ data : ArrowArrayExportable ,
311+ ** kwargs ,
312+ ) -> Union [ScatterplotLayer , PathLayer , SolidPolygonLayer ]:
313+ schema_capsule , array_capsule = data .__arrow_c_array__ ()
314+
315+ # If the user doesn't have pyarrow extension types registered for geoarrow types,
316+ # `pa.array()` will lose the extension metadata. Instead, we manually persist the
317+ # extension metadata by extracting both the field and the array.
318+
319+ class ArrayHolder :
320+ schema_capsule : object
321+ array_capsule : object
322+
323+ def __init__ (self , schema_capsule , array_capsule ) -> None :
324+ self .schema_capsule = schema_capsule
325+ self .array_capsule = array_capsule
326+
327+ def __arrow_c_array__ (self , requested_schema ):
328+ return self .schema_capsule , self .array_capsule
329+
330+ if not hasattr (pa .Field , "_import_from_c_capsule" ):
331+ raise KeyError (
332+ "Incompatible version of pyarrow: pa.Field does not have"
333+ " _import_from_c_capsule method"
334+ )
335+
336+ field = pa .Field ._import_from_c_capsule (schema_capsule )
337+ array = pa .array (ArrayHolder (field .__arrow_c_schema__ (), array_capsule ))
338+ schema = pa .schema ([field .with_name ("geometry" )])
339+ table = pa .Table .from_arrays ([array ], schema = schema )
340+
341+ num_rows = len (array )
342+ if num_rows <= np .iinfo (np .uint8 ).max :
343+ arange_col = np .arange (num_rows , dtype = np .uint8 )
344+ elif num_rows <= np .iinfo (np .uint16 ).max :
345+ arange_col = np .arange (num_rows , dtype = np .uint16 )
346+ elif num_rows <= np .iinfo (np .uint32 ).max :
347+ arange_col = np .arange (num_rows , dtype = np .uint32 )
348+ else :
349+ arange_col = np .arange (num_rows , dtype = np .uint64 )
350+
351+ table = table .append_column ("row_index" , pa .array (arange_col ))
352+ return _viz_geoarrow_table (table , ** kwargs )
353+
354+
299355def _viz_geoarrow_table (
300356 table : pa .Table ,
301357 * ,
0 commit comments