pygml package¶
Submodules¶
pygml.axisorder module¶
- pygml.axisorder.get_crs_code(crs: str) Union[int, str] ¶
Extract the CRS code from the given CRS identifier string, which can be one of:
EPSG:<EPSG code>
http://www.opengis.net/def/crs/EPSG/0/<EPSG code>
http://www.opengis.net/gml/srs/epsg.xml#<EPSG code>
urn:EPSG:geographicCRS:<epsg code>
urn:ogc:def:crs:EPSG::<EPSG code>
urn:ogc:def:crs:OGC::<EPSG code>
urn:ogc:def:crs:EPSG:<EPSG code>
Returns the code as an integer in case of EPSG code or as the string
'CRS84'
.>>> get_crs_code('EPSG:4326') 4326 >>> get_crs_code('urn:ogc:def:crs:OGC::CRS84') 'CRS84' >>> get_crs_code('something') Traceback (most recent call last): ... ValueError: Failed to retrieve CRS code
pygml.basics module¶
- pygml.basics.parse_coordinates(value: str, cs: str = ',', ts: str = ' ', decimal: str = '.') List[Tuple[float, ...]] ¶
Parses the the values of a gml:coordinates node to a list of lists of floats. Takes the coordinate separator and tuple separator into account, and also custom decimal separators.
>>> parse_coordinates('12.34 56.7,89.10 11.12') [(12.34, 56.7), (89.1, 11.12)] >>> parse_coordinates('12.34 56.7;89.10 11.12', cs=';') [(12.34, 56.7), (89.1, 11.12)] >>> parse_coordinates('12.34:56.7,89.10:11.12', ts=':') [(12.34, 56.7), (89.1, 11.12)] >>> parse_coordinates('12.34:56.7;89.10:11.12', cs=';', ts=':') [(12.34, 56.7), (89.1, 11.12)] >>> parse_coordinates( ... '12,34:56,7;89,10:11,12', cs=';', ts=':', decimal=',' ... ) [(12.34, 56.7), (89.1, 11.12)]
- pygml.basics.parse_pos(value: str) Tuple[float, ...] ¶
Parses a single gml:pos to a Coordinate structure.
>>> parse_pos('12.34 56.7') (12.34, 56.7) >>> parse_pos('12.34 56.7 89.10') (12.34, 56.7, 89.1)
- pygml.basics.parse_poslist(value: str, dimensions: int = 2) List[Tuple[float, ...]] ¶
Parses the value of a single gml:posList to a Coordinates structure.
>>> parse_poslist('12.34 56.7 89.10 11.12') [(12.34, 56.7), (89.1, 11.12)] >>> parse_poslist('12.34 56.7 89.10 11.12 13.14 15.16', dimensions=3) [(12.34, 56.7, 89.1), (11.12, 13.14, 15.16)] >>> parse_poslist('12.34 56.7 89.10 11.12', dimensions=3) Traceback (most recent call last): ... ValueError: Invalid dimensionality of pos list
- pygml.basics.swap_coordinate_xy(coordinate: Tuple[float, ...]) Tuple[float, ...] ¶
Swaps the X and Y coordinates of a given coordinate
>>> swap_coordinate_xy((12.34, 56.7)) (56.7, 12.34) >>> swap_coordinate_xy((12.34, 56.7, 89.10)) (56.7, 12.34, 89.1)
- pygml.basics.swap_coordinates_xy(coordinates: List[Tuple[float, ...]]) List[Tuple[float, ...]] ¶
Swaps the X and Y coordinates of a given coordinates list
>>> swap_coordinates_xy( ... [(12.34, 56.7), (89.10, 11.12)] ... ) [(56.7, 12.34), (11.12, 89.1)] >>> swap_coordinates_xy( ... [(12.34, 56.7, 89.10), (11.12, 13.14, 15.16)] ... ) [(56.7, 12.34, 89.1), (13.14, 11.12, 15.16)]
pygml.dimensionality module¶
- pygml.dimensionality.get_dimensionality(geometry: pygml.types.GeomDict) Optional[int] ¶
Returns the dimensionality of a given GeoJSON geometry. This is obtained by descending into the first coordinate and using its length. When no coordinates can be retrieved (e.g: in case of GeometryCollections) None is returned.
>>> get_dimensionality({ ... 'type': 'Polygon', ... 'coordinates': [ ... [ ... (0.5, 1.0), ... (0.5, 2.0), ... (1.5, 2.0), ... (1.5, 1.0), ... (0.5, 1.0) ... ] ... ] ... }) 2 >>> get_dimensionality({ ... 'type': 'MultiPoint', ... 'coordinates': [ ... (1.0, 1.0, 1.0), ... (2.0, 2.0, 1.0), ... ] ... }) 3 >>> get_dimensionality({ ... 'type': 'GeometryCollection', ... 'geometries': [ ... { ... 'type': 'Point', ... 'coordinates': (1.0, 1.0) ... }, ... { ... 'type': 'Polygon', ... 'coordinates': [ ... [(1.0, 1.0)], ... [(1.0, 1.0)], ... ] ... }, ... ] ... })
pygml.georss module¶
- pygml.georss.encode_georss(geometry: pygml.types.GeomDict, gml_encoder: Callable[[pygml.types.GeomDict, str], lxml.etree._Element] = <function encode_pre_v32>) lxml.etree._Element ¶
Encodes a GeoJSON geometry as a GeoRSS
lxml.etree.Element
. Tries to use the native GeoRSS elementspoint
,line
, orpolygon
when possible. Falls back togeorss:where
with using thegml_encoder
function (defaulting to GML 3.2):MultiPoint, MultiLineString, MultiPolygon geometries
Polygons with interiors
GeometryCollections
any geometry with CRS other than CRS84 or EPSG:4326
when dealing with >2D geometries
- pygml.georss.parse_georss(element: lxml.etree._Element) pygml.types.GeomDict ¶
Parses the GeoRSS basic elements to their respective GeoJSON representation. As all coordinates in GeoRSS are expressed in WGS84 and in Latitude/Longitude order, the coordinates are swapped to XY order.
In case of georss:where, it is expected that it contains a single GML element which is parsed as either GML 3.1.1, GML 3.2 or GML 3.3 CE.
pygml.parse module¶
- pygml.parse.parse(source: Union[lxml.etree._Element, str]) pygml.types.Geometry ¶
pygml.pre_v32 module¶
- pygml.pre_v32.encode_pre_v32(geometry: pygml.types.GeomDict, identifier: Optional[str] = None) lxml.etree._Element ¶
Encodes the given GeoJSON dict to its most simple GML 3 representation.
In preparation of the encoding, the coordinates may have to be swapped from XY order to YX order, depending on the used CRS. This includes the case when no CRS is specified, as this means the default WGS84 in GeoJSON, which in turn uses latitude/longitude ordering GML.
This function returns an
lxml.etree._Element
which can be altered or serialized.>>> from pygml.pre_v32 import encode_pre_v32 >>> from lxml import etree >>> tree = encode_pre_v32({ ... 'type': 'Point', ... 'coordinates': (1.0, 1.0) ... }, 'ID') >>> print(etree.tostring(tree, pretty_print=True).decode()) <gml:Point xmlns:gml="http://www.opengis.net/gml" srsName="urn:ogc:def:crs:OGC::CRS84" gml:id="ID"> <gml:pos>1.0 1.0</gml:pos> </gml:Point>
- pygml.pre_v32.parse_pre_v32(element: lxml.etree._Element) pygml.types.GeomDict ¶
Main parsing function for GML 3.0 and 3.1 XML structures.
The following XML tags can be parsed to their respective GeoJSON counterpart:
gml:Point -> Point
gml:MultiPoint -> MultiPoint
gml:LineString -> LineString
gml:MultiCurve (with only gml:LineString curve members) -> MultiLineString
gml:MultiLineString -> MultiLineString
gml:Polygon -> Polygon
gml:MultiPolygon -> MultiPolygon
gml:MultiSurface (with only gml:Polygon surface members) -> MultiPolygon
gml:MultiGeometry (with any of the aforementioned types as geometry members) -> GeometryCollection
The SRS of the geometry is determined and the coordinates are flipped to XY order in GeoJSON when they are in YX order in GML.
- Returns:
the parsed GeoJSON geometry as a dict. Contains a ‘type’ field, a ‘coordinates’ field and potentially a ‘crs’ field when the geometries SRS could be determined. This field follows the structure laid out in the draft for GeoJSON.
pygml.types module¶
- class pygml.types.Geometry(geometry: pygml.types.GeomDict)¶
Bases:
object
Simple container class to hold a geometry and expose it via the
__geo_interface__
property- geometry: pygml.types.GeomDict¶
pygml.v32 module¶
- pygml.v32.encode_v32(geometry: pygml.types.GeomDict, identifier: str) lxml.etree._Element ¶
Encodes the given GeoJSON dict to its most simple GML 3.2 representation. As in GML 3.2 the gml:id attribute is mandatory, the identifier must be passed as well.
In preparation of the encoding, the coordinates may have to be swapped from XY order to YX order, depending on the used CRS. This includes the case when no CRS is specified, as this means the default WGS84 in GeoJSON, which in turn uses latitude/longitude ordering GML.
This function returns an
lxml.etree._Element
which can be altered or serialized.>>> from pygml.v32 import encode_v32 >>> from lxml import etree >>> tree = encode_v32({ ... 'type': 'Point', ... 'coordinates': (1.0, 1.0) ... }, 'ID') >>> print(etree.tostring(tree, pretty_print=True).decode()) <gml:Point xmlns:gml="http://www.opengis.net/gml/3.2" srsName="urn:ogc:def:crs:OGC::CRS84" gml:id="ID"> <gml:pos>1.0 1.0</gml:pos> </gml:Point>
- pygml.v32.parse_v32(element: lxml.etree._Element) pygml.types.GeomDict ¶
Main parsing function for GML 3.2 XML structures.
The following XML tags can be parsed to their respective GeoJSON counterpart:
gml:Point -> Point
gml:MultiPoint -> MultiPoint
gml:LineString -> LineString
gml:MultiCurve (with only gml:LineString curve members) -> MultiLineString
gml:Polygon -> Polygon
gml:MultiSurface (with only gml:Polygon surface members) -> MultiPolygon
gml:MultiGeometry (with any of the aforementioned types as geometry members) -> GeometryCollection
The SRS of the geometry is determined and the coordinates are flipped to XY order in GeoJSON when they are in YX order in GML.
- Returns:
the parsed GeoJSON geometry as a dict. Contains a ‘type’ field, a ‘coordinates’ field and potentially a ‘crs’ field when the geometries SRS could be determined. This field follows the structure laid out in the draft for GeoJSON.
pygml.v33 module¶
- class pygml.v33.GML33CEEncoder¶
Bases:
pygml.v3_common.GML3Encoder
- pygml.v33.encode_v33_ce(geometry: pygml.types.GeomDict, identifier: str) lxml.etree._Element ¶
Encodes the given GeoJSON dict to its most simple GML 3.3 CE representation, with a fallback to encoding it GML 3.2 when the compact encoding is not possible. As in GML 3.2 the gml:id attribute is mandatory, the identifier must be passed as well.
In preparation of the encoding, the coordinates may have to be swapped from XY order to YX order, depending on the used CRS. This includes the case when no CRS is specified, as this means the default WGS84 in GeoJSON, which in turn uses latitude/longitude ordering GML.
This function returns an
lxml.etree._Element
which can be altered or serialized.>>> from pygml.v33 import encode_v33_ce >>> from lxml import etree >>> tree = encode_v33_ce({ ... 'type': 'Polygon', ... 'coordinates': [ ... [ ... (1.0, 2.0), ... (1.0, 3.0), ... (2.0, 2.0), ... (1.0, 2.0), ... ], ... ], ... }, 'ID') >>> print(etree.tostring(tree, pretty_print=True).decode()) <gmlce:SimpleTriangle xmlns:gmlce="http://www.opengis.net/gml/3.3/ce" xmlns:gml="http://www.opengis.net/gml/3.2" srsName="urn:ogc:def:crs:OGC::CRS84" gml:id="ID"> <gml:posList>1.0 2.0 1.0 3.0 2.0 2.0</gml:posList> </gmlce:SimpleTriangle>
- pygml.v33.parse_simple_multi_point(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v33.parse_simple_polygon(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v33.parse_simple_triangle_or_rectangle(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v33.parse_v33_ce(element: lxml.etree._Element) pygml.types.GeomDict ¶
Main parsing function for GML 3.3 CE XML structures.
The following XML tags can be parsed to their respective GeoJSON counterpart:
gmlce:SimpleTriangle -> Polygon
gmlce:SimpleRectangel -> Polygon
gmlce:SimplePolygon -> Polygon
TODO: gmlce:SimpleMultiPoint -> MultiPoint
gml:Point -> Point
gml:MultiPoint -> MultiPoint
gml:LineString -> LineString
gml:MultiCurve (with only gml:LineString curve members) -> MultiLineString
gml:Polygon -> Polygon
gml:MultiSurface (with only gml:Polygon surface members) -> MultiPolygon
gml:MultiGeometry (with any of the aforementioned types as geometry members) -> GeometryCollection
The SRS of the geometry is determined and the coordinates are flipped to XY order in GeoJSON when they are in YX order in GML.
- Returns:
the parsed GeoJSON geometry as a dict. Contains a ‘type’ field, a ‘coordinates’ field and potentially a ‘crs’ field when the geometries SRS could be determined. This field follows the structure laid out in the draft for GeoJSON.
pygml.v3_common module¶
- class pygml.v3_common.GML3Encoder(namespace: str, nsmap: Dict[str, str], id_required: bool)¶
Bases:
object
- encode(geometry: pygml.types.GeomDict, identifier: Optional[str] = None) lxml.etree._Element ¶
- encode_multi_line_string(coordinates: List[Tuple[float, ...]], identifier: str, attrs: dict) lxml.etree._Element ¶
- encode_multi_point(coordinates: List[Tuple[float, ...]], identifier: str, attrs: dict) lxml.etree._Element ¶
- class pygml.v3_common.GML3Parser(namespaces: List[str], nsmap: Dict[str, str], handlers: Dict[str, Callable[[lxml.etree._Element, Dict[str, str]], Tuple[pygml.types.GeomDict, str]]])¶
Bases:
object
- parse(element: lxml.etree._Element) pygml.types.GeomDict ¶
- pygml.v3_common.maybe_swap_coordinates(geometry: pygml.types.GeomDict, srs: str) pygml.types.GeomDict ¶
- pygml.v3_common.parse_coord(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[float, ...] ¶
- pygml.v3_common.parse_envelope(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v3_common.parse_linestring_or_linear_ring(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v3_common.parse_multi_curve(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v3_common.parse_multi_geometry(element: lxml.etree._Element, nsmap: Dict[str, str], geometry_parser: Callable[[lxml.etree._Element], pygml.types.GeomDict]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v3_common.parse_multi_linestring(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v3_common.parse_multi_point(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v3_common.parse_multi_polygon(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v3_common.parse_multi_surface(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v3_common.parse_point(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
- pygml.v3_common.parse_polygon(element: lxml.etree._Element, nsmap: Dict[str, str]) Tuple[pygml.types.GeomDict, str] ¶
Module contents¶
- pygml.parse(source: Union[lxml.etree._Element, str]) pygml.types.Geometry ¶