Rendering map data with Mapnik and Python
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 95 | |
Author | ||
License | CC Attribution 4.0 International: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/32336 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
FrOSCon 201711 / 95
4
8
9
15
20
22
23
24
25
27
29
32
36
37
38
39
40
45
46
47
48
49
50
51
53
54
59
63
64
65
74
75
76
79
83
84
86
87
88
89
91
92
93
94
95
00:00
Sheaf (mathematics)Formal languageTrailSet (mathematics)Process (computing)XMLComputer animation
00:54
Process (computing)DatabaseGeometryComputer engineeringPresentation of a groupLecture/Conference
02:23
CodeCartesian coordinate systemLibrary (computing)Computer programmingSpeech synthesisFile formatBitGraphics softwareForm (programming)outputProgram codeLevel (video gaming)Medical imagingKeyboard shortcutScalabilityType theoryProbability density functionDifferent (Kate Ryan album)TelecommunicationArtistic renderingPotenz <Mathematik>Formal languageData typeAreaPolygonComputer fontInformationDevice driverComputer fileMoment (mathematics)DatabaseData storage deviceSound effectDiagramConfiguration spaceShape (magazine)Process (computing)BuildingLine (geometry)Vector graphicsLatent heat1 (number)Point (geometry)Attribute grammarCuboidProjective planeComputing platformPhysical systemWindowRevision controlRepository (publishing)Source codeInclusion mapSimilarity (geometry)Raster graphicsGraph coloringAcoustic shadowSimulationComputer sciencePlug-in (computing)Slide ruleGeometryReading (process)Function (mathematics)Vector spaceRaw image formatElectronic visual displayFlow separationLecture/ConferenceComputer animation
10:19
outputCASE <Informatik>Rule of inferenceLevel (video gaming)File formatForm (programming)Computer fileObject (grammar)InformationDifferent (Kate Ryan album)Attribute grammarSimulationGraph coloringComputer configurationNumberDigitizingDigital photographyPattern languageBuildingSymbol tablePolygonLine (geometry)AreaSolid geometryMedical imagingFunction (mathematics)Electronic visual display1 (number)Shape (magazine)CircleShooting methodEndliche ModelltheorieMeta elementConnectivity (graph theory)Type theoryDependent and independent variablesSquare numberPoint (geometry)Artistic renderingMetropolitan area networkGradientBitMusical ensembleQuicksortLibrary (computing)Arrow of timeDirection (geometry)Physical lawGroup actionQuery languageForestTriangleNetwork topologyGeometryDot productView (database)RectangleRaster graphicsTesselationCuboidMereologyError messageGreen's functionComputer animation
18:12
Rule of inferenceLine (geometry)Symbol tablePoint (geometry)Content (media)Slide rulePolygonComputer fileShape (magazine)ResultantWordComputer fontMultiplicationGraph coloringCodeDefault (computer science)Green's functionLevel (video gaming)outputMedical imagingOpen sourceObject (grammar)2 (number)Negative numberCartesian coordinate systemFile formatFitness functionZoom lensDivisorExterior algebraAttribute grammarSystem callBitInformationMultiplication signSoftwareCommunications protocolCASE <Informatik>Different (Kate Ryan album)Sampling (statistics)Single-precision floating-point formatWater vaporVotingField (computer science)Event horizonView (database)Product (business)Functional (mathematics)Form (programming)Network topologySimilarity (geometry)Service (economics)StapeldateiPhysical lawMathematicsLogicCondition numberParticle systemXML
26:04
Group actionKey (cryptography)RectangleLine (geometry)Graph coloringArtistic renderingLight fieldPhysical lawEmailLibrary (computing)Medical imagingMathematicsRevision controlPoint (geometry)Complex (psychology)Slide ruleConjugacy classAdditionStructural loadPhase transitionGame controllerPosition operatorCircleBuildingCartesian coordinate systemNeighbourhood (graph theory)Combinational logicSummierbarkeitProbability density functionCodeService (economics)Subject indexingExpert systemVideo gameForestAreaOcean currentContext awarenessResultantComputer fileFigurate numberConnectivity (graph theory)Symbol tableSolid geometryStudent's t-testGreatest elementNumberLevel (video gaming)QuicksortEvent horizonRight angleMetadataDifferent (Kate Ryan album)ComputerSurfaceCovering spacePolygonPattern languageFrame problemHoaxAdventure gameBus (computing)Square numberWikiRepository (publishing)Functional (mathematics)Program flowchart
33:57
Computer fileComputer-assisted translationMultiplication signData storage deviceCartesian coordinate systemRoundness (object)Standard deviationInstance (computer science)RoutingEndliche ModelltheorieSurfaceStudent's t-testContext awarenessDampingLevel (video gaming)Cycle (graph theory)Computer configurationBasis <Mathematik>Identity managementFile formatData conversionComputer animationLecture/Conference
36:47
Open sourceDatabaseAdditionOrder (biology)CASE <Informatik>Sound effectEntropie <Informationstheorie>Lecture/Conference
37:48
Computer animation
Transcript: English(auto-generated)
00:07
Hello and welcome to our second section. I want to present the Foskis Social Club first in the English language.
00:33
So the technical difficulties are away, I hope so. Okay, the Foskis Social Club is the German chapter of the OSBO and OSM.
00:47
We make this conference together with the FrostCon team here with the OSBO and OSM track. Now we have a talk from Hartmut Holzgräfe.
01:02
I saw his talks last year here also at the FrostCon. So he's maybe the oldest presenter here at the GEO talk at FrostCon.
01:22
Yeah, but now have a nice talk. Okay, thank you. So my name is Hartmut, we already know that. And I'm living in Bielefeld here in Germany, really.
01:46
I studied electric engineering and computer science and doing OpenStreetMap since almost 10 years now. So next weekend it's going to be 10 years for me.
02:06
And in my primary job I do not really work with geo data or maps or stuff. I am a database support engineer for MariaDB and formally for MySQL.
02:21
So I'm usually doing the boring database stuff in my day job. I try to do other things on the side like what we have now. So I'm going to have two talks today. This one is describing the basics I learned while working on the application
02:40
that I will present in the second one in the afternoon about printable OpenStreetMap for which this big printer here is hopefully being operational in the afternoon. So what is MapNec? For this we have the usual computer science diagram.
03:03
We have some big box in the middle. We have input coming in and output coming out and some configuration coming from the side and some code that is controlling what is happening. MapNec is actually a library that sits in the middle
03:21
and that is processing map data and is converting it into pretty pictures. That's the simple story. So for this MapNec can read several different kinds of input
03:40
like shape files which is a specific format for geo data and it can read geo data that comes from SQL databases. It has native drivers for Postgres and for spatial light. I'm losing the microphone.
04:07
And it also has support for other database via the special extra plugin library. It can natively read GeoJSON
04:22
and it can also read a lot of other formats via two extra plugins. There is one using the OGR library that is supporting both vector and raster images. So this can be used for example to read raw OSM data and GPX files.
04:43
There is GDAL that is only there to read raster images and display pre-rendered images that you want to embed in a map. And on the other side we have different output formats that we can support.
05:00
That is we can produce PNG files, both full color files or reduced color 8-bit files to make the files a bit smaller. As maps usually don't have that many colors. We can produce JPEG. We can produce scalable vector graphics.
05:21
That's especially interesting if you want to create a map and then use that in a graphics program like Inkscape or Adobe Tools to then add more stuff to it. We can produce printable PDF right away
05:42
and also still can produce printable PostScript whether it is still needed. Whereas PostScript and PDF are sort of similar. So we have our input on one side that goes in and on the other side we want to have pretty pictures.
06:02
So we need the third thing and that is the render styles that tell the MapNIC library how to take the input data and transform it into pretty pictures. For this we can either define render styles directly in the program code
06:24
or we can use external XML style files that describe how we want to see our stuff rendered. Both have their disadvantages that we will see later. There are also some other style sheet languages
06:42
that can be converted into the MapNIC XML format like Carto CSS for example that is used for the main OpenSuiteMap style that are a bit more readable than the XML format. MapNIC itself is not a standalone program.
07:01
It is a library. So we need at least a little bit of extra code around it to make a full rendering application. The library itself is written in C++. Then there is Python bindings so that you do not have to use C++ code directly
07:22
but can use it in parsing programs which is usually going to be easier. We also have experimental bindings for PHP which I have found just lately and have not tried yet. I cannot really tell how good that works yet.
07:43
This talk is only about the Python bindings. A few things we need to start is that we obviously need Python and it works both with Python 2 and 3 but some features may only be in the latest version
08:02
that only works with 3. We also have two different versions of MapNIC version 2 and version 3 that is not related to the Python versioning. It is just also 2 and 3 by coincidence. We had Python bindings in MapNIC 2
08:21
included in the main MapNIC source code and now with MapNIC 3 it is two separate projects or two separate repositories. You have the main library in C++ and then you have a second project that does the Python bindings. Usually you do not really have to care about it.
08:42
Like on Debian or Ubuntu you just install Python MapNIC and that pulls in all the other things that are needed. There is still a todo item here on the slides because I did not test it in other platforms. I know that on Mac OS all the stuff is in the Homebrew system.
09:01
I know that there are Windows packages somewhere but I do not know anything about Windows so I have no idea how to install it there. What MapNIC does on the input side is that all the input front ends we have
09:24
deliver just four data types to the actual library and that is points, that is points of interest that have some attributes. That is lines, like for example a street. That is polygons, that is all kinds of areas like land use areas or the shape of a building.
09:42
So everything that is a closed line that actually defines an area is a polygon and there is also the possibility to import images that are already pre-rendered and for example this is used in some OpenStreetMap online maps
10:02
to include height information by making one side of a mountain a bit darker to have a 3D effect. That is done not by MapNIC itself but by using pre-rendered images that have this height shadow simulation data
10:24
pre-rendered as a big TIFF file. This is not necessarily the data format that data is in the actual input files like when we use raw OSM files the input format is different so the input layer has to convert it into these formats
10:44
and each of these objects can also have additional information not only the geometry information but also different attributes that can be used to decide what gets rendered and how it gets rendered like in the most basic case almost every object that we are going to render
11:01
is going to have a name and this name can be used in style rule to say I want the name displayed here. You can also see that later. So then we have the style definition in MapNIC
11:24
that again consists of three different basic kinds of objects. The first is what is called the layer. The layer defines what data we want to use and what style or what multiple styles
11:41
we want to use to display the data. The style can filter like it can say I only want to I want to take the input data but I only want to render the stuff the things that have a name or that have a certain size or whatever attributes you have
12:01
and then it uses what is called symbolizers that is the MapNIC components that do the actual drawing of things. So we have four basic types of symbolizers that directly map to the four basic kinds of objects.
12:21
There is point symbolizer, line symbolizer, polygon symbolizer and raster symbolizer and these are pretty easy like the point symbolizer either just draws a little square or you can give it the name of a symbol file you want to render.
12:50
Similarly for the line symbolizer that just gets information how thick you want to draw your line what color you want to draw a line in and you have some basic options
13:01
like you can have a dotted line or you can describe I want the dots in this size and the gaps in this size. Polygon symbolizer just takes an area and fills it with solid color and the raster symbolizer just takes the input raster image maybe resizes it but otherwise
13:21
just puts it directly into the output without modifying it. And then we have more complex ones this marker symbolizer that can put markers on a line like when you have a one way street you can put the little arrows as marker on the line
13:40
to show that you can only use it in that direction. We have what's called the line pattern symbolizer no spelling error it's pattern not patter and that can be used to draw little symbols on the side of a line like when you have an edge
14:02
in the landscape where the landscape goes down you have these little triangles and usual map styles at the side of the line these can be drawn using a line pattern symbolizer and there is a very important thing
14:22
the text symbolizer that is as the name says used to show text and usually it uses the name attribute or whatever you have in your data that gives the name for an object and then puts that on the symbol
14:40
and that can be used for points for lines and for polygons for points it will just put the text next to the point for lines it will put the text along the line and for polygons it will just try to find the middle of the polygon and put it there and depending on how complex the shape is that can be perfectly fine
15:01
or perfectly somewhere where you don't expect it like if you have like a half moon the text will not be in that half moon shape but it will in the middle of the circle that would be the full moon and then there is a special kind of a marker symbolizer
15:21
that is the shield symbolizer I'm using the microphone again okay so the shield symbolizer is used mostly for highway numbers so that's why it's called shield symbolizers
15:40
because on US maps these are usually shown in little shields so what the shield symbolizer does is it has a basic image of the shield and then it knows how to extend it to fit the number of the text you want to display in it so if you have a one digit number it's small two digit, three digit
16:02
it automatically gets wider and then the final one we have is polygon pattern symbolizer that is similar to the basic polygon symbolizer but it can fill the polygon not only with a solid color but with a background image
16:22
so usually you take a small repeatable image like for a forest you have green background and one or two trees on it that give the polygon pattern symbolizer the instruction use this image just tile it
16:41
and put it into the polygon until it's fully filled up there's a very special one the building symbolizer that's a pretty new experimental one that draws buildings in sort of a isometric sort of 3D view
17:02
so you have instead of just a rectangle for a building you have a little sort of box that also can take into account the height of the building so now let's get to the
17:20
bison part again this is the very basic use of the mapnik library so you have to import it you have to define a map object and give it a size and then in the end for the map you created
17:41
give it a file name and a file type and then a file is written so this obviously does nothing but it at least creates an empty file with transparent background not that interesting yet so we add a bit more here so we start by giving
18:01
the map a background color it's still blue here then we define a polygon symbolizer it also gets a fill color in light green and we create a rule object we append the polygon symbolizer to the rule we create a style object we append the rule to the style
18:21
so the style can have multiple rules rules that get stacked while drawing like when you want to draw a road you may first draw a white line then you draw a slightly smaller line in a different color so you have a road with visible edge
18:40
and then as a third rule you may then put text on top of the road to print the road name here we only have one rule so one symbolizer one rule, one style we append the style to the map so now the map object knows there's a rule called countries
19:01
with the given style which just creates a lot of polygons here and then we create a layer so that's what combines the data and the style we call that layer world and as a data source here we use a shapefile
19:21
it's a predefined file that has the shapes for all countries in the world we append that style we defined to the layer we append the layer to the map we give the map instruction to zoom all it is to zoom far enough
19:41
that everything in the input file can be seen and in the end we render our file again so it looks better already we have the blue background the green foreground we didn't give any rule for showing the borders the borders here are just
20:01
artifacts due to gathering on the edges of the polygons so by default it has anti-aliasing enabled that's more obviously the edges here but you can turn that off then we would only have the continents in green without borders
20:24
so next let's add a second rule so we have a polygon symbolizer again the other polygon symbolizer is the previous code and now we add
20:41
a second polygon symbolizer that fills polygons in red and we add a second rule here called Germany and for this rule we define a filter that filter is supposed to only render things that have the name Germany and the name attribute is also
21:03
set in the shape file we imported so we append the second rule in the same style and the rest of the code is like the previous one and something else changed here because really the borders are gone
21:22
but we see now Germany is not green anymore Germany is now red but we also see that we have to write a lot of code here so there is the alternative to not do this all in Python code
21:44
so we replace all the rule and style and layer definitions we had with just a call to load map and give it an XML file to read this is what the XML file looks this is exactly the same style
22:01
as before all countries are filled green one country is filled red and we get country information from that country shape file and so the result is obviously also the same
22:22
but even as unreadable as XML sometimes is I think it's still more readable than this so the advantage of doing things in Python code directly is that you can change rules dynamically as you go so in an interactive application
22:40
where you won't use this to be able to change styles this would take more work but it would be more flexible while this is more suitable when you have predefined styles that you do not want to change anymore so for the rest of these examples
23:01
I will use the XML format which is a better fit for the slide size here so I have a few examples of symbolizers here unfortunately I was not able to finish to copy all of them over because of the network failure and didn't finish my slides in time
23:22
guilty but you get the idea and then the other styles are also described in the mappnik documentation and for most of the symbolizers there are code examples both for XML and for Python so we only do the very basic things here
23:41
like the file name is still word XML here but the contents are different as you can see on the next slide so what we do here is we still zoom into all the data but the new data file only has two points in it
24:02
and if you just zoom in on these two points we would have the two points at the edges and then style as symbols for these two points you would only see half of the point because the other half would be outside of the image so we do another zoom call that has a negative zoom factor
24:22
so it zooms out and the factor is 1.1 so we zoom out by 10% and that is enough to see all the features we want and that is our style file we have a point symbolizer that just
24:41
shows a point dot png that is a png file and now as a data source we do not use the big clunky shape file anymore but a small geoJSON file this is the geoJSON file that we are going to use here it only has two points in it
25:03
in different places and so this is the final map we get with just these two points obviously not that useful but as an example how it works it's the most basic thing to do so in real map you would have multiple styles stacked on each other
25:22
that would draw different things to make a complete map but here we only have two points and the second example now this is a bit more complex let's maybe see the geoJSON
25:42
yeah I told you a few slides are missing so in this example we have actually another geoJSON file that only has a simple line in it and we use two symbolizers one blind symbolizer that draws a simple line and one text symbolizer
26:01
that uses a certain font a certain size this black color and a white halo around it we will see what the halo is soon and so that's also fully correct here
26:26
so please ignore the background text there this style file is actually rendered it's just a blue line and the text here on top so the text aligns with the line and you can see it is black text on blue
26:41
with a slight white frame around it that's the halo so that is when for example you have black text on top of something else that is also black you can still read the text yes so
27:01
the other symbolizers I didn't cover in the examples we had the polygon symbolizer in the first code example already I told you about the marker symbolizer that is used for lines with symbols on the side with symbols on top
27:22
shield symbolizer for highway numbers and stuff like that line pattern symbolizers for lines that have some small things on the side and polygon pattern symbolizer for filling a like a forest area
27:41
with a repeated forest background image and the building symbolizer for buildings in fake 3D so and all of this we could have done with just a stand alone map neck renderer wouldn't really need to write our own code for it
28:02
but what makes the combination of python map neck interesting is that you can also use other drawing functions to not draw things around or on top of your map like you can use Cairo graphics and tell
28:21
map neck not to render files itself but we create a PDF service so we are going to generate a PDF file to create what is called a context context is what you actually draw into in Cairo
28:41
we still create a map of a certain size we load our style sheet we zoom in but now what is different is we do not render to a file right away but we render to the surface we define so we actually render into an image that is controlled
29:04
and change later that is what we are going to do here we set the color we want to use to black the line width we want to use to five points and then we
29:21
say we want to have a rectangle of a certain size and context stroke is what actually draws the rectangle using the line widths and the color we defined and then in the end this map neck does not render the file anymore we tell the Cairo surface
29:40
that we finished and that it is now supposed to write the PDF file so the result is we have our two points again here which are from the map data and we have the rectangle that is not map data at all but that we put on top ourselves
30:01
and we can also use that to not only draw stuff directly but we can also pretty easily put SVG images on top so we also need to import our SVG library here we draw our map as we did before
30:22
then we read our SVG file here set the coordinates where we want to draw it this image is actually too large for the map we are going to render so we resize it so it's only half of the size
30:42
we render it to the Cairo context that our map data is already in and again say finish, write our results out of the file and so now we get this we have our two map points again now we have the SVG image that tells us where the north on the map is
31:05
so it's a summary this is what a complete application looks like that uses all these components to draw a map so we have the actual map here we have decorations on the side
31:22
on the top and on the bottom so we have a title on top we have some copyright notice and other text on the bottom we have an index on the side and on top of the map we have extra SVG markers for the things in the index
31:41
like bus stop Weststrasse is here in map square C4 at this position and we have the red circle which is the you are here marker and all this was created using the components we've seen in this talk
32:01
but in a larger application that I will talk about in the afternoon in more detail and that's also what the big printer is here for that is hopefully going to be operational so if all goes well if you want to have a map of your neighborhood we could arrange that in the afternoon during the breaks, not during the talks
32:23
so to summarize this talk what have you learned or what have I learned in my first adventure into Python land it is once you've figured out all the ways how not to do it it is actually pretty simple you have not seen much code here
32:42
and the devil here is in the styles not in the code and obviously it's always in all the details but most of the work is not on the code side but on the style file side the combination of Mapnik, Python and Cairo
33:01
allows for a very flexible map rendering and putting things around the map on top of the map in addition to the actual Mapnik rendering and what I learned personally is the Mapnik documentation
33:21
is not as good as I expected it to be so there is mostly a wiki on the Mapnik git repository and it describes all the stuff but sometimes you only have a header and just this does this without any further explanation
33:42
and what's more annoying is often enough you have this only works with this version so does it work with the version I have now if it doesn't anymore what is the replacement now you don't really know you often enough have to find out yourself so that's it and I want to give a special thank
34:02
to our cat Leila which has helped to produce this talk or has not succeeded in preventing me from doing it so now is the time for questions Can I get some style files
34:37
some predefined style files for instance those used on the OSM street map things
34:42
there are different layers Can I download them somewhere in a compatible format? I've set up all the public style files I could get hold of like the official OpenStreetMap style and the German OpenStreetMap style and stuff like that but that's actually stuff I cover
35:00
in the other talk in the afternoon Yes, it is time consuming to do a style from scratch so you usually either use one of the normal styles that already exist or there is a style called OSM bright
35:20
which can be used as a basis to put your stuff on top or what I do in that application I'll show in the afternoon is first use a standard style to render the map and then use a second style to just put on top stuff I'm really interested in like hiking routes or fire fighter facilities
35:42
so that way you don't have to do a style from scratch just put on top of existing style what you're interested in so putting several styles into the same Cairo context is not a problem Any more questions?
36:04
Can you hear me? Yes Mapnik has its own style file format is there an option to have map CSS for definition of styles? Unfortunately there is no option to have map CSS because I have one style
36:21
I really like to offer in the other application that is only coming with the map CSS style and there are converters for converting Mapnik into map CSS but not the other way around Ok, thanks So further questions?
36:54
What is the preferred data source you use in your style files? Is it really Postgres?
37:00
No, what I'm actually using and what most of the predefined styles use is actually an OSM to PGSQL import of OSM data into a PostGIS database but I wanted to have stand-alone examples here that do not need an extra database that's why you choose gayo-json here to have something small self-contained But I guess that's not really feasible
37:23
for Germany or Europe or something Alright Additional questions? No, I don't see Ok, so at first thank you for the great talk