Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

31634: Fix pylint errors for azure-maps-search #34998

Merged
merged 1 commit into from
Mar 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 129 additions & 13 deletions sdk/maps/azure-maps-search/azure/maps/search/_shared/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,30 @@ def _reformat_coordinates(
style: str
) -> Union[list, tuple]:
"""
Converts tuples, tuples of tuples, lists of tuples, etc. into lists and
lists of lists, etc. and preserves points/coordinate pairs as lists or
tuples depending on the desired style.
**Reformat Coordinates**

Converts and reformats coordinate data structures between lists and tuples to ensure compatibility
with either GeoJSON or geo_interface specifications. This function can handle nested structures
like lists of lists or tuples of tuples, commonly used in geographical data representations.

:param item:
The coordinate data to be reformatted. This can be a single coordinate pair (e.g., `[longitude, latitude]`),
a list of coordinate pairs (e.g., `[[lng1, lat1], [lng2, lat2], ...]`), or a nested structure of these pairs.
:type item:
Union[list, tuple]
:param style:
The desired output format of the coordinates. Use 'geojson' to convert all coordinate pairs to lists,
or 'geo_interface' to convert them to tuples.
:type style:
str

:return:
The reformatted coordinate data structured as per the specified `style`.
:rtype:
Union[list, tuple]

:raises ValueError:
If `style` is not 'geojson' or 'geo_interface', indicating an unknown formatting style.
"""
if type(item) in {tuple, list} and type(item[0]) in {tuple, list}:
return [_reformat_coordinates(x, style) for x in item]
Expand All @@ -44,13 +65,61 @@ def _reformat_coordinates(
raise ValueError('Unknown style')

def geo_interface_to_geojson(geo_interface: dict) -> dict:
"""Converts a geo_interface dictionary into a raw GeoJSON dictionary."""
"""
**Geo Interface to GeoJSON Conversion**

Transforms a dictionary representing a geographic object in geo_interface format to a GeoJSON
format dictionary. This conversion ensures the structure of the coordinates is compliant with
the GeoJSON specification.

:param geo_interface:
A dictionary that represents a geographical feature, adhering to the geo_interface format.
It must include at least 'type' and 'coordinates' keys. For example, a simple point may be
represented as `{"type": "Point", "coordinates": (x, y)}`, and more complex structures are
supported for types like `Polygon` or `MultiPoint`.
:type geo_interface:
dict

:return:
A dictionary formatted according to the GeoJSON specification, representing the same geographical
feature as the input. This dictionary will include 'type' and 'coordinates' keys at a minimum,
with additional keys as required by the specific geographical feature type.
:rtype:
dict

:raises ValueError:
If `geo_interface` does not contain the required keys or if the coordinates cannot be
successfully reformatted to the GeoJSON format.
"""
coords = _reformat_coordinates(geo_interface['coordinates'], 'geojson')

return {'type': geo_interface['type'], 'coordinates': coords}

def wkt_to_geo_interface(wkt: str) -> dict:
"""Converts a WKT string to a geo_interface dictionary."""
"""
**WKT to Geo Interface Conversion**

Translates a Well-Known Text (WKT) representation of geographic geometries into a dictionary
compliant with the geo_interface specification. It supports various geometry types like Point,
LineString, and Polygon among others.

:param wkt:
The Well-Known Text (WKT) representation of the geometry to be converted. WKT is a text
markup language for representing vector geometry objects on a map.
:type wkt:
str

:return:
A dictionary formatted according to the geo_interface specification, containing 'type' and
'coordinates' keys, where 'type' is the geometry type and 'coordinates' is a tuple (or nested
tuples) representing the geometry's coordinates.
:rtype:
dict

:raises ValueError:
If the `wkt` string cannot be parsed into a valid geo_interface dictionary, indicating that
the string is not in a proper WKT format or is unsupported.
"""
try:
wkt_type, coords = re.split(r'(?<=[A-Z])\s', wkt)

Expand Down Expand Up @@ -80,17 +149,64 @@ def wkt_to_geo_interface(wkt: str) -> dict:
elif geo_type == 'MultiPolygon' and type(coords[0][0][0]) in numbers:
coords = [coords] # type: ignore

except Exception:
raise ValueError('{} is not a WKT string'.format(wkt))
except Exception as ex:
raise ValueError('{} is not a WKT string'.format(wkt)) from ex

return {'type': geo_type, 'coordinates': coords}

def wkt_to_geojson(wkt: str) -> str:
"""Converts a WKT string to GeoJSON."""
"""
**WKT to GeoJSON Conversion**

Transforms a Well-Known Text (WKT) string into its corresponding GeoJSON string representation.
This function leverages the geo_interface format as an intermediate step to ensure accurate
translation from WKT to GeoJSON.

:param wkt:
The Well-Known Text (WKT) representation of the geometry to be converted. WKT is a standard
text notation for representing vector geometry objects.
:type wkt:
str

:return:
A string formatted in GeoJSON representing the same geometric object as defined in the input WKT.
:rtype:
str

:raises ValueError:
If the `wkt` string cannot be converted into GeoJSON, indicating that the WKT string is not in
a valid format or represents a geometry type that is not supported.
"""
return geo_interface_to_geojson(wkt_to_geo_interface(wkt))

def parse_geometry_input(geo_thing: Union[str, dict]) -> dict:
"""Checks to see if the string is geojson or WKT or geo_interface property"""
"""
**Parse Geometry Input**

Interprets various input formats and standardizes them into a GeoJSON dictionary. This function
can handle GeoJSON strings, Well-Known Text (WKT) strings, GeoJSON-like dictionaries, and objects
that implement the `__geo_interface__` protocol.

:param geo_thing:
The geometry input to parse, which can be one of the following:
- A GeoJSON string.
- A WKT string.
- A dictionary with 'type' and 'coordinates' keys that follows the GeoJSON structure.
- An object that has a `__geo_interface__` property representing the geometry.
:type geo_thing:
Union[str, dict]

:return:
A dictionary with a 'geometry' key containing the standardized geometry in GeoJSON format.
:rtype:
dict

:raises ValueError:
If the string input is not a valid GeoJSON or WKT representation, or if a dictionary input
does not conform to the GeoJSON structure.
:raises AttributeError:
If the input is an object lacking a `__geo_interface__` property.
"""
error_msg = 'Strings must be valid GeoJSON or WKT or geo_interface property'
geometry={}
# Input might be WKT
Expand All @@ -107,15 +223,15 @@ def parse_geometry_input(geo_thing: Union[str, dict]) -> dict:
# or assume it is a valid Geo Json obejct
else:
geom = geo_thing
except ValueError:
raise ValueError(error_msg)
except ValueError as ex:
raise ValueError(error_msg) from ex
else:
# Input might be an object with a geo_interface
try:
geo_interface = geo_thing.__geo_interface__
geom = geo_interface_to_geojson(geo_interface)
except AttributeError:
raise AttributeError('Object has no geo_interface.')
except AttributeError as ex:
raise AttributeError('Object has no geo_interface.') from ex

geometry['geometry'] = geom
return geometry
Loading