Source code for adhocracy_core.sheets.geo

"""Sheets related to geographical information."""
from enum import Enum

from colander import Float
from colander import drop
from colander import Range
from colander import OneOf

from adhocracy_core.interfaces import ISheet
from adhocracy_core.interfaces import SheetToSheet
from adhocracy_core.sheets import add_sheet_to_registry
from adhocracy_core.sheets import sheet_meta
from adhocracy_core.schema import Reference
from adhocracy_core.schema import SingleLine
from adhocracy_core.schema import MappingSchema
from adhocracy_core.schema import SequenceSchema
from adhocracy_core.schema import SequenceOptionalJsonInSchema
from adhocracy_core.schema import TupleSchema
from adhocracy_core.schema import get_choices_by_interface


[docs]class WebMercatorLongitude(MappingSchema): """A a web mercator longitude value. Validation values taken from http://epsg.io/3857. """ schema_type = Float default = 0 missing = drop validator = Range(min=-20026376.3, max=20026376.3)
[docs]class WebMercatorLatitude(MappingSchema): """A a web mercator latitude value. Validation values taken from http://epsg.io/3857. """ schema_type = Float default = 0 missing = drop validator = Range(min=-20048966.10, max=20048966.10)
[docs]class Point(TupleSchema): """A geographical point on the earth. `x`: longitude in web mercator `y`: latitude in web mercator """ default = (0, 0) missing = drop x = WebMercatorLongitude() y = WebMercatorLatitude()
[docs]class LineString(SequenceOptionalJsonInSchema): """List of geographical points on the earth.""" missing = [] point = Point()
[docs]class Polygon(SequenceSchema): """List of geographical lines on the earth.""" missing = [] line = LineString()
[docs]class MultiPolygon(SequenceSchema): """List of geographical polygons on the earth.""" missing = [] polygon = Polygon()
[docs]class IMultiPolygon(ISheet): """Market interface for the multi polygon sheet."""
[docs]class PartOfReference(SheetToSheet): """Reference to a geographical object.""" source_isheet = IMultiPolygon source_isheet_field = 'part_of' target_isheet = IMultiPolygon
[docs]class GermanAdministrativeDivisions(Enum): """Administrative division names/levels based on the wikidata ontology.""" staat = 2 bundesland = 4 regierungsbezirk = 5 kreis = 6 landkreis = 6 gemeinde = 8 stadt = 8 stadtbezirk = 9 ortsteil = 10 bezirksregion = 10 """Custom definition. Is part of stadtbezirk but not part of ortsteil."""
[docs]class AdministrativeDivisionName(SingleLine): """Administrative division, see :class`GermanAdministrativeDivisions`."""
[docs] def validator(self, node, cstruct): """Validator.""" division_names = GermanAdministrativeDivisions.__members__.keys() return OneOf(division_names)(node, cstruct)
[docs]class MultiPolygonSchema(MappingSchema): """A geographical MultiPolygon object. GeoJSON like geometry object fields: `type`: 'MultiPolygon' (geometry object type) `coordinates`: list of list of list of points with (longitude, latitude). Metadata property fields: `administrative_level`: administrative division level `administrative_division`: administrative division name `part_of`: surrounding geographical object """ type = SingleLine(default='MultiPolygon', readonly=True) coordinates = MultiPolygon() administrative_division = AdministrativeDivisionName() part_of = Reference(reftype=PartOfReference)
multipolygon_meta = sheet_meta._replace(isheet=IMultiPolygon, schema_class=MultiPolygonSchema, editable=False, create_mandatory=True, )
[docs]class ILocationReference(ISheet): """Marker interface for the location reference sheet."""
[docs]class LocationReference(SheetToSheet): """Reference to a geographical object.""" source_isheet = ILocationReference source_isheet_field = 'location' target_isheet = IMultiPolygon
[docs]def get_location_choices(context, request) -> []: """Return location resources choices.""" return get_choices_by_interface(IMultiPolygon, context, request)
[docs]class LocationReferenceSchema(MappingSchema): """Data structure for the location reference sheet.""" location = Reference(reftype=LocationReference, choices_getter=get_location_choices)
location_reference_meta = sheet_meta._replace( isheet=ILocationReference, schema_class=LocationReferenceSchema, )
[docs]class IPoint(ISheet): """Market interface for the point sheet."""
[docs]class PointSchema(MappingSchema): """A geographical Point object. GeoJSON like geometry object fields: `type`: 'Point' (geometry object type) `coordinates`: tuple of points with (longitude, latitude). """ type = SingleLine(default='Point', readonly=True) coordinates = Point()
point_meta = sheet_meta._replace(isheet=IPoint, schema_class=PointSchema, editable=True, create_mandatory=False, )
[docs]def includeme(config): """Register sheets.""" add_sheet_to_registry(point_meta, config.registry) add_sheet_to_registry(multipolygon_meta, config.registry) add_sheet_to_registry(location_reference_meta, config.registry)