Skip to content

Commit

Permalink
Added support for a configuration file
Browse files Browse the repository at this point in the history
  • Loading branch information
roelderickx committed Oct 24, 2019
1 parent ce152d4 commit 89f06cb
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 51 deletions.
39 changes: 33 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Render paper maps from Openstreetmap data using mapnik.
# Render paper maps from Openstreetmap data using mapnik

This program renders an area with given boundaries using data from Openstreetmap. It is designed to work with hikingmap but it can be used standalone as well if desired.

Expand Down Expand Up @@ -27,7 +27,7 @@ Options:
| `-S, --scale-factor` | Scale factor, default 1.0
| `-m, --mapstyle` | Mapnik stylesheet file, default mapnik_style.xml
| `--hikingmapstyle` | Hikingmap stylesheet file, contains the CartoCSS for the tracks and the waypoints. The default is hikingmapstyle.xml, see the repository for an example.
| `-f, --format` | Output format. Consult the mapnik documentation for possible values, default png
| `-f, --format` | Output format. Consult the [mapnik documentation](http://mapnik.org/docs/v2.2.0/api/python/mapnik._mapnik-module.html#render_to_file) for possible values, default png
| `gpxfiles` | The GPX track(s) to render.

After these parameters you are required to make a choice between bbox and center. In bbox mode the rendered area will be a defined bounding box and in center mode you can specify a center coordinate and a scale.
Expand All @@ -51,6 +51,37 @@ Options for center mode:
| `--lat` | Latitude of the center of the page
| `--scale` | Scale denominator, default 50000

## Configuration file

Because most of the time you will want to use the same parameters, you can optionally override the defaults in a configuration file. hm-render-mapnik will search for a file hm-render-mapnik.config.xml in the current directory, if not found it will resort to ~/.hm-render-mapnik.config.xml

```
<?xml version="1.0" encoding="utf-8"?>
<hm-render-mapnik>
<mapstyle>mapnik_style.xml</mapstyle>
<hikingmapstyle>hikingmap_style.xml</hikingmapstyle>
<outputformat>pdf</outputformat>
<dpi>300</dpi>
<scalefactor>1.0</scalefactor>
<fontdirs>
<fontdir>/usr/share/fonts/noto</fontdir>
<fontdir>/usr/share/fonts/noto-cjk</fontdir>
<fontdir>/usr/share/fonts/TTF</fontdir>
</fontdirs>
</hm-render-mapnik>
```

Options:

| Tag | Description
| --- | -----------
| mapstyle | Mapnik stylesheet file, contains the style to draw the map.
| hikingmapstyle | Hikingmap stylesheet file, contains the CartoCSS for the tracks and the waypoints, see the repository for an example.
| outputformat | Output format. Consult the [mapnik documentation](http://mapnik.org/docs/v2.2.0/api/python/mapnik._mapnik-module.html#render_to_file) for possible values.
| dpi | Amount of detail to render in dots per inch. This value is unrelated to the setting on your printer, a higher value will simply result in smaller icons, thinner roads and unreadable text.
| scalefactor | The scale factor to compensate for a higher dpi value.
| fontdirs | Optional. Can contain one or more fontdir subtags with additional font directories to be used by mapnik.

## Prerequisites

To run this script you should have a working installation of [python 3](https://www.python.org/) and [mapnik](http://mapnik.org/). Make sure you also have [python-mapnik](https://github.com/mapnik/python-mapnik/) installed.
Expand All @@ -59,7 +90,3 @@ To run this script you should have a working installation of [python 3](https://

The mapnik stylesheet should be configured before use and you need to set up a datasource as well. Consult the HTML documentation in this repository for a detailed explanation on how to achieve this.

## TODO

Since most of the time the same configuration and tile source will be used, the program should be able to read these parameters from a config file.

6 changes: 3 additions & 3 deletions hm_render_mapnik.config.xml → hm-render-mapnik.config.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<hm_render_mapnik>
<hm-render-mapnik>
<mapstyle>mapnik_style.xml</mapstyle>
<hikingmapstyle>hikingmap_style.xml</hikingmapstyle>
<outputformat>png</outputformat>
<dpi>300</dpi>
<dpi>400</dpi>
<scalefactor>1.0</scalefactor>
<fontdirs>
<fontdir>/usr/share/fonts/noto</fontdir>
<fontdir>/usr/share/fonts/noto-cjk</fontdir>
<fontdir>/usr/share/fonts/TTF</fontdir>
</fontdirs>
</hm_render_mapnik>
</hm-render-mapnik>

115 changes: 78 additions & 37 deletions hm_render_mapnik/hm_render_mapnik.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,87 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import argparse, math, mapnik
import os, argparse, math, mapnik
from xml.dom import minidom

# global constants
earthCircumference = 40041.44 # km (average, equatorial 40075.017 km / meridional 40007.86 km)
cmToKmFactor = 100000.0
inch = 2.54 # cm

def search_configfile():
filename = 'hm-render-mapnik.config.xml'
if os.path.exists(filename):
return os.path.abspath(filename)
elif os.path.exists(os.path.join(os.path.expanduser('~'), '.' + filename)):
return os.path.join(os.path.expanduser('~'), '.' + filename)
else:
return None


def get_xml_subtag_value(xmlnode, sublabelname):
elements = xmlnode.getElementsByTagName(sublabelname)
return str(elements[0].firstChild.nodeValue) if elements and elements[0].childNodes else None


def parse_configfile():
config = {}
config['mapstyle'] = 'mapnik_style.xml'
config['hikingmapstyle'] = 'hikingmap_style.xml'
config['output_format'] = 'png'
config['dpi'] = 300
config['scale_factor'] = 1.0

configfile = search_configfile()

if configfile:
xmldoc = None
xmlmapnik = None

try:
xmldoc = minidom.parse(configfile)
except:
pass

if xmldoc:
xmlmapnik_element = xmldoc.getElementsByTagName('hm-render-mapnik')
if xmlmapnik_element:
xmlmapnik = xmlmapnik_element[0]

if xmlmapnik:
mapstyle = get_xml_subtag_value(xmlmapnik, 'mapstyle')
if mapstyle:
config['mapstyle'] = mapstyle

hikingmapstyle = get_xml_subtag_value(xmlmapnik, 'hikingmapstyle')
if hikingmapstyle:
config['hikingmapstyle'] = hikingmapstyle

output_format = get_xml_subtag_value(xmlmapnik, 'outputformat')
if output_format:
config['output_format'] = output_format

dpi = get_xml_subtag_value(xmlmapnik, 'dpi')
if dpi:
config['dpi'] = int(dpi)

scale_factor = get_xml_subtag_value(xmlmapnik, 'scalefactor')
if scale_factor:
config['scale_factor'] = float(scale_factor)

xmlfontdirlist = xmlmapnik.getElementsByTagName('fontdirs')

for xmlfontdir in xmlfontdirlist:
fontdir = get_xml_subtag_value(xmlfontdir, 'fontdir')
if fontdir:
mapnik.FontEngine.register_fonts(fontdir, True)

return config


def parse_commandline():
config = parse_configfile()

parser = argparse.ArgumentParser(description = "Render a map on paper using mapnik")
parser.add_argument('--pagewidth', dest = 'pagewidth', type = float, default = 20.0, \
help = "page width in cm")
Expand All @@ -38,16 +110,16 @@ def parse_commandline():
help = "temp waypoints file to render")
parser.add_argument('-v', dest = 'verbose', action = 'store_true')
# hm-render-mapnik specific parameters
parser.add_argument('-d', '--dpi', type=int, default=300, \
parser.add_argument('-d', '--dpi', type=int, default=config['dpi'], \
help = "amount of detail to render in dots per inch (default: %(default)s)")
parser.add_argument('-S', '--scale-factor', type=float, default=1.0, \
parser.add_argument('-S', '--scale-factor', type=float, default=config['scale_factor'], \
help = "scale factor (default: %(default)s)")
parser.add_argument('-m', '--mapstyle', default='mapnik_style.xml', \
parser.add_argument('-m', '--mapstyle', default=config['mapstyle'], \
help = "mapnik stylesheet file (default: %(default)s)")
parser.add_argument('--hikingmapstyle', default='hikingmap_style.xml', \
parser.add_argument('--hikingmapstyle', default=config['hikingmapstyle'], \
help = "hikingmap stylesheet file, contains the CartoCSS for " + \
"the tracks and the waypoints (default: %(default)s)")
parser.add_argument('-f', '--format', dest='output_format', default='png', \
parser.add_argument('-f', '--format', dest='output_format', default=config['output_format'], \
help = "output format, consult the mapnik documentation for " + \
"possible values (default: %(default)s)")
# --
Expand Down Expand Up @@ -100,35 +172,6 @@ def assure_bbox_mode(parameters):
parameters.maxlon = parameters.lon + pagesize_lon / 2
parameters.maxlat = parameters.lat + pagesize_lat / 2

'''
def __get_xml_subtag_value(self, xmlnode, sublabelname, defaultvalue):
elements = xmlnode.getElementsByTagName(sublabelname)
return str(elements[0].firstChild.nodeValue) \
if elements and elements[0].childNodes \
else defaultvalue
def parse_configfile(self):
xmldoc = minidom.parse("render_mapnik.config.xml")
xmlmapnik = xmldoc.getElementsByTagName('render_mapnik')[0]
self.mapstyle = self.__get_xml_subtag_value(xmlmapnik, 'mapstyle', 'mapnik_style.xml')
self.hikingmapstyle = self.__get_xml_subtag_value(xmlmapnik, 'hikingmapstyle', \
'hikingmap_style.xml')
self.output_format = self.__get_xml_subtag_value(xmlmapnik, 'outputformat', 'pdf')
self.dpi = int(self.__get_xml_subtag_value(xmlmapnik, 'dpi', '300'))
self.scale_factor = float(self.__get_xml_subtag_value(xmlmapnik, 'scalefactor', '1.0'))
xmlfontdirlist = xmlmapnik.getElementsByTagName('fontdirs')
for xmlfontdir in xmlfontdirlist:
fontdir = self.__get_xml_subtag_value(xmlfontdir, 'fontdir', '')
if fontdir != '':
mapnik.FontEngine.register_fonts(fontdir, True)
return True
'''

def render(parameters):
if not parameters.verbose:
mapnik.logger.set_severity(getattr(mapnik.severity_type, 'None'))
Expand Down Expand Up @@ -179,8 +222,6 @@ def render(parameters):
def main():
parameters = parse_commandline()
assure_bbox_mode(parameters)

#parse_configfile(parameters)

render(parameters)

Expand Down
13 changes: 8 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

setuptools.setup(
name="hm-render-mapnik",
version="0.0.1",
version="0.0.2",
license='GNU General Public License (GNU GPL v3 or above)',
author="Roel Derickx",
author_email="roel.derickx AT gmail",
author_email="hikingmap.pypi@derickx.be",
description="Render a map for a given area to paper using mapnik",
long_description=README,
long_description_content_type="text/markdown",
Expand All @@ -23,9 +23,12 @@
'console_scripts': ['hm-render-mapnik = hm_render_mapnik.hm_render_mapnik:main']
},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License (GPL)",
"Operating System :: OS Independent",
'Environment :: Console',
'Topic :: Scientific/Engineering :: GIS',
'Development Status :: 5 - Production/Stable',
'Programming Language :: Python :: 3',
'License :: OSI Approved :: GNU General Public License (GPL)',
'Operating System :: OS Independent',
],
)

0 comments on commit 89f06cb

Please sign in to comment.