Source code for karta.vector._geojson

import picogeojson
from .utilities import _as_nested_lists, _reproject_nested
from ..crs import LonLatWGS84

def crs_from_urn(urn):
    return {'type': 'name', 'properties': {'name': urn}}

def crs_from_karta(crs):
    if hasattr(crs, "jsonhref") and hasattr(crs, "jsontype"):
        return {'type': 'link', 'properties': {'href': crs.jsonname, 'type': crs.jsontype}}
    elif hasattr(crs, "jsonname"):
        return {'type': 'name', 'properties': {'name': crs.jsonname}}
    else:
        # NOTE: make sure CRS gets written to file by caller
        return {'type': 'link', 'properties': {'href': "", 'type': 'proj4'}}

[docs]class GeoJSONOutMixin(object): """ Mixin class to be added to geometry objects, adding geojson functionality. """ _serializer = picogeojson.Serializer(antimeridian_cutting=False, enforce_poly_winding=False) @staticmethod def _as_named_tuple(geom, **kwargs): """ Convert one or more Geometry instances to GeoJSON-structured named tuples. Parameters ---------- *geoms : subtypes of karta.Geometry karta vector geometries to convert urn : str, optional URN defining a specific CRS to use Returns ------- Either a Feature or a FeatureCollection Raises ------ TypeError if one or more of geoms has an unrecognized `_geotype` attribute """ if kwargs.get("urn", None) is not None: crs = crs_from_urn(kwargs["urn"]) else: crs = crs_from_karta(geoms[0].crs) if geom._geotype == "Point": g = picogeojson.Point(geom.vertex, crs) elif geom._geotype == "Line": g = picogeojson.LineString(_as_nested_lists(geom.vertices), crs) elif geom._geotype == "Polygon": verts = [_as_nested_lists(geom.vertices_ring)] for sub in geom.subs: verts.append(_as_nested_lists(sub.vertices)) g = picogeojson.Polygon(verts, crs) elif geom._geotype == "Multipoint": g = picogeojson.MultiPoint(_as_nested_lists(geom.vertices), crs) elif geom._geotype == "Multiline": g = picogeojson.MultiLineString(_as_nested_lists(geom.vertices), crs) elif geom._geotype == "Multipolygon": g = picogeojson.MultiPolygon(_as_nested_lists(geom.vertices_ring), crs) else: raise TypeError("unhandled type: {0}".format(type(geom))) data = {} if hasattr(geom, "data"): for field in geom.data.fields: data[field] = geom.d[field] properties = geom.properties properties.update(data) return picogeojson.Feature(g, properties)
[docs] def as_geojson(self, indent=None, urn=None, force_wgs84=True): """ Output representation of internal data as a GeoJSON string. Parameters ---------- indent : int, optional indentation of generated GeoJSON (default 2) force_wgs84 : bool, optional Forces output to use geographical coordinates with the WGS84 datum, as recommended by the GeoJSON draft specification (https://datatracker.ietf.org/doc/draft-ietf-geojson/). If *urn* is not set, "urn:ogc:def:crs:OGC:1.3:CRS84" is used. (default True) urn : str, optional overrides GeoJSON CRS with provided URN string """ if force_wgs84 and (urn is None): urn = "urn:ogc:def:crs:OGC:1.3:CRS84" if force_wgs84 and (self.crs != LonLatWGS84): kw = dict(properties=self.properties, crs=LonLatWGS84) if hasattr(self, "data"): kw["data"] = self.data if hasattr(self, "vertices"): vertices = _reproject_nested(self.vertices, self.crs, LonLatWGS84) else: vertices = _reproject(self.vertex, self.crs, LonLatWGS84) geo = type(self)(vertices, **kw) else: geo = self return self._serializer(self._as_named_tuple(geo, urn=urn), indent=indent)
[docs] def to_geojson(self, f, indent=None, urn=None, force_wgs84=True): """ Write data as a GeoJSON string to a file-like object `f`. Parameters ---------- f : str or file-like object file to receive GeoJSON string indent : int, optional indentation of generated GeoJSON (default None) force_wgs84 : bool, optional Forces output to use geographical coordinates with the WGS84 datum, as recommended by the GeoJSON draft specification (https://datatracker.ietf.org/doc/draft-ietf-geojson/). If *urn* is not set, "urn:ogc:def:crs:OGC:1.3:CRS84" is used. (default True) urn : str, optional overrides GeoJSON CRS with provided URN string """ try: if not hasattr(f, "write"): fobj = open(f, "w") else: fobj = f fobj.write(self.as_geojson(indent=indent, urn=urn, force_wgs84=force_wgs84)) finally: if not hasattr(f, "write"): fobj.close() return