Updated Managing complex map files using XML entities (markdown)
parent
83484906ec
commit
6b15f5911a
1 changed files with 55 additions and 49 deletions
|
@ -20,9 +20,11 @@ components using external entities and XInclude.
|
||||||
## Mapnik XML support
|
## Mapnik XML support
|
||||||
|
|
||||||
Mapnik currently supports three different XML parsers:
|
Mapnik currently supports three different XML parsers:
|
||||||
- the boost spirit based parser
|
|
||||||
- the tinyxml parser
|
* the boost spirit based parser
|
||||||
- libxml2
|
* the tinyxml parser
|
||||||
|
* libxml2
|
||||||
|
|
||||||
The three parsers differ in size, external dependencies and the number of XML
|
The three parsers differ in size, external dependencies and the number of XML
|
||||||
features they support. The most comprehensive parser is the libxml2 parser and
|
features they support. The most comprehensive parser is the libxml2 parser and
|
||||||
it is the only one that supports XML entities. As of Mapnik 0.6.0 libxml2 is the default
|
it is the only one that supports XML entities. As of Mapnik 0.6.0 libxml2 is the default
|
||||||
|
@ -34,9 +36,9 @@ when building the Mapnik source with SCons, and available in the Windows binarie
|
||||||
If not default in your Mapnik version (< 0.6.0) the libxml2 parser is enabled by setting the XMLPARSER option at
|
If not default in your Mapnik version (< 0.6.0) the libxml2 parser is enabled by setting the XMLPARSER option at
|
||||||
compile time:
|
compile time:
|
||||||
|
|
||||||
|
```sh
|
||||||
#!sh
|
|
||||||
$ python scons/scons.py configure XMLPARSER=libxml2
|
$ python scons/scons.py configure XMLPARSER=libxml2
|
||||||
|
```
|
||||||
|
|
||||||
Of course this requires the libxml2 library and, depending on the distribution
|
Of course this requires the libxml2 library and, depending on the distribution
|
||||||
the corresponding devel package. If `xml2-config` is not in the PATH its location
|
the corresponding devel package. If `xml2-config` is not in the PATH its location
|
||||||
|
@ -44,31 +46,31 @@ can be set using the `XML2_CONFIG` option.
|
||||||
|
|
||||||
For example, if you have installed the latest libxml2 on mac os x via Macports, you might need to do:
|
For example, if you have installed the latest libxml2 on mac os x via Macports, you might need to do:
|
||||||
|
|
||||||
|
```sh
|
||||||
#!sh
|
|
||||||
$ python scons/scons.py configure XML2_CONFIG=/opt/local/bin/xml2-config
|
$ python scons/scons.py configure XML2_CONFIG=/opt/local/bin/xml2-config
|
||||||
|
```
|
||||||
|
|
||||||
## Internal Entities
|
## Internal Entities
|
||||||
|
|
||||||
All XML parsers have some built-in entities to escape otherwise illegal
|
All XML parsers have some built-in entities to escape otherwise illegal
|
||||||
characters:
|
characters:
|
||||||
- >
|
|
||||||
- <
|
* >
|
||||||
- &
|
* <
|
||||||
- "
|
* &
|
||||||
- '
|
* "
|
||||||
|
* '
|
||||||
|
|
||||||
The XML document type definition (DTD) provides a way to declare new, user
|
The XML document type definition (DTD) provides a way to declare new, user
|
||||||
defined entities:
|
defined entities:
|
||||||
|
|
||||||
|
```xml
|
||||||
#!text/xml
|
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE Map[
|
<!DOCTYPE Map[
|
||||||
<!ENTITY water_color "#b5d0d0">
|
<!ENTITY water_color "#b5d0d0">
|
||||||
]>
|
]>
|
||||||
<Map bgcolor="&water_color;"/>
|
<Map bgcolor="&water_color;"/>
|
||||||
|
```
|
||||||
|
|
||||||
This XML document declares an internal entity named water_color. This entity is
|
This XML document declares an internal entity named water_color. This entity is
|
||||||
referenced by the bgcolor attribute of the Map element. The parser replaces all
|
referenced by the bgcolor attribute of the Map element. The parser replaces all
|
||||||
|
@ -85,8 +87,7 @@ reoccurring value is a candidate for an entity.
|
||||||
|
|
||||||
It is allowed to nest entities:
|
It is allowed to nest entities:
|
||||||
|
|
||||||
|
```xml
|
||||||
#!text/xml
|
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE Map[
|
<!DOCTYPE Map[
|
||||||
<!ENTITY home_dir "/home/david">
|
<!ENTITY home_dir "/home/david">
|
||||||
|
@ -100,17 +101,16 @@ It is allowed to nest entities:
|
||||||
</Rule>
|
</Rule>
|
||||||
</Style>
|
</Style>
|
||||||
</Map>
|
</Map>
|
||||||
|
```
|
||||||
|
|
||||||
However, these internal entities are not suitable for larger blocks. They also
|
However, these internal entities are not suitable for larger blocks. They also
|
||||||
do not help with sharing common styles and layers between different maps.
|
do not help with sharing common styles and layers between different maps.
|
||||||
|
|
||||||
|
|
||||||
## External Entities
|
## External Entities
|
||||||
|
|
||||||
External entities are declared by adding the keyword SYSTEM:
|
External entities are declared by adding the keyword SYSTEM:
|
||||||
|
|
||||||
|
```xml
|
||||||
#!text/xml
|
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE Map[
|
<!DOCTYPE Map[
|
||||||
<!ENTITY db_settings SYSTEM "settings/db_settings">
|
<!ENTITY db_settings SYSTEM "settings/db_settings">
|
||||||
|
@ -127,6 +127,7 @@ External entities are declared by adding the keyword SYSTEM:
|
||||||
</Datasource>
|
</Datasource>
|
||||||
</Layer>
|
</Layer>
|
||||||
</Map>
|
</Map>
|
||||||
|
```
|
||||||
|
|
||||||
The entity declaration assigns the content of the file `settings/db_settings` to
|
The entity declaration assigns the content of the file `settings/db_settings` to
|
||||||
the entity `&db_settings;`. When parsed the reference to `&db_settings;` in the
|
the entity `&db_settings;`. When parsed the reference to `&db_settings;` in the
|
||||||
|
@ -135,12 +136,13 @@ filename is given the file is searched relative to the document. The file
|
||||||
`settings/db_settings` could look like this:
|
`settings/db_settings` could look like this:
|
||||||
|
|
||||||
|
|
||||||
#!text/xml
|
```xml
|
||||||
<Parameter name="type">postgis</Parameter>
|
<Parameter name="type">postgis</Parameter>
|
||||||
<Parameter name="host">www.example.org</Parameter>
|
<Parameter name="host">www.example.org</Parameter>
|
||||||
<Parameter name="port">5433</Parameter>
|
<Parameter name="port">5433</Parameter>
|
||||||
<Parameter name="user">david</Parameter>
|
<Parameter name="user">david</Parameter>
|
||||||
<Parameter name="dbname">geo</Parameter>
|
<Parameter name="dbname">geo</Parameter>
|
||||||
|
```
|
||||||
|
|
||||||
Note that this is not a legal XML document on its own because it does not have
|
Note that this is not a legal XML document on its own because it does not have
|
||||||
a single root element. It is a list of elements. But the tags have to be well
|
a single root element. It is a list of elements. But the tags have to be well
|
||||||
|
@ -152,7 +154,7 @@ limited form of parameterization. Consider the following example:
|
||||||
|
|
||||||
File earthquake.map:
|
File earthquake.map:
|
||||||
|
|
||||||
#!text/xml
|
```xml
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE Map[
|
<!DOCTYPE Map[
|
||||||
<!ENTITY since_year "1970">
|
<!ENTITY since_year "1970">
|
||||||
|
@ -173,23 +175,25 @@ File earthquake.map:
|
||||||
&common_styles;
|
&common_styles;
|
||||||
&common_layers;
|
&common_layers;
|
||||||
</Map>
|
</Map>
|
||||||
|
```
|
||||||
|
|
||||||
File earthquakes_since.lay:
|
File earthquakes_since.lay:
|
||||||
|
|
||||||
#!text/xml
|
```xml
|
||||||
<Layer name="earthquakes_since" status="on">
|
<Layer name="earthquakes_since" status="on">
|
||||||
<StyleName>earthquakes</StyleName>
|
<StyleName>earthquakes</StyleName>
|
||||||
<Datasource>
|
<Datasource>
|
||||||
|
|
||||||
<Parameter name="table">
|
<Parameter name="table">
|
||||||
(SELECT * FROM earthquakes
|
(SELECT * FROM earthquakes
|
||||||
WHERE year >= &since_year; ) AS earthquakes_since
|
WHERE year >= &since_year; ) AS earthquakes_since
|
||||||
</Parameter>
|
</Parameter>
|
||||||
|
|
||||||
&db_settings;
|
&db_settings;
|
||||||
|
|
||||||
</Datasource>
|
</Datasource>
|
||||||
</Layer>
|
</Layer>
|
||||||
|
```
|
||||||
|
|
||||||
This is a quite flexible setup. It is very easy to add and remove thematic
|
This is a quite flexible setup. It is very easy to add and remove thematic
|
||||||
overlays. Other overlays may use the same parameters by referencing the
|
overlays. Other overlays may use the same parameters by referencing the
|
||||||
|
@ -198,7 +202,6 @@ same entities. Styles can be changed by replacing the reference to
|
||||||
many map files all referencing the same set of styles and layer files but with
|
many map files all referencing the same set of styles and layer files but with
|
||||||
different settings.
|
different settings.
|
||||||
|
|
||||||
|
|
||||||
## Entities Summary
|
## Entities Summary
|
||||||
|
|
||||||
Entities provide a way to use symbolic names in the map file. This improves
|
Entities provide a way to use symbolic names in the map file. This improves
|
||||||
|
@ -208,7 +211,6 @@ general more maintainable. External entities can store whole blocks of XML.
|
||||||
This helps to build reusable collections of layers and styles. These reusable
|
This helps to build reusable collections of layers and styles. These reusable
|
||||||
components can be parameterized using other entities as needed.
|
components can be parameterized using other entities as needed.
|
||||||
|
|
||||||
|
|
||||||
## Including external files using XInclude
|
## Including external files using XInclude
|
||||||
|
|
||||||
libxml2 also provides support for decomposing large mapnik XML files through the use of XInclude.
|
libxml2 also provides support for decomposing large mapnik XML files through the use of XInclude.
|
||||||
|
@ -217,7 +219,7 @@ To enable XInclude in your root file, modify the Map container tag, adding the x
|
||||||
|
|
||||||
File tests/data/good_maps/xinclude/map.xml:
|
File tests/data/good_maps/xinclude/map.xml:
|
||||||
|
|
||||||
#!text/xml
|
```xml
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE Map >
|
<!DOCTYPE Map >
|
||||||
<Map xmlns:xi="http://www.w3.org/2001/XInclude" srs="+init=epsg:4326" bgcolor="rgb(255,255,255)" >
|
<Map xmlns:xi="http://www.w3.org/2001/XInclude" srs="+init=epsg:4326" bgcolor="rgb(255,255,255)" >
|
||||||
|
@ -229,6 +231,7 @@ File tests/data/good_maps/xinclude/map.xml:
|
||||||
<xi:include href="layers.xml" />
|
<xi:include href="layers.xml" />
|
||||||
|
|
||||||
</Map>
|
</Map>
|
||||||
|
```
|
||||||
|
|
||||||
Included files wrap their content within an Include tag. XInclude replaces the xi:include tags with the contents of the included file, yielding a single, merged XML document.
|
Included files wrap their content within an Include tag. XInclude replaces the xi:include tags with the contents of the included file, yielding a single, merged XML document.
|
||||||
mapnik's XML parser then merges the contents of the Include tag into the Map tag, resulting in an XML document tree identical to one produced by processing a single file containing
|
mapnik's XML parser then merges the contents of the Include tag into the Map tag, resulting in an XML document tree identical to one produced by processing a single file containing
|
||||||
|
@ -236,7 +239,7 @@ all Style and Layer tags.
|
||||||
|
|
||||||
File styles.xml:
|
File styles.xml:
|
||||||
|
|
||||||
#!text/xml
|
```xml
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Include xmlns:xi="http://www.w3.org/2001/XInclude">
|
<Include xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
|
||||||
|
@ -254,10 +257,11 @@ File styles.xml:
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
</Include>
|
</Include>
|
||||||
|
```
|
||||||
|
|
||||||
File layers.xml:
|
File layers.xml:
|
||||||
|
|
||||||
#!text/xml
|
```xml
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Include xmlns:xi="http://www.w3.org/2001/XInclude">
|
<Include xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
|
||||||
|
@ -270,6 +274,7 @@ File layers.xml:
|
||||||
</Layer>
|
</Layer>
|
||||||
|
|
||||||
</Include>
|
</Include>
|
||||||
|
```
|
||||||
|
|
||||||
## Combining XInclude and External Entities
|
## Combining XInclude and External Entities
|
||||||
|
|
||||||
|
@ -279,7 +284,7 @@ A common pattern found in mapnik XML file sets is specifying the zoom levels for
|
||||||
|
|
||||||
file: zoomsymbols.txt
|
file: zoomsymbols.txt
|
||||||
|
|
||||||
#!text/html
|
```xml
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<!ENTITY zoom00max "750000000" >
|
<!ENTITY zoom00max "750000000" >
|
||||||
|
@ -290,14 +295,14 @@ file: zoomsymbols.txt
|
||||||
|
|
||||||
<!ENTITY zoom02max "250000000" >
|
<!ENTITY zoom02max "250000000" >
|
||||||
<!ENTITY zoom02min "130000000" >
|
<!ENTITY zoom02min "130000000" >
|
||||||
|
```
|
||||||
|
|
||||||
Adding a DOCTYPE line to the layers.xml file to include the external entities file, and adding parameterized minzoom and maxzoom attributes to the layer yields the file below:
|
Adding a DOCTYPE line to the layers.xml file to include the external entities file, and adding parameterized minzoom and maxzoom attributes to the layer yields the file below:
|
||||||
|
|
||||||
|
|
||||||
File layers_with_entities.xml:
|
File layers_with_entities.xml:
|
||||||
|
|
||||||
#!text/xml
|
```xml
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE Include SYSTEM "zoomsymbols.txt">
|
<!DOCTYPE Include SYSTEM "zoomsymbols.txt">
|
||||||
|
|
||||||
|
@ -312,6 +317,7 @@ File layers_with_entities.xml:
|
||||||
</Layer>
|
</Layer>
|
||||||
|
|
||||||
</Include>
|
</Include>
|
||||||
|
```
|
||||||
|
|
||||||
## Further Reading
|
## Further Reading
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue