@@ -49,6 +49,83 @@ def geometry_ds():
49
49
return cf_ds , shp_ds
50
50
51
51
52
+ @pytest .fixture
53
+ def geometry_line_ds ():
54
+ from shapely .geometry import LineString , MultiLineString
55
+
56
+ # empty/fill workaround to avoid numpy deprecation(warning) due to the array interface of shapely geometries.
57
+ geoms = np .empty (3 , dtype = object )
58
+ geoms [:] = [
59
+ MultiLineString ([[[0 , 0 ], [1 , 2 ]], [[4 , 4 ], [5 , 6 ]]]),
60
+ LineString ([[0 , 0 ], [1 , 0 ], [1 , 1 ]]),
61
+ LineString ([[1.0 , 1.0 ], [2.0 , 2.0 ], [1.7 , 9.5 ]]),
62
+ ]
63
+
64
+ ds = xr .Dataset ()
65
+ shp_da = xr .DataArray (geoms , dims = ("index" ,), name = "geometry" )
66
+
67
+ cf_ds = ds .assign (
68
+ x = xr .DataArray (
69
+ [0 , 1 , 4 , 5 , 0 , 1 , 1 , 1.0 , 2.0 , 1.7 ], dims = ("node" ,), attrs = {"axis" : "X" }
70
+ ),
71
+ y = xr .DataArray (
72
+ [0 , 2 , 4 , 6 , 0 , 0 , 1 , 1.0 , 2.0 , 9.5 ], dims = ("node" ,), attrs = {"axis" : "Y" }
73
+ ),
74
+ part_node_count = xr .DataArray ([4 , 3 , 3 ], dims = ("index" ,)),
75
+ node_count = xr .DataArray ([2 , 2 , 3 , 3 ], dims = ("segment" ,)),
76
+ crd_x = xr .DataArray ([0.0 , 0.0 , 1.0 ], dims = ("index" ,), attrs = {"nodes" : "x" }),
77
+ crd_y = xr .DataArray ([0.0 , 0.0 , 1.0 ], dims = ("index" ,), attrs = {"nodes" : "y" }),
78
+ geometry_container = xr .DataArray (
79
+ attrs = {
80
+ "geometry_type" : "line" ,
81
+ "node_count" : "node_count" ,
82
+ "part_node_count" : "part_node_count" ,
83
+ "node_coordinates" : "x y" ,
84
+ "coordinates" : "crd_x crd_y" ,
85
+ }
86
+ ),
87
+ )
88
+
89
+ cf_ds = cf_ds .set_coords (["x" , "y" , "crd_x" , "crd_y" ])
90
+
91
+ return cf_ds , shp_da
92
+
93
+
94
+ @pytest .fixture
95
+ def geometry_line_without_multilines_ds ():
96
+ from shapely .geometry import LineString
97
+
98
+ # empty/fill workaround to avoid numpy deprecation(warning) due to the array interface of shapely geometries.
99
+ geoms = np .empty (2 , dtype = object )
100
+ geoms [:] = [
101
+ LineString ([[0 , 0 ], [1 , 0 ], [1 , 1 ]]),
102
+ LineString ([[1.0 , 1.0 ], [2.0 , 2.0 ], [1.7 , 9.5 ]]),
103
+ ]
104
+
105
+ ds = xr .Dataset ()
106
+ shp_da = xr .DataArray (geoms , dims = ("index" ,), name = "geometry" )
107
+
108
+ cf_ds = ds .assign (
109
+ x = xr .DataArray ([0 , 1 , 1 , 1.0 , 2.0 , 1.7 ], dims = ("node" ,), attrs = {"axis" : "X" }),
110
+ y = xr .DataArray ([0 , 0 , 1 , 1.0 , 2.0 , 9.5 ], dims = ("node" ,), attrs = {"axis" : "Y" }),
111
+ node_count = xr .DataArray ([3 , 3 ], dims = ("segment" ,)),
112
+ crd_x = xr .DataArray ([0.0 , 1.0 ], dims = ("index" ,), attrs = {"nodes" : "x" }),
113
+ crd_y = xr .DataArray ([0.0 , 1.0 ], dims = ("index" ,), attrs = {"nodes" : "y" }),
114
+ geometry_container = xr .DataArray (
115
+ attrs = {
116
+ "geometry_type" : "line" ,
117
+ "node_count" : "node_count" ,
118
+ "node_coordinates" : "x y" ,
119
+ "coordinates" : "crd_x crd_y" ,
120
+ }
121
+ ),
122
+ )
123
+
124
+ cf_ds = cf_ds .set_coords (["x" , "y" , "crd_x" , "crd_y" ])
125
+
126
+ return cf_ds , shp_da
127
+
128
+
52
129
@requires_shapely
53
130
def test_shapely_to_cf (geometry_ds ):
54
131
from shapely .geometry import Point
@@ -87,12 +164,45 @@ def test_shapely_to_cf(geometry_ds):
87
164
assert set (out .dims ) == {"features" , "node" }
88
165
89
166
167
+ @requires_shapely
168
+ def test_shapely_to_cf_for_lines_as_da (geometry_line_ds ):
169
+ expected , in_da = geometry_line_ds
170
+
171
+ actual = cfxr .shapely_to_cf (in_da )
172
+ xr .testing .assert_identical (actual , expected )
173
+
174
+ in_da = in_da .assign_coords (index = ["a" , "b" , "c" ])
175
+ actual = cfxr .shapely_to_cf (in_da )
176
+ xr .testing .assert_identical (actual , expected .assign_coords (index = ["a" , "b" , "c" ]))
177
+
178
+
179
+ @requires_shapely
180
+ def test_shapely_to_cf_for_lines_as_sequence (geometry_line_ds ):
181
+ expected , in_da = geometry_line_ds
182
+ actual = cfxr .shapely_to_cf (in_da .values )
183
+ xr .testing .assert_identical (actual , expected )
184
+
185
+
186
+ @requires_shapely
187
+ def test_shapely_to_cf_for_lines_without_multilines (
188
+ geometry_line_without_multilines_ds ,
189
+ ):
190
+ expected , in_da = geometry_line_without_multilines_ds
191
+ actual = cfxr .shapely_to_cf (in_da )
192
+ xr .testing .assert_identical (actual , expected )
193
+
194
+
90
195
@requires_shapely
91
196
def test_shapely_to_cf_errors ():
92
- from shapely .geometry import LineString , Point
197
+ from shapely .geometry import Point , Polygon
93
198
94
- geoms = [LineString ([[1 , 2 ], [2 , 3 ]]), LineString ([[2 , 3 , 4 ], [4 , 3 , 2 ]])]
95
- with pytest .raises (NotImplementedError , match = "Only point geometries conversion" ):
199
+ geoms = [
200
+ Polygon ([[1 , 1 ], [1 , 3 ], [3 , 3 ], [1 , 1 ]]),
201
+ Polygon ([[1 , 1 , 4 ], [1 , 3 , 4 ], [3 , 3 , 3 ], [1 , 1 , 4 ]]),
202
+ ]
203
+ with pytest .raises (
204
+ NotImplementedError , match = "Polygon geometry conversion is not implemented"
205
+ ):
96
206
cfxr .shapely_to_cf (geoms )
97
207
98
208
geoms .append (Point (1 , 2 ))
@@ -122,16 +232,47 @@ def test_cf_to_shapely(geometry_ds):
122
232
123
233
124
234
@requires_shapely
125
- def test_cf_to_shapely_errors (geometry_ds ):
126
- in_ds , expected = geometry_ds
127
- in_ds .geometry_container .attrs ["geometry_type" ] = "line"
128
- with pytest .raises (NotImplementedError , match = "Only point geometries conversion" ):
235
+ def test_cf_to_shapely_for_lines (geometry_line_ds ):
236
+ in_ds , expected = geometry_line_ds
237
+
238
+ actual = cfxr .cf_to_shapely (in_ds )
239
+ assert actual .dims == ("index" ,)
240
+ xr .testing .assert_identical (actual .drop_vars (["crd_x" , "crd_y" ]), expected )
241
+
242
+
243
+ @requires_shapely
244
+ def test_cf_to_shapely_for_lines_without_multilines (
245
+ geometry_line_without_multilines_ds ,
246
+ ):
247
+ in_ds , expected = geometry_line_without_multilines_ds
248
+ actual = cfxr .cf_to_shapely (in_ds )
249
+ assert actual .dims == ("index" ,)
250
+ xr .testing .assert_identical (actual , expected )
251
+
252
+ in_ds = in_ds .assign_coords (index = ["b" , "c" ])
253
+ actual = cfxr .cf_to_shapely (in_ds )
254
+ assert actual .dims == ("index" ,)
255
+ xr .testing .assert_identical (
256
+ actual .drop_vars (["crd_x" , "crd_y" ]), expected .assign_coords (index = ["b" , "c" ])
257
+ )
258
+
259
+
260
+ @requires_shapely
261
+ def test_cf_to_shapely_errors (geometry_ds , geometry_line_ds ):
262
+ in_ds , _ = geometry_ds
263
+ in_ds .geometry_container .attrs ["geometry_type" ] = "polygon"
264
+ with pytest .raises (NotImplementedError , match = "Polygon geometry" ):
129
265
cfxr .cf_to_shapely (in_ds )
130
266
131
267
in_ds .geometry_container .attrs ["geometry_type" ] = "punkt"
132
268
with pytest .raises (ValueError , match = "Valid CF geometry types are " ):
133
269
cfxr .cf_to_shapely (in_ds )
134
270
271
+ in_ds , _ = geometry_line_ds
272
+ del in_ds .geometry_container .attrs ["node_count" ]
273
+ with pytest .raises (ValueError , match = "'node_count' must be provided" ):
274
+ cfxr .cf_to_shapely (in_ds )
275
+
135
276
136
277
@requires_shapely
137
278
def test_reshape_unique_geometries (geometry_ds ):
0 commit comments