<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>GIS &#38; Chips &#187; Mapnik</title>
	<atom:link href="http://www.gisandchips.org/tag/mapnik/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gisandchips.org</link>
	<description>Geografía útil para llevar</description>
	<lastBuildDate>Tue, 29 Nov 2011 10:38:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Thumbnails con Mapnik y OpenStreetMap</title>
		<link>http://www.gisandchips.org/2009/11/04/thumbnails-con-mapnik-y-openstreetmap/</link>
		<comments>http://www.gisandchips.org/2009/11/04/thumbnails-con-mapnik-y-openstreetmap/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 20:12:13 +0000</pubDate>
		<dc:creator>jose</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Mapnik]]></category>
		<category><![CDATA[OpenStreetMap]]></category>
		<category><![CDATA[thumbnails]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=543</guid>
		<description><![CDATA[¿Alguna vez te has visto en la tesitura de conocer el estado en OpenStreetMap de una determinada provincia, municipio, comunidad autónoma, región etc. en una fecha concreta? Pues bien, en este artículo intentaremos afrontar esta cuestión desde una perspectiva más pedagógica que profesional Objetivo: Crear thumbnails (imágenes reducidas) de cada provincia que serán generadas cada [...]]]></description>
			<content:encoded><![CDATA[<p>¿Alguna vez te has visto en la tesitura de conocer el estado en OpenStreetMap de una determinada provincia, municipio, comunidad autónoma, región etc. en una fecha concreta? Pues bien, en este artículo intentaremos afrontar esta cuestión desde una perspectiva más pedagógica que profesional</p>
<p><strong>Objetivo</strong>:<br />
Crear thumbnails (imágenes reducidas) de cada provincia que serán generadas cada semana para ver la evolución histórica de las aportaciones de usuarios a OpenStreetMap. Cada imagen tendrá como nombre la fecha de su creación, y se almacenarán cada una en su carpeta de provincia correspondiente. Estas imágenes serán visibles en un servicio web para su consulta pública.</p>
<p>Fases:</p>
<p>Para llevar a cabo este objetivo precisamos de:</p>
<ol>
<li>Actualizar cada semana la base de datos con el último &#8220;planet osm&#8221;</li>
<li>Generar las imágenes de cada provincia (mediante un script en Python)</li>
<li>Colocarlas en el lugar adecuado de nuestro servidor web</li>
<li>Programar la tarea para que se ejecute de forma automática cada semana, sin intervención del usuario.</li>
</ol>
<p>Figura: <em>Ejemplo del renderizado de una imagen de la provincia de Alicante</em></p>
<p style="text-align: center">
<div id="attachment_585" class="wp-caption alignnone" style="width: 410px"><img class="size-full wp-image-585" src="http://www.gisandchips.org/wp-content/2009-11-03.png" alt="Tile de Alicante" width="400" height="400" /><p class="wp-caption-text">Tile de Alicante el 3 de noviembre de 2009</p></div>
<p><span id="more-543"></span></p>
<p><strong>Descripción:</strong><br />
A lo largo de este pequeño artículo mostraremos las posibilidades conjuntas de OSM, PostGIS y Mapnik para que, con muy pocas líneas de código, seamos capaces de generar un repositorio de imágenes de cada provincia (en nuestro caso, aunque se puede adaptar a comunidades autónomas, municipios, etc.) que serán generadas por un script en python programado para ejecutarse una vez a la semana. Dicho script utilizará los módulos de Mapnik para generar imágenes a partir de un mapfile, y PsycoPg para llamar a sentencias SQL de PostgreSQL.</p>
<p><!--more--></p>
<p><strong>Punto de partida:</strong><br />
Tenemos instalado un servidor con las siguientes aplicaciones instaladas y configuradas:</p>
<ul>
<li>Python</li>
<li>PostgreSQL y PostGIS</li>
<li>Mapnik y utilidad Mapnik de OSM</li>
<li>Una tabla de PostGIS con las provincias</li>
<li>Un servidor web para mostrar los resultados</li>
</ul>
<p>Actualizar la base de datos de OSM cada semana</p>
<p>Para realizar esta fase necesitamos un script que automatice todas las funciones:</p>
<ul>
<li>Borrar la bbdd existente</li>
<li>Descarga del planet</li>
<li>Creación de la bbdd con PostGIS</li>
<li>Carga de datos con osm2pgsql</li>
</ul>
<p><strong>Script Bash para recargar la base de datos de OSM</strong></p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/sh
echo &quot;Borrando spain.osm.bz2&quot;
rm spain.osm.bz2
echo &quot;Descargando fichero osm de Spain desde Cloudmade.com&quot;
wget http://downloads.cloudmade.com/europe/spain/spain.osm.bz2
echo &quot;Descomprimiendo&quot;
bzip2 -d spain.osm.bz2
echo &quot;Borrando bbdd osm&quot;
dropdb -h localhost -U postgres osm
echo &quot;Creando bbdd osm&quot;
createdb -U postgres -E UTF8 osm
echo &quot;Instalar lenguaje pl/pgsql y Postgis en bbdd osm&quot;
createlang -U postgres plpgsql osm
psql -U postgres -f /usr/share/pgsql/contrib/postgis.sql osm
psql -U postgres -f /usr/share/pgsql/contrib/spatial_ref_sys.sql osm
echo &quot;Añadir datos d espain.osm a la bbdd osm&quot;
echo &quot;Tiempo aproximado: 11 minutos&quot;
/home/&lt;user&gt;/compilar/osm2pgsql/osm2pgsql --slim -H localhost -U postgres -d osm ./spain.osm
echo &quot;fin&quot;
exit 0
</pre>
<p><strong>Programar tarea con CRONTAB</strong><br />
Como ya sabes, los &#8220;crones&#8221; son tareas (<em>deaemon</em>) que se programan para ejecutarse en el momento (tiempo) que decidamos. Sí deseas más información aquí tienes un buen enlace: <a href="http://dns.bdat.net/documentos/cron/x50.html">http://dns.bdat.net/documentos/cron/x50.html</a></p>
<p><strong>Generar el árbol de directorios</strong>.<br />
Creamos un script bash para generar las carpetas de cada provincia. Vamos a utilizar el código de cada provincia por cuestión de comodidad</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash
# Crear directorios para provincias.

for provincias in 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
do
  echo $provincias
  mkdir -p $provincias
done

exit 0
</pre>
<p>Este sencillo script, que seguro podrás mejorar, debemos de ejecutarlo en el directorio de nuestro website donde se alojarán el servicio para ver la evolución de OSM</p>
<p><strong>Generar imágenes de OSM por provincia</strong><br />
Este script en Python hace uso de los módulos de Mapnik para generar la imagen, y de Psycopg para ejecutar sentencias SQL. Fíjate que la clave consiste en calcular por cada provincia las columnas con los valores de la extensión (xmin, ymin, xmax, ymax). Opcionalmente puedes añadirle una tolerancia para que el límite no se circunscriba a la caja de la provincia, sino que sea como una especie de buffer.<br />
En nuestro caso, la tabla &#8220;provincias&#8221; está en la proyección UTM-ED50 del uso 30 (epsg: 23030), por lo que para utilizarlo con los datos de OSM necesitamos proyectar los valores de la extensión a Mercator (EPSG: 900913)</p>
<p>NOTA: Si no tienes instalago psycopg (o psycopg2 según la distro) lo puedes instalar con</p>
<pre class="brush: bash; title: ; notranslate">yum install python-psycopg2.x86_64</pre>
<p>Script de Python</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
## DNS de la bbdd que contiene las provincias
DSN = 'host=localhost user=postgres dbname=demos'

import sys, psycopg, mapnik
## Nota: Si obtienes algun error aqui, cambia psycopg por psycopg2
from datetime import date

## mapnik
mapfile = 'osm.xml'
## tamaño de la imagen
m = mapnik.Map(400, 400)

if len(sys.argv) &gt; 1:
    DSN = sys.argv[1]

print 'Abrir conexion usando dns', DSN
conn = psycopg.connect(DSN)
## Nota: Si obtienes algun error aqui, cambia psycopg por psycopg2
curs = conn.cursor()

curs.execute('select codigo, st_xmin(st_extent(st_transform(geometria,900913))) as xmin, st_ymin(st_extent(st_transform(geometria,900913))) as ymin, st_xmax(st_extent(st_transform(geometria,900913))) as xmax, st_ymax(st_extent(st_transform(geometria,900913))) as ymax from ine.provincias group by codigo')

row = curs.fetchone()

rows = curs.fetchall()
print 'Creando imagenes...';
for row in rows:
    now = date.today()
    ## A cada imagen le asignamos como nombre la fecha de creación de la imagen
    map_output = 'miniaturas/'+row[0]+'/'+now.strftime(&quot;%Y-%m-%d&amp;&quot;)+'.png'
    mapnik.load_map(m, mapfile)
    bbox = mapnik.Envelope(mapnik.Coord(row[1],row[2]), mapnik.Coord(row[3],row[4]))
    m.zoom_to_box(bbox)
    mapnik.render_to_file(m, map_output)

conn.commit()
</pre>
<p>Ejecutamos el script</p>
<pre class="brush: bash; title: ; notranslate">
python miniatura_provincias.py
</pre>
<p>Por último sólo nos queda hacer visible a nuestro servidor web las tiles. Para ello tenemos dos opciones:</p>
<p>a) Copiamos el directorio miniaturas a nuestra carpeta de publicación web</p>
<pre class="brush: bash; title: ; notranslate">cp /home/mapnik/miniaturas /var/www/&lt;tu_ruta&gt;/</pre>
<p>b) Crear un enlace rígido en nuestra web que apunte al directorio &#8220;miniaturas&#8221;</p>
<pre class="brush: bash; title: ; notranslate">ln -d /home/mapnik/miniaturas /var/www/&amp;lt;tu_ruta&amp;gt;/miniaturas</pre>
<p>Este segundo método es más recomendable, puesto que nos permite aislar la lógica de nuestra aplicación del servicio web.</p>
<p><strong>Test</strong><br />
Probamos el ejemplo<br />
<a href="http://www.gisandchips.org/demos/j3m/miniaturas/">http://www.gisandchips.org/demos/j3m/miniaturas/</a></p>
<p><strong>Automatización:</strong></p>
<p>Sí queremos automatizar estas tareas, de forma que cada semana obtengamos una nueva imagen, cuyo nombre de imagen es la fecha en que se lanza el <a href="http://www.telefonica.net/web2/dinsalpa/crontab/crontab.htm">cron</a>, debemos de lanzar un script que, como root, realice estos pasos. A modo de ejemplo, este sería el Bash:</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/sh
cd &lt;ruta_directorio_volcado_bbdd_osm&gt;
python ./&lt;fichero python para generar miniaturas&gt;
cp /home/mapnik/miniaturas /var/www/&lt;tu_ruta&gt;
</pre>
<p>Este artículo es el tercero de una serie formada por:</p>
<ul>
<li><a href="http://www.gisandchips.org/2009/10/22/renderizado-de-osmcon-mapnik-para-usar-en-openlayers/#more-387">Renderizado con Mapnik</a></li>
<li><a href="http://www.gisandchips.org/2009/10/23/openstreetmap-y-mapnik/">Mapnik y OpenStreetMap</a></li>
<li>Thumbnails con Mapnik y OpenStreetMap  (este post)</li>
<li>Uso de TMS de OpenStreetMap con OpenLayers</li>
<li>TMS de OpenStreetMap con Mod_tile</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2009/11/04/thumbnails-con-mapnik-y-openstreetmap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenStreetMap y Mapnik</title>
		<link>http://www.gisandchips.org/2009/10/23/openstreetmap-y-mapnik/</link>
		<comments>http://www.gisandchips.org/2009/10/23/openstreetmap-y-mapnik/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 11:42:23 +0000</pubDate>
		<dc:creator>jose</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mapfile]]></category>
		<category><![CDATA[Mapnik]]></category>
		<category><![CDATA[OpenStreetMap]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=420</guid>
		<description><![CDATA[Objetivo: Siguiendo con la serie de artículos sobre OSM vamos a introducirnos en las posibilidades que nos ofrece Mapnik para renderizar datos de OSM contenidos en una geodatabase que hemos creado con &#8220;osm2pgsql&#8221; (ver artículo previo). El objetivo final es crear un fichero de mapa (mapfile) en XML para utilizarlo con Python y los bindings [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Objetivo</strong>:<br />
Siguiendo con la serie de artículos sobre OSM vamos a introducirnos en las posibilidades que nos ofrece <a href="http://mapnik.org/">Mapnik </a>para renderizar datos de OSM contenidos en una geodatabase que hemos creado con &#8220;osm2pgsql&#8221; (ver artículo <a href="http://www.gisandchips.org/2009/10/22/renderizado-de-osmcon-mapnik-para-usar-en-openlayers/#more-387">previo</a>).<br />
El objetivo final es crear un fichero de mapa (mapfile) en XML para utilizarlo con Python y los bindings de Mapnik. Una vez realizado este proceso podremos generar tanto imágenes como conjuntos de teselas (tiles)</p>
<p><img src="http://www.gisandchips.org/wp-content/ali_zoom14-300x300.png" alt="" width="300" height="300" /></p>
<p><span id="more-420"></span></p>
<p><strong>Descarga de utilidades OSM para Mapnik</strong><br />
En el repositorio subversion de OSM tenemos todo lo necesario para montar nuestro propio motor de renderizado de imágenes y conjuntos de tiles.<br />
Para descargar estas utilidades nos situamos en la raíz de nuestro &#8220;home&#8221; y procedemos a la descarga:</p>
<pre class="brush: bash; title: ; notranslate">
svn co http://svn.openstreetmap.org/applications/rendering/mapnik/ mapnik
cd mapnik
</pre>
<p>Este es el contenido de la carpeta &#8220;mapnik&#8221;:</p>
<ul>
<li> <em>symbols</em>: carpeta con los iconos utilizados &#8220;oficialmente&#8221; en el &#8220;slippy map&#8221; de www.openstreetmap.org</li>
<li><em>osm_template.xml</em>:  plantilla por defecto para generar un mapfile de OSM</li>
<li><em>set_mapnik.env</em>:  script de configuración de directorios, datasources, etc.</li>
<li><em>generate_image.py</em>:  script para generar una imagen</li>
<li><em>generate_tiles.py</em>:  script para generar tiles</li>
<li>otros archivos</li>
</ul>
<p><strong>Descarga de shapefiles</strong>:</p>
<p>OSM necesita una serie de shapefiles para poder renderizar aspectos como la costa, paises, masas de agua, etc.<br />
Lo ideal es que dentro del directorio &#8220;mapnik&#8221; creemos una carpeta donde almacenarlos</p>
<pre class="brush: bash; title: ; notranslate">
mkdir world_boundaries
</pre>
<p>Ahora descargamos los shapefiles y los descomprimimos</p>
<pre class="brush: bash; title: ; notranslate">
echo &quot;Tamaño 50 Mb&quot;
wget http://tile.openstreetmap.org/world_boundaries-spherical.tgz
echo &quot;processed_p: Tamaño 227 Mb&quot;
wget http://tile.openstreetmap.org/processed_p.tar.bz2
echo &quot;shoreline_300: Tamaño 46 Mb&quot;
$ wget http://tile.openstreetmap.org/shoreline_300.tar.bz2
cd world_boundaries
echo &quot;Descomprimir&quot;
tar -xvzf world_boundaries-spherical.tgz
tar jxvf processed_p.tar.bz2
tar jxvf shoreline_300.tar.bz2
</pre>
<p>De todas las shapes de estos archivos nos interesan fundamentalmente tres:</p>
<ul>
<li><em>shoreline_300</em> : polígonos con los contienentes y en cuadrículas, utilizado para el renderizado de la costa. El detalle es muy tosco, por lo que se utiliza para escalas superiores a 1/600.000</li>
<li><em>processed_p</em>:  polígonos con los contienentes y en cuadrículas, utilizado para el renderizado de la costa. Tienen gran detalle, por lo que se utiliza para escalas inferiores a 1/600.000</li>
<li><em>builtup_area</em>:  polígonos con masas de agua continentales (lagos)</li>
</ul>
<p><strong>Configuración de Mapnik para OSM</strong></p>
<p>El siguiente paso es configurar el fichero &#8220;set_mapnik.env&#8221; donde especificaremos las rutas a las carpetas de símbolos, shapefiles y conexiones a PostGIS.<br />
Este fichero será utilizado por la plantilla de OSM (&#8220;osm_template.xml&#8221;) para sustituir las variables contenidas entre &#8220;%&#8221;, como por ejemplo &#8220;%HOST%&#8221;, por nuestros valores personalizados.</p>
<p>Contenido del fichero &#8220;set_mapnik.env&#8221;</p>
<pre class="brush: python; title: ; notranslate">
#!/bin/sh
# Nombre del mapfile
export MAPNIK_MAP_FILE=/home/&lt;usuario&gt;/mapnik/osm.xml

# carpeta de símbolos
export MAPNIK_SYMBOLS_DIR=/home/&lt;usuario&gt;/mapnik/symbols

# carpeta de shapefiles
export MAPNIK_WORLD_BOUNDARIES_DIR=/home/&lt;usuario&gt;/mapnik/world_boundaries

# Carpeta donde se generarán las tiles
export MAPNIK_TILE_DIR=/home/&lt;usuario&gt;/mapnik/tiles/

# Host de PostgreSQL
export MAPNIK_DBHOST='localhost';

# Puerto de PostgreSQL
export MAPNIK_DBPORT=''

# Nombre de la base de datos del planet OSM
export MAPNIK_DBNAME='osm'

# Nombre del usuario de Postgres con derechos sobre la base de datos OSM
export MAPNIK_DBUSER='postgres'

# Password del usuario de PostgreSQL
export MAPNIK_DBPASS='';

# Prefijo utilizado en las tablas. Este prefijo es generado si se utiliza
# el parámetro &quot;-p &lt;nombre&gt;&quot; en la utilidad &quot;osm2pgsql&quot;. Si no lo utilizamos
# se entiende que será &quot;planet_&quot;;
export MAPNIK_PREFIX=''
$*
#-----------------------------------------------------------------------------
</pre>
<p>NOTA: En el script sustituye &#8220;&#8221; por tu nombre de usuario.</p>
<p><strong>Configuración de la plantilla de OSM</strong></p>
<p>Como ya hemos indicado, entre los ficheros proporcionados en la carpeta &#8220;mapnik&#8221;, tenemos uno muy especial, &#8220;osm_template.xml&#8221;. Como habeis deducido se trata de la plantilla que utiliza Mapnik para generar el mapfile (&#8220;osm.xml&#8221;). Sí no tocamos nada de este archivo obtendremos un renderizado de imágenes o tiles igual que el utilizado por el &#8220;slippy map&#8221; de <a href="http://www.openstreetmap.org">www.openstreetmap.org</a>. Es aquí, por tanto, donde debemos de agudizar nuestro ingenio para establecer una simbología acorde con nuestros intereses: cambiar colores, retocar las SQL de las layers, añadir o cambiar iconos, etc.</p>
<p>En lo referente a este artículo, sólo vamos a realizar pequeños cambios.</p>
<p>1. Vamos a resaltar las paradas del tranvía para que aparezca el logotipo &#8220;oficial&#8221; por el que se conoce en Alicante a este medio de transporte (<a href="http://www.fgvalicante.com">TRAM</a>)</p>
<p>En el documento cambiamos este texto:</p>
<pre class="brush: xml; title: ; notranslate">
     &lt;Rule&gt;
      &lt;MaxScaleDenominator&gt;100000&lt;/MaxScaleDenominator&gt;
      &lt;MinScaleDenominator&gt;25000&lt;/MinScaleDenominator&gt;
      &lt;Filter&gt;[railway]='station' and not [disused]='yes'&lt;/Filter&gt;
      &lt;PointSymbolizer file =  &quot;%SYMBOLS_DIR%/station_small.png&quot; type=&quot;png&quot; width=&quot;6&quot; height=&quot;6&quot; /&gt;
    &lt;/Rule&gt;
</pre>
<p>Por este otro</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;Rule&gt;
      &lt;MaxScaleDenominator&gt;100000&lt;/MaxScaleDenominator&gt;
      &lt;MinScaleDenominator&gt;25000&lt;/MinScaleDenominator&gt;
      &lt;Filter&gt;[railway]='station' and not [disused]='yes'&lt;/Filter&gt;
      &lt;PointSymbolizer file =  &quot;%SYMBOLS_DIR%/tram2.png&quot; type=&quot;png&quot; width=&quot;20&quot; height=&quot;20&quot; /&gt;
    &lt;/Rule&gt;
</pre>
<p>2. Por otra parte vamos a cambiar el color de fondo para las áreas residenciales<br />
Color: <span style="color: #F6CEE3">♦♦♦♦♦</span></p>
<pre class="brush: xml; title: ; notranslate">
    &lt;Rule&gt;
      &lt;MaxScaleDenominator&gt;1000000&lt;/MaxScaleDenominator&gt;
      &lt;MinScaleDenominator&gt;1000&lt;/MinScaleDenominator&gt;
      &lt;Filter&gt;[landuse] = 'residential'&lt;/Filter&gt;
      &lt;PolygonSymbolizer&gt;
        &lt;CssParameter name=&quot;fill&quot;&gt;#F6CEE3&lt;/CssParameter&gt;
      &lt;/PolygonSymbolizer&gt;
    &lt;/Rule&gt;
</pre>
<p><strong>Crear imágenes</strong></p>
<p>Una vez configurado nuestro mapfile (&#8220;osm.xml&#8221;) pasamos a generar imágenes utilizando el script &#8220;generate_image.py&#8221;. Te recomendamos que hagas una copia de ese archivo para no trabajar con el original. Con un editor de textos tienes que modificar los siguientes parámetros:</p>
<pre class="brush: python; title: ; notranslate">
#!/bin/sh
# ... resto de código
    mapfile = &quot;osm.xml&quot;
    map_uri = &quot;image.png&quot;

    #---------------------------------------------------
    #  Change this to the bounding box you want
    #
    # Área metropolitana de Alicante
    ll = (-0.5534, 38.3245, -0.4267, 38.4071)
    #---------------------------------------------------
    z = 18
    imgx = 50 * z
    imgy = 50 * z
# ... resto de código
</pre>
<p>Cómo ves sólo es necesario modificar tres aspectos:</p>
<ol>
<li>Extensión de la imagen en grados decimales: xmin,ymin,xmax,ymax</li>
<li>Nivel de zoom: del 1 (mundo) al 18 (máximo de detalle)</li>
<li>Dimensiones de la imagen en píxeles</li>
</ol>
<p>NOTA:</p>
<p>Para evitar resultados desagradables intenta ajustar el BBOX y las dimensiones de la imagen.</p>
<p>Por último debemos de realizar los siguientes pasos para generar la imagen</p>
<p>1. Leer las variables que hemos definido en &#8220;set_mapnik.env&#8221;</p>
<pre class="brush: bash; title: ; notranslate">source set-mapnik-env</pre>
<p>2.  Utilizar la plantilla &#8220;osm-template.xml&#8221; para generar el fichero &#8220;oxm.xml&#8221;</p>
<pre class="brush: bash; title: ; notranslate">
./customize-mapnik-map &gt;$MAPNIK_MAP_FILE
</pre>
<p>3. Lanzar el script:</p>
<pre class="brush: bash; title: ; notranslate">python mi_genera_imagen.py</pre>
<p>Este es el resultado:</p>
<p>Zoom 14<br />
<img src="http://www.gisandchips.org/wp-content/ali_zoom14-300x300.png" alt="" width="300" height="300" /></p>
<p>Zoom 18 (fíjate en el renderizado de las estaciones del TRAM)<br />
<img src="http://www.gisandchips.org/wp-content/ali_zoom18.png" alt="" width="300" height="300" /></p>
<p><strong>Crear las tiles</strong></p>
<p>Esta es la parte de Mapnik que tiene más interés para nosotros, puesto que nos permitirá generar nuestro propio TMS para ser utilizado con independencia del &#8220;Slippy map&#8221; de OpenStreetMap.</p>
<p>1. Creamos el directorio donde se guardarán las tiles creadas:</p>
<pre class="brush: bash; title: ; notranslate">mkdir -p $MAPNIK_TILE_DIR</pre>
<p>2. Editamos el fichero &#8220;generate_tiles.py&#8221; para definir las zonas a renderizar</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/python
# resto de código
# directorio donde se almacenan las imágenes
        tile_dir = home + &quot;/osm/tiles/&quot;

    #-------------------------------------------------------------------------
    #
    # Change the following for different bounding boxes and zoom levels
    #
    # Start with an overview
    # World
    bbox = (-180.0,-90.0, 180.0,90.0)

    render_tiles(bbox, mapfile, tile_dir, 0, 5, &quot;World&quot;)

    # Europa
    minZoom = 6
    maxZoom = 8
    bbox = (1.0,10.0, 20.6,50.0)
    render_tiles(bbox, mapfile, tile_dir, minZoom, maxZoom)

    # Provincia de Alicante
    bbox = (-1.498,37.622,0.529,38.946)
    render_tiles(bbox, mapfile, tile_dir, 9, 11 , &quot;Europe+&quot;)

    # Área metropolitana de la ciudad de Alicante
    bbox = (-0.6171,38.295,-0.3637,38.4602)
    render_tiles(bbox, mapfile, tile_dir, 12, 18 , &quot;Alicante&quot;)
</pre>
<p>Cómo habrás podido deducir vamos a generar tiles en cuatro intervalos de escala:</p>
<ul>
<li>Escalas pequeñas: Zoom del 1 al 5</li>
<li>Escalas medias: 6 al 8</li>
<li>Escalas grandes (más detalles): 9 al 11</li>
<li>Escalas de máximo detalle): 12 al 18</li>
</ul>
<p>3. Ejecutamos el script</p>
<pre class="brush: bash; title: ; notranslate">python ./mi_genera_tiles.py</pre>
<p>4. Comprobación:<br />
Fíjate que en la carpeta &#8220;tiles&#8221; tendremos una carpeta por cada nivel de zoom. En los niveles superiores es donde habrán más imágenes (las de mayor detalle)</p>
<pre class="brush: bash; title: ; notranslate">ls tiles</pre>
<p>Por fin, ya hemos creado nuestro directorio de tiles listo para ser utilizado por OpenLayers como un TMS.</p>
<p>Esto es todo. Espero que os haya gustado. Comentarios y críticas serán bien recibidas</p>
<p>Este artículo es el segundo de una serie formada por:</p>
<ul>
<li><a href="http://www.gisandchips.org/2009/10/22/renderizado-de-osmcon-mapnik-para-usar-en-openlayers/#more-387">Renderizado con Mapnik</a></li>
<li>Mapnik y OpenStreetMap (este post)</li>
<li>Thumbnails con Mapnik y OpenStreetMap</li>
<li>Uso de TMS de OpenStreetMap con OpenLayers</li>
<li>TMS de OpenStreetMap con Mod_tile</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2009/10/23/openstreetmap-y-mapnik/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Renderizado con Mapnik</title>
		<link>http://www.gisandchips.org/2009/10/22/renderizado-de-osmcon-mapnik-para-usar-en-openlayers/</link>
		<comments>http://www.gisandchips.org/2009/10/22/renderizado-de-osmcon-mapnik-para-usar-en-openlayers/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 08:43:27 +0000</pubDate>
		<dc:creator>jose</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Mapnik]]></category>
		<category><![CDATA[OpenStreetMap]]></category>
		<category><![CDATA[render]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=387</guid>
		<description><![CDATA[En el planteamiento que presenté en el primer artículo sobre OSM y PgRouting no estaba incluido el tema del renderizado, pero tras indagar el tema de Mapnik me he dado cuenta de las magníficas posibilidades que ofrece este renderizador, de ahí que haga un inciso para introducir esta cuestión. Mapnik es un toolkit en C++ [...]]]></description>
			<content:encoded><![CDATA[<p>En el planteamiento que presenté en el primer artículo sobre OSM y PgRouting no estaba incluido el tema del renderizado, pero tras indagar el tema de <a href="http://mapnik.org/">Mapnik</a> me he dado cuenta de las magníficas posibilidades que ofrece este renderizador, de ahí que haga un inciso para introducir esta cuestión.</p>
<p>Mapnik es un toolkit en C++ para renderizar varios orígenes de datos, que tiene bindings para Python. La calidad de este paquete, a mi juicio, está por encima de otros renderizadores como Osmarender o Kosmos. Profundizar en él me ha permitido aprender algo de Python, que nunca viene mal y sumergirme en las entrañas de la edición cartográfica. En cualquiera de los casos, los resultados estarán limitados a nuestra destreza para la composición de mapas, pero nunca a las limitaciones del programa.</p>
<p><span id="more-387"></span></p>
<p>Mapnik entiende los siguientes orígenes de datos:</p>
<ul>
<li>Shapefiles</li>
<li>PostGIS</li>
<li>Raster (generalmente TIFF, aunque si se compila Mapnik con GDAL podemos ampliar el espectro de formatos)</li>
</ul>
<p><span style="font-weight: bold">OBJETIVO</span>:</p>
<p>En muchas de nuestras aplicaciones web incluimos una layer del proveedor OSM, utilizando OpenLayers, Mapfish u otras. El resultado es fácil de implementar, pero tiene el problema de depender del estado de salud del servidor oficial de www.openstreetmap.org. Además, puede que en un momento dado nos planteemos utilizar nuestra propia simbolización, cambiando los colores de las vias, o añadiendo unos iconos diferentes a los oficiales Aquí nos planteamos crear un TMS (Tile Map Service), o lo que es lo mismo, un conjunto de imágenes de mapa (tiles) de reducido tamaño (256 * 256) , personalizadas con nuestros criterios de simbolización gráfica, que están ordenadas en carpetas, cada una de las cuales recibe el nombre del nivel de zoom utilizado, que oscila entre 1 y 18, siguiendo la estructura del &#8220;<a href="http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames">mapnik slippy map</a>&#8220;, que es una forma de ordenar las tiles en función de la proyección utilizada (Mercator).</p>
<p>REFERENCIAS WEB:</p>
<ul>
<li><a href="http://weait.com/content/build-your-own-openstreetmap-server">http://weait.com/content/build-your-own-openstreetmap-server</a> Interesante portal con artículos sobre OSM y Mapnik. Os lo recomiendo para instalar Mapnik y realizar pruebas</li>
</ul>
<p><span style="font-weight: bold">DESARROLLO</span>:</p>
<ol>
<li><span style="background-color: #ffffff"> Compilación de librerías necesarias (Mapnik y osm2pgsql)</span></li>
<li><span style="background-color: #ffffff">Creación de una geodatabase con datos OSM utilizando Osm2Pgsql</span></li>
<li><span style="background-color: #ffffff">Configuración de la plantilla de mapa (XML mapfile)</span></li>
<li><span style="background-color: #ffffff">Pruebas de renderizado</span></li>
<li><span style="background-color: #ffffff">Creación del TMS</span></li>
<li><span style="background-color: #ffffff">Implementación del TMS en OpenLayers</span></li>
</ol>
<p><span style="font-weight: bold">COMPILACIÓN DE LIBRERÍAS</span>:</p>
<p>Entrando en faena vamos a compilar el paquete Mapnik, que como no podía ser de otra manera tiene una dependencia insalvable, BOOST, que ya vimos en el anterior artículo. No obstante indico rápidamente su compilación:</p>
<p><span style="font-weight: bold">COMPILACIÓN DE BOOST</span></p>
<p>1. Añadir dependencias. Según la distro necesitaremos una u otra (python-devel, freetype-devel, etc). En este paso vamos a incluir una librería que me ha dado varios quebraderos de cabeza: EXPAT. No sólo es necesaria instalarla, sino que además debemos de indicar algunas variables de configuración. Empezamos por su instalación desde la paquetería</p>
<p>Ubuntu: $  sudo apt-get install libexpat1-dev</p>
<p>$ sudo apt-get install libltdl7-dev libpng12-dev libtiff4-dev libicu-dev libboost-regex-dev libboost-iostreams-dev libboost-filesystem-dev libboost-thread-dev libboost-python1.34.1 libboost-python-dev libfreetype6-dev libcairo2-dev libcairomm-1.0-dev libboost-program-options-dev python-cairo-dev libboost-serialization-dev imagemagick</p>
<p>Centos: $ yum install expat expat-devel.x86_64</p>
<p>NOTA: Fíjate que para expat le indico específicamente la plataformas de 64 bits. Es importante indicarla. Si ponemos &#8220;yum install expat-devel&#8221; instalará las dos, y nos proporcionará problemas en el futuro (por ejemplo compilando nuestra querida GDAL). Indícale cual es tu plataforma (x86_64 / i386)</p>
<p>2. Define variables para expat:</p>
<pre class="brush: bash; title: ; notranslate">&lt;br&gt;export EXPAT_INCLUDE=/usr/include&lt;br&gt;export EXPAT_LIBPATH=/usr/lib&lt;br&gt;</pre>
<p>3. Descargar la version 1.39 y descomprimir en /usr/local/</p>
<pre class="brush: bash; title: ; notranslate">
mkdir /usr/local/include/boost
wget http://downloads.sourceforge.net/project/boost/boost/1.39.0/boost_1_39_0.tar.bz2
tar -xjvf boost_1_39_0.tar.bz2&lt;br&gt;cd boost_1_39_0
</pre>
<p>4. Compilar:</p>
<pre class="brush: bash; title: ; notranslate">./bootstrap.sh --prefix=/usr/local/
./bjam install --includedir=/usr/local/include/boost/
</pre>
<p>Como root:</p>
<pre class="brush: bash; title: ; notranslate">/sbin/ldconfig</pre>
<p>Este comando es mano de santo para que los compiladores encuentren las librerías.<br />
<span style="font-weight: bold">COMPILAR MAPNIK</span><br />
Para compilar en Ubuntu os recomiendo seguir las indicaciones de este <a href="http://weait.com/content/build-your-own-openstreetmap-server">enlace</a>. Para Centos estos son los pasos a seguir:</p>
<pre class="brush: bash; title: ; notranslate">cd /home/&lt;usuario&gt;/compilar</pre>
<p>1. Descargar y descomprimir la fuente de Mapnik  (versión 0.6.1)</p>
<pre class="brush: bash; title: ; notranslate">wget http://download.berlios.de/mapnik/mapnik-0.6.1.tar.bz2
tar -xjvf mapnik-0.6.1.tar.bz2
cd mapnik-0.6.1&lt;br&gt;
</pre>
<p>2. Compilar:</p>
<pre class="brush: bash; title: ; notranslate">python scons/scons.py configure
python scons/scons.py BOOST_INCLUDES=/usr/local/include/boost/boost-1_39/ BOOST_LIBS=/usr/local/lib BOOST_TOOLKIT=gcc41
</pre>
<p>Como root:</p>
<pre class="brush: bash; title: ; notranslate">
python scons/scons.py BOOST_INCLUDES=/usr/local/include/boost/boost-1_39/ BOOST_LIBS=/usr/local/lib BOOST_TOOLKIT=gcc41 install
</pre>
<p>3. Actualizar rutas de librerías (como root):</p>
<pre class="brush: bash; title: ; notranslate">/sbin/ldconfig</pre>
<p>4. Comprobación de la instalación:</p>
<p>Las fuentes contienen una demo para comprobar la instalación. Se trata de un script en Python que tras su ejecución llama a algunos shapefiles y genera unas imágenes en PNG. También lo hará en otros formatos (PDF, PS, etc.)  sí has compilado Mapnik con Cairo y PyCairo. En Ubuntu es muy fácil ya que estas librerías se encuentran en el repositorio, pero en Centos he sido incapaz de utilizarlas (si alguno lo consigue su comentario será de agradecer).</p>
<p>Mapnik utiliza la librería <a href="http://www.antigrain.com/">AGG</a> para crear las imágenes, siendo ésta la librería de uso por defecto, aunque también puede utilizar Cairo.<br />
1. Cambia al directorio de pruebas</p>
<pre class="brush: bash; title: ; notranslate">
cd &lt;fuente&gt;/demo/python
python rundemo.py
</pre>
<p>Obtendrás este mensaje:</p>
<pre>Skipping cairo examples as Pycairo not available
3 maps have been rendered in the current directory:
- demo.png
- demo256.png
- demo.jpg
Have a look!</pre>
<p>Bueno, pues ya está. Si las imágenes se han generado Mapnik funciona. Sí te da algun error es que te falta alguna librería. Otra manera de ver que errores hay es utilizando la propia consola de python. Escribe lo que está en negrita:</p>
<p>jose@jose:~/compilar$ <span style="font-weight: bold">python</span></p>
<p>Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)</p>
<p><span style="background-color: #ffffff">[GCC 4.3.3] on linux2</span><span style="background-color: #ffffff">Type &#8220;help&#8221;, &#8220;copyright&#8221;, &#8220;credits&#8221; or &#8220;license&#8221; for more information.</span><br />
<span style="background-color: #ffffff">&gt;&gt;&gt;<span style="font-weight: bold"> import mapnik</span></span><br />
&gt;&gt;&gt; <span style="font-weight: bold">exit()</span></p>
<p><span style="background-color: #ffffff">Sí tras escribir &#8220;import mapnik&#8221; obtienes algunas líneas de error es que algo te falta.  De lo contrario el intérprete de Python entiende que la llamada a la librería funciona y no devuelve nada.</span><br />
<span style="font-weight: bold">CREACIÓN DE UNA GEODATABASE CON EL PLANET DE OSM</span></p>
<p>Nuestro objetivo es ahora crear una geodatabase de PostGIS con datos procedente de un planet.osm. Con ello,  conseguiremos tener un repositorio de datos cuyo único fin es ser utilizado por Mapnik para renderizar tiles, y no para otras funciones como la de routing.  Por esta razón utilizamos &#8220;osm2pgsql&#8221;. Esta herramienta suele formar parte de los repositorios de las distros, por lo que sólo necesitas:</p>
<pre>Ubuntu: sudo apt-get install osm2pgsql
Centos: yum install osm2pgsql</pre>
<p><span style="font-weight: bold">Compilación de osm2pgsql</span>:</p>
<pre class="brush: bash; title: ; notranslate">&lt;br&gt;svn co http://svn.openstreetmap.org/applications/utils/export/osm2pgsql/&lt;br&gt;cd osm2pgsql&lt;br&gt;make&lt;br&gt;</pre>
<p><span style="background-color: #ffffff">Crear una geodatabase con datos de OSM es una labor sencilla, pero ten en cuenta que OSM cambia constantemente, por lo que la validez de tus datos tienen una caducidad. Por esta razón es importante que articulemos algún sistema para que cada cierto tiempo la base de datos de OSM se actualice sólo. Por ello te recomiendo que personalices el siguiente script en bash que te facilitará la labor:</span><span style="background-color: #ffffff"> </span></p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/sh
echo &quot;Script en Bash para actualizar un planet.osm en una base de datos OSM con Postgis v. 1.4.&quot;
echo &quot;Borrando spain.osm.bz2&quot;
rm spain.osm.bz2
echo &quot;Descargando fichero osm de Spain desde Cloudmade.com&quot;
wget http://downloads.cloudmade.com/europe/spain/spain.osm.bz2
echo &quot;Descomprimiendo&quot;
bzip2 -d spain.osm.bz2
echo &quot;Borrando bbdd osm&quot;
dropdb -h localhost -U postgres osm
echo &quot;Creando bbdd osm&quot;
createdb -U postgres -E UTF8 osm
echo &quot;Instalar lenguaje pl/pgsql y Postgis en bbdd osm&quot;
createlang -U postgres plpgsql osm
psql -U postgres -f /usr/share/pgsql/contrib/postgis.sql osm
psql -U postgres -f /usr/share/pgsql/contrib/spatial_ref_sys.sql osm
echo &quot;Añadir datos de spain.osm a la bbdd osm&quot;
echo &quot;Tiempo aproximado: 11 minutos&quot;
osm2pgsql --slim -H localhost -U postgres -d osm ./spain.osm
echo &quot;fin&quot;
</pre>
<p>NOTA: Es muy importante utilizar el parámetro &#8220;slim&#8221; en osm2pgsql, puesto que permite introducir datos directamente a la base de datos, lo que resulta muy útil con planet.osm de mucho peso. Si no se usa, cargará en memoria todo el osm hasta que ocupe toda la memoria de tu ordenador.  Contenido de la geodatabase</p>
<pre>psql -h localhost -U postgres osm
Welcome to psql 8.3.8 (server 8.3.7), the PostgreSQL interactive terminal.

Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help with psql commands
       \g or terminate with semicolon to execute query
       \q to quit

osm=# \d
                     List of relations
 Schema |            Name            |   Type   |  Owner
--------+----------------------------+----------+----------
 public | geometry_columns           | table    | postgres
 public | planet_osm_line            | table    | postgres
 public | planet_osm_line_pid_seq    | sequence | postgres
 public | planet_osm_nodes           | table    | postgres
 public | planet_osm_point           | table    | postgres
 public | planet_osm_point_pid_seq   | sequence | postgres
 public | planet_osm_polygon         | table    | postgres
 public | planet_osm_polygon_pid_seq | sequence | postgres
 public | planet_osm_rels            | table    | postgres
 public | planet_osm_roads           | table    | postgres
 public | planet_osm_roads_pid_seq   | sequence | postgres
 public | planet_osm_ways            | table    | postgres
 public | spatial_ref_sys            | table    | postgres
(13 rows)</pre>
<p><span style="font-weight: bold">INTRODUCCIÓN A MAPNIK CON PYTHON</span><br />
Como ya he dicho, no soy un especialista en este lenguaje, aunque su sintaxis me parece muy clara para entenderla sin problemas.<br />
Lo primero que debemos de tener en cuenta es que el diagrama de flujo de Mapnik exige para su uso de un script en Python (o desde la misma consola de Python) donde se aprecien las siguientes fases:</p>
<p>1. Cargar los paquetes (bindings) de Mapnik para Python<br />
2. Indicar la fuente de datos (datasource) de cada layer a representar<br />
3. Definir la simbología de cada layer<br />
4. Indicar los parámetros de la imagen a crear: tamaño, nombre del fichero</p>
<p>Veamos el ejemplo más sencillo: Crear una imagen a partir de un shapefile</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
# Fichero: hola_mundo.py
# Cargamos los bindings de mapnik
import mapnik
# Definimos un objeto mapa, con un tamaño (en píxeles) y una proyección según PROJ4
m = mapnik.Map(600,300,'+proj=latlong +datum=WGS84')
# Indicamos el color de fondo
m.background = mapnik.Color('steelblue')
# Creamos un estilo. Un estilo es un tipo de objeto que puede almacenar una o varias reglas (rules)
# para la representación cartográfica
s = mapnik.Style()
# Creamos un objeto rule
r=mapnik.Rule()
# Aplicamos parámetros a esa regla. En este caso:
# 1. relleno del polígono
# 2. simbología de la línea (outline)
r.symbols.append(mapnik.PolygonSymbolizer(mapnik.Color('#f2eff9')))
r.symbols.append(mapnik.LineSymbolizer(mapnik.Color('rgb(50%,50%,50%)'),0.1))
# asociamos la &quot;rule&quot; (r) al estilo (s)
s.rules.append(r)
# Asignamos un nombre al estilo
m.append_style('My Style',s)
# Creamos un objeto layer de mapnik: un nombre y una projección. En este caso la geodésica mundial EPSG:4326
lyr = mapnik.Layer('world','+proj=latlong +datum=WGS84')
# Definimos el origen de datos
lyr.datasource = mapnik.Shapefile(file='/Users/path/to/your/data/world_borders')
# Asociamos a la layer el estilo que hemos creado
lyr.styles.append('My Style')
# Asociamos la layer al objeto mapa (m)
m.layers.append(lyr)
# Indicamos que se renderizará el total de la extensión del shapefile
m.zoom_to_box(lyr.envelope())
# Renderizamos la imagen: indicando el objeto mapa (m) y el nombre del fichero de imagen a crear
mapnik.render_to_file(m,'world.png', 'png')
# Si queremos que los parámetros indicados en el objeto mapa sean serializados a un fichero
# mapfile (XML) sólo tenemos que añadir esta linea
mapnik.save_map(m,'mi_mapfile.xml')
</pre>
<p>Fíjate en la línea que hace referencia a la proyección a utilizar. ¿De donde saco estos parámetros? En esta página puedes encontrar los parámetros necesarios: <a href="http://spatialreference.org/ref/epsg/">http://spatialreference.org/ref/epsg/</a>. Veamos algunos ejemplos:</p>
<ul>
<li><span style="background-color: #ffffff">EPSG 4326: +proj=latlong +datum=WGS84 (<a href="http://spatialreference.org/ref/epsg/4326/proj4/">http://spatialreference.org/ref/epsg/4326/proj4/</a>)</span></li>
<li><span style="background-color: #ffffff">EPSG 900913: <span>+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs (<a href="http://spatialreference.org/ref/sr-org/6627/proj4/">http://spatialreference.org/ref/sr-org/6627/proj4/</a>)</span></span></li>
<li><span style="background-color: #ffffff">EPSG 23030: <span>+proj=utm +zone=30 +ellps=intl +units=m +no_defs (<a href="http://spatialreference.org/ref/epsg/23030/proj4/">http://spatialreference.org/ref/epsg/23030/proj4/</a>)</span></span></li>
</ul>
<p>Para ejecutar este script sólo tienes que indicarle que es un ejecutable:</p>
<pre class="brush: bash; title: ; notranslate">&lt;br&gt;chmod +x hola_mundo.py&lt;br&gt;</pre>
<p>Y ahora lo ejecutamos:</p>
<pre class="brush: bash; title: ; notranslate">&lt;br&gt;python hola_mundo.py&lt;br&gt;</pre>
<p>Resultado:</p>
<p style="text-align: center">
<div class="mceTemp mceIEcenter">
<dl>
<dt><img class="size-medium wp-image-704" src="http://www.gisandchips.org/wp-content/hola_mundo-300x150.png" alt="hola munco con Mapnik" width="300" height="150" /></dt>
<dd>hola mundo con Mapnik</dd>
</dl>
</div>
<p><span style="font-weight: bold">Mapfile de Mapnik</span><br />
Como ves, con muy pocas líneas tenemos una imagen creada con Mapnik, pero, ¿porque no separamos la lógica de representación y los orígenes de datos en un fichero de mapa (mapfile)? Posiblemente este nos recuerda a más de uno los famosos &#8220;mapfile&#8221; de MapServer, y realmente bastante se parecen a ellos, pero esta vez la lógica está en un fichero XML.  Manos a la obra. Primero generamos el script de Python sin referencia alguna a la simbología y los datasources:</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
import mapnik
mapfile = 'hola_mundo.xml'
map_output = 'hola_mundo.png'
m = mapnik.Map(600, 300)
mapnik.load_map(m, mapfile)
bbox = mapnik.Envelope(mapnik.Coord(-180.0, -90.0), mapnik.Coord(180.0, 90.0))
m.zoom_to_box(bbox)
mapnik.render_to_file(m, map_output)
</pre>
<p>Fíjate que en la tercera línea llamamos a un fichero de mapa. Se trata de un fichero XML con una estructura definida, donde se indican los datasources (layers) y su representación (styles y rules dentro de ella)</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;!DOCTYPE Map&gt;
&lt;Map bgcolor=&quot;steelblue&quot; srs=&quot;+proj=latlong +datum=WGS84&quot;&gt;
  &lt;Style name=&quot;My Style&quot;&gt;
    &lt;Rule&gt;
      &lt;PolygonSymbolizer&gt;
        &lt;CssParameter name=&quot;fill&quot;&gt;#f2eff9&lt;/CssParameter&gt;
      &lt;/PolygonSymbolizer&gt;
      &lt;LineSymbolizer&gt;
        &lt;CssParameter name=&quot;stroke&quot;&gt;rgb(50%,50%,50%)&lt;/CssParameter&gt;
        &lt;CssParameter name=&quot;stroke-width&quot;&gt;0.1&lt;/CssParameter&gt;
      &lt;/LineSymbolizer&gt;
    &lt;/Rule&gt;
  &lt;/Style&gt;&lt;
  &lt;Layer name=&quot;world&quot; srs=&quot;+proj=latlong +datum=WGS84&quot;&gt;
    &lt;StyleName&gt;My Style&lt;/StyleName&gt;
    &lt;Datasource&gt;
      &lt;Parameter name=&quot;type&quot;&gt;shape&lt;/Parameter&gt;
      &lt;Parameter name=&quot;file&quot;&gt;&lt;ruta al shapefile, pero sin extensión .shp&gt;&lt;/Parameter&gt;
    &lt;/Datasource&gt;
  &lt;/Layer&gt;
&lt;/Map&gt;
</pre>
<p>En resumen tenemos:<br />
- Fondo de mapa<br />
- Style &#8211;&gt; Rule &#8211;&gt; Simbología<br />
- Layer &#8211;&gt; Proyección &#8211;&gt; DataSource &#8211;&gt; Style</p>
<p>Estos dos ejemplos utilizan shapefile. Para indicar un datasource PostGIS hay que especificar estas líneas</p>
<p>a) En el caso del fichero Python sin XML</p>
<pre class="brush: python; title: ; notranslate">
# proyección UTM ED-50 (España) --&gt; EPSG 23030
lyr = mapnik.Layer('spain','+proj=utm +zone=30 +ellps=intl +units=m +no_defs')
lyr = mapnik.Layer('Layer de PostGIS')
lyr.datasource = mapnik.PostGIS(host='localhost',user='postgres',password='',dbname='hispania',table='provincias')
lyr.styles.append('Mi estilo')
</pre>
<p>b) En el caso de un XML este sería el contenido de la parte referente a la layer</p>
<pre class="brush: xml; title: ; notranslate">
&lt;Layer name=&quot;provincias&quot; status=&quot;on&quot; srs=&quot;+proj=utm +zone=30 +ellps=intl +units=m +no_defs&quot;&gt;
    &lt;StyleName&gt;mi estilo&lt;/StyleName&gt;
    &lt;Datasource&gt;
      &lt;Parameter name=&quot;type&quot;&gt;postgis&lt;/Parameter&gt;
      &lt;Parameter name=&quot;host&quot;&gt;localhost&lt;/Parameter&gt;
      &lt;Parameter name=&quot;user&quot;&gt;postgres&lt;/Parameter&gt;
      &lt;Parameter name=&quot;password&quot;&gt;&lt;/Parameter&gt;
      &lt;Parameter name=&quot;dbname&quot;&gt;hispania&lt;/Parameter&gt;
      &lt;Parameter name=&quot;table&quot;&gt;provincias&lt;/Parameter&gt;
      &lt;Parameter name=&quot;estimate_extent&quot;&gt;false&lt;/Parameter&gt;
      &lt;Parameter name=&quot;extent&quot;&gt;-510000.0,3800000.0,1200000.0,4900000.0&lt;/Parameter&gt;
    &lt;/Datasource&gt;
&lt;/Layer&gt;
</pre>
<p>El parámetro table (provincias) podemos sustituir el nombre de una tabla geométrica por una consulta SQL encerrada entre paréntesis:<br />
(select * from provincias)</p>
<p>Resultado:<br />
<img src="http://www.gisandchips.org/wp-content/hola_spain_xml-300x300.png" alt="hola spain" width="300" height="300" /></p>
<p>Enlazando con lo último, en el momento en que definimos en una &#8220;layer&#8221; un &#8220;datasource&#8221;, sea un shapefile o PostGIS, con su correspondiente &#8220;style&#8221;, tenemos a disposición de las &#8220;rules&#8221; todas las columnas o campos del datasource, que pueden ser utilizados como filtros, lo que resulta muy util para la edición de cartografía temática.<br />
Fichero: mapa_spain_xml2.py</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
import mapnik
mapfile = 'provincias2.xml'
map_output = 'hola_spain_xml2.png'
m = mapnik.Map(600, 600)
mapnik.load_map(m, mapfile)
bbox = mapnik.Envelope(mapnik.Coord(-510000.0, 3800000.0), mapnik.Coord(1200000.0, 4900000.0))
m.zoom_to_box(bbox)
mapnik.render_to_file(m, map_output)
</pre>
<p>Ahora el fichero<br />
Fichero provincias2.xml</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;!DOCTYPE Map&gt;
&lt;Map bgcolor=&quot;steelblue&quot; srs=&quot;+proj=utm +zone=30 +ellps=intl +units=m +no_defs&quot;&gt;
  &lt;Style name=&quot;mi estilo provincias&quot;&gt;
    &lt;Rule&gt;
      &lt;PolygonSymbolizer&gt;
        &lt;CssParameter name=&quot;fill&quot;&gt;#f2eff9&lt;/CssParameter&gt;
      &lt;/PolygonSymbolizer&gt;
      &lt;LineSymbolizer&gt;
        &lt;CssParameter name=&quot;stroke&quot;&gt;rgb(50%,50%,50%)&lt;/CssParameter&gt;
        &lt;CssParameter name=&quot;stroke-width&quot;&gt;0.1&lt;/CssParameter&gt;
      &lt;/LineSymbolizer&gt;
    &lt;/Rule&gt;
  &lt;/Style&gt;
  &lt;Style name=&quot;mi estilo vias&quot;&gt;
&lt;!-- autopistas --&gt;
    &lt;Rule&gt;
      &lt;Filter&gt;[level] = 41&lt;/Filter&gt;
      &lt;LineSymbolizer&gt;
        &lt;CssParameter name=&quot;stroke&quot;&gt;#506077&lt;/CssParameter&gt;
        &lt;CssParameter name=&quot;stroke-width&quot;&gt;4&lt;/CssParameter&gt;
      &lt;/LineSymbolizer&gt;
      &lt;TextSymbolizer name=&quot;codigo&quot; face_name=&quot;DejaVu Sans Book&quot; size=&quot;11&quot; fill=&quot;#000&quot; halo_radius=&quot;1&quot; spacing=&quot;400&quot; placement=&quot;line&quot; /&gt;
    &lt;/Rule&gt;
&lt;!-- nacionales --&gt;
    &lt;Rule&gt;
      &lt;Filter&gt;[level] = 40&lt;/Filter&gt;
      &lt;LineSymbolizer&gt;
        &lt;CssParameter name=&quot;stroke&quot;&gt;#a37b48&lt;/CssParameter&gt;
        &lt;CssParameter name=&quot;stroke-width&quot;&gt;2&lt;/CssParameter&gt;
       &lt;/LineSymbolizer&gt;
    &lt;/Rule&gt;
  &lt;/Style&gt;
&lt;Layer name=&quot;provincias&quot; status=&quot;on&quot; srs=&quot;+proj=utm +zone=30 +ellps=intl +units=m +no_defs&quot;&gt;
    &lt;StyleName&gt;mi estilo provincias&lt;/StyleName&gt;
    &lt;Datasource&gt;
      &lt;Parameter name=&quot;type&quot;&gt;postgis&lt;/Parameter&gt;
      &lt;Parameter name=&quot;host&quot;&gt;localhost&lt;/Parameter&gt;
      &lt;Parameter name=&quot;user&quot;&gt;postgres&lt;/Parameter&gt;
      &lt;Parameter name=&quot;password&quot;&gt;&lt;/Parameter&gt;
      &lt;Parameter name=&quot;dbname&quot;&gt;hispania&lt;/Parameter&gt;
      &lt;Parameter name=&quot;table&quot;&gt;provincias&lt;/Parameter&gt;
      &lt;Parameter name=&quot;estimate_extent&quot;&gt;false&lt;/Parameter&gt;
      &lt;Parameter name=&quot;extent&quot;&gt;-510000.0,3800000.0,1200000.0,4900000.0&lt;/Parameter&gt;
    &lt;/Datasource&gt;&lt;br&gt;&lt;/Layer&gt;
&lt;Layer name=&quot;vias&quot; status=&quot;on&quot; srs=&quot;+proj=utm +zone=30 +ellps=intl +units=m +no_defs&quot;&gt;
    &lt;StyleName&gt;mi estilo vias&lt;/StyleName&gt;
    &lt;Datasource&gt;
      &lt;Parameter name=&quot;type&quot;&gt;postgis&lt;/Parameter&gt;
      &lt;Parameter name=&quot;host&quot;&gt;localhost&lt;/Parameter&gt;
      &lt;Parameter name=&quot;user&quot;&gt;postgres&lt;/Parameter&gt;
      &lt;Parameter name=&quot;password&quot;&gt;&lt;/Parameter&gt;
      &lt;Parameter name=&quot;dbname&quot;&gt;hispania&lt;/Parameter&gt;
      &lt;Parameter name=&quot;table&quot;&gt;vias&lt;/Parameter&gt;
      &lt;Parameter name=&quot;estimate_extent&quot;&gt;false&lt;/Parameter&gt;
      &lt;Parameter name=&quot;extent&quot;&gt;-510000.0,3800000.0,1200000.0,4900000.0&lt;/Parameter&gt;
    &lt;/Datasource&gt;
&lt;/Layer&gt;
&lt;/Map&gt;
</pre>
<p>Este mapfile consta de:<br />
- 2 datasources<br />
- provincias &#8211;&gt; asociado al style &#8220;mi estilo provincias&#8221;<br />
- vias &#8211;&gt; asociado al style &#8220;mi estilo vias&#8221;<br />
- 2 styles<br />
- &#8220;mi estilo provincias&#8221;  &#8211;&gt; con una sola &#8220;rule&#8221;<br />
- &#8220;mi estilo vias&#8221; &#8211;&gt; con 2 &#8220;rules&#8221;<br />
&#8211;&gt; Autopistas: Filtro: &#8220;[level] = 40&#8243;, Texto: ver TextSymbolizer<br />
&#8211;&gt; Nacionales: [level] = 40</p>
<p>Resultado:</p>
<p><img src="http://www.gisandchips.org/wp-content/hola_spain_xml2-300x300.png" alt="hola spain 2" width="300" height="300" /></p>
<p>Este artículo es el primero de una serie formada por:</p>
<ul>
<li>Renderizado con Mapnik (este post)</li>
<li>Mapnik y OpenStreetMap</li>
<li>Thumbnails con Mapnik y OpenStreetMap</li>
<li>Uso de TMS de OpenStreetMap con OpenLayers</li>
<li>TMS de OpenStreetMap con Mod_tile</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2009/10/22/renderizado-de-osmcon-mapnik-para-usar-en-openlayers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

