@@ -31,9 +31,30 @@ def _reformat_coordinates(
31
31
style : str
32
32
) -> Union [list , tuple ]:
33
33
"""
34
- Converts tuples, tuples of tuples, lists of tuples, etc. into lists and
35
- lists of lists, etc. and preserves points/coordinate pairs as lists or
36
- tuples depending on the desired style.
34
+ **Reformat Coordinates**
35
+
36
+ Converts and reformats coordinate data structures between lists and tuples to ensure compatibility
37
+ with either GeoJSON or geo_interface specifications. This function can handle nested structures
38
+ like lists of lists or tuples of tuples, commonly used in geographical data representations.
39
+
40
+ :param item:
41
+ The coordinate data to be reformatted. This can be a single coordinate pair (e.g., `[longitude, latitude]`),
42
+ a list of coordinate pairs (e.g., `[[lng1, lat1], [lng2, lat2], ...]`), or a nested structure of these pairs.
43
+ :type item:
44
+ Union[list, tuple]
45
+ :param style:
46
+ The desired output format of the coordinates. Use 'geojson' to convert all coordinate pairs to lists,
47
+ or 'geo_interface' to convert them to tuples.
48
+ :type style:
49
+ str
50
+
51
+ :return:
52
+ The reformatted coordinate data structured as per the specified `style`.
53
+ :rtype:
54
+ Union[list, tuple]
55
+
56
+ :raises ValueError:
57
+ If `style` is not 'geojson' or 'geo_interface', indicating an unknown formatting style.
37
58
"""
38
59
if type (item ) in {tuple , list } and type (item [0 ]) in {tuple , list }:
39
60
return [_reformat_coordinates (x , style ) for x in item ]
@@ -44,13 +65,61 @@ def _reformat_coordinates(
44
65
raise ValueError ('Unknown style' )
45
66
46
67
def geo_interface_to_geojson (geo_interface : dict ) -> dict :
47
- """Converts a geo_interface dictionary into a raw GeoJSON dictionary."""
68
+ """
69
+ **Geo Interface to GeoJSON Conversion**
70
+
71
+ Transforms a dictionary representing a geographic object in geo_interface format to a GeoJSON
72
+ format dictionary. This conversion ensures the structure of the coordinates is compliant with
73
+ the GeoJSON specification.
74
+
75
+ :param geo_interface:
76
+ A dictionary that represents a geographical feature, adhering to the geo_interface format.
77
+ It must include at least 'type' and 'coordinates' keys. For example, a simple point may be
78
+ represented as `{"type": "Point", "coordinates": (x, y)}`, and more complex structures are
79
+ supported for types like `Polygon` or `MultiPoint`.
80
+ :type geo_interface:
81
+ dict
82
+
83
+ :return:
84
+ A dictionary formatted according to the GeoJSON specification, representing the same geographical
85
+ feature as the input. This dictionary will include 'type' and 'coordinates' keys at a minimum,
86
+ with additional keys as required by the specific geographical feature type.
87
+ :rtype:
88
+ dict
89
+
90
+ :raises ValueError:
91
+ If `geo_interface` does not contain the required keys or if the coordinates cannot be
92
+ successfully reformatted to the GeoJSON format.
93
+ """
48
94
coords = _reformat_coordinates (geo_interface ['coordinates' ], 'geojson' )
49
95
50
96
return {'type' : geo_interface ['type' ], 'coordinates' : coords }
51
97
52
98
def wkt_to_geo_interface (wkt : str ) -> dict :
53
- """Converts a WKT string to a geo_interface dictionary."""
99
+ """
100
+ **WKT to Geo Interface Conversion**
101
+
102
+ Translates a Well-Known Text (WKT) representation of geographic geometries into a dictionary
103
+ compliant with the geo_interface specification. It supports various geometry types like Point,
104
+ LineString, and Polygon among others.
105
+
106
+ :param wkt:
107
+ The Well-Known Text (WKT) representation of the geometry to be converted. WKT is a text
108
+ markup language for representing vector geometry objects on a map.
109
+ :type wkt:
110
+ str
111
+
112
+ :return:
113
+ A dictionary formatted according to the geo_interface specification, containing 'type' and
114
+ 'coordinates' keys, where 'type' is the geometry type and 'coordinates' is a tuple (or nested
115
+ tuples) representing the geometry's coordinates.
116
+ :rtype:
117
+ dict
118
+
119
+ :raises ValueError:
120
+ If the `wkt` string cannot be parsed into a valid geo_interface dictionary, indicating that
121
+ the string is not in a proper WKT format or is unsupported.
122
+ """
54
123
try :
55
124
wkt_type , coords = re .split (r'(?<=[A-Z])\s' , wkt )
56
125
@@ -80,17 +149,64 @@ def wkt_to_geo_interface(wkt: str) -> dict:
80
149
elif geo_type == 'MultiPolygon' and type (coords [0 ][0 ][0 ]) in numbers :
81
150
coords = [coords ] # type: ignore
82
151
83
- except Exception :
84
- raise ValueError ('{} is not a WKT string' .format (wkt ))
152
+ except Exception as ex :
153
+ raise ValueError ('{} is not a WKT string' .format (wkt )) from ex
85
154
86
155
return {'type' : geo_type , 'coordinates' : coords }
87
156
88
157
def wkt_to_geojson (wkt : str ) -> str :
89
- """Converts a WKT string to GeoJSON."""
158
+ """
159
+ **WKT to GeoJSON Conversion**
160
+
161
+ Transforms a Well-Known Text (WKT) string into its corresponding GeoJSON string representation.
162
+ This function leverages the geo_interface format as an intermediate step to ensure accurate
163
+ translation from WKT to GeoJSON.
164
+
165
+ :param wkt:
166
+ The Well-Known Text (WKT) representation of the geometry to be converted. WKT is a standard
167
+ text notation for representing vector geometry objects.
168
+ :type wkt:
169
+ str
170
+
171
+ :return:
172
+ A string formatted in GeoJSON representing the same geometric object as defined in the input WKT.
173
+ :rtype:
174
+ str
175
+
176
+ :raises ValueError:
177
+ If the `wkt` string cannot be converted into GeoJSON, indicating that the WKT string is not in
178
+ a valid format or represents a geometry type that is not supported.
179
+ """
90
180
return geo_interface_to_geojson (wkt_to_geo_interface (wkt ))
91
181
92
182
def parse_geometry_input (geo_thing : Union [str , dict ]) -> dict :
93
- """Checks to see if the string is geojson or WKT or geo_interface property"""
183
+ """
184
+ **Parse Geometry Input**
185
+
186
+ Interprets various input formats and standardizes them into a GeoJSON dictionary. This function
187
+ can handle GeoJSON strings, Well-Known Text (WKT) strings, GeoJSON-like dictionaries, and objects
188
+ that implement the `__geo_interface__` protocol.
189
+
190
+ :param geo_thing:
191
+ The geometry input to parse, which can be one of the following:
192
+ - A GeoJSON string.
193
+ - A WKT string.
194
+ - A dictionary with 'type' and 'coordinates' keys that follows the GeoJSON structure.
195
+ - An object that has a `__geo_interface__` property representing the geometry.
196
+ :type geo_thing:
197
+ Union[str, dict]
198
+
199
+ :return:
200
+ A dictionary with a 'geometry' key containing the standardized geometry in GeoJSON format.
201
+ :rtype:
202
+ dict
203
+
204
+ :raises ValueError:
205
+ If the string input is not a valid GeoJSON or WKT representation, or if a dictionary input
206
+ does not conform to the GeoJSON structure.
207
+ :raises AttributeError:
208
+ If the input is an object lacking a `__geo_interface__` property.
209
+ """
94
210
error_msg = 'Strings must be valid GeoJSON or WKT or geo_interface property'
95
211
geometry = {}
96
212
# Input might be WKT
@@ -107,15 +223,15 @@ def parse_geometry_input(geo_thing: Union[str, dict]) -> dict:
107
223
# or assume it is a valid Geo Json obejct
108
224
else :
109
225
geom = geo_thing
110
- except ValueError :
111
- raise ValueError (error_msg )
226
+ except ValueError as ex :
227
+ raise ValueError (error_msg ) from ex
112
228
else :
113
229
# Input might be an object with a geo_interface
114
230
try :
115
231
geo_interface = geo_thing .__geo_interface__
116
232
geom = geo_interface_to_geojson (geo_interface )
117
- except AttributeError :
118
- raise AttributeError ('Object has no geo_interface.' )
233
+ except AttributeError as ex :
234
+ raise AttributeError ('Object has no geo_interface.' ) from ex
119
235
120
236
geometry ['geometry' ] = geom
121
237
return geometry
0 commit comments