-
Notifications
You must be signed in to change notification settings - Fork 40
Description
Context
Thanks for the great library. I appreciate that the ArcLayer is clearly flagged as experimental but it is already very useful for visualising graphs of spatial data.
I've seen that there have been recent fixes to it but at the moment I can't get either the examples in the fixes, the main published example, or my own examples to work. I constantly run into KeyError: b'ARROW:extension:name'
I think this is a bug but it may be that I am not constructing my inputs properly (I have tried both Arrow and Numpy options). Might it be helpful to have a MWE with a clear example of what acceptable input to the ArcLayer looks like?
Resulting behaviour, error message or logs
The error that I get occurs at the moment of creating the ArcLayer and looks like this:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
Cell In[12], line 15
11 target = np.array([(53.4808, 2.2426), (51.4545, 2.5879), (51.5072, 0.1276)])
13 table = pa.table(data)
---> 15 lb.experimental.ArcLayer(
16 table,
17 get_source_position=source,
18 get_target_position=target
19 )
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/experimental/_layer.py:170](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/experimental/_layer.py#line=169), in ArcLayer.__init__(self, table, get_source_position, get_target_position, _rows_per_chunk, **kwargs)
153 def __init__(
154 self,
155 table: ArrowStreamExportable,
(...) 160 **kwargs: Unpack[ArcLayerKwargs],
161 ) -> None:
162 """Construct an ArcLayer from existing Arrow data.
163
164 Keyword Args:
(...) 168
169 """
--> 170 super().__init__(
171 table=table,
172 _rows_per_chunk=_rows_per_chunk,
173 get_source_position=get_source_position, # type: ignore
174 get_target_position=get_target_position, # type: ignore
175 **kwargs,
176 )
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/_layer.py:399](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/_layer.py#line=398), in BaseArrowLayer.__init__(self, table, _rows_per_chunk, **kwargs)
395 self._rows_per_chunk = rows_per_chunk
397 table_o3 = table_o3.rechunk(max_chunksize=rows_per_chunk)
--> 399 super().__init__(table=table_o3, **kwargs)
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/_layer.py:101](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/_layer.py#line=100), in BaseLayer.__init__(self, extensions, **kwargs)
89 def __init__(
90 self,
91 *,
(...) 96 # widgets where the layer is defined. We wish to allow extensions and their
97 # properties to be passed in the layer constructor. _However_, if
99 extension_kwargs = remove_extension_kwargs(extensions, kwargs)
--> 101 super().__init__(extensions=extensions, **kwargs)
103 # Dynamically set layer traits from extensions after calling __init__
104 self._add_extension_traits(extensions)
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/_base.py:25](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/_base.py#line=24), in BaseWidget.__init__(self, **kwargs)
22 if provided_trait_name not in layer_trait_names:
23 raise TypeError(msg.format(provided_trait_name=provided_trait_name))
---> 25 super().__init__(**kwargs)
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/ipywidgets/widgets/widget.py:503](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/ipywidgets/widgets/widget.py#line=502), in Widget.__init__(self, **kwargs)
501 """Public constructor"""
502 self._model_id = kwargs.pop('model_id', None)
--> 503 super().__init__(**kwargs)
505 Widget._call_widget_constructed(self)
506 self.open()
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/traitlets/traitlets.py:1355](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/traitlets/traitlets.py#line=1354), in HasTraits.__init__(self, *args, **kwargs)
1353 for key, value in kwargs.items():
1354 if self.has_trait(key):
-> 1355 setattr(self, key, value)
1356 changes[key] = Bunch(
1357 name=key,
1358 old=None,
(...) 1361 type="change",
1362 )
1363 else:
1364 # passthrough args that don't set traits to super
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/traitlets/traitlets.py:716](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/traitlets/traitlets.py#line=715), in TraitType.__set__(self, obj, value)
714 if self.read_only:
715 raise TraitError('The "%s" trait is read-only.' % self.name)
--> 716 self.set(obj, value)
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/traitlets/traitlets.py:690](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/traitlets/traitlets.py#line=689), in TraitType.set(self, obj, value)
689 def set(self, obj: HasTraits, value: S) -> None:
--> 690 new_value = self._validate(obj, value)
691 assert self.name is not None
692 try:
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/traitlets/traitlets.py:722](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/traitlets/traitlets.py#line=721), in TraitType._validate(self, obj, value)
720 return value
721 if hasattr(self, "validate"):
--> 722 value = self.validate(obj, value)
723 if obj._cross_validation_lock is False:
724 value = self._cross_validate(obj, value)
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/traits.py:588](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/traits.py#line=587), in PointAccessor.validate(self, obj, value)
585 self.error(obj, value)
587 assert isinstance(value, ChunkedArray)
--> 588 _, value = convert_struct_column_to_interleaved(field=value.field, column=value)
590 if not DataType.is_fixed_size_list(value.type):
591 self.error(obj, value, info="Point arrow array to be a FixedSizeList")
File [~/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/_geoarrow/ops/coord_layout.py:55](http://localhost:8888/home/nick/miniconda3/envs/sds/lib/python3.13/site-packages/lonboard/_geoarrow/ops/coord_layout.py#line=54), in convert_struct_column_to_interleaved(field, column)
49 def convert_struct_column_to_interleaved(
50 *,
51 field: Field,
52 column: ChunkedArray,
53 ) -> tuple[Field, ChunkedArray]:
54 """Convert a GeoArrow column from struct to interleaved coordinate layout."""
---> 55 extension_type_name = field.metadata[b"ARROW:extension:name"]
57 new_chunked_array = _convert_column(column, extension_type_name=extension_type_name)
58 return field.with_type(new_chunked_array.type), new_chunked_array
KeyError: b'ARROW:extension:name'
Environment
- OS: Mac & Ubuntu
- Browser: Chrome
- Lonboard Version: 0.12.1
Steps to reproduce the bug
My MWE currently looks like this:
import numpy as np
import pyarrow as pa
import lonboard as lb
data = {
'source' : ['London', 'Manchester', 'Bristol'],
'target' : ['Manchester', 'Bristol', 'London']
}
source = np.array([(51.5072, 0.1276),(53.4808, 2.2426), (51.4545, 2.5879)])
target = np.array([(53.4808, 2.2426), (51.4545, 2.5879), (51.5072, 0.1276)])
table = pa.table(data)
lb.experimental.ArcLayer(
table,
get_source_position=source,
get_target_position=target
)
I have been trying GeoArrow arrays as well but I haven't got those to work either.
Thanks!