-
Notifications
You must be signed in to change notification settings - Fork 0
Kartograph.py API v2.0
This is the draft for the upcoming Kartograph.py API. It's not implemented, yet.
The Kartograph map generator has just one method, which is there to generate SVG maps (surprise). All parameters are passed through a single config dictionary which is described in detail in this wiki page. The benefit of having a single dictionary is that it's easy to store map descriptions in JSON files.
Kartograph.generate(config, outfile='map.svg')
The command line interface of version 1.0 is replaced by this
kartograph generate -c config.json -o map.svg
The config object has this basic structure.
{
"proj": { },
"bounds": { },
"layers": [ ],
"export": { }
}
Of course, you may want to define the map projection that will be used to project the geo data:
"proj": {
"id": "laea",
"lon0": 11.0,
"lat0": 52.0
}
Other projections might require different parameters:
"proj": {
"id": "satellite",
"lon0": 11.0,
"lat0": 52.0,
"dist": 1.3,
"up": 45.0
}
In some situations you can leave out some projection parameters or set them to "auto". Then, Kartograph will try to figure out useful values itself (e.g. the geographic center of the displayed polygons). You can even mix automatic and user-defined projection parameters:
"proj": {
"id": "robinson",
"lon0": "auto",
"lat0": 52.0
}
For a list of all available map projections and their parameters, check out this page (todo).
The layers config is basically about what data you will see on the map. You can set up as much layer as you want. If not otherwise specified, the layers will be stacked on top of each other.
"layers": [{
"id": "countries",
"src": "ne_adm_level0.shp"
},{
"id": "regions",
"src": "ne_adm_level1.shp"
}]
In most cases you not only want to store the polygons but also some of their attributes (e.g. the ISO codes).
{
"id": "countries",
"src": "ne_admin_level0.shp",
"attributes": ["ISO3", "ISO2", "Area"]
}
However, sometimes the attributes found in shapefiles have fairly long (and ugly) names which you probably don't want to include in your final map. Therefore Kartograph allows renaming of the attributes:
{
"id": "countries",
"src": "ne_admin_level0.shp",
"attributes": [{
"src": "NE_COUNTRY_ISO_3",
"tgt": "ISO3"
}]
}
For each layer you can set up a filter which allows you to explicitly include or exclude polygons from that layer. In the next example, only the four specified countries are included in the map. Consequently you can change the filter type to exclude if you want to show every country except the specified ones.
{
"id": "countries",
"src": "ne_admin_level0.shp",
"filter": {
"type": "include",
"attribute": "ISO_3",
"equals": ["DEU","FRA","ITA","ESP"]
}
}
This allows you to create combined maps like this:
"layers": [{
"id": "countries",
"src": "ne_adm_level0.shp",
"filter": {
"type": "exclude",
"attribute": "ISO_3",
"equals": ["FRA"]
}
},{
"id": "regions",
"src": "ne_adm_level1.shp",
"filter": {
"type": "include",
"attribute": "ISO_3",
"equals": ["FRA"]
}
}]
For numerical attributes, Kartograph provides the filter parameters greater-than and less-than.
{
"id": "regions",
"src": "ne_adm_level1.shp",
"filter": {
"type": "include",
"attribute": "area",
"greater-than": 100000
}
}
In some situations you might want to join some polygons of a layer. For instance, you might want to create world map of continents instead of showing individual countries. Another use case would be that inner-country region polygons might be too detailed.
{
"id": "countries",
"src": "ne_admin_level0.shp",
"join": {
"new_attr": "continent",
"attribute": "ISO_3",
"groups": {
"europe": ["DEU","FRA","ITA","ESP"]
}
}
}
In the above example, the defined country polygons would be joined to a new polygon with the id continent set to "europe". If polygons within a group share the same border (like Germany and France) this shared border won't appear in the joined polygon.
You can drastically reduce both the quality and the file size of your map using the built in polygon simplification. It can be defined per layer, since sometimes you might want to have different levels of detail (e.g. high quality on the centered country and low quality on the surrounding polygons that are just there to give some context).
{
"id": "countries",
"src": "ne_admin_level0.shp",
"simplify": 20
}
The default simplification algorithm just iterates over all points and basically removes every point whose distance to the last not-deleted point is lower than the set amount. In future versions, Kartograph will also add support for other simplification algorithms. The "extended" API will look something like this:
{
"id": "countries",
"src": "ne_admin_level0.shp",
"simplify": {
"method": "douglas-peucker",
"amount": 20
}
}
You can limit the map view by defining a map boundary.
The mode bbox allows you to define a minimum/maximum value for latitude and longitudes. Kartograph will ensure that the entire lon,lat is visible in the map. Note that the layer polygons are not cropped to the viewport rectangle, but to the lon/lat range, whose actual shape depends on the used map projection.
"bounds": {
"mode": "bbox",
"data": [70,17,135,54]
}
If no bounds are set up at all, Kartograph will fallback to the full lon/lat range [-180,-90,180,90].
In some situations you don't want to mess around with lon/lat bounding boxes, but you simply want one or many polygons to be fully visible in the map. That's what the polygons mode is for:
"bounds": {
"mode": "polygons",
"data": {
"layer": "countries",
"attribute": "NE_ISO_3",
"ids": ["DEU","FRA","ITA","GBR"]
}
}
The layer option refers to the id of a layer defined in the layers section.
But wait, now comes the tricky part of using automatically calculated bounding boxes for geographic polygons. Since many geographic regions consist of multiple polygons, you often don't want to crop your map to the full extends. If you, for instance, want to crop the map to Spain you probably don't want have all these tiny islands included (see image above). Therefore, Kartograph allows you to set the parameter min_area. The bounding box calculation will ignore every polygon whose area is less than min_area multiplied with the area of the largest polygon.
"bounds": {
"mode": "polygons",
"data": {
"layer": "countries",
"attribute": "NE_ISO_3",
"ids": ["ESP"],
"min_area": 0.20
}
}
The points mode allows you to define a set of points (that is pairs of lon/lat values), that will be visible in the map. Kartograph will crop the map to the smallest rectangle that includes all defined points. Note that the calculation is done after the projection of the coordinates.
"bounds": {
"mode": "points",
"data": [[11.2,34.2],[23,33.3]]
}
The export section is where you can set up things like the dimension of the exported map:
"export": {
"width": 1000,
"height": 500
}
Instead of defining the width/height explicitly, you can also use a combination of width/height and a ratio.
"export": {
"width": 1000,
"ratio": 0.5
}
If you leave out either the width or height and have no ratio specified, Kartograph will automatically use the ratio of the projected map.
"export": {
"width": 1000
}
If you set export.round to other values than false (which is the default behaviour), all point coordinates will be round to the specified number of digits. The following would force Kartograph to round all coordinates to the first decimal digit (e.g. 115.4 instead of 115.38749493).
"export": {
"round": 1
}