diff --git a/lonboard/traits/_float.py b/lonboard/traits/_float.py index af52c72f..ef3ee5b8 100644 --- a/lonboard/traits/_float.py +++ b/lonboard/traits/_float.py @@ -5,15 +5,9 @@ from typing import TYPE_CHECKING, Any import numpy as np -from arro3.core import ( - Array, - ChunkedArray, - DataType, -) - -from lonboard._serialization import ( - ACCESSOR_SERIALIZATION, -) +from arro3.core import Array, ChunkedArray, DataType + +from lonboard._serialization import ACCESSOR_SERIALIZATION from lonboard.traits._base import FixedErrorTraitType if TYPE_CHECKING: diff --git a/lonboard/traits/_map.py b/lonboard/traits/_map.py index 870005e5..dd7f26a2 100644 --- a/lonboard/traits/_map.py +++ b/lonboard/traits/_map.py @@ -6,9 +6,7 @@ import traitlets from lonboard._environment import DEFAULT_HEIGHT -from lonboard._serialization import ( - serialize_view_state, -) +from lonboard._serialization import serialize_view_state from lonboard.models import ViewState from lonboard.traits._base import FixedErrorTraitType diff --git a/lonboard/traits/_normal.py b/lonboard/traits/_normal.py index 62ee2b21..27b93f57 100644 --- a/lonboard/traits/_normal.py +++ b/lonboard/traits/_normal.py @@ -6,17 +6,9 @@ from typing import TYPE_CHECKING, Any import numpy as np -from arro3.core import ( - Array, - ChunkedArray, - DataType, - Field, - fixed_size_list_array, -) - -from lonboard._serialization import ( - ACCESSOR_SERIALIZATION, -) +from arro3.core import Array, ChunkedArray, DataType, Field, fixed_size_list_array + +from lonboard._serialization import ACCESSOR_SERIALIZATION from lonboard.traits._base import FixedErrorTraitType if TYPE_CHECKING: diff --git a/lonboard/traits/_point.py b/lonboard/traits/_point.py index a337c341..2597dcfa 100644 --- a/lonboard/traits/_point.py +++ b/lonboard/traits/_point.py @@ -5,17 +5,11 @@ from typing import TYPE_CHECKING, Any import numpy as np -from arro3.core import ( - Array, - ChunkedArray, - DataType, - fixed_size_list_array, -) +from arro3.core import Array, ChunkedArray, DataType, Field, fixed_size_list_array +from lonboard._geoarrow.extension_types import CoordinateDimension, coord_storage_type from lonboard._geoarrow.ops.coord_layout import convert_struct_column_to_interleaved -from lonboard._serialization import ( - ACCESSOR_SERIALIZATION, -) +from lonboard._serialization import ACCESSOR_SERIALIZATION from lonboard.traits._base import FixedErrorTraitType if TYPE_CHECKING: @@ -63,8 +57,27 @@ def _numpy_to_arrow(self, obj: BaseArrowLayer, value: np.ndarray) -> ChunkedArra info="Point array to have 2 or 3 as its second dimension", ) - assert np.issubdtype(value.dtype, np.float64) - array = fixed_size_list_array(value.ravel("C"), list_size) + if not np.issubdtype(value.dtype, np.float64): + self.error(obj, value, info="Point array to have float64 type.") + + # Set geoarrow extension metadata + field = Field( + "", + coord_storage_type( + interleaved=True, + dims=CoordinateDimension.XY + if list_size == 2 + else CoordinateDimension.XYZ, + ), + nullable=True, + metadata={"ARROW:extension:name": "geoarrow.point"}, + ) + array = fixed_size_list_array( + value.ravel("C"), + list_size, + type=field, + ) + return ChunkedArray([array]) def validate( diff --git a/lonboard/traits/_table.py b/lonboard/traits/_table.py index b3e3dd6c..3e1ce0b3 100644 --- a/lonboard/traits/_table.py +++ b/lonboard/traits/_table.py @@ -5,16 +5,11 @@ from typing import TYPE_CHECKING, Any from typing import cast as type_cast -from arro3.core import ( - DataType, - Table, -) +from arro3.core import DataType, Table from lonboard._constants import EXTENSION_NAME from lonboard._geoarrow.box_to_polygon import parse_box_encoded_table -from lonboard._serialization import ( - TABLE_SERIALIZATION, -) +from lonboard._serialization import TABLE_SERIALIZATION from lonboard._utils import get_geometry_column_index from lonboard.traits._base import FixedErrorTraitType diff --git a/lonboard/traits/_text.py b/lonboard/traits/_text.py index d01916e5..8ec14db7 100644 --- a/lonboard/traits/_text.py +++ b/lonboard/traits/_text.py @@ -5,15 +5,9 @@ from typing import TYPE_CHECKING, Any import numpy as np -from arro3.core import ( - Array, - ChunkedArray, - DataType, -) - -from lonboard._serialization import ( - ACCESSOR_SERIALIZATION, -) +from arro3.core import Array, ChunkedArray, DataType + +from lonboard._serialization import ACCESSOR_SERIALIZATION from lonboard.traits._base import FixedErrorTraitType if TYPE_CHECKING: diff --git a/lonboard/traits/_timestamp.py b/lonboard/traits/_timestamp.py index 0e0549f5..c916539f 100644 --- a/lonboard/traits/_timestamp.py +++ b/lonboard/traits/_timestamp.py @@ -20,9 +20,7 @@ from traitlets.traitlets import TraitType from lonboard._constants import MAX_INTEGER_FLOAT32, MIN_INTEGER_FLOAT32 -from lonboard._serialization import ( - TIMESTAMP_ACCESSOR_SERIALIZATION, -) +from lonboard._serialization import TIMESTAMP_ACCESSOR_SERIALIZATION from lonboard._utils import get_geometry_column_index from lonboard.traits import FixedErrorTraitType diff --git a/tests/layers/test_arc_layer.py b/tests/layers/test_arc_layer.py index 4109db16..ed97e2a4 100644 --- a/tests/layers/test_arc_layer.py +++ b/tests/layers/test_arc_layer.py @@ -1,6 +1,6 @@ import numpy as np import pyarrow as pa -from arro3.core import Table +from arro3.core import ChunkedArray, Table from geoarrow.rust.core import point, points from lonboard import ArcLayer, Map @@ -40,3 +40,18 @@ def test_arc_layer_geoarrow_separated(): ) m = Map(layer) assert isinstance(m.layers[0], ArcLayer) + + +def test_arc_layer_numpy(): + 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) + + layer = ArcLayer(table, get_source_position=source, get_target_position=target) + assert isinstance(layer.get_source_position, ChunkedArray)