Concepts ======== In Shelley a map is created by drawing geometries with visual styles, for example a line or polygon with a particular width or a certain colour. Geometries ---------- The geometries are provided by features. A feature has a dictionary of properties and a geometry. The geometry has a type and coordinates. .. doctest:: :hide: >>> from shelley.datasources.simple import Feature, Geometry, FeatureSource >>> feature = Feature( ... geometry=Geometry(type='LineString', coordinates=[[20, 32.5], [43, 134]]), ... properties={'road': 'motorway'} ... ) .. doctest:: >>> feature.properties['road'] 'motorway' >>> feature.geometry.type 'LineString' >>> feature.geometry.coordinates [[20, 32.5], [43, 134]] A sequence of features is supplied by a FeatureSource. .. doctest:: :hide: >>> data_source = FeatureSource(features=[feature]) .. doctest:: >>> features = data_source.features() Styles ------ Styling is defined by symbolizers, which draw the geometries provided by features. >>> from shelley import symbolizers >>> symbolizer = symbolizers.LineSymbolizer(color='red', width=5) Map definitions --------------- Shelley allows alternative "mappers" for defining a map. Mapnik Maps ^^^^^^^^^^^ One such mapper is based on the abstractions provided by the Mapnik map rendering library. >>> from shelley.mappers import mapnik Rules conditionally draw a list of symbolizers in order and can filter the features by their properties or only draws when the scale of the map falls within a particular range. .. doctest:: >>> rule = mapnik.Rule([symbolizer], filter=mapnik.Filter("[road] = 'motorway'"), max_scale_denom=500) Styles collect rules together with a name. The rules are applied in order. >>> style = mapnik.Style('MyRoadStyle', rules=[rule]) Layers bring styles and geometries together. The styles are applied to each feature yielded from a datasource in the order of the styles list. >>> layer = mapnik.Layer(name='roads', data_source=data_source, styles=[style]) A map has a list of layers. The layers are drawn in order. >>> map = mapnik.Map(layers=[layer]) Views ------ Common to all map mappers is the concept of the view we wish to draw. A view of a map is defined by the area of the map to draw and an optional target spatial reference to transform to. If no spatial reference is defined then it is assumed the source geometries are all in the correct spatial reference already. >>> import shelley >>> view = shelley.Box(min_x=10, min_y=-10, max_x=145, max_y=80) The view of the map can then rendered to a particular format by a renderer. .. doctest:: :hide: >>> import doc_utils >>> path = doc_utils.scratch_path('road_map.png') >>> from shelley.renderers import cairorender >>> format = cairorender.Image(width=300, height=200, path=path) .. doctest:: >>> shelley.render(map, view, format) .. image:: .scratch/road_map.png