1
1
"""pydantic models for GeoJSON Geometry objects."""
2
- from __future__ import annotations
3
-
4
2
import abc
5
3
from typing import Any , Dict , Iterator , List , Literal , Protocol , Union
6
4
@@ -80,6 +78,8 @@ class _GeometryBase(BaseModel, abc.ABC):
80
78
type : str
81
79
coordinates : Any
82
80
81
+ __wkt_coordinates__ : _WktCallable
82
+
83
83
@property
84
84
def __geo_interface__ (self ) -> Dict [str , Any ]:
85
85
"""GeoJSON-like protocol for geo-spatial (GIS) vector data.
@@ -94,27 +94,17 @@ def has_z(self) -> bool:
94
94
"""Checks if any coordinate has a Z value."""
95
95
...
96
96
97
- @property
98
- @abc .abstractmethod
99
- def _wkt_coordinates (self ) -> _WktCallable :
100
- ...
101
-
102
- @property
103
- def _wkt_type (self ) -> str :
104
- """Return the WKT name of the geometry."""
105
- return self .type .upper ()
106
-
107
97
@property
108
98
def wkt (self ) -> str :
109
99
"""Return the Well Known Text representation."""
110
100
# Start with the WKT Type
111
- wkt = self ._wkt_type
101
+ wkt = self .type . upper ()
112
102
has_z = self .has_z
113
103
if self .coordinates :
114
104
# If any of the coordinates have a Z add a "Z" to the WKT
115
105
wkt += " Z " if has_z else " "
116
106
# Add the rest of the WKT inside parentheses
117
- wkt += f"({ self ._wkt_coordinates (self .coordinates , force_z = has_z )} )"
107
+ wkt += f"({ self .__wkt_coordinates__ (self .coordinates , force_z = has_z )} )"
118
108
else :
119
109
# Otherwise it will be "EMPTY"
120
110
wkt += " EMPTY"
@@ -128,63 +118,55 @@ class Point(_GeometryBase):
128
118
type : Literal ["Point" ]
129
119
coordinates : Position
130
120
121
+ __wkt_coordinates__ = staticmethod (_position_wkt_coordinates )
122
+
131
123
@property
132
124
def has_z (self ) -> bool :
133
125
"""Checks if any coordinate has a Z value."""
134
126
return _position_has_z (self .coordinates )
135
127
136
- @property
137
- def _wkt_coordinates (self ) -> _WktCallable :
138
- return _position_wkt_coordinates
139
-
140
128
141
129
class MultiPoint (_GeometryBase ):
142
130
"""MultiPoint Model"""
143
131
144
132
type : Literal ["MultiPoint" ]
145
133
coordinates : MultiPointCoords
146
134
135
+ __wkt_coordinates__ = staticmethod (_position_list_wkt_coordinates )
136
+
147
137
@property
148
138
def has_z (self ) -> bool :
149
139
"""Checks if any coordinate has a Z value."""
150
140
return _position_list_has_z (self .coordinates )
151
141
152
- @property
153
- def _wkt_coordinates (self ) -> _WktCallable :
154
- return _position_list_wkt_coordinates
155
-
156
142
157
143
class LineString (_GeometryBase ):
158
144
"""LineString Model"""
159
145
160
146
type : Literal ["LineString" ]
161
147
coordinates : LineStringCoords
162
148
149
+ __wkt_coordinates__ = staticmethod (_position_list_wkt_coordinates )
150
+
163
151
@property
164
152
def has_z (self ) -> bool :
165
153
"""Checks if any coordinate has a Z value."""
166
154
return _position_list_has_z (self .coordinates )
167
155
168
- @property
169
- def _wkt_coordinates (self ) -> _WktCallable :
170
- return _position_list_wkt_coordinates
171
-
172
156
173
157
class MultiLineString (_GeometryBase ):
174
158
"""MultiLineString Model"""
175
159
176
160
type : Literal ["MultiLineString" ]
177
161
coordinates : MultiLineStringCoords
178
162
163
+ __wkt_coordinates__ = staticmethod (_lines_wtk_coordinates )
164
+
179
165
@property
180
166
def has_z (self ) -> bool :
181
167
"""Checks if any coordinate has a Z value."""
182
168
return _lines_has_z (self .coordinates )
183
169
184
- @property
185
- def _wkt_coordinates (self ) -> _WktCallable :
186
- return _lines_wtk_coordinates
187
-
188
170
189
171
class LinearRingGeom (LineString ):
190
172
"""LinearRing model."""
@@ -204,6 +186,8 @@ class Polygon(_GeometryBase):
204
186
type : Literal ["Polygon" ]
205
187
coordinates : PolygonCoords
206
188
189
+ __wkt_coordinates__ = staticmethod (_lines_wtk_coordinates )
190
+
207
191
@validator ("coordinates" )
208
192
def check_closure (cls , coordinates : List ) -> List :
209
193
"""Validate that Polygon is closed (first and last coordinate are the same)."""
@@ -229,10 +213,6 @@ def has_z(self) -> bool:
229
213
"""Checks if any coordinates have a Z value."""
230
214
return _lines_has_z (self .coordinates )
231
215
232
- @property
233
- def _wkt_coordinates (self ) -> _WktCallable :
234
- return _lines_wtk_coordinates
235
-
236
216
@classmethod
237
217
def from_bounds (
238
218
cls , xmin : float , ymin : float , xmax : float , ymax : float
@@ -252,15 +232,13 @@ class MultiPolygon(_GeometryBase):
252
232
type : Literal ["MultiPolygon" ]
253
233
coordinates : MultiPolygonCoords
254
234
235
+ __wkt_coordinates__ = staticmethod (_polygons_wkt_coordinates )
236
+
255
237
@property
256
238
def has_z (self ) -> bool :
257
239
"""Checks if any coordinates have a Z value."""
258
240
return any (_lines_has_z (polygon ) for polygon in self .coordinates )
259
241
260
- @property
261
- def _wkt_coordinates (self ) -> _WktCallable :
262
- return _polygons_wkt_coordinates
263
-
264
242
@validator ("coordinates" )
265
243
def check_closure (cls , coordinates : List ) -> List :
266
244
"""Validate that Polygon is closed (first and last coordinate are the same)."""
@@ -294,11 +272,6 @@ def __getitem__(self, index: int) -> Geometry:
294
272
"""get geometry at a given index"""
295
273
return self .geometries [index ]
296
274
297
- @property
298
- def _wkt_type (self ) -> str :
299
- """Return the WKT name of the geometry."""
300
- return self .type .upper ()
301
-
302
275
@property
303
276
def wkt (self ) -> str :
304
277
"""Return the Well Known Text representation."""
@@ -307,7 +280,7 @@ def wkt(self) -> str:
307
280
if self .geometries
308
281
else "EMPTY"
309
282
)
310
- return f"{ self ._wkt_type } { coordinates } "
283
+ return f"{ self .type . upper () } { coordinates } "
311
284
312
285
@property
313
286
def __geo_interface__ (self ) -> Dict [str , Any ]:
0 commit comments