<?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; geometry simplification</title>
	<atom:link href="http://www.gisandchips.org/tag/geometry-simplification/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>Aumentar velocidad de carga de un mapfile utilizando simplificación de geometrías</title>
		<link>http://www.gisandchips.org/2009/11/05/aumentar-velocidad-de-carga-de-un-mapfile-utilizando-simplificacion-de-geometrias/</link>
		<comments>http://www.gisandchips.org/2009/11/05/aumentar-velocidad-de-carga-de-un-mapfile-utilizando-simplificacion-de-geometrias/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 11:48:58 +0000</pubDate>
		<dc:creator>pepe</dc:creator>
				<category><![CDATA[Comparativa]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[geometry simplification]]></category>
		<category><![CDATA[mapfile]]></category>
		<category><![CDATA[mapscript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[PostGIS]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=492</guid>
		<description><![CDATA[En el anterior post creamos un mapfile dinámicamente con PHPMapScript, ahora lo que vamos a ver es como conseguir que la velocidad de carga de este mapfile se reduzca de forma considerable utilizando simplificación de geometrías mediante una función en PostGIS, esperando obtener un mapa con los municipios de toda España. Resultado esperado: El código [...]]]></description>
			<content:encoded><![CDATA[<p>En el anterior <a href="http://www.gisandchips.org/2009/11/02/creacion-de-un-mapfile-de-forma-dinamica-al-vuelo/" target="_blank">post</a> creamos un mapfile dinámicamente con PHPMapScript, ahora lo que vamos a ver es como conseguir que la velocidad de carga de este mapfile se reduzca de forma considerable utilizando simplificación de geometrías mediante una función en PostGIS, esperando obtener un mapa con los municipios de toda España.</p>
<p style="text-align: center;">Resultado esperado:<img class="aligncenter size-full wp-image-1082" title="4b024cb4_7df_1" src="http://www.gisandchips.org/wp-content/4b024cb4_7df_1.gif" alt="Mapa simplificado" width="300" height="300" /></p>
<p style="text-align: center;">
<p>El código de generación del mapfile será el mismo que en el  <a href="http://www.gisandchips.org/2009/11/02/creacion-de-un-mapfile-de-forma-dinamica-al-vuelo/" target="_blank">post</a> de creación del mapfile &#8220;al vuelo&#8221;, tan solo habría que cambiar la forma de obtener los datos, para que en lugar de obtenerlos con una simple sentencia sql, llamar a una función que obtuviera las geometrías simplificadas a costa de perder nivel de detalle (inapreciable a la vista).</p>
<p><span id="more-492"></span></p>
<p>Cuando se trata de simplificar geometrías hay que tener en cuenta la dimensión del mapa que queremos obtener para en función de esta dimensión, poder obtener de alguna forma un coeficiente de simplificación que se adecue a la simplificación que pretendemos obtener (es decir, ni que no nos haga casi simplificación, ni que simplifique demasiado).</p>
<p>Para obtener este factor de simplificación, podemos hacer varias operaciones, en este caso realizaremos una operación como la siguiente, dividiremos el resultado de restar a la xmax la xmin de la entensión de la geometria entre el ancho del mapa que queremos obtener.</p>
<p>Es decir, obtenemos la extensión de la geometría que estamos analizando , sacamos al xmax y la xmin, las restamos y el resultado lo dividimos entre el ancho del mapa que queremos obtener:</p>
<p>(xmax(extent(geometria) )- xmin(extent(geometria)))/Ancho del mapa</p>
<p>Creamos una función en sql para obtener el factor de simplificación que deseamos:</p>
<pre class="brush: php; title: ; notranslate">
create or replace function fs(float8) returns float8 AS $$
 select (xmax(extent(geometria))-xmin(extent(geometria)))/$1 from ine.municipios;
$$ LANGUAGE SQL;
</pre>
<p>Una vez que tenemos el factor de simplificación obtenido con la función anterior, ya podemos aplicar la simplificación con el factor de simplificación obtenido anteriormente.</p>
<p>Podemos hacer una comparativa del aumento de velocidad entre realizar una consulta sin simplificación y otra con la simplificación, por ejemplo para un mapa bastante grande de 4000px.</p>
<p>1ª consulta: &#8220;<strong><em>select geometria  from municipios2</em></strong>&#8221;</p>
<p>2ª consulta:&#8221;<strong><em>select st_simplify(geometria,factor_simplificacion) from municipios2</em></strong>&#8221;</p>
<p>En PostgreSQL, al ejecutar las dos sentencias podemos comparar y obtener:</p>
<p>1ª consulta</p>
<ul>
<li>Tiempo de ejecución de la consulta: <strong>50,84 segundos</strong></li>
<li>Numero de vertices: <strong>393666</strong></li>
</ul>
<p>2ª consulta</p>
<ul>
<li>Tiempo de ejecución de la consulta: <strong>19,51 segundos</strong></li>
<li>Numero de vertices: <strong>141610</strong></li>
</ul>
<p>De esta manera comprobamos que se produce un aumento en la velocidad a cambio de reducir el nivel de detalle, circunstancia que nos viene bien de cara a la publicación web, ya que no necesitamos un nivel de detalle elevado.</p>
<p>Para constaruir ahora la layer en MapScript, la sentencia SQL para obtener los datos sería como esta:</p>
<pre class="brush: php; title: ; notranslate">
$name = $Layer2-&gt;set(&quot;name&quot;,&quot;Municipios&quot;);
$type = $Layer2-&gt;set(&quot;type&quot;,MS_LAYER_POLYGON);
$status = $Layer2-&gt;set(&quot;status&quot;,MS_ON);
//Conexión con nuestra base de datos que va as er de tipo POSTGIS
$Layer2-&gt;setConnectionType(MS_POSTGIS);
//Cadena de conexión a la base de datos donde tenemos nuestros datos

//En primer lugar, debemos obtener el factor de simplificación que obtenemos mediante consulta a postgresql desde php:
$conexion = pg_pconnect(&quot;host=localhost port=5432 dbname=demos user=postgres&quot;);

$sql=&quot;select fs(&quot;.$Map-&gt;width.&quot;)&quot;;
$resultado=pg_exec($conexion,$sql);
$factor=pg_result($resultado,0,0);

$Layer2-&gt;set(&quot;connection&quot;,&quot;user=postgres dbname=demos host=localhost&quot;);
//Filtro en sql que vamos a introducir para sacar nuestros datos a mostrar, aplicando el factor obtenido anteriormente
$data=&quot;geometria from (select st_simplify(geometria,&quot;.$factor.&quot;) as geometria, nombre,provincia,gid from municipios) as foo using SRID=23030, using unique gid&quot;;
$Layer2-&gt;set(&quot;data&quot;,$data);
//Una vez definida la estructura d ela capa procedemos a definir el estilo de nuestra capa número 1
</pre>
<p>Para la comparación de velocidad de creación de un mapfile con una única capa PostGIS utilizando una sentencia SQL normal y utilizando simplificación de geometrías, utilizando para ello varios test de medición de velocidad de carga, asumimos que vamos a crear un mapa bastante grande de una dimensión de 2000&#215;2000 pixeles.</p>
<p><a href="http://www.gisandchips.org/demos/mapscript/index_norm.php" target="_blank">Sin simplificación de geometrías </a>(tal y como se hizo en el artículo anterior, pero con una sola capa y de tamaño 2000&#215;2000 píxeles)</p>
<p><a href="http://www.gisandchips.org/demos/mapscript/index_simp.php" target="_blank">Con simplificación de geometrías</a> (utilizando la función que hemos programado anteriormente)</p>
<p>Para realizar la comparativa de cargas he utilizado la herramienta <a href="http://www.websitegoodies.com/tools/speed-test.php" target="_blank">Speed-Test </a></p>
<p>El resultado que he obtenido es el siguiente:<br />
(no se aprecia mucha diferencia, pero es debido a que se ha guardado en la caché y no es significativa la diferencia)<br />
- Con la sentencia normal (sin simplificación)</p>
<table style="border: 1px solid #cccccc;" border="0">
<tbody>
<tr>
<td style="padding: 0pt 5px;"><strong>URL:</strong></td>
<td style="padding: 0pt 5px;">http://www.gisandchips.org/demos/mapscript/index_norm.php</td>
</tr>
<tr>
<td style="padding: 0pt 5px;"><strong>Load Time:</strong></td>
<td style="padding: 0pt 5px;">1.048 seconds</td>
</tr>
<tr>
<td style="padding: 0pt 5px;"><strong>Page Size:</strong></td>
<td style="padding: 0pt 5px;">0.19 kb</td>
</tr>
</tbody>
</table>
<p>- Utilizando el factor de simplificación y realizando una simplificación de las geometrías:</p>
<table style="border: 1px solid #cccccc;" border="0">
<tbody>
<tr>
<td style="padding: 0pt 5px;"><strong>URL:</strong></td>
<td style="padding: 0pt 5px;">http://www.gisandchips.org/demos/mapscript/index_simp.php</td>
</tr>
<tr>
<td style="padding: 0pt 5px;"><strong>Load Time:</strong></td>
<td style="padding: 0pt 5px;">1.013 seconds</td>
</tr>
<tr>
<td style="padding: 0pt 5px;"><strong>Page Size:</strong></td>
<td style="padding: 0pt 5px;">0.18 kb</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2009/11/05/aumentar-velocidad-de-carga-de-un-mapfile-utilizando-simplificacion-de-geometrias/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Simplify Workbench: banco de pruebas para geometría simplificada</title>
		<link>http://www.gisandchips.org/2009/04/29/simplify-workbench-banco-de-pruebas-para-geometria-simplificada/</link>
		<comments>http://www.gisandchips.org/2009/04/29/simplify-workbench-banco-de-pruebas-para-geometria-simplificada/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 09:40:18 +0000</pubDate>
		<dc:creator>josetomas</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[geometry simplification]]></category>
		<category><![CDATA[PostGIS]]></category>
		<category><![CDATA[SharpMap]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/wordpress/?p=22</guid>
		<description><![CDATA[Optimizar nuestro cliente GIS, tanto para web como para escritorio, implica entre otras cosas afinar al máximo los rangos de escala de visualización para cada una de nuestras capas. Sin embargo puede darse el caso de que este mecanismo no sea aplicable. Ante esta situación, es importante que no renunciemos al ahorro en los tiempos [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">Optimizar nuestro cliente GIS, tanto para web como para escritorio, implica entre otras cosas afinar al máximo los rangos de escala de visualización para cada una de nuestras capas. Sin embargo puede darse el caso de que este mecanismo no sea aplicable. Ante esta situación, es importante que no renunciemos al ahorro en los tiempos de proceso, y en este sentido puede ser útil recurrir a la simplificación o generalización de la geometría.</p>
<p style="text-align: justify">Lo que aquí os ofrecemos es una herramienta que, dada una determinada entidad PostgreSQL/PostGIS, permite explorar rápidamente cuál es la relación entre tamaño de imagen, extensión del mapa, degradación visual y tiempo de proceso <span id="more-22"></span>para un máximo de 4 valores de tolerancia designados por el usuario. Se trata de una aplicación sencilla, escrita en C#, en la que el área de trabajo se divide en cuatro paneles. En cada panel podemos asignar una tolerancia, visualizar la geometría simplificada resultante, echar un vistazo a la sentencia SQL ejecutada en PostgreSQL y comprobar el tiempo de proceso transcurrido en realizar la transacción en el servidor y generar la imagen resultante en el cliente. Además, en todo momento conocemos cuál es la dimensión en píxeles de la imagen y el ancho del mapa. La instantánea inferior muestra una sesión de Simplify Workbench en la que se compara la geometría simplificada de los municipios de España procedentes de la Base de Datos de Líneas Límite a escala 1:1.000.000 del <a title="IDEE" href="http://www.idee.es" target="_blank">IDEE</a>. Se puede observar cómo el tiempo de proceso del panel C es casi 4 veces menor que el del panel A, mientras que el impacto en la visualización es casi inapreciable. Por el contrario, la reducción del tiempo de proceso en el panel D conlleva una degradación visual que, para la resolución de la imagen, no es aceptable.</p>
<div id="attachment_42" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.gisandchips.org/wp-content/simplifyworkbench3.png"><img class="size-medium wp-image-42" src="http://www.gisandchips.org/wp-content/simplifyworkbench3-300x290.png" alt="Geometría simplificada de los municipios de España en Simplify Workbench. Fuente de datos: IDEE" width="300" height="290" /></a><p class="wp-caption-text">Geometría simplificada de los municipios de España en Simplify Workbench. Fuente de datos: IDEE</p></div>
<p style="text-align: center">
<p style="text-align: justify">Podéis disponer del código fuente de Simplify Workbench bajo licencia GPL haciendo un <em>checkout </em>del siguiente repositorio Subversion de GIS&amp;Chips:</p>
<p style="text-align: justify;padding-left: 30px"><code>svn co http://www.gisandchips.org/svn/simplifyworkbench</code></p>
<p style="text-align: justify">Para los que queráis probarlo de inmediato, tened en cuenta que los datos de conexión a PostgreSQL y entidad PostGIS se configuran en el fichero XML <strong>app.config</strong> que acompaña al ejecutable. Por defecto, os proporcionamos una conexión al servidor PostgreSQL de GIS &amp; Chips para que podáis hacer tests con los municipios del IDEE. Si vais a realizar pruebas con vuestros propios datos tened en cuenta que la función de simplificación de PostGIS (<em>simplify</em> o <em>st_simplify</em>) no opera sobre geometrías en coordenadas geográficas (e.g. SRID = 4326), por lo que la aplicación no realizará el tratamiento esperado. Tampoco opera sobre entidades con sistema de referencia espacial indeterminado en la tabla <em>geometry_columns </em>(i.e. SRID = -1).</p>
<p style="text-align: justify">Si eres desarrollador y te vas a &#8216;zambullir&#8217; en el código seguramente te interesará conocer que Simplify Workbench no es más que una extensión de <a title="SharpMap" href="http://www.codeplex.com/SharpMap" target="_blank">SharpMap</a> con un interfaz gráfico en Windows.Forms. Formalmente es una solución desarrollada en el IDE de código abierto <a title="SharpDevelop" href="http://www.icsharpcode.net/OpenSource/SD/" target="_blank">SharpDevelop</a>, escrita en C# sobre el framework 2.0 de .NET. Integra tres proyectos:  <strong>SharpMap </strong>(versión 0.9), <strong>SharpMapSimplifyExtension</strong> y <strong>Simplify</strong>.</p>
<p style="text-align: justify">Seguramente alguno de vosotros ya conozca <a title="SharpMap" href="http://www.codeplex.com/SharpMap" target="_blank">SharpMap</a>. Desde que <a title="Morten Nielsen" href="http://www.sharpgis.net/" target="_blank">Morten Nielsen</a>, su creador, publicó allá por 2005-2006  este versátil renderizador de cartografía basado en GDI+, una pequeña revolución se ha producido en el ámbito de los clientes GIS libres sobre plataforma .NET y de hecho el proyecto no sólo continúa muy activo sino que ha conseguido integrar un equipo consolidado de desarrolladores en torno a un ecosistema de proyectos interrelacionados. El proyecto <strong>SharpMap</strong> de Simplify Workbench corresponde a los fuentes de la versión 0.9, la versión estable, aunque observaréis que el namespace SharpMap.Data.Providers incluye el proveedor de PostGIS (<a title="PostGIS.cs" href="http://sharpmap.codeplex.com/Wiki/View.aspx?title=PostGIS" target="_blank">PostGIS.cs</a>) y una referencia a <a title="Npgsql" href="http://npgsql.projects.postgresql.org/" target="_blank">Npgsql</a>, la librería de acceso a datos de PostgreSQL en su versión 2.0.4.</p>
<p style="text-align: justify">El proyecto <strong>SharpMapSimplifyExtension</strong> consta de dos clases: <strong>PostGISSimplify</strong> y <strong>VectorSimplifiedLayer</strong>. La primera es una derivación de la clase SharpMap.Data.Providers.PostGIS que modifica el método <em>GetGeometriesInView</em> de forma que la sentencia SQL subyacente invoque la función <em>simplify</em> de PostGIS con la tolerancia de entrada. También añade un delegado que permite recuperar mediante un evento tanto la sentencia SQL final como el ancho del <em>bounding box</em>. La segunda deriva de la clase SharpMap.Layers.VectorLayer, sobrecarga el constructor para instanciar capas vectoriales especificando una tolerancia de simplificación y modifica el método <em>Render</em>. Con estas dos simples extensiones podemos definir  una capa vectorial que muestre geometría simplificada de PostGIS sin variar sustancialmente la lógica habitual de trabajo con SharpMap, tal y como se muestra en este ejemplo:</p>
<pre class="brush: csharp; title: ; notranslate">
//
//
//
string cnstr = &quot;Server=your.pgsql.server;Port=5432;User Id=user;Password=secret;Database=yourDB&quot;;
string tableName = &quot;yourPolygons&quot;;
string geomFieldName = &quot;geometry&quot;;
string oidFieldName = &quot;oid&quot;;
//Instance of data provider for PostGIS simplified geometry
PostGISSimplify src = new PostGISSimplify(cnstr, tableName, geomFieldName, oidFieldName);
//Instance of vector layer to hold simplified PostGIS geometry
//Third parameter is an integer corresponding to tolerance in Douglas-Peucker vertex reduction algorithm
VectorSimplifiedLayer lyr = new VectorSimplifiedLayer(&quot;SIMPLIFIED_LAYER&quot;, src, 1000);
lyr.Style.EnableOutline = true;
lyr.Style.Fill = Brushes.Transparent;
//Map object, the layer container and rendering logic construct in SharpMap
Map m = new Map(new System.Drawing.Size(350, 275));
m.BackColor = Color.White;
m.Layers.Add(lyr);
//Zoom to extents internally invokes the modified GetGeometriesInView method in PostGISSimplify class
m.ZoomToExtents();
//Retrieve map image
System.Drawing.Image img = m.GetMap();
//
</pre>
<p style="text-align: justify">El proyecto <strong>Simplify</strong> incluye el formulario estructurado en cuatro paneles comentado más arriba y una clase de conveniencia, <strong>MapRenderer</strong>, que encapsula la lógica de lectura del fichero app.config, definición de layer, obtención de la imagen, recuperación de la sentencia SQL y cálculo del tiempo de proceso. En el directorio de este proyecto encontraréis también el fichero de solución de SharpDevelop (Simplify.sln).</p>
<p style="text-align: justify">Para terminar, y puesto que muchos de nosotros aquí en GIS &amp; Chips somos fans del framework de código abierto Mono, os animamos a que probéis a compilar usando esta plataforma. Sabemos positivamente que SharpMap 0.9, con pequeñas modificaciones, es compilable sobre Mono. Creemos, aunque no lo hemos comprobado, que el código de Simplify Workbench también lo es. Si alguno lo consigue nos alegrará que nos lo comente.</p>
<p style="text-align: justify">¡Disfrutad con Simplify Workbench!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2009/04/29/simplify-workbench-banco-de-pruebas-para-geometria-simplificada/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

