Python Geo Interface
Specified here is a simple interface, when provided, allows objects to be easily adapted for use with GeoJSON, or Shapely. It is inspired by the Numpy Array Interface, and aims to play a similar role in GIS or geospatial programming. The Geo Interface has 3 levels: feature collections, features, and geometries.
The Python geo interface tracks the geojson.org GeoJSON draft specification.
Feature Collection
A feature collection maps 1 item:
features: a sequence of objects that provide the next (feature) level of the interface.
Feature
A feature object maps 3 items:
id: a unique string identifier.
properties: a mapping of feature properties.
geometry: an object that provides the next (geometry) level of the interface.
Geometry
A geometry object maps 2 items:
type: 'Point', 'LineString', 'Polygon', (multi-types not yet under consideration).
coordinates: a sequence of float values in x, y, (and maybe z) order, or a sequence of such (see http://wiki.geojson.org/GeoJSON_draft_version_2#Geometries).
Coordinate Systems
Version 1.0 does not consider coordinate systems. In the absence of any other information from the source, one should assume WGS 1984 with x=longitude, and y=latitude.
The Simplest Possible Example
Here is the simplest example of all 3 levels of the interface
# feature collection { 'type': 'FeatureCollection', 'features': [ # feature { 'type': 'Feature', 'id': '1', 'properties': {'title': 'Member One'}, 'geometry': { # geometry 'type': 'Point', 'coordinates': (-106.0, 40.0) } } ] }
What the Geo Interface does is allow geometries to be adapted for use with Shapely
>>> shapely_geom = shapely.geometry.asShape(data['members'][0]['geometry'])
Providing the Interface
A Python object may provide the interface directly (as a dict), or expose an attribute named {{geo_interface}} that directly provides the interface. The latter is inspired by the Numpy array interface. For example:
class Point(object): def __init__(self, x, y): self.x = x self.y = y @property def __geo_interface__(self): return {'type': 'Point', 'coordinates': (self.x, self.y)}
class Feature(object): def __init__(self, id, title, geom={}): """The geom *must* provide the geometry geo interface.""" self.id = id self.title = title self.geom = geom @property def __geo_interface__(self): return {'type': 'Feature', 'id': self.id, 'properties': {'title': self.title}, 'geometry': self.geom}
class Collection(object): def __init__(self, features=[]): """The features *must* provide the geometry geo interface.""" self.features = features @property def __geo_interface__(self): return {'type': 'FeatureCollection', 'features': self.features}
or directly subclass the built-in 'list' type:
class Collection(list): @property def __geo_interface__(self): return {'type': 'FeatureCollection', 'features': self}
