<?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; Análisis</title>
	<atom:link href="http://www.gisandchips.org/category/review/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>GeoFOV: Incorporando el campo de visión a una geodatabase multimedia</title>
		<link>http://www.gisandchips.org/2011/11/21/geofov-incorporando-el-campo-de-vision-a-una-geodatabase-multimedia/</link>
		<comments>http://www.gisandchips.org/2011/11/21/geofov-incorporando-el-campo-de-vision-a-una-geodatabase-multimedia/#comments</comments>
		<pubDate>Sun, 20 Nov 2011 22:56:39 +0000</pubDate>
		<dc:creator>benizar</dc:creator>
				<category><![CDATA[Análisis]]></category>
		<category><![CDATA[Presentación]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[campo de visión]]></category>
		<category><![CDATA[EXIF]]></category>
		<category><![CDATA[field of view]]></category>
		<category><![CDATA[GIS & Chips]]></category>
		<category><![CDATA[NTS]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=1937</guid>
		<description><![CDATA[Hola a todos, quiero compartir aquí el enlace de mi segunda presentación en slideshare. Es de un taller que no se llegó a realizar pero espero que os resulte interesante. En esta presentación comento un poco cómo se utilizan los metadatos de las imágenes para generar información espacial de interés o incluso cómo puede evolucionar [...]]]></description>
			<content:encoded><![CDATA[<p>Hola a todos, quiero compartir aquí el enlace de mi segunda presentación en slideshare. Es de un taller que no se llegó a realizar pero espero que os resulte interesante. En esta presentación comento un poco cómo se utilizan los metadatos de las imágenes para generar información espacial de interés o incluso cómo puede evolucionar el panorama de los geotags a corto plazo.</p>
<p>Más adelante, cuando tenga tiempo, colgaré una librería que he desarrollado en mi tesis y explicaré en detalle el código.</p>
<p>Hasta pronto.</p>
<div style="width:425px" id="__ss_10245372"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/BeniZaragoz/geofov-incorporando-el-campo-de-visin-en-una-multimedia-geodatabase" title="GeoFOV: Incorporando el campo de visión en una multimedia geodatabase" target="_blank">GeoFOV: Incorporando el campo de visión en una multimedia geodatabase</a></strong> <object id="__sse10245372" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=geofov-111120161539-phpapp01&#038;stripped_title=geofov-incorporando-el-campo-de-visin-en-una-multimedia-geodatabase&#038;userName=BeniZaragoz" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><param name="wmode" value="transparent"/><embed name="__sse10245372" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=geofov-111120161539-phpapp01&#038;stripped_title=geofov-incorporando-el-campo-de-visin-en-una-multimedia-geodatabase&#038;userName=BeniZaragoz" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" width="425" height="355"></embed></object>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/BeniZaragoz" target="_blank">Beni Zaragozí</a> </div>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2011/11/21/geofov-incorporando-el-campo-de-vision-a-una-geodatabase-multimedia/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Presentación de RAPID para las Jornadas de Geografía 3.0</title>
		<link>http://www.gisandchips.org/2011/11/17/presentacion-de-rapid-para-las-jornadas-de-geografia-3-0/</link>
		<comments>http://www.gisandchips.org/2011/11/17/presentacion-de-rapid-para-las-jornadas-de-geografia-3-0/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 11:16:24 +0000</pubDate>
		<dc:creator>benizar</dc:creator>
				<category><![CDATA[Análisis]]></category>
		<category><![CDATA[Presentación]]></category>
		<category><![CDATA[AForge.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Teledetección orientada a objetos]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=1867</guid>
		<description><![CDATA[En este post quiero compartir la primera presentación que subo a Slideshare En ella justifico y describo el programa RAPID que ya había introducido en un post, pero con un enfoque ligeramente distinto. Mi idea es subir otras presentaciones que tengo por ahí que puedan ser de interés para G&#38;C. RAPID: Rough Agricultural Plot IDentifier. [...]]]></description>
			<content:encoded><![CDATA[<p>En este post quiero compartir la primera presentación que subo a Slideshare <img src='http://www.gisandchips.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  En ella justifico y describo el programa RAPID que ya había introducido en un post, pero con un enfoque ligeramente distinto. Mi idea es subir otras presentaciones que tengo por ahí que puedan ser de interés para G&amp;C.</p>
<div style="width:510px" id="__ss_10197659"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/BeniZaragoz/rapid-10197659" title="RAPID: Rough Agricultural Plot IDentifier. Un contador de árboles con software libre. " target="_blank">RAPID: Rough Agricultural Plot IDentifier. Un contador de árboles con software libre. </a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/10197659" width="510" height="426" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/BeniZaragoz" target="_blank">Beni Zaragozí</a> </div>
</p></div>
<p>Espero que os guste. Cuando tenga un rato subo más!!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2011/11/17/presentacion-de-rapid-para-las-jornadas-de-geografia-3-0/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Paralelización con SIMD</title>
		<link>http://www.gisandchips.org/2011/10/20/paralelizacion-con-simd/</link>
		<comments>http://www.gisandchips.org/2011/10/20/paralelizacion-con-simd/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 16:31:37 +0000</pubDate>
		<dc:creator>josetomas</dc:creator>
				<category><![CDATA[Análisis]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Mono.Simd]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=1744</guid>
		<description><![CDATA[En este artículo os presento un test en el que medimos los tiempos que un programa escrito en C# emplea para procesar una serie de modelos digitales del terreno. El objetivo final es comparar el rendimiento de un código que hace un cálculo secuencial frente a otro que hace uso de una tecnología de paralelización [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">En este artículo os presento un test en el que medimos los tiempos que un programa escrito en C# emplea para procesar una serie de modelos digitales del terreno. El objetivo final es comparar el rendimiento de un código que hace un cálculo secuencial frente a otro que hace uso de una tecnología de paralelización de datos por hardware denominada SIMD, disponible en la mayoría de microprocesadores que usamos hoy en día. Y el resultado es muy interesante.<div id="attachment_1801" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.gisandchips.org/wp-content//SIMD_performance.png"><img src="http://www.gisandchips.org/wp-content//SIMD_performance-300x131.png" alt="SIMD performance test" width="300" height="131" class="size-medium wp-image-1801" /></a><p class="wp-caption-text">Test de rendimiento SIMD con Mono.Simd.Vector8s</p></div><span id="more-1744"></span></p>
<p style="text-align: justify">Las técnicas de computación paralela encuentran en los sistemas de información geográfica una de sus aplicaciones más elocuentes dada la naturaleza masiva de los datos geográficos, en particular si hablamos de estructuras de datos raster. No en vano, allá por el año 1997, Richard Healey, junto con otros compañeros del Dpto. de Geografía de la Universidad de Edimburgo, editó &#8220;Parallel Processing Algorithms For GIS&#8221;. El profesor Healey es un geógrafo que ya a principios de los 90 planteaba a sus alumnos problemas de geoprocesamiento paralelo que éstos habían de resolver con ADA, el único lenguaje accesible que por aquel entonces prefiguraba el paradigma OOP y permitía definir tareas concurrentes. Desde entonces se han producido muchos avances en paralelización de procesos, tanto a nivel de software como de hardware. Sin embargo, existe un tipo de paralelización que no parece haber alcanzado demasiada notoriedad en el campo de los GIS: se trata del conjunto de instrucciones <a href="http://en.wikipedia.org/wiki/SIMD">SIMD</a> (Single Instruction, Multiple Data) que permite realizar operaciones aritméticas entre pares de vectores mediante una sola instrucción. No se trata por tanto de concurrencia de procesos, sino de paralelismo a nivel de datos. Lo más curioso es que, desde 1996, los fabricantes de microprocesadores han ido incorporando extensiones que soportan en mayor o menor medida este juego de instrucciones.</p>
<p style="text-align: justify">Cualquier PC o videoconsola actual permite ejecutar instrucciones SIMD. Evidentemente los desarrolladores de juegos hace tiempo que explotan este tipo de paralelización. Sin embargo, encontrar referencias recientes a SIMD en el ámbito de la Geomática resulta más complicado: <a href="http://gisws.media.osaka-cu.ac.jp/grass04/viewpaper.php?id=15">aquí tenéis una interesante ponencia</a> de la conferencia de usuarios de GRASS del 2004. Seguramente habrá más trabajos publicados, así que hacednos saber lo que encontréis.</p>
<p style="text-align: justify">Yo sinceramente no sabía nada de esto hasta que leí <a href="http://tirania.org/blog/archive/2008/Nov-03.html">este post de Miguel de Icaza</a>, anunciando la publicación de <a href="http://docs.go-mono.com/monodoc.ashx?link=N%3aMono.Simd">Mono.Simd</a>. Este API es un paso en la estrategia de Mono por entrar de lleno en la industria del &#8220;gaming&#8221;. ¿Y para las desarrolladores de GIS? En mi opinión significa un abanico de posibilidades a la hora de paralelizar geoprocesos que queda pendiente de explorar.</p>
<p style="text-align: justify">En este artículo sólo quiero dejar constancia de un test para un caso extremo de optimización con SIMD. En la práctica carece de utilidad, mi única intención es medir diferencias de tiempo en un escenario absolutamente favorable a la paralelización mediante vectores. Dado un grid de elevaciones, donde cada valor de altitud puede representarse como un entero de 16 bits, se trata simplemente de doblar el valor de cada pixel para &#8220;exagerar&#8221; el modelo del terreno. Estas son las especificaciones de la máquina en que he realizado el test:</p>
<ul>
<li>Intel Q8300 @ 2.50GHz</li>
<li>3.9 GiB RAM</li>
<li>Ubuntu 11.04 i686</li>
<li>Mono 2.10.5</li>
</ul>
<p style="text-align: justify">El test se ha realizado sobre 4 ficheros <a href="http://en.wikipedia.org/wiki/Esri_grid">ARC/INFO ASCII GRID</a> de distintos tamaños. Para cada fichero se han tomado 5 muestras del tiempo transcurrido en el cálculo aritmético sin aceleración de hardware, pixel a pixel, tomando finalmente la mediana. La misma metodología de muestreo se ha empleado para obtener los tiempos con aceleración de hardware, es decir, empleando Mono.Simd para multiplicar los pixels de 8 en 8 mediante una única instrucción. Para ello es necesario agrupar previamente los valores de altitud y almacenar cada vector en una lista de tipo Mono.Simd.Vector8s. Estos son los resultados:</p>
<table style="height: 5px;width: 80%" border="1" cellspacing="1" cellpadding="1" align="center">
<thead>
<tr>
<th scope="col"><span class="Apple-style-span" style="font-weight: normal">File size (MiB)</span></th>
<th scope="col"><span class="Apple-style-span" style="font-weight: normal">Elapsed time (miliseconds)</span></th>
<th scope="col"><span class="Apple-style-span" style="font-weight: normal">Elapsed time with SIMD (miliseconds)</span></th>
<th scope="col"><span class="Apple-style-span" style="font-weight: normal">Time reduction</span></th>
<th scope="col"><span class="Apple-style-span" style="font-weight: normal">Performance gain</span></th>
</tr>
</thead>
<tbody>
<tr>
<td>12.0</td>
<td>49.7447</td>
<td>14.2542</td>
<td>71.3</td>
<td><span style="background-color: #ffd700"><strong>3.5x</strong></span></td>
</tr>
<tr>
<td>48.2</td>
<td>197.5251</td>
<td>56.149</td>
<td>71.6</td>
<td><span style="background-color: #ffd700"><strong>3.5x</strong></span></td>
</tr>
<tr>
<td>192.7</td>
<td>783.0778</td>
<td>216.305</td>
<td>72.4</td>
<td><span style="background-color: #ffd700"><strong>3.6x</strong></span></td>
</tr>
<tr>
<td>535.4</td>
<td>2180.8665</td>
<td>618.2225</td>
<td>71.7</td>
<td><span style="background-color: #ffd700"><strong>3.5x</strong></span></td>
</tr>
</tbody>
</table>
<p style="text-align: justify">Como veis, en todos los casos, con SIMD el proceso de cálculo se completa en torno a 3,5 veces más rápido. Esto es una buena noticia, pero no significa que este tipo de paralelismo sea la panacea. En mi opinión la conclusión es que, si con un escenario favorable se puede reducir el tiempo de proceso en más de un 70%, merece la pena explorar otros escenarios con verdadera utilidad práctica.</p>
<p style="text-align: justify">Si alguien se pregunta por la incidencia que puede tener esta mejora en el rendimiento si contabilizamos el proceso de lectura y carga en memoria de los datos, me atrevería a decir que escasa. En cualquier caso, los procesos de lectura y manejo de grandes volúmenes de información raster constituyen un problema distinto y existen diversas técnicas para su optimización.</p>
<p style="text-align: justify">Si os pica la curiosidad, podeis averiguar el conjunto de instrucciones SIMD que soporta vuestro procesador ejecutando el código de ejemplo que aparece en la documentación de la clase <a href="http://docs.go-mono.com/monodoc.ashx?link=T%3aMono.Simd.SimdRuntime">Mono.Simd.SimdRuntime</a> (es posible que tengáis que hacer algunas modificaciones). Para aquellos que quieran reproducir un test de rendimiento con sus propios ficheros ASCII GRID, aquí os dejo el código C# que he usado (por cierto, ni es óptimo ni puedo garantizar que esté libre de bugs):</p>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.IO;
using Mono.Simd;
using System.Collections.Generic;
using System.Globalization;
using System.Diagnostics;
using System.Linq;

namespace SIMDTest
{
 class MainClass
 {
  public static void Main (string[] args)
  {
   bool useSIMD = true;
   string path = string.Empty;
   CultureInfo formatProvider = null;
   try {
    if (args.Length == 0) {
     Console.WriteLine (&quot;Usage: SIMDTest [ASC GRID file name] [specific culture name]&quot;);
     return;
    }
    if (args.Length &gt; 0)
     path = args[0];
    if (args.Length &gt; 1)
     formatProvider = CultureInfo.GetCultureInfo (args[1]);
    Console.WriteLine (&quot;Use hardware acceleration? [y / n]? : &quot;);
    ConsoleKeyInfo key = Console.ReadKey ();
    while (key.Key != ConsoleKey.Y &amp;&amp; key.Key != ConsoleKey.N) {
     Console.WriteLine (&quot;Press 'y' to use hardware acceleration, 'n' otherwise: &quot;);
     key = Console.ReadKey ();
    }
    Console.WriteLine ();
    Console.WriteLine (&quot;Processing, please wait ...&quot;);
    useSIMD = (key.Key == ConsoleKey.Y);
    ElevationModel dem = new ElevationModel(path, formatProvider);
    Stopwatch stopwatch = new Stopwatch ();
    if (useSIMD) {
     Vector8s scale = new Vector8s (2);
     foreach (IList vPage in dem.EnumerateVectors ()) {
      stopwatch.Start ();
      for (int i = 0; i &lt; vPage.Count; i ++)
       vPage[i] = vPage[i] * scale;
      stopwatch.Stop ();
     }
    } else {
     foreach (IList page in dem.EnumerateData ()) {
      stopwatch.Start ();
      for (int i = 0; i &lt; page.Count; i ++)
       page[i] = (short) (page[i] * 2);
      stopwatch.Stop ();
     }
    }
    Console.WriteLine (&quot;Time elapsed: {0}&quot;, stopwatch.Elapsed);
   } catch (Exception ex) {
    Console.WriteLine (ex.Message);
   }
  }
 }

 class ElevationModel
 {
  string _path;
  IFormatProvider _formatProvider = CultureInfo.CurrentCulture;
  short _noData = -9999;
  int BOD = 0;

  public ElevationModel (string path, IFormatProvider formatProvider)
  {
   if (string.IsNullOrEmpty (path))
    throw new ArgumentNullException ();
   else if (!File.Exists (path))
    throw new FileNotFoundException ();
   else {
    _path = path;
    if (formatProvider != null)
     _formatProvider = formatProvider;
    this.SetMetadata ();
   }
  }

  public ElevationModel (string path) : this(path, null)
  {
  }

  void SetMetadata ()
  {
   using (StreamReader reader = new StreamReader (_path)) {
    //skip GRID header
    for (int i = 0; i &lt; 5; i++)
     reader.ReadLine ();
    _noData = short.Parse (reader.ReadLine ().Split (' ')[1], _formatProvider);
    reader.BaseStream.Position = 0;
    reader.DiscardBufferedData ();
    char[] buffer = new char[512];
    reader.Read(buffer, 0, buffer.Length);
    BOD = this.GetBeginOfData (buffer);
   }
  }

  int GetBeginOfData (char[] source)
  {
   int i = 0;
   bool isNewHeaderLine = false;
   bool isNewLine = true;
   foreach (char c in source) {
    if (char.IsLetter (c) &amp;&amp; isNewLine) {
     isNewHeaderLine = true;
     isNewLine = false;
    } else if ((char.IsDigit (c) || c == '-') &amp;&amp; isNewLine &amp;&amp; !isNewHeaderLine) {
     break;
    } else if (char.IsControl (c)) {
     isNewLine = true;
     isNewHeaderLine = false;
    }
    i++;
   }
   return i;
  }

  IList&lt;short&gt; GetPage (char[] source, int sourceIndex, int sourceLength, IList pendingDigits)
  {
   IList&lt;short&gt; page = new List&lt;short&gt; ();
   for (int i = sourceIndex; i &lt; sourceLength; i++) {
    if (char.IsDigit (source[i]) || source[i] == '-')
     pendingDigits.Add (source[i]);
    else if (pendingDigits.Count &gt; 0 &amp;&amp; (char.IsWhiteSpace (source[i]) || char.IsControl (source[i]))) {
     short n = _noData;
     string s = new string(pendingDigits.ToArray ());
     if (!short.TryParse(s, NumberStyles.Integer, _formatProvider, out n))
      Console.WriteLine (&quot;Error parsing {0}&quot;, s);
     page.Add (n);
     pendingDigits.Clear ();
    }
   }
   return page;
  }

  public IEnumerable&lt;IList&lt;short&gt;&gt; EnumerateData ()
  {
   using (StreamReader reader = new StreamReader (_path)) {
    char[] buffer = new char[25000 * 1024];
    int beginOfData = 0;
    IList pendingDigits = new List ();
    int charCount = 0;
    while ((charCount = reader.Read (buffer, 0, buffer.Length)) &gt; 0) {
     if (beginOfData == 0) {
      beginOfData = this.BOD;
      yield return this.GetPage (buffer, beginOfData, charCount, pendingDigits);
     } else
      yield return this.GetPage (buffer, 0, charCount, pendingDigits);
    }
   }
  }

  IList&lt;Vector8s&gt; GetVectorPage(IList page, IList pendingValues)
  {
   List vPage = new List ();
   foreach (short n in page) {
    pendingValues.Add (n);
    if (pendingValues.Count == 8 ) {
     vPage.Add (new Vector8s (pendingValues[0], pendingValues[1],
      pendingValues[2], pendingValues[3], pendingValues[4],
      pendingValues[5], pendingValues[6], pendingValues[7]));
     pendingValues.Clear ();
    }
   }
   return vPage;
  }

  public IEnumerable&lt;IList&lt;Vector8s&gt;&gt; EnumerateVectors ()
  {
   int lastPageSize = -1;
   IList pendingValues = new List ();
   foreach (IList page in this.EnumerateData ()) {
    IList vPage = this.GetVectorPage (page, pendingValues);
    // complete last vector in last page
    if (lastPageSize != -1 &amp;&amp; vPage.Count &lt; lastPageSize) {
     if (pendingValues.Count &gt; 0 &amp;&amp; pendingValues.Count &lt; 8 ) {
      for (int i = pendingValues.Count; i &lt; 8; i++)
	pendingValues.Add(_noData);
      vPage.Add (new Vector8s (pendingValues[0], pendingValues[1],
       pendingValues[2], pendingValues[3], pendingValues[4],
       pendingValues[5], pendingValues[6], pendingValues[7]));
     }
    }
    lastPageSize = vPage.Count;
    yield return vPage;
   }
  }
 }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2011/10/20/paralelizacion-con-simd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Usando RSAGA para procesar un raster &#8220;grande&#8221; por partes</title>
		<link>http://www.gisandchips.org/2011/01/13/usando-rsaga-para-procesar-un-raster-grande-por-partes/</link>
		<comments>http://www.gisandchips.org/2011/01/13/usando-rsaga-para-procesar-un-raster-grande-por-partes/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 17:20:21 +0000</pubDate>
		<dc:creator>benizar</dc:creator>
				<category><![CDATA[Análisis]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[GIS libre]]></category>
		<category><![CDATA[R]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=1692</guid>
		<description><![CDATA[Hola a todos, hoy propongo una de las posibles soluciones a un problema que suele aparecer trabajando con GIS: ¿qué hacer cuando queremos procesar un raster “relativamente grande” y los GIS de escritorio más populares tienen problemas de memoria o no acaban el proceso? En algunas ocasiones la solución a estos problemas sería “trocear” el [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-weight: normal;font-size: 13px">Hola a todos, hoy propongo una de las posibles soluciones a un problema que suele aparecer trabajando con GIS: ¿qué hacer cuando queremos procesar un raster “relativamente grande” y los GIS de escritorio más populares tienen problemas de memoria o no acaban el proceso?</span></p>
<p>En algunas ocasiones la solución a estos problemas sería “trocear” el raster y procesarlo por partes. Esto lo podríamos hacer con varios software y en todos ellos sería interesante poder automatizar la tarea al máximo.</p>
<div id="attachment_1695" class="wp-caption aligncenter" style="width: 250px"><a href="http://www.gisandchips.org/wp-content/mdt1.jpg"><img class="size-medium wp-image-1695 " src="http://www.gisandchips.org/wp-content/mdt1-300x300.jpg" alt="" width="240" height="240" /></a><p class="wp-caption-text">1. Modelo digital raster</p></div>
<p>En este post propongo realizar una prueba con RSAGA, que es un modulo de R que permite acceder a las funciones disponibles en la consola de SAGA GIS. Para este post he trabajado en Windows, con R 2.10.1 y SAGA 2.0.4, aunque supongo que no habrá problemas con usar otras versiones más recientes. Además, deberéis instalar en R el paquete RSAGA.<span id="more-1692"></span></p>
<div id="attachment_1696" class="wp-caption aligncenter" style="width: 248px"><a href="http://www.gisandchips.org/wp-content/municipios1.jpg"><img class="size-medium wp-image-1696 " src="http://www.gisandchips.org/wp-content/municipios1-298x300.jpg" alt="" width="238" height="240" /></a><p class="wp-caption-text">2. Shapefile de polígonos con que trocearemos el raster</p></div>
<p>Para esta práctica podéis <a title="descargar ficheros de prueba" href="http://dl.dropbox.com/u/17558342/rsaga_tests.rar" target="_blank">descargar dos ficheros</a> (Imagenes 1 y 2), uno raster y otro vectorial (polígonos). A efectos didácticos se utilizan ficheros pequeños, pero esto resultaría más útil en caso de necesitar fragmentar más el raster. Por ejemplo, en artículos anteriores he presentado código para trabajar imágenes a nivel de parcelas agrícolas. En aquellos artículos trabajábamos las imágenes de una en una y ya estaban recortadas, pero las parcelas podrían ser miles y no queremos hacer eso a mano.</p>
<h3>Conociendo SAGA GIS</h3>
<p>Lo principal, como en tantos otros casos, sería conocer como se trocea un fichero raster con SAGA GIS. Para ello abrimos la GUI de SAGA y vamos a la pestaña “modules” que tiene forma de TOC, generalmente se encuentra a la izquierda de la ventana principal. En esta pestaña podemos encontrar las distintas librerías que agrupan módulos que se relacionan por algún motivo. Explorar estas librerías y practicar con ellas es el mejor modo de estar seguro de lo que se quiere hacer.</p>
<div id="attachment_1697" class="wp-caption aligncenter" style="width: 148px"><a href="http://www.gisandchips.org/wp-content/toc.jpg"><img class="size-medium wp-image-1697" src="http://www.gisandchips.org/wp-content/toc-172x300.jpg" alt="" width="138" height="240" /></a><p class="wp-caption-text">3. TOC de SAGA GIS donde podemos explorar las librerías y los módulos disponibles. </p></div>
<p>Finalmente, he decidido que lo mejor es empezar por separar el shapefile original por polígonos (shapes-tools/separate shapes) y después realizar un recorte por cada uno de los nuevos shapefiles (shapes-grid/clip grid with polygon). Practicar con el interfaz gráfico es un bueno modo de estar seguros de los parámetros que nos pide cada módulo.</p>
<p>Antes de empezar a usar RSAGA he tenido que averiguar los nombres exactos de los módulos y los parámetros que aceptan. Esto lo he hecho con los métodos rsaga.get.modules() y rsaga.get.usage(). Aunque generalmente se puede averiguar también viendo los nombres en el SAGA GUI o mirando en la carpeta donde se contienen las *.dll.</p>
<h3>Trabajando con RSAGA</h3>
<pre class="brush: bash; title: ; notranslate">
## Abrimos la consola de R y cargamos la librería
library(RSAGA)

## Seleccionamos el fichero raster que queremos trocear y una capa vectorial que queramos usar como límites. También especificamos el directorio donde van los outputs. Para trabajar con Windows recomiendo rutas sin espacios.
raster&lt;- file.choose()
poligonos&lt;- file.choose()
directorio &lt;-choose.dir()

## Consultamos hasta encontrar la herramienta que nos separa un shapefile en varios, obteniendo un shapefile por cada polígono, o lo que quisiéramos. Por ejemplo:
## rsaga.get.modules(&quot;shapes_grid&quot;)
## rsaga.get.usage(&quot;shapes_tools&quot;, 7)
## Se ejecuta el método con los parámetros necesarios.
rsaga.geoprocessor(lib=&quot;shapes_tools&quot;, module=7, param=list(SHAPES=poligonos, PATH=directorio, NAMING=0, FIELD=6))
</pre>
<p>Una vez ejecutado este proceso ya disponemos de un shapefile por cada polígono, esto significa que aunque el shapefile original tuviera miles de registros solamente cargaremos en memoria uno a la vez. Esto ya supone un ahorro importante de recursos.</p>
<pre class="brush: bash; title: ; notranslate">
# Listamos los nuevos shapefiles
shapefiles &lt;- list.files(directorio, full.names=T, pattern=&quot;\\.shp&quot;)
## Por último utilizamos RSAGA para realizar tantos recortes del raster como polígonos habíamos extraído
for(i in 1:length(shapefiles)){
select &lt;- shapefiles[i]&lt;/code&gt;
rsaga.geoprocessor(lib=&quot;shapes_grid&quot;, module=7, param=list(OUTPUT=select, INPUT=raster, POLYGONS=select))
}#fin bucle
</pre>
<h3>Conclusiones</h3>
<p>Tras ver este ejemplo nos queda más claro el uso de RSAGA y se visualiza bien como se podrían automatizar gran número de tareas habituales en los GIS. Intentar realizar estas tareas herramientas básicas y generales podría ser algo trabajoso.</p>
<p>En nuestro fichero de prácticas había 18 polígonos por lo que nuestro resultado es una carpeta donde encontramos guardados 18 shapefiles y 18 ficheros raster. Los recortes quedan como se puede ver en la siguiente imagen:</p>
<div id="attachment_1702" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.gisandchips.org/wp-content/recorte.jpg"><img class="size-medium wp-image-1702" src="http://www.gisandchips.org/wp-content/recorte-300x289.jpg" alt="" width="300" height="289" /></a><p class="wp-caption-text">4. Uno de los 18 raster resultantes de los recortes y al fondo el shapefile original</p></div>
<p>En caso de ser necesario, se podría realizar más tareas sobre todos estos ficheros, con este software o con otros programas. Incluso se plantea la posibilidad de usar multithreading en R para ejecutar tareas con RSAGA. Proximamente haremos alguna demostración de esto.</p>
<p>Antes de acabar, solo quiero recordar quando trabajamos con RSAGA en Windows es posible que nos afecten algunas particularidades sobre el modo en que se forman las rutas (espacios, barras de directorios…) y los mensajes de error que aparecen no son de gran ayuda.</p>
<p>——————————————————————</p>
<p>Si queréis contactar podéis enviarme un email (asunto: gisandchips):</p>
<p>Benito M. Zaragozí</p>
<p>benito.zaragozi@ua.es</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2011/01/13/usando-rsaga-para-procesar-un-raster-grande-por-partes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extracción de características estructurales de una imagen ( II ) (Semi-variograma de una imagen usando R).</title>
		<link>http://www.gisandchips.org/2010/01/28/extraccion-de-caracteristicas-estructurales-de-una-imagen-ii-semi-variograma-de-una-imagen-usando-r-2/</link>
		<comments>http://www.gisandchips.org/2010/01/28/extraccion-de-caracteristicas-estructurales-de-una-imagen-ii-semi-variograma-de-una-imagen-usando-r-2/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 12:45:08 +0000</pubDate>
		<dc:creator>benizar</dc:creator>
				<category><![CDATA[Análisis]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Fields]]></category>
		<category><![CDATA[Mineria de datos espacial]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[Teledetección orientada a objetos]]></category>
		<category><![CDATA[Variograma]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=1303</guid>
		<description><![CDATA[En este artículo usaremos una librería de R (“fields”), que contiene métodos para calcular el semi-variograma empírico de una imagen, lo cual quiere decir que calcularemos el semi-variograma de una gran cantidad de puntos. Y a partir de ahí, analizaremos la existencia de patrones espaciales en tres parcelas agrícolas arbóreas. Figura 1: Parcelas estudiadas en [...]]]></description>
			<content:encoded><![CDATA[<p>En este artículo usaremos una librería de R (“fields”), que contiene métodos para calcular el semi-variograma empírico de una imagen, lo cual quiere decir que calcularemos el semi-variograma de una gran cantidad de puntos. Y a partir de ahí, analizaremos la existencia de patrones espaciales en tres parcelas agrícolas arbóreas.</p>
<h5><strong>Figura 1: Parcelas estudiadas en este artículo.</strong></h5>
<p><strong><a href="http://www.gisandchips.org/wp-content/parcelas.jpg"><img class="aligncenter size-medium wp-image-1238" src="http://www.gisandchips.org/wp-content/parcelas-300x115.jpg" alt="" width="415" height="158" /></a></strong></p>
<p><span id="more-1303"></span></p>
<p>Espero que este sea el primero de varios posts donde aprendamos a estudiar las ortoimagenes, extrayendo características de distintos tipos como ya hicimos en un post anterior (<a href="../2009/11/11/procesamiento-de-imagenes-digitales-con-c-y-una-aplicacion-para-el-analisis-de-parcelas-agricolas/">http://www.gisandchips.org/2009/11/11/procesamiento-de-imagenes-digitales-con-c-y-una-aplicacion-para-el-analisis-de-parcelas-agricolas/</a> ). En aquel caso, se extrajeron algunas sencillas frecuencias a partir del cálculo de la Transformada de Hough que nos proporcionaba AForge.NET, lo cual nos servía para automatizar la decisión de si una parcela era una plantación arbórea y realizar un conteo automático del número de árboles que contenía. En dicho post, se ofrece una aplicación llamada RAPID, que incorpora una galería de imágenes de parcelas agrícolas. Hemos extraído tres de ellas para realizar los siguientes análisis. Son las siguientes:</p>
<p>Al estudiar las 3 parcelas que aparecen en la <strong>Figura 1</strong> con el RAPID: La primera es identificada totalmente como agrícola y nos permite contar con bastante certidumbre el número de árboles de un modo automático. En el caso de la segunda, su estructura en hileras no permite el conteo de árboles pues están muy juntos. Y por último, en los olivos de la tercera no se cumplía la regla de una estructura normal, aunque sí que podíamos contar los árboles. Este último caso era el único donde RAPID no podía “acertar” pues identificaba la parcela como no agrícola debido a que la diferencia angular entre las direcciones principales de la Transformada de Hough no se aproximaba a 90º.</p>
<p><strong>¿Qué es un variograma experimental?</strong> (una breve explicación para entender los resultados)</p>
<p>Los variogramas se utilizan para caracterizar la posible estructura espacial de un conjunto de datos. Podemos distinguir dos tipos de variogramas, el experimental y el modelizado. De estos nos interesa más el experimental. Este último se usa para describir los datos de una muestra, habitualmente una nube de puntos (xyz)</p>
<p>Matemáticamente el semi-variograma, o variograma/2, se puede definir como la mitad del promedio de las diferencias al cuadrado.</p>
<h5><strong><strong>Figura 2: Fórmula para calcular el semi-variograma</strong></strong></h5>
<p><strong><strong><a href="http://www.gisandchips.org/wp-content/formula_vario.jpg"><img class="aligncenter size-full wp-image-1342" src="http://www.gisandchips.org/wp-content/formula_vario.jpg" alt="" width="254" height="46" /></a><br />
</strong></strong></p>
<p>Donde Np(h) es el número de pares a la distancia h, h es el incremento.</p>
<p>Z(xi) son los valores experimentales.</p>
<p>xi localizaciones donde son medidos los valores z(xi).</p>
<p>Aplicado a imágenes, el semi-variograma (o variograma/2), mide el grado de correlación espacial entre los píxeles de una imagen. Podemos comentar varios conceptos (ver <strong>Figura 3</strong>):</p>
<ul>
<li>Sill o meseta: representa la varianza máxima.</li>
<li>Range, rango o alcance: muestra la distancia (en nuestro caso en píxeles) a la que el semi-variograma alcanza la meseta.</li>
<li>Nugget o “efecto pepita”, es la discontinuidad en el origen. Ésta es debida a que el semivariograma, en la práctica, no es nulo en el origen.</li>
</ul>
<h5><strong><strong>Figura 3: Interpretación del semivariograma</strong></strong></h5>
<p><strong><strong><a href="http://www.gisandchips.org/wp-content/variogram.jpg"><img class="aligncenter size-medium wp-image-1343" src="http://www.gisandchips.org/wp-content/variogram-300x184.jpg" alt="" width="300" height="184" /></a><br />
</strong></strong></p>
<p><strong>Ejemplos de cálculo en R</strong></p>
<p>Os aviso de que las imágenes referidas en el código estan en formato *.ppm aunque R tiene muchas librerías capaces de convertir a este formato. También podéis utilizar OpenOffice.</p>
<p>En este post, aplicamos el siguiente código para calcular el semi-variograma empírico de cada una de estas imágenes:</p>
<pre class="brush: bash; title: ; notranslate">
&lt;pre&gt;# Instalo los packages necesarios:

#-------------------------------------------------

install.packages(&quot;pixmap&quot;, dependencies= T)

install.packages(&quot;fields&quot;, dependencies= T)

# Cargo las librerias:
#-------------------------------------------------
library(pixmap)

library(fields)

# Hago una lista con las imagenes de las parcelas y las cargo todas:
#-------------------------------------------------
imag_dir &lt;- list.files(&quot;C:\\ ... \\Articulos Gisandchips\\ parcelas_ppm\\&quot;, full.names=T)

parcela1 &lt;- read.pnm(imag_dir[1])

parcela2 &lt;- read.pnm(imag_dir[2])

parcela3 &lt;- read.pnm(imag_dir[3])

# Aislamos una banda...
#-------------------------------------------------
matriz1&lt;-parcela1@green

matriz2&lt;-parcela2@green

matriz3&lt;-parcela3@green

# Calculamos el semivariograma (si queremos podemos acabar antes cambiando el alcance de 40  a 10, por ejemplo, pero los resultados pueden cambiar y quedará menos bonito (-: )
#-------------------------------------------------
vgram1_40&lt;-vgram.matrix( matriz1, R=40) # esto llevará un poco de tiempo

vgram2_40&lt;-vgram.matrix( matriz2, R=40) # esto llevará un poco de tiempo

vgram3_40&lt;-vgram.matrix( matriz3, R=40) # esto llevará un poco de tiempo

# Añadimos al Plot las matrices que acabamos de calcular
#-------------------------------------------------
plot.vgram.matrix(vgram1_40)# La matriz del variograma

plot.vgram.matrix(vgram2_40)# La matriz del variograma

plot.vgram.matrix(vgram3_40)# La matriz del variograma

# Creamos una curva que ajuste bien sobre la muestra y la añadimos al variograma
#-------------------------------------------------
polyfit1_40_20 &lt;- lm(vgram1_40$vgram ~ poly(vgram1_40$d, 20));

plot(vgram1_40$d, vgram1_40$vgram)

lines(sort(vgram1_40$d), polyfit1_40_20$fit[order(vgram1_40$d)], col=2, lwd=4)

polyfit2_40_20 &lt;- lm(vgram2_40$vgram ~ poly(vgram2_40$d, 20));

plot(vgram2_40$d, vgram2_40$vgram)

lines(sort(vgram2_40$d), polyfit2_40_20$fit[order(vgram2_40$d)], col=2, lwd=4)

polyfit3_40_20 &lt;- lm(vgram3_40$vgram ~ poly(vgram3_40$d, 20));

plot(vgram3_40$d, vgram3_40$vgram)

lines(sort(vgram3_40$d), polyfit3_40_20$fit[order(vgram3_40$d)], col=2, lwd=4)
</pre>
<p>El plot que obtenemos es el siguiente, o similar si es que hemos preferido cambiar algún parámetro:</p>
<h5><strong><strong>Figura 4: Panel donde mostramos los resultados</strong></strong></h5>
<p><strong><strong><a href="http://www.gisandchips.org/wp-content/variograma_3parcelas_polyfit.jpg"><img class="aligncenter size-medium wp-image-1344" src="http://www.gisandchips.org/wp-content/variograma_3parcelas_polyfit-299x299.jpg" alt="" width="327" height="327" /></a><br />
</strong></strong></p>
<p>En la imagen vemos las parcelas, la matriz de su variograma y el variograma, con una curva que ajustamos mucho al los datos. Es fácil interpretar que en la estructura de las parcelas se llega a apreciar cierta &#8220;ciclicidad&#8221;, ya que encontramos mesetas a distintas distancias. Cada meseta se  corresponde aproximadamente a las hileras de árboles. El alcance es el que hemos definido (40, en este caso 40 píxeles; puede que unos 20 m. en la realidad).</p>
<p>Viendo estas imágenes nos podemos dar cuenta de que es más fácil determinar una regla de clasificación que cuando lo hacíamos en el caso del RAPID. En este caso, nos fijamos en el número de máximos relativos de la función polinómica de ajuste del variograma. A simple vista, la primera parcela tiene unos 4, la segunda apenas 1 y la última 3 o 4. <strong>En este caso, podríamos citar una nueva regla para nuestro programa según la que a partir de 2 o 3 máximos relativos una parcela puede ser considerada una plantación arbórea.</strong></p>
<p>Como nos interesa automatizar la tarea creamos una función que nos cuente los máximos relativos. Aquí viene el ejemplo aplicado a la primera parcela:</p>
<pre class="brush: bash; title: ; notranslate">

# Encontrar máximos relativos en la función 1

#--------------------------------------------------

maxRelativos1=0

hMaxRelativos1=0

for(i in 1:(length(polyfit1_40_20$fitted.values)-1))

{

if (polyfit1_40_20$fitted.values[i] &gt; polyfit1_40_20$fitted.values[i+1] &amp;&amp; polyfit1_40_20$fitted.values[i] &gt; polyfit1_40_20$fitted.values[i-1])

{maxRelativos1[i]&lt;- polyfit1_40_20$fitted.values[i]

hMaxRelativos1[i]&lt;- vgram1_40$d[i]}

}

MaxRelativos1&lt;-data.frame(hMaxRelativos1,maxRelativos1)

MaxRelativos1&lt;- na.omit(MaxRelativos1)

NumMaxRelat1_40&lt;-length(rownames(MaxRelativos1))
</pre>
<p>Consultamos los vértices de la curva que hemos dibujado mediante un bucle, de modo que si el vértice <strong>i</strong> tiene un valor superior al vértice anterior y también al vértice posterior entonces es considerado un máximo relativo y queda almacenado en la lista.</p>
<h3>Algunos comentarios sobre todo esto:</h3>
<p>(1) El semivariograma implica un gran esfuerzo de cálculo por parte del ordenador. Esto hace que aún habiendo varias librerías en R que obtienen el semivariograma de una nube de puntos, sean significativamente más lentas que <strong>Fields. </strong>Además, <strong>Fields</strong> hace directamente lo que necesitábamos. No obstante, en un futuro no muy lejano, intentaré desarrollar una librería en C# para reproducir un análisis de este tipo y otras cosillas relacionadas.</p>
<p>(2) Por cuestiones de tiempo no he tratado de crear funciones para las distintas etapas de la demostración. Puede ser un buen ejercicio tratar de implementar todo esto en funciones que permitan entre sus parámetros especificar la banda con la que trabajar, el alcance del semivariograma…</p>
<p>(3) Existen más posibilidades a la hora de establecer reglas, por ejemplo podríamos explorar la distancia que separa los máximos relativos para distinguir los cultivos más intensivos de los más tradicionales. Se me ocurren muchas más posibilidades.</p>
<p>(4) Por último, aunque no le doy mucha importancia, deciros que el número de máximos relativos no es del todo correcto pues el cero siempre aparece en el conteo (sale 5, 2, 5 y no 4, 1, 4 como he dicho más arriba), esto es porqué no he trabajado bastante el bucle, pero es fácil restar 1 a la lista final.  Mi idea principal es la de explorar el concepto y dar unos ejemplos de código a modo de ideas.</p>
<h3>Referencias:</h3>
<p>Para entender bien todo esto creo que es interesante ver mi artículo anterior&#8230;</p>
<p>Solamente os remito al siguiente tutorial de Surfer. Es bastante didáctico. <a href="http://www.goldensoftware.com/variogramTutorial.pdf">http://www.goldensoftware.com/variogramTutorial.pdf</a></p>
<p>De todos modos la red está llena de materiales, apuntes de clase, libros en PDF… No tendréis problemas en encontrar información sobre los variogramas.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>Si quereis contactar podeis enviarme un email (asunto: gisandchips):</p>
<p>Benito M. Zaragozí</p>
<p>benito.zaragozi@ua.es</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2010/01/28/extraccion-de-caracteristicas-estructurales-de-una-imagen-ii-semi-variograma-de-una-imagen-usando-r-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Procesamiento de imágenes digitales con C# (y una aplicación para el análisis de parcelas agrícolas).</title>
		<link>http://www.gisandchips.org/2009/11/11/procesamiento-de-imagenes-digitales-con-c-y-una-aplicacion-para-el-analisis-de-parcelas-agricolas/</link>
		<comments>http://www.gisandchips.org/2009/11/11/procesamiento-de-imagenes-digitales-con-c-y-una-aplicacion-para-el-analisis-de-parcelas-agricolas/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 13:05:28 +0000</pubDate>
		<dc:creator>benizar</dc:creator>
				<category><![CDATA[Análisis]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[AForge.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Mineria de datos espacial]]></category>
		<category><![CDATA[Procesamiento digital de imagenes]]></category>
		<category><![CDATA[RAPID]]></category>
		<category><![CDATA[Teledetección orientada a objetos]]></category>
		<category><![CDATA[Transformada de Hough]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=1038</guid>
		<description><![CDATA[En este artículo voy a exponer una aplicación de ejemplo que he realizado con C# utilizando Aforge.NET. Dicha aplicación trata (y a veces lo consigue    ) de distinguir si una parcela dada puede ser una plantación  agrícola arbórea mediante el análisis de la Transformada de Hough, y luego se posibilita el conteo automático de [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">En este artículo voy a exponer una aplicación de ejemplo que he realizado con C# utilizando Aforge.NET. Dicha aplicación trata (y a veces lo consigue  <img src='http://www.gisandchips.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />   ) de distinguir si una parcela dada puede ser una plantación  agrícola arbórea mediante el análisis de la  Transformada de Hough, y luego se posibilita el conteo automático de los árboles. Al tratarse de un programa con finalidad didáctica los análisis se realizan para una sola parcela y por pasos muy definidos. No obstante, cabe pensar que su mayor utilidad vendría de un análisis masivo de parcelas.</p>
<h4 style="text-align: center"><a href="http://www.gisandchips.org/wp-content/hough_direcciones.jpg"><img class="size-full wp-image-1041 aligncenter" src="http://www.gisandchips.org/wp-content/hough_direcciones.jpg" alt="hough1" width="392" height="314" /></a>Imagen1</h4>
<p style="text-align: justify"><span id="more-1038"></span>En primer lugar, Aforge.NET es un Framework con distintas librerías que abarcan un amplio rango de campos relacionados con el tratamiento digital de imágenes. Se trata de un proyecto GNU GPL disponible en <a href="http://code.google.com/p/aforge/">http://code.google.com/p/aforge/</a> . Es un proyecto consolidado pero también muy prometedor, en el que Andrew Kirillov tiene un gran trabajo realizado.</p>
<p style="text-align: justify">Según vemos en la página Web entre sus librerías se encuentran:</p>
<ul style="text-align: justify">
<li><strong>AForge.Imaging</strong> &#8211; library with image      processing routines and filters;</li>
<li><strong>AForge.Vision</strong> &#8211; computer vision library;</li>
<li><strong>AForge.Neuro</strong> &#8211; neural networks computation      library;</li>
<li><strong>AForge.Genetic</strong> &#8211; evolution programming      library;</li>
<li><strong>AForge.Fuzzy</strong> &#8211; fuzzy computations library;</li>
<li><strong>AForge.MachineLearning</strong> &#8211; machine learning library;</li>
<li><strong>AForge.Robotics</strong> &#8211; library providing support of      some robotics kits;</li>
<li><strong>AForge.Video</strong> &#8211; set of libraries for video      processing</li>
<li>etc…</li>
</ul>
<p style="text-align: justify">Se me ocurre que alguien se podría plantear un <strong>AForge.GIS</strong>. Pensaremos en ello…</p>
<p style="text-align: justify">Nosotros hemos trabajado únicamente con Aforge.Imaging, pero salta a la vista la potencialidad que prácticamente todas las librerías tendrían para realizar análisis espaciales.</p>
<p style="text-align: justify">
<h3 style="text-align: justify">Introducción</h3>
<p style="text-align: justify">Actualmente, al trabajar en cuestiones de teledetección aplicada a fotografías aéreas e imágenes de satélite se esta aplicando cada vez más el paradigma del Análisis Orientado a Objetos (AOO), pasando de hablar de los valores de los píxeles, a las propiedades de los objetos. Podríamos resumirlo como: teledetección orientada a objetos.</p>
<p style="text-align: justify">No voy a tratar de hablar de análisis orientado a objetos, pues considero que hay abundante información en Internet.</p>
<p style="text-align: justify">Solamente por sentar el ejemplo que vamos a trabajar en este artículo, “Objeto” sería una parcela agrícola que podría tener múltiples “propiedades” como un área, perímetro, otros índices de forma… pero también tendría propiedades basadas en la respuesta espectral de la superficie que encierra, por ejemplo los valores de un índice de vegetación. También serían propiedades muy descriptivas de la parcela aquellas que describan la estructura generada por la distribución de los píxeles. Así pues, para una sola parcela podríamos tener muchísimas propiedades que la describieran, claro está, siempre unas lo harían mejor que otras.</p>
<p style="text-align: justify">En AForge.Imaging están disponibles distintas funciones de análisis para la extracción de estas propiedades o características a partir de una imagen, como por ejemplo la Transformada de Fourier, distintos algoritmos de detección de bordes y la que nos interesa aquí: La <strong>Transformada</strong><strong> de Hough</strong>.</p>
<p style="text-align: justify">En definitiva, hemos elaborado una aplicación de escritorio que calcula la transformada de Hough para la imagen aérea de una parcela, y después de aplicar unas sencillas reglas para decidir si se trata de una parcela agrícola y arbórea, permite contar automáticamente los árboles de dicha parcela.</p>
<p style="text-align: justify">
<h3 style="text-align: justify">La Transformada de Hough</h3>
<p style="text-align: justify">Se trata de una técnica utilizada para extraer elementos, con una forma particular, a partir de una imagen. Es comúnmente aplicada para encontrar y describir líneas rectas en una imagen, aunque también se pueden hallar círculos y otras formas. En la carpeta de ejemplos de AForge podéis encontrar el ejemplo en el que me he basado, en el cual se aplica Hough para hallar líneas y círculos dentro de una imagen.</p>
<p style="text-align: justify">Aquí no vamos a explicar los fundamentos de cálculo, sino la interpretación que podemos hacer de los resultados en nuestro caso del análisis de parcelas.</p>
<p style="text-align: justify">En concreto uno de los datos que obtenemos aplicando Hough es la inclinación de cada una de todas las líneas rectas halladas, como también la intensidad de cada línea (en nuestro caso tendrán mayor intensidad las líneas que más árboles atraviesen).</p>
<p style="text-align: justify">Solamente viendo la <strong>imagen1</strong> podríamos intuir cuales serían las inclinaciones/direcciones de las dos líneas de mayor intensidad halladas por Hough, pero como se ve en la imagen no hay una coincidencia exacta debido a pequeños detalles (los árboles no están homogéneamente separados, la parcela no es cuadrada…).</p>
<p style="text-align: justify"><strong>Nota: las líneas rojas no son las de mayor intensidad, solamente muestran las direcciones.</strong></p>
<p style="text-align: justify">En la <strong>Imagen2</strong> vemos como las direcciones principales son muy similares, y esto nos indica que difícilmente la parcela tendrá la estructura necesaria para realizar el conteo de árboles.</p>
<h4 style="text-align: center"><a href="http://www.gisandchips.org/wp-content/hough_direcciones2.jpg"><img class="size-full wp-image-1043 aligncenter" src="http://www.gisandchips.org/wp-content/hough_direcciones2.jpg" alt="hough_direcciones2" width="417" height="274" /></a>Imagen2</h4>
<h3 style="text-align: justify">Reglas de decisión</h3>
<p style="text-align: justify">Una vez calculado Hough usamos algunas estadísticas de las líneas halladas para crear reglas de decisión que ayuden a distinguir automáticamente la estructura de la parcela.</p>
<p style="text-align: justify">De un modo arbitrario a partir de las pocas parcelas vistas he decidido que serán agrícolas – arbóreas aquellas parcelas cumplan lo siguiente:</p>
<ul style="text-align: justify">
<li>aquellas parcelas que tengan una diferencia angular entre las dos direcciones principales comprendida entre 80 y 120,</li>
<li>o que el % de líneas en la 1ª dirección no sea mucho mayor que el % de la 2ª (&lt;2x)</li>
</ul>
<p style="text-align: justify">Estas reglas deberían ser más complejas y basadas en algún clasificador estadístico o matemático. Pero para ser didáctico es más que suficiente.</p>
<p style="text-align: justify">
<h3 style="text-align: justify">Rough Agricultural Plots IDentifier (RAPID)</h3>
<p style="text-align: justify">RAPID es el nombre que le hemos dado a nuestra aplicación de ejemplo. Es un identificador “basto” de parcelas agrícolas. No hay que esperar maravillas, pero veréis que acierta bastante.</p>
<p style="text-align: center"><a href="http://www.gisandchips.org/wp-content/RAPID.jpg"><img class="aligncenter size-medium wp-image-1448" src="http://www.gisandchips.org/wp-content/RAPID-300x176.jpg" alt="" width="300" height="176" /></a></p>
<h4 style="text-align: center">Imagen3</h4>
<p style="text-align: justify">La aplicación muestra una barra de tareas donde se secuencian los pasos de análisis y a medida que se realiza cada paso se activan nuevos botones.</p>
<p style="text-align: justify">Los botones son:</p>
<ul style="text-align: justify">
<li>OpenImage: permite añadir imágenes propias.</li>
<li>Binarize: binariza la imagen aplicando el umbral especificado en el cuadro de texto.</li>
<li>Calc Hough: calcula la transformada de Hough para la imagen binaria y muestra algunas estadísticas en es cuadro de la derecha. También muestra un mensaje sobre la adecuación, o no, de la parcela.</li>
<li>Count Trees: realiza el recuento de árboles de la imagen binaria y muestra el resultado en el cuadro “Trees estimation”. Este último no debería activarse en caso de que no se cumplieran las condiciones establecidas en nuestras reglas, pero se activa para facilitar todo tipo de pruebas.</li>
</ul>
<p style="text-align: justify">Por último, y para ahorrar tiempo se ha añadido una galería de imágenes de parcelas extraídas del visor del SIGPAC (<a href="http://sigpac.mapa.es/fega/visor/">http://sigpac.mapa.es/fega/visor/</a> ). He intentado que haya cierta variedad. Hay algunas parcelas donde resulta fácil el recuento (1, 2, 6, 8 ), pero también es muy interesante ver como se rechazan las otras parcelas. En algunos casos el conteo de árboles sería difícil incluso manualmente sobre la imagen.</p>
<p>En el caso de la parcela 8 de los ejemplos, vemos que RAPID hace un recuento bastante preciso de los olivos de la parcela 8 de los ejemplos (SIGPAC = 148; RAPID +/- 150, según el Threshold). Por supuesto que seríamos más precisos si elimináramos los ruidos que los bordes de la parcela introducen en el análisis.</p>
<p><a href="http://www.gisandchips.org/wp-content/parcela8_sigpac.jpg"><img class="size-medium wp-image-1449   alignleft" src="http://www.gisandchips.org/wp-content/parcela8_sigpac-242x300.jpg" alt="" width="199" height="246" /></a><a href="http://www.gisandchips.org/wp-content/parcela8_rapid.jpg"><img class="aligncenter size-medium wp-image-1450" src="http://www.gisandchips.org/wp-content/parcela8_rapid-241x300.jpg" alt="" width="202" height="251" /></a></p>
<p style="text-align: center">
<h5 style="text-align: center">Imagenes 4 y 5</h5>
<p style="text-align: justify">Podéis ajustar el umbral, y veréis como el recuento mejora en algunas imágenes. Esto también se podría automatizar.</p>
<p style="text-align: justify">Otra cuestión es que hemos trabajado sobre una imagen RGB, pero es evidente que la distinción de los árboles mejoraría mucho si dispusiéramos de una banda de infrarrojo próximo y la combináramos con las otras antes de realizar la binarización.</p>
<p style="text-align: justify">
<h3 style="text-align: justify">Algunas cosas sobre el código</h3>
<p style="text-align: justify">
<p style="text-align: justify">La mayor parte del código que he escrito se corresponde con aspectos del UI, lo que da una idea de cómo de bueno es AForge.</p>
<p style="text-align: justify">He organizado el código en un fórmulario y tres clases. Hay una clase para binarizar una imagen aplicando unos pocos filtros, otra para obtener las estadísticas de Hough y la última realiza el recuento de “blobs”, en este caso árboles.</p>
<p style="text-align: justify">Solamente me interesa destacar el uso de FilterSequence que permite predefinir el uso de varios filtros, lo cual resulta muy práctico.</p>
<pre class="brush: csharp; title: ; notranslate">

// binarization filtering sequence

FiltersSequence filter = new FiltersSequence(

new ContrastCorrection(),

new Mean(),

new GrayscaleBT709(),

new Threshold()

);
</pre>
<p style="text-align: justify">Por otra parte, si usando filtros y otras herramientas notáis que hacen justo lo contrario de lo que deberían, es porque justamente están haciendo lo contrario <img src='http://www.gisandchips.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  . Deberéis aplicar un Invert() al Bitmap. Esto me pasaba con el BlobCounter(), pues me devolvía la cuenta de todo lo que no eran árboles. También deberéis invertir la imagen si queréis usar filtros del tipo Erosion() o Dilatation().</p>
<p style="text-align: justify">
<p style="text-align: justify"><strong>El codigo fuente lo podeis obtener haciendo un checkout del siguiente repositorio subversion: </strong>svn co http://www.gisandchips.org/svn/rapid/</p>
<h3 style="text-align: justify">Referencias</h3>
<ul style="text-align: justify">
<li>De nuevo la página del proyecto: <a href="http://code.google.com/p/aforge/">http://code.google.com/p/aforge/</a></li>
</ul>
<ul style="text-align: justify">
<li>Para entender mejor esta técnica podéis consultar <a href="http://en.wikipedia.org/wiki/Hough_transform">http://en.wikipedia.org/wiki/Hough_transform</a></li>
</ul>
<ul style="text-align: justify">
<li>Antes del verano asistí a un curso en Valencia (Esp.) donde aprendí bastante de este tema. Como me gustó bastante os adjunto la referencia por si lo repiten de nuevo el año que viene: Teledetección aplicada a la actualización de cartografía de ocupación del suelo: técnicas de clasificación orientada a objetos. Curso teórico-práctico. <a href="http://cgat.webs.upv.es/bigfiles/c_objetos/index.html">http://cgat.webs.upv.es/bigfiles/c_objetos/index.html</a></li>
</ul>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>Si quereis contactar podeis enviarme un email (asunto: gisandchips):</p>
<p>Benito M. Zaragozí</p>
<p>benito.zaragozi@ua.es</p>
<p style="text-align: justify">
<p style="text-align: justify">
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2009/11/11/procesamiento-de-imagenes-digitales-con-c-y-una-aplicacion-para-el-analisis-de-parcelas-agricolas/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Información Geográfica, TURISMO, RA y la necesidad de estándares abiertos</title>
		<link>http://www.gisandchips.org/2009/11/09/informacion-geografica-turismo-ra-y-la-necesidad-de-estandares-abiertos/</link>
		<comments>http://www.gisandchips.org/2009/11/09/informacion-geografica-turismo-ra-y-la-necesidad-de-estandares-abiertos/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 13:03:23 +0000</pubDate>
		<dc:creator>Novatores</dc:creator>
				<category><![CDATA[Análisis]]></category>
		<category><![CDATA[Estándares Abiertos]]></category>
		<category><![CDATA[Geolocalización]]></category>
		<category><![CDATA[Información Geografica]]></category>
		<category><![CDATA[Nuevas Tecnologías en Turismo]]></category>
		<category><![CDATA[Realidad Aumentada]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=452</guid>
		<description><![CDATA[Hace 16 años les decía a mis alumnos de Nuevas Tecnologías en Turismo que llegaría un momento en que la gente preferiría pasar el tiempo navegando por páginas WEB en Internet que viendo la televisión, aunque aquéllos me expresaban desconfianza (todos los profesores de este tipo de materias reconocemos esas miradas que nos delatan a [...]]]></description>
			<content:encoded><![CDATA[<p>Hace 16 años les decía a mis alumnos de Nuevas Tecnologías en Turismo que llegaría un momento en que la gente preferiría pasar el tiempo <em>navegando</em> por <em>páginas </em><em>WEB</em> en <em>Internet </em>que viendo la televisión, aunque aquéllos me expresaban desconfianza (todos los profesores de este tipo de materias reconocemos esas miradas que nos delatan a los ojos del auditorio como “profetas iluminados” con una “visión”&#8230;). Un par de años después,  sentí lo mismo  impartiendo un curso a empresarios del sector, les aseguraba que casi todos los vehículos acabarían incorporando un navegador <em>GPS</em> de serie en el que se consultaría  información geográfica de los callejeros y de la ubicación de determinados servicios, para poder llegar a ellos con facilidad. ¡Todavía recuerdo la expresión de un grupo de ellos que  murmuraba con mueca incredula: “&#8230;¡con lo fácil que es bajar la ventanilla y preguntar&#8230;!”<a class="edit-post-status hide-if-no-js" href="post.php?action=edit&amp;post=452&amp;message=1#post_status">Edit</a></p>
<p>En los tres o cuatro últimos meses afloran referencias en los blogs y foros de <strong>Sistemas de Información Geográfica</strong> (<em>SIG</em>) sobre la <a href="http://video.google.es/videosearch?sourceid=chrome&amp;q=augmented%20reality%20android&amp;um=1&amp;ie=UTF-8&amp;sa=N&amp;hl=es&amp;tab=wv#">tecnología <em>Layar</em> y <em>Android</em></a>. Pero mientras muchos nos dedicamos a saborear cómo se materializa la información geográfica en aplicaciones de Realidad Virtual, como la <strong>Realidad Aumentada</strong>, quizá valdría la pena pararse a considerar la magnitud que puede alcanzar el fenómeno, sus consecuencias e incluso, permitirnos el lujo de recoger opiniones y sugerencias inspiradas en otras experiencias anteriores de propagación de tecnologías de la Información y la Comunicación (<em>TIC</em>) muy cercanas todavía en el tiempo.</p>
<p><a href="http://www.androidmarketiza.com/aplicaciones/layar-la-realidad-aumentada-ya-esta-en-el-market-de-espana-y-a-nivel-mundial/"><img class="aligncenter size-full wp-image-1030" src="http://www.gisandchips.org/wp-content/3831042176_ccfd58d2a0_o.jpg" alt="3831042176_ccfd58d2a0_o" width="500" height="335" /></a><span id="more-452"></span></p>
<p>Partiendo de las ideas expuestas en el <a href="http://programmerjoe.com/"><strong>Blog de Joe Ludwuig</strong></a> acerca de este tema, me gustaría dedicar un tiempo a reflexionar sobre la expectativa de éxito de la realidad aumentada (<em>RA</em>) y los Sistemas de Información Geográfica (<em>SIG</em>), pues parece evidente que la mayor rentabilidad para un proveedor de plataforma de RA no será a corto plazo&#8230;, pero si algo hemos aprendido del estudio de cómo se ha desarrollado la <em>WEB</em>, es que pese a ello no erraríamos al vaticinar un extraordinario desarrollo de esta tecnología en un par de años.</p>
<p>Precisamente, la <strong>naturaleza abierta del <em>WEB</em></strong> y su <strong>facilidad de uso</strong> permitieron en su momento que cualquiera se animará a participar, no hizo falta convencer a nadie, tampoco lo hubiera/n podido hacer una empresa o grupo de empresas en solitario, el éxito de la <em>WEB, </em>desde princios de los noventa fue la participación masiva a un bajo coste, con la posibilidad de que una <strong><em>buena idea</em></strong> pudiera convertirse en un<em><strong> f</strong><strong>abuloso negocio</strong></em>. Es decir, una nueva forma de divulgar la información proporcionaba la estimulación de nuevas facetas de mercado y de relación (también comercial) entre los grupos humanos.</p>
<p>Si tomamos el ejemplo de desarrollo de la navegación <em>WEB</em> , debemos considerar que la <em>RA</em> tiene un extraordinario potencial, pero no debemos perder de vista que una de las claves del éxito en el desarrollo de la <em>WEB</em> fue la <strong>ausencia de barreras institucionales</strong> que obstaculizaran su vertiginoso ascenso; gracias ello, la <em>WEB</em> pudo crecer en la misma medida que crecía la RED DE USUARIOS y la <em>RA</em> haría muy bien en “tomar nota de esto”.</p>
<p style="text-align: center"><strong><em>RA-“a”</em>: Realidad Aumentada y “Abierta”</strong></p>
<p>Si el nuevo ecosistema de la <em>RA</em> quiere crecer tan rápido como la <em>WEB</em> lo hizo, no puede depender de que una empresa, grupo de empresa o instituciones dicten el permiso o arbitren los protocolos encaminados a dejar que los usuarios existentes puedan obtener una nueva capacidad y ello impone que cualquiera pueda publicar contenido en el sistema y que por tanto, no haya “cuellos de botella” para ello, ni siquiera justificados en la calidad o pertinencia adecuada de los datos.</p>
<p>En el <em>mundo</em> de la información geográfica tenemos un buen ejemplo de ello en iniciativas exitosas como <a href="http://maps.google.es/">Google Maps</a> u <a href="http://www.openstreetmap.org/">OpenStreetMap</a>, incluso en otras opciones que parecían más modestas, como <a href="http://es.wikiloc.com/wikiloc/home.do">WikiLOC</a> (reconocido con el <a href="http://geotourism.changemakers.com/es/node/22687">Geoturism Challenge 2009</a> de Ashoka Changemaker y National Geographic). Todas ellas deben una buena parte de su éxito al <strong>uso de formatos normalizados y abiertos</strong>, sin exceso de trabas o controles institucionales, lo que conduce la generación de aplicaciones que piensan más en el usuario, sus capacidades y sus necesidades, generando iniciativas de <strong>carácter participativo y colaborativo </strong>muy capaces de <strong>enriquecer la cantidad y  utilidad de la información </strong>en la que se basan estos servicios.</p>
<p>La información debe estar accesible para múltiples clientes, desde distintos proveedores. Cualquiera debe ser capaz de crear un cliente que pueda trabajar con estos contenidos de información sin “grandes complicaciones”. Del otro lado, la solicitud de información de estos clientes debe poderse satisfacer por la respuesta de múltiples proveedores de contenido y de forma totalmente transparente al usuario final (recordemos la <em>Teoría del Iceberg</em>: gran cantidad y complejidad de recursos, pero puestos a disposición del usuario de forma muy simple, la facilidad de uso es inversamente proporcional a la infraestructura de información <em>puesta en juego</em>, sólo vemos una pequeña parte de lo que <em>hay por debajo</em>)</p>
<p>Tampoco debería ser un sistema basado en la rigidez de un directorio central de contenidos o de un directorio por cada uno de los proveedores de contenidos, pues al estilo de los servicios <em>WEB</em> del Open Geospatial Consortium (<em>OGC</em>), los contenidos deberán estar accesibles y adaptados de manera abierta a una <strong>normalización de los formatos que faciliten su uso</strong> (concepto de “usabilidad”).</p>
<p>Finalmente, la infraestructura tecnológica debe ser independiente de la información, de los datos que se transmiten por ella. Los proveedores de Internet Móvil, las empresas fabricantes de <em>smartphones</em>, etc,<em> </em> no deben controlar o ser parte especialmente implicada en el sector de los proveedores de información y de los desarrolladores de aplicaciones.</p>
<p>La &#8220;brecha digital&#8221; para esta tecnología se situará pivotada en dos puntos: <strong>disponibilidad de información o aplicaciones</strong>, por un lado,  y acceso a <strong>equipos de calidad apropiados </strong>para este tipo de tecnologías. No nos engañemos, los equipos de telefonía móvil compatibles son sofisticados y todavía de un precio elevado para muchos de los posibles usuarios de nuestro país (500-600 €)  y la ausencia de datos &#8211; aplicaciones disponibled no justifica todavía el alto grado de inversión económica requerido para el uso de la RA y la información geográfica por parte del consumidor medio.</p>
<p>En esta estadística sobre el país de procedencia de los usuarios de <a href="http://www.signo-geo.com/layarspain/blog/">LayarSPAIN</a> (empresa SIGNO Ingenieria del Territorio),  se pone claramente de manifiesto lo que queremos decir:</p>
<p style="text-align: center"><a href="http://www.signo-geo.com/layarspain/blog/?p=147"><img class="size-full wp-image-1335 aligncenter" src="http://www.gisandchips.org/wp-content/est-layarSpain_2009.png" alt="" width="267" height="98" /></a></p>
<p>El uso de esta tecnología para la información turística de LayarSpain por usuarios españoles se limita al 6%, mientras que estadounidenses, holandeses y británicos representan el 40% de los usuarios.  Precisamente ahí es dónde el uso de estándares abiertos puede ayudar a hacer más <em>pública </em>la tecnología; en efecto, la facilidad para desarrollar aplicaciones y publicar contenidos  puede ser la  solución a este problema, pues a mayor cantidad y calidad de la información mayor número de usuarios dispuestos a &#8220;pagar por&#8230;&#8221; , a mayor cantidad de usuarios mayor abaratamientos de costes en dispositivos, mayor accesibilidad tecnológica, desarrollo de más innnovaciones y en definitiva, lo que podríamos entender como una <strong>sinergia favorable</strong>.</p>
<p style="text-align: center"><strong>La clave del éxito: estándares abiertos</strong></p>
<p>Las consideraciones anteriores no implican la necesidad de un papel protagonístico del software abierto como Linux, Apache, Perl, PHP, etc. Aunque este tipo de aplicaciones han sido cruciales en el desarrollo de <em>Internet</em>, ello no implica que el uso de la información geográfica en el desarrollo de la RA se tenga que limitar necesariamente a ellas.</p>
<p>Sin embargo, la normalización de los datos, el fácil manejo de la información mediante el uso de fórmulas sencillas, es algo que sí puede convertirse en la espina vertebral del proceso. En los últimos años tenemos ejemplos de cómo el desarrollo de una nueva normalización está lleno de peligros, sobre todo, por que el exceso de celo puede llevar a la “asfixia” del proceso, como en el caso del lenguaje de modelado de Realidad Virtual (<em>VRML</em>). Afortunadamente, para el uso de la información geográfica y la RA, hay normalización ya vigente que se presta muy bien a resolver los problemas que los desarrolladores de realidad aumentada pueden encontrar en este sentido (protocolos de intercambio de información, formatos de datos, servicios WEB,&#8230;).</p>
<p>La primera de ellas es el antiguo <strong>protocolo de transporte de hipertexto</strong> (<em>HTTP</em>) que se ajusta a las características de “usabilidad” que hemos comentado antes. Es un protocolo que se entiende bien, descentralizado y disponible en el servidor o en forma de biblioteca cliente para cada plataforma. Además, están surgiendo nuevos y eficaces estándares para la consulta de localización específica de datos.</p>
<p>Un formato normalizado que los desarrolladores de <em>RA</em> pueden adoptar es el  <a><strong> </strong></a><strong><em>keyhole markup language</em> </strong>(<em>KML)</em>, de <em>Google</em> y que <em>Google Earth</em> utiliza para representar la información geocodificada. Tiene la ventaja de hacer uso de una gramática muy similar y casi compartida con el GML del OGC,  con un buen soporte para los objetos geográficos-geométricos. Es un estándar abierto y es soportado por muchos programas de <em>SIG</em>, además de que <em>Google Maps</em> y <em>Google Earth</em> han contribuido a su divulgación hasta el punto de hacerlo norma, con la garantía de haber divulgar la información geográfica como aplicaciones basadas en él, lo que significa un buen banco de pruebas).</p>
<p>De hecho, el 14 de abril de 2008 <em>Google</em> consiguió que el <em>OGC</em> estableciera el formato <a href="http://www.opengeospatial.org/standards/kml/">KML como un estándar abierto</a>, lo que casi lo consagra como punto de partida. Todavía está caliente del horno el <a href="http://www.openarml.org/">estandar ARML</a>, como efecto derivado de lo anterior, evidencia la intensidad de lo que estamos apuntando. Aunque hay quien todavía afirma que es mucho más práctico el uso de otros protocolos o estándares como IRC o RSS, usando canales como capas de información que se pudieran activar o desactivar, compartir o no a voluntad.</p>
<p>En definitiva, cualquier cliente de RA que se base en conexiones a datos y a lugares, mediante navegadores <em>WEB</em> (URLs), podrá beneficiarse de las ventajas de éstos y otros numerosos estándares que ya existen para los navegadores de <em>Internet</em>, con garantía de éxito. Sin embargo, hay muy poco hecho respecto a como los diferentes sistemas de RA pueden trabajar juntos; aquí podría residir el principal problema, pues si salimos de los centros de desarrollo y programación, los actuales sistemas de RA que están vigentes en la calle son los del equipo holandés de Raimo van der Klein, Claire Boonstra &amp; Maarten Lens-FitzGerald <a href="http://translate.googleusercontent.com/translate_c?hl=es&amp;ie=UTF-8&amp;sl=en&amp;tl=es&amp;u=http://layar.eu/&amp;rurl=translate.google.es&amp;usg=ALkJrhgPILMJAaMIFZIyknqIGfPOCDspug">(Layar</a>) y los de IBM (<a href="http://gizmodo.com/5299581/ibm-seer-augmented-reality-ures-no-confused-android-users-at-wimbledon&amp;anno=2">Vidente)</a>, siendo precisamente Layar  la iniciativa más abierta, hasta el punto de abrir su API en julio de este año (<a href="http://translate.googleusercontent.com/translate_c?hl=es&amp;ie=UTF-8&amp;sl=en&amp;tl=es&amp;u=http://layar.com/api&amp;rurl=translate.google.es&amp;usg=ALkJrhg8LdTCJz57WckUPwQSjNldrRAFqQ">http://layar.com/api</a>).</p>
<p>Mientras la tecnología de <a href="http://video.google.es/videosearch?hl=es&amp;client=firefox-a&amp;rls=org.mozilla:es-ES:official&amp;hs=aMn&amp;q=vidente+augmented+reality&amp;um=1&amp;ie=UTF-8&amp;ei=4Pn3SsG9JYPG4QbenqXdAw&amp;sa=X&amp;oi=video_result_group&amp;ct=title&amp;resnum=5&amp;ved=0CCIQqwQwBA#">Vidente</a> se ha centrado en apliaciones muy concretas destinadas a usuarios con <a href="http://studierstube.icg.tu-graz.ac.at/vidente/">especialización tecnológica</a> (infraestructuras, &#8230;), Layar se está dando los pasos para abrirse y llegar mejor al <em>usuario de la calle</em>. Convendría meditar hasta que punto puede residir aquí la clave del éxito y  propiciar nuevos modelos de negocio, pues el software o el hardware se irá robusteciendo en la medida que haya posibilidad de beneficio, pero la capacidad de los creadores de contenidos depende de la creación de un estándar abierto para la <em>RA </em>que permita ofrecer un adecuado nivel de información.</p>
<p>La estandarización es vital, pues aunque las aplicaciones individuales de RA no tengan que interactuar entre sí, muchos de ellas tendrán que hacerlo con el usuario al mismo tiempo para dar una sensación de facilidad de uso y transparencia.  Múltiples aplicaciones deberán ofrecer su producción al usuario a través de un medio único de comunicación. No se trata de inventar primero la normalización, pero las personas que están construyendo estos sistemas deberían seguir una dirección que permita a los proveedores estándares intersectoriales.</p>
<p style="text-align: center"><strong>Información geográfica, RA y Turismo: enorme potencial por la coincidencia de información (GIS), comunicación (smartphone), tiempo (on-line-street) y espacio (GPS)<br />
</strong></p>
<p>En España y puede que en el mundo entero, un efecto inducido de la capacidad de abrirse de la RA es el que puede estar teniendo el estandar de Layar sobre la actividad turística. Las posibilidades son muchas y muy atractivas, un buen ejemplo de ello son las ya citadas de la empresa <a href="http://signo.wordpress.com/">SIGNO</a>, una de las empresas pioneras en desarrollar aplicaciones y prospectar el potencial de esta tecnologías, como se puede ver en los ejemplos de Santiago de Compostela y el <a href="http://www.codigocero.com/A-galega-Signo-aplica-no-Camino-de">Camino de Santiago</a>.</p>
<p>El protagonismo alcanzado ha sido tal que ha llegado a generar la creación y mantenimiento de un <a href="http://www.signo-geo.com/layarspain/blog/">blog específico</a> dedicado a este tema, en el que podemos ver, entre otras muchas cosas&#8230;, la creación de una aplicación (Beta) con acceso a 70.000 hoteles de todo el mundo y la capacidad de consultar mediante RA y relizar la reserva.</p>
<p style="text-align: center"><a href="http://www.signo-geo.com/layarspain/blog/?p=137"><img class="size-medium wp-image-1334 aligncenter" src="http://www.gisandchips.org/wp-content/layarSpain-210x300.png" alt="" width="210" height="300" /></a></p>
<p>Está aplicación de &#8220;Hotels near YOU&#8221;  ha sido posible precisamente gracias a la integración de información y a la colaboración con el portal <a href="http://www.booking.com/">Booking</a> de reservas <em>on-line</em> y viene a representar un importante <em>botón de muestra</em> de lo que estamos defendiendo en este post.</p>
<p>En este aspecto, las posibilidades de funciones como las del  <em>graffiti virtual </em>pueden integrar esta tecnología en el WEB 2.0, lo que permitirá la generación de comentarios privados, opiniones, etc&#8230; que tan útiles están resultando en los portales de información turística sobre alojamientos, hoteles, rutas y demás productos de consumo, con la ventaja de ser pensamientos u opiniones dejados en lugares vinculados con GPS en casi cualquier parte del mundo, con distintos niveles de acceso o incluso el seguimiento de los comentarios o mensajes de otras personas al respecto.</p>
<p>En definitiva, la RA puede abrir un abanico inmenso de posibilidades a los profesionales de la información geográfica o geocodificada y si aprendemos del pasado y partimos del uso de estándares abiertos, su desarrollo en cantidad, calidad y usuarios puede ser tremendo, hasta el punto de convulsionar muchas de las formas habituales de consumir información, generando nuevas y sugerentes formas de negocio y de gestión.</p>
<p>En el caso de Informción Geográfica y Turismo, ya no dependeremos de acceder desde un ordenador en el punto de <em>origen </em>del turista (desde casa, antes de salir de viaje o desde el hotel&#8230;), ahora la Realidad Aumentada nos permitirá acceder a la información en <em>destino</em>, en la calle, <strong>en el momento y el espacio en el que se necesita esa información y con altos niveles de improvisación por parte del usuario, lo que diferenciará la navegación del visitante en paises desarrollados y generará &#8220;confianza&#8221; en la elección del destino.</strong></p>
<p>Como especialista en Tecnologías de la Información Geográfica y Turismo mis conocimientos técnicos no me permiten profundizar más allá, en los entresijos de esta tecnología, pero no puedo evitar presumir sus enormes posibilidades de futuro.  ¿Quién sabe?&#8230; igual muy pronto, ver al típico turista desplegando un plano en la esquina de una ciudad quedará como una imagen para el recuerdo y comenzaremos ver transeúntes con un ojo puesto en el paisaje y otro en su <em>smartphone</em>, viendo cosas que van más allá de lo que ven los moradores habituales sin ese “ojo electrónico” de la RA.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2009/11/09/informacion-geografica-turismo-ra-y-la-necesidad-de-estandares-abiertos/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Análisis de redes con OpenStreetMap y PgRouting en un ambiente web</title>
		<link>http://www.gisandchips.org/2009/10/03/analisis-de-redes-con-openstreetmap-y-pgrouting-en-un-ambiente-web/</link>
		<comments>http://www.gisandchips.org/2009/10/03/analisis-de-redes-con-openstreetmap-y-pgrouting-en-un-ambiente-web/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 23:50:27 +0000</pubDate>
		<dc:creator>jose</dc:creator>
				<category><![CDATA[Análisis]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[OpenStreetMap]]></category>
		<category><![CDATA[pgRouting]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=290</guid>
		<description><![CDATA[OBJETIVO: El objetivo de esta serie de artículos es proporcionar una metodología para crear servicios de enrutamiento (routing) en portales web utilizando datos de OpenStreetMap (http://www.openstreetmap.org) que serán añadidos a una geodatabase de PostgreSQL, con la extensión PostGIS y PgRouting. Para llevar a cabo este servicio son necesarias las siguientes fases: Instalación de las extensiones [...]]]></description>
			<content:encoded><![CDATA[<p><strong>OBJETIVO</strong>:</p>
<p>El objetivo de esta serie de artículos es proporcionar una metodología para crear servicios de enrutamiento (routing) en portales web utilizando datos de OpenStreetMap (<a href="http://www.openstreetmap.org/">http://www.openstreetmap.org</a>) que serán añadidos a una geodatabase de PostgreSQL, con la extensión PostGIS y PgRouting.</p>
<p>Para llevar a cabo este servicio son necesarias las siguientes fases:</p>
<ol>
<li>Instalación de las extensiones PostGIS y PgRouting</li>
<li>Importación de los datos de OSM</li>
<li>Conversión a una geodatabase de PostGIS en PostgreSQL</li>
<li>Explotación de una geodatabase con PgRouting.</li>
<li>Diseño de la interfaz de usuario. Contenedor HTML y Javascript (Openlayers)</li>
<li>Creación de lógica de enrutamiento en PHP</li>
</ol>
<p>En la medida en que vaya finalizando los capítulos serán publicados en esta web. En este primer artículo se abordarán las tres primeras fases.</p>
<p><span id="more-290"></span></p>
<p><strong>OBSERVACIONES</strong>:</p>
<p>Para la realización del presente documento me he basado en las referencias web de los portales de PgRouting (<a href="http://pgrouting.postlbs.org/">http://pgrouting.postlbs.org/</a>) y OpenLayers (<a href="http://openlayers.org/">http://openlayers.org</a>), así como en diferentes páginas encontradas en Internet. En la medida en que se utilice información de otra fuente será convenientemente citada, salvo olvido.</p>
<p><strong>ÁMBITO DE APLICACIÓN</strong></p>
<p>Todas las fases se han ensayado satisfactoriamente en los siguientes entornos: Ubuntu 9.04 y Centos 5.3. (clon de Red Hat Enterpise Linux). No obstante, las indicaciones y comandos utilizados en este artículo hacen referencia a este último sistema operativo.</p>
<p>Partimos de la base que tenemos un servidor Linux con el sistema operativo Centos 5.3 de 64 bits, con la base de datos PostgreSQL 8.3 ya instaladas. Por defecto, Centos dispone de PostgreSQL 8.1, si bien hemos preferido añadir los repositorios para la 8.3.7. Para información sobre la instalación ver este enlace: <a href="https://projects.commandprompt.com/public/pgcore">https://projects.commandprompt.com/public/pgcore</a></p>
<p><strong><em>NOTA</em></strong><em>: La instalación de PostgreSQL desde este repositorio “oficial” de PostgreSQL no ha sido todo lo gratificante que esperaba. Hay problemas de dependencias con respecto a otras librerías del sistema Centos. Esto en cambio no ocurre con Ubuntu, que por defecto tiene en su paquetería las últimas versión de esta base de datos.</em></p>
<p>APLICACIONES UTILIZADAS</p>
<ul>
<li>PostgreSQL 8.3</li>
<li>PostGIS 1.4</li>
<li>OpenLayers 2.8</li>
<li>PgRouting 1.03</li>
<li>Osm2pgRouting</li>
<li>Osmosis</li>
</ul>
<p><strong>INSTRUCCIONES Y RECOMENDACIONES GENERALES:</strong></p>
<p>Las instrucciones para la instalación o compilación de programas se especifican mediante comandos de la consola Linux, sin tener que recurrir a ninguna herramienta gráfica. Esta forma de actuar puede ser útil para aquellos usuarios que disponen de acceso a un servidor remoto, donde sólo se tiene acceso mediante la consola.</p>
<p>Con el fin de facilitar las tareas conviene crear un directorio donde descargar, descomprimir y compilar las fuentes de los programas. Para ello, crea un directorio de compilación dentro del home del usuario<br />
<code><br />
$ mkdir /home/&lt;usuario&gt;/compilar</code></p>
<p><code> </code></p>
<p><code>$ cd /home/&lt;usuario&gt;/compilar<br />
</code></p>
<p><strong><em>NOTA</em></strong><em>: El símbolo “$” es sólo el indicativo del prompt del sistema, no es necesario escribirlo.</em></p>
<p>Otra opción es crear un directorio de fuentes (por ejemplo “src” dentro de la carpeta “usr/local/”, y trabajar siempre como root. Yo particularmente prefiero la primera opción.</p>
<p><strong>INSTALACIÓN DE POSTGIS</strong></p>
<p>Aunque es posible utilizar la paquetería de PostGIS que aparece en el repositorio (yum info Postgis) he preferido compilar el paquete con el fin de tener la última versión estable de PostGIS</p>
<p>Sí no estás interesado en compilar PostGIS, puedes instalar el paquete oficial que viene con el repositorio de Postgres para Centos. Utiliza estos comandos</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top"># yum info postgis</td>
</tr>
</tbody>
</table>
<p>Y obtendrás esta información:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">Available PackagesName : postgisArch : x86_64Version : 1.3.6Release : 1.rhel5Size : 1.0 MRepo : pgdg83Summary : Geographic Information Systems Extensions to PostgreSQLURL : <a href="http://postgis.refractions.net/">http://postgis.refractions.net/</a></p>
<p>License : GPL</p>
<p>Description: PostGIS adds support for geographic objects to the PostgreSQL</p>
<p>: object-relational database. In effect, PostGIS “spatially enables”</p>
<p>: the PostgreSQL server, allowing it to be used as a backend spatial</p>
<p>: database for geographic information systems (GIS), much like ESRI’s</p>
<p>: SDE or Oracle’s Spatial extension. PostGIS follows the OpenGIS</p>
<p>: “Simple Features Specification for SQL” and has been certified as</p>
<p>: compliant with the “Types and Functions” profile.</td>
</tr>
</tbody>
</table>
<p>Luego, como superusuario:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top"># yum install postgis</td>
</tr>
</tbody>
</table>
<p><strong>Compilación de PostGIS 1.4</strong></p>
<p>Por suerte, PostGIS es una extensión bastante utilizada, y por tanto su compilación está muy bien detallada en el portal de Reflaction Research (<a href="http://postgis.refractions.net/">http://postgis.refractions.net/</a>)</p>
<p>Esta extensión requiera para su compilación de dos librerías de las que depende (dependencias), por una parte PROJ y por otra GEOS. Ambas son bien conocidas y utilizadas en multitud de programas de SIG de código abierto. Ambas son opcionales, y no son necesarias para la compilación, pero sin ellas dejariamos a PostGIS huerfano de utilidades de reproyección y geoprocesamiento.</p>
<p><strong>Instalación de la librería PROJ.4</strong></p>
<p>PROJ.4 (<a href="http://trac.osgeo.org/proj/">http://trac.osgeo.org/proj/</a>) es la librería más utilizada para las proyecciones cartográficas y permite, como no podía ser de otra manera realizar conversiones entre diferentes proyecciones cartográficas.</p>
<p><strong><em>NOTA</em></strong><em>: En el blog de Geomaticblog.net hay un excelente post de como utlizar esta librería desde aplicaciones como GDAL/OGR o GvSIG. Particularmente, me ha resultado útil para transformar datos desde ED50 a WGS84. Enlace: <a href="http://geomaticblog.net/2009/01/23/2009-01-23-ogrs_y_rejillas_ntv2/">http://geomaticblog.net/2009/01/23/2009-01-23-ogrs_y_rejillas_ntv2/</a></em></p>
<p>Pasos para la compilación:</p>
<p>1. Descargar la fuente</p>
<p>$ wget <a href="http://download.osgeo.org/proj/proj-4.7.0.tar.gz">http://download.osgeo.org/proj/proj-4.7.0.tar.gz</a></p>
<p>2. Descomprimirla</p>
<p>$ tar xzvf proj-4.7.0.tar.gz</p>
<p>3. Cambio de directorio</p>
<p>$ cd proj-4.7.0</p>
<p>4. Configuración y puesta a punto. El siguiente comando prepara la compilación advirtiéndonos si falta algún que otro paquete</p>
<p>$ ./configure</p>
<p><em>NOTA: Es posible que en este paso aparezcan errores porque falta algún paquete. Tan sólo fíjate en que es lo que falta e instálalo (con “yum” o “apt” en el caso de Ubuntu). Habitualmente serán necesarias algunas herramienta propias de la compilación, como flex, bison, make, etc. En Ubuntu tienes un paquete específico para ello: “sudo apt-get install build-essential”.</em></p>
<p>5. Compilación</p>
<p>$ make</p>
<p>6. Colocar las librerias en su sitio como “root”</p>
<p>$ make install</p>
<p>Para “impersonarse” como superusuario sólo tienes que escribir: “<strong>su -</strong>”. En Ubuntu sólo tienes que anteceder la palabra “<strong>sudo</strong>” a cualquier comando que quieras ejecutar como root. En ambos casos te pedirá la clave de acceso del administrador del sistema.</p>
<p>7. Comprobación</p>
<p>$ proj</p>
<p>Obtendremos lo siguiente:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">Rel. 4.7.1, 23 September 2009usage: proj [ -beEfiIlormsStTvVwW [args] ] [ +opts[=arg] ] [ files ]</td>
</tr>
</tbody>
</table>
<p><strong>Instalación de GEOS (Geometry Engine Open Source)</strong></p>
<p>GEOS (<a href="http://trac.osgeo.org/geos/">http://trac.osgeo.org/geos/</a>) es una librería que proporciona a PostGIS la capacidad de realizar geoprocesamiento. Sin ella no podriamos realizar las típicas operaciones de unión, intersección, diferencia, buffer, etc, todas ellas correspondiente a la especificación SFA (Simple Feature Access) del OGC. GEOS es un porting de la librería JTS (Java Topology Suite) en el lenguaje C++, lo que le convierte en una máquina de geoprocesos bastante eficiente.</p>
<p>Pasos para la compilación</p>
<p>1. Descarga de la fuente</p>
<p>$ wget <a href="http://download.osgeo.org/geos/geos-3.1.1.tar.bz2">http://download.osgeo.org/geos/geos-3.1.1.tar.bz2</a></p>
<p>2.Descomprimir:</p>
<p>$ tar -xjvf geos-3.1.1.tar.bz2</p>
<p>3.Cambio de directorio</p>
<p>$ cd geos-3.1.1</p>
<p>4.Configuración</p>
<p>$ LDFLAGS=-lstdc++ ./configure</p>
<p>La directiva LDFLAGS tiene como objetivo enlazar expliciatamente PostgreSQL con el estándar C++</p>
<p>5. Compilar</p>
<p>$ make</p>
<p>El tiempo de compilación suele ser bastante largo (en torno a los 7-10 minutos)</p>
<p>6. Colocar librerías en su sitio (Como usuario root):</p>
<p>$ make install</p>
<p>7. Comprobación</p>
<p>$ geos-config –version</p>
<p>Devolverá:</p>
<p>3.1.1</p>
<p><strong>Instalar PostGIS</strong></p>
<p>Sí las dos librerías anteriores han sido instaladas correctamente deberás de tener los siguientes archivos en el directorio “/usr/local/lib”. Compruébalo:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">$ ls /usr/local/lib/libproj*/usr/local/lib/libproj.a /usr/local/lib/libproj.so.0/usr/local/lib/<a href="http://libproj.la/">libproj.la</a> /usr/local/lib/libproj.so.0.5.5/usr/local/lib/libproj.so /usr/local/lib/libproj.so.0.6.6$ ls /usr/local/lib/libgeos*/usr/local/lib/<a href="http://libgeos-3.1.0.so/">libgeos-3.1.0.so</a> /usr/local/lib/<a href="http://libgeos_c.la/">libgeos_c.la</a>/usr/local/lib/<a href="http://libgeos-3.1.1.so/">libgeos-3.1.1.so</a> /usr/local/lib/libgeos_c.so/usr/local/lib/libgeos.a /usr/local/lib/libgeos_c.so.1/usr/local/lib/<a href="http://libgeos.la/">libgeos.la</a> /usr/local/lib/libgeos_c.so.1.5.0</p>
<p>/usr/local/lib/libgeos.so /usr/local/lib/libgeos_c.so.1.6.0</td>
</tr>
</tbody>
</table>
<p><strong>Proceso de instalación:</strong></p>
<p>1. Descarga de las fuentes:</p>
<p>$ wget <a href="http://postgis.refractions.net/download/postgis-1.4.0.tar.gz">http://postgis.refractions.net/download/postgis-1.4.0.tar.gz</a></p>
<p>2. Descomprimir:</p>
<p>$ tar xzvf postgis-1.4.0</p>
<p>3. Cambiar de directorio</p>
<p>$ cd postgis-1.4.0</p>
<p>4. Configurar</p>
<p>Es el paso que más atención debemos de prestar, puesto que al final del comando emitirá un informe con las dependencias satisfechas</p>
<p>$ ./configure</p>
<p>Sí todo va bien obtendremos un mensaje similar a este:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">PostGIS is now configured for x86_64-unknown-linux-gnu&#8212;&#8212;&#8212;&#8212;&#8211; Compiler Info &#8212;&#8212;&#8212;&#8212;-C compiler: gcc -g -O2C++ compiler: g++ -g -O2&#8212;&#8212;&#8212;&#8212;&#8211; Dependencies &#8212;&#8212;&#8212;&#8212;&#8211;GEOS config: /usr/local/bin/geos-configGEOS version: 3.1PostgreSQL config: /usr/bin/pg_configPostgreSQL version: 8.3</p>
<p>PROJ4 version: 47</p>
<p>PostGIS debug level: 0</p>
<p>&#8212;&#8212;&#8211; Documentation Generation &#8212;&#8212;&#8211;</p>
<p>xsltproc: /usr/bin/xsltproc</p>
<p>xsl style sheets:</p>
<p>dblatex:</p>
<p>convert:</td>
</tr>
</tbody>
</table>
<p>5.Compilación y colocación de las librerías</p>
<p>$ make</p>
<p>$ make install (como root)</p>
<p><strong>Post-instalación de PostGIS</strong></p>
<p>El siguiente paso es de vital importancia y nos puede ahorrar muchos problemas en el futuro. Por defecto las librerías se instalan en el directorio ya citado (”/usr/local/lib”), sin embargo, éste directorio no es reconocido por los programas de compilación como un directorio válido para instalar librerías, por lo que es necesario indicárselo de forma expresa. Para ello como root:</p>
<p>1. Edita el fichero “/etc/ld.so.conf” con tu editor preferido (vi, pico, nano, etc):</p>
<p>$ nano /etc/ld.so.conf</p>
<p>Y añade las siguientes líneas al final del documento</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">/usr/local/lib/usr/local/lib64</td>
</tr>
</tbody>
</table>
<p>2. Finalmente ejecuta este comando</p>
<p>$ /sbin/ldconfig</p>
<p><strong>INSTALACIÓN DE LA LIBRERÍA PgRouting</strong></p>
<p>PgRouting (<a href="http://pgrouting.postlbs.org/">http://pgrouting.postlbs.org</a>), al igual que PostGIS, es una extensión de PostgreSQL que permite trabajar con redes</p>
<p>A diferencia de PostGIS, aun no tenemos un paquete que instale PgRouting que satisfaga todas sus dependencias, por ello es necesario optar por la compilación de todas y cada una de las librerías utilizadas.</p>
<p>Librerías de las que depende:</p>
<ul>
<li>BOOST (<a href="http://www.boost.org/">http://www.boost.org</a> ): Es la librería principal, y la única que es obligatoria. Se trata de un basto conjunto de utilidades, entre las que destacan las referidas al análisis y explotación de grafos.</li>
<li>GAUL (Genetic Algorithm Utility Library): Esta librería sólo es necesario si deseamos dotar a PostgreSQL de la utilidad de cálculo del llamado “Problema del viajante”, conocida por sus signas en inglés, TSP (Traveling Salesman Problem), es decir, proporcionar la ruta óptima pasando por varios sitios. Enlace: <a href="http://gaul.sourceforge.net/">http://gaul.sourceforge.net/</a></li>
<li>CGAL (Computacional Geometric Algorithm Library): Librería especializada en el cálculo y procesamiento de estructuras geométricas en 2D y 3D. En el caso de PgRouting proporciona el algoritmo de cálculo conocido como Driving Distance.</li>
</ul>
<p><em>NOTA: Adicionalmente compilaremos el compilador CMAKE</em></p>
<p><strong>BOOST</strong></p>
<p>Como ya se ha comentado se trata de una librería muy ambiciosa por la gran cantidad de utilidades que engloba, de ahí que se compilación sea muy pesada (en tiempo de compilación). En los repositorios, Centos dispone actualmente de la versión 1.33.1, bastante antigua, si pensamos que la última estable es la 1.4.0. No obstante, para este artículo utilizaré la 1.39.0 que es la que tenemos más ensayada.</p>
<p>Con todo, de esta líbrería sólo necesitamos las utilidades de grafos (graphs)</p>
<p>Para ver la versión de las fuentes boost del repositorio:</p>
<p>$ yum info boost-devel</p>
<p>Sí no queremos complicarnos la vida con la compilación añade el paquete con “yum”:</p>
<p>$ yum install boost-devel</p>
<p>En Ubuntu 9.04, la versión disponible es la 1.34, sería:</p>
<p>$ sudo apt-get install libboost-graph-dev</p>
<p><strong>Compilación de las fuentes de boost 1.39</strong></p>
<p>1. Descarga las fuentes:</p>
<p>wget <a href="http://sourceforge.net/projects/boost/files/boost/1.39.0/boost_1_39_0.tar.bz2/download">http://sourceforge.net/projects/boost/files/boost/1.39.0/boost_1_39_0.tar.bz2/download</a></p>
<p>2. Descomprimir</p>
<p>$ tar –xjvf boost_1_39_0.tar.bz2</p>
<p>3. Cambiamos al usuario administrador</p>
<p>$ su -</p>
<p>4. Instalar dependencias:</p>
<p>$ yum install expat-devel</p>
<p>$ yum install python-devel</p>
<p>$ yum install freetype-devel</p>
<p>5. Cambio de directorio</p>
<p>$ cd /home/&lt;usuario&gt;/compilar/boost_1_39_0</p>
<p>6. Configuración</p>
<p>Para obtener ayuda sobre la configuración</p>
<p>$ ./bootstrap.sh –help</p>
<p>Configuración genérica: Instala todas las librerías en este directorio</p>
<p>$ ./bootstrap.sh –prefix=/usr/local/</p>
<p>Sí sólo necesitamos compilar la librería de cabezera (header library)</p>
<p>$ ./bootstrap.sh –prefix=/usr/local/ &#8211;with-libraries=graph</p>
<p>5. Compilar</p>
<p>$ ./bjam install</p>
<p>Es posible que tengas al inicio de la compilación algún mensaje relacionado con la librería EXPAT ques es utilizada por libGraph.  Para evitar este mensaje define estas variables:</p>
<p>$ export EXPAT_INCLUDE=/usr/include</p>
<p>$ export EXPAT_LIBPATH=/usr/lib</p>
<p>Y de nuevo ejecuta</p>
<p><span style="background-color: #ffffff">$ ./bjam install</span></p>
<p><em>NOTA</em><em>: Sí deseas compilar versiones anteriores, como la 1.36 y 1.37, la compilación es más sencilla. Usa los clásicos: ./configure, make, make install</em></p>
<p><strong>GAUL</strong></p>
<p>Instalación de Gaul (librería necesaria para el algoritmo TSP -Traveling Salesman Problem)</p>
<p>$ wget <a href="http://nfsi.dl.sourceforge.net/sourceforge/gaul/gaul-devel-0.1849-0.tar.gz">http://nfsi.dl.sourceforge.net/sourceforge/gaul/gaul-devel-0.1849-0.tar.gz</a></p>
<p>$ tar xzvf gaul-devel-0.1849-0.tar.gz</p>
<p>$ ./configure &#8211;disable-slang</p>
<p><strong>Instalar CMAKE</strong></p>
<p>Este compilador sólo se instalará para el usuario, y no estará disponible para todos (no hacer nunca “make install” como root)</p>
<p>$ wget <a href="http://www.cmake.org/files/v2.4/cmake-2.4.8.tar.gz">http://www.cmake.org/files/v2.4/cmake-2.4.8.tar.gz</a></p>
<p>$ tar -zxvf cmake-2.4.8.tar.gz</p>
<p>$ cd cmake-2.4.8</p>
<p>$ ./configure</p>
<p>Como usuario (¡no como administrador¡)</p>
<p>$ gmake</p>
<p><strong>CGAL</strong></p>
<p>Librería necesaria para utilizar el algoritmo Driving Distance). La versión que vamos a compilar es la 3.3.1, aunque existe otra más moderna (3.4). Sin lugar a dudas es la libraría que más problemas ofrece.</p>
<p>$ wget <a href="ftp://ftp.mpi-sb.mpg.de/pub/outgoing/CGAL/CGAL-3.3.1.tar.gz">ftp://ftp.mpi-sb.mpg.de/pub/outgoing/CGAL/CGAL-3.3.1.tar.gz</a></p>
<p>$ tar xzvf CGAL-3.3.1.tar.gz</p>
<p>$ cd CGAL-3.3.1</p>
<p>Compilar como root:</p>
<p>$ ./install_cgal &#8211;prefix=/usr/local &#8211;with-boost=n &#8211;without-autofind -ni /usr/bin/g++</p>
<p>Las librerías y los include se colocan en estos directorios:</p>
<p>/usr/local/lib/</p>
<p>/usr/local/include/</p>
<p><strong>INSTALACIÓN DE LA LIBRERÍA PGROUTING</strong></p>
<p>Una vez satisfechas todas las dependencias de librerías vamos a compilar PgRouting<span> </span></p>
<p>1. Primero nos descargamos las fuentes desde el repositorio subversión. Recuerda que debes de tener instalada dicha utilidad (“yum install subversión”)</p>
<p>$ svn checkout <a href="http://pgrouting.postlbs.org/svn/pgrouting/trunk">http://pgrouting.postlbs.org/svn/pgrouting/trunk</a> pgrouting</p>
<p>2. Nos cambiamos al directorio</p>
<p>$ cd pgrouting</p>
<p>3. Configuramos</p>
<p>Para ello utilizamos el compilador CMAKE que ya tenemos disponibles.</p>
<p>Compilar (no olvides el punto al final del comando)</p>
<p>La sintaxis de compilación es:</p>
<p>&lt;ruta al ejecutable CMAKE) .</p>
<p>NOTA: No olvides el punto al final. Es para indicarle que compile el directorio actual</p>
<p>Con ello instalaremos la librería, pero apenas nos servirá de nada porque no hemos hecho referencia a que queremos los algoritmos “Driving Distance (DD)” y TSP.</p>
<p>Por ello cambia lo anterior por esto</p>
<p># ../cmake-2.4.8/bin/cmake -DWITH_TSP=ON -DWITH_DD=ON .</p>
<p>Resultado del configure</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">Output directory for libraries is set to /usr/lib64/pgsqlInstallation directory for libraries is set to /usr/lib64/pgsql and for SQL files is set to /usr/share/postlbsInstallation directory for libraries is set to /usr/lib64/pgsql&#8211; Configuring done&#8211; Generating done&#8211; Build files have been written to: /home/jose/compilar/pgrouting../cmake-2.4.8/bin/cmake -DWITH_TSP=ON -DWITH_DD=ON .</p>
<p>&#8211; Check for working C compiler: /usr/bin/gcc</p>
<p>&#8211; Check for working C compiler: /usr/bin/gcc &#8212; works</p>
<p>&#8211; Check size of void*</p>
<p>&#8211; Check size of void* &#8211; done</p>
<p>&#8211; Check for working CXX compiler: /usr/bin/c++</p>
<p>&#8211; Check for working CXX compiler: /usr/bin/c++ &#8212; works</p>
<p>&#8211; Found PostgreSQL: /usr/include/pgsql/server, /usr/lib64/libpq.so</p>
<p>Boost headers were found here: /usr/local/include</p>
<p>Output directory for libraries is set to /usr/lib64/pgsql</p>
<p>&#8211; Found PGROUTING_CORE core: /home/jose/compilar/pgrouting/core/src</p>
<p>Installation directory for libraries is set to /usr/lib64/pgsql and for SQL files is set to /usr/share/postlbs</p>
<p>&#8211; Found GAUL: /usr/local/lib/libgaul.so, /usr/local/lib/libgaul_util.so</p>
<p>Installation directory for libraries is set to /usr/lib64/pgsql</p>
<p>&#8211; Found CGAL: /usr/local/include, /usr/local/lib/libCGAL.so</p>
<p>&#8211; Configuring done</p>
<p>&#8211; Generating done</p>
<p>&#8211; Build files have been written to: /home/jose/compilar/pgrouting</td>
</tr>
</tbody>
</table>
<p>4. Finalmente generamos la librería</p>
<p># make</p>
<p>Resultado de la compilación</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">Scanning dependencies of target routing_tsp[ 8%] Building C object extra/tsp/src/CMakeFiles/routing_tsp.dir/tsp.o[ 16%] Building CXX object extra/tsp/src/CMakeFiles/routing_tsp.dir/tsp_solver.oLinking CXX shared library ../../../lib/librouting_tsp.so[ 16%] Built target routing_tspScanning dependencies of target routing_dd[ 25%] Building C object extra/driving_distance/src/CMakeFiles/routing_dd.dir/alpha.o</p>
<p>[ 33%] Building CXX object extra/driving_distance/src/CMakeFiles/routing_dd.dir/alpha_drivedist.o</p>
<p>[ 41%] Building CXX object extra/driving_distance/src/CMakeFiles/routing_dd.dir/boost_drivedist.o</p>
<p>[ 50%] Building C object extra/driving_distance/src/CMakeFiles/routing_dd.dir/drivedist.o</p>
<p>Linking CXX shared library ../../../lib/librouting_dd.so</p>
<p>[ 50%] Built target routing_dd</p>
<p>Scanning dependencies of target routing</p>
<p>[ 58%] Building C object core/src/CMakeFiles/routing.dir/dijkstra.o</p>
<p>[ 66%] Building C object core/src/CMakeFiles/routing.dir/astar.o</p>
<p>[ 75%] Building C object core/src/CMakeFiles/routing.dir/shooting_star.o</p>
<p>[ 83%] Building CXX object core/src/CMakeFiles/routing.dir/boost_wrapper.o</p>
<p>[ 91%] Building CXX object core/src/CMakeFiles/routing.dir/astar_boost_wrapper.o</p>
<p>[100%] Building CXX object core/src/CMakeFiles/routing.dir/shooting_star_boost_wrapper.o</p>
<p>Linking CXX shared library ../../lib/librouting.so</p>
<p>[100%] Built target routing</td>
</tr>
</tbody>
</table>
<p>5. Por último colocamos los archivos en su sitio (como root):</p>
<p>$ make install</p>
<p>Resultados</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">[ 16%] Built target routing_tsp[ 50%] Built target routing_dd[100%] Built target routingLinking CXX shared library CMakeFiles/CMakeRelink.dir/librouting_tsp.soLinking CXX shared library CMakeFiles/CMakeRelink.dir/librouting_dd.soInstall the project&#8230;&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Installing /usr/lib64/pgsql/librouting.so</p>
<p>&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Installing /usr/share/postlbs/routing_core.sql</p>
<p>&#8211; Installing /usr/share/postlbs/routing_core_wrappers.sql</p>
<p>&#8211; Installing /usr/share/postlbs/routing_topology.sql</p>
<p>&#8211; Installing /usr/share/postlbs/matching.sql SELECT assign_vertex_id(&#8216;ways&#8217;, 0.00001, &#8216;the_geom&#8217;, &#8216;gid&#8217;);</p>
<p>&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Installing /usr/lib64/pgsql/librouting_tsp.so</p>
<p>&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Installing /usr/share/postlbs/routing_tsp.sql</p>
<p>&#8211; Installing /usr/share/postlbs/routing_tsp_wrappers.sql</p>
<p>&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Installing /usr/lib64/pgsql/librouting_dd.so</p>
<p>&#8211; Install configuration: &#8220;&#8221;</p>
<p>&#8211; Installing /usr/share/postlbs/routing_dd.sql</p>
<p>&#8211; Installing /usr/share/postlbs/routing_dd_wrappers.sql</td>
</tr>
</tbody>
</table>
<p>Ya tenemos PgRouting disponible</p>
<p><strong>OSM2PGROUTING</strong></p>
<p>Descripción:</p>
<p>Se trata de una utilidad que permite convertir un fichero de OpenStreetMap, en formato OSM o XML, en una base de datos PostgreSQL que tenga instaladas las extensiones PostGIS y PgRouting.</p>
<p>Esta utilidad está específicamente diseñada para OSM, y realiza un especial tratamiento de los datos teniendo en cuenta los tags OSM, de forma tal que es capaz de generar un grafo adecuado para el ruteo. Bien es cierto que tenemos otras posibilidades, como descargar un shapefile de datos OSM de cualquiera de los servidores existentes (Geofabrik, CloudMade) y convertirlos a PostgreSQL con la utilidad “shp2pgsql” provista por PostGIS, sin embargo el resultado no será el mismo. Veamos un ejemplo</p>
<p>Fíjate en esta zona donde tenemos vías que aparecen a distinto nivel: <a href="http://www.openstreetmap.org/?lat=38.379259&amp;lon=-0.452301&amp;zoom=18&amp;layers=B000FTF">http://www.openstreetmap.org/?lat=38.379259&amp;lon=-0.452301&amp;zoom=18&amp;layers=B000FTF</a></p>
<p><img class="alignnone size-full wp-image-288" src="http://www.gisandchips.org/wp-content/osm_cruce.png" alt="osm_cruce" width="470" height="509" /></p>
<p>Sí no utilizamos esta utilidad se generará un nodo por cada cruce de vías, independientemente de que si están o no a diferentes niveles. Osm2pgrouting entiende los tags de OSM y evita colocar nodos donde no le corresponde.</p>
<p>Nodos en OpenStreetMap. Las vías es azul contienen el tag bridge=yes, y por tanto están a diferente nivel</p>
<p><strong><img class="alignnone size-full wp-image-289" src="http://www.gisandchips.org/wp-content/osm_cruce_josm.png" alt="osm_cruce_josm" width="508" height="466" /></strong></p>
<p><strong>Compilar osm2pgrouting</strong></p>
<p>$ svn checkout <a href="http://pgrouting.postlbs.org/svn/pgrouting/tools/osm2pgrouting/trunk">http://pgrouting.postlbs.org/svn/pgrouting/tools/osm2pgrouting/trunk</a> osm2pgrouting</p>
<p>$ cd osm2pgrouting</p>
<p>$ make</p>
<p>Como administrador:</p>
<p>$ make install</p>
<p><strong>CREAR UNA PLANTILLA DE GEODATABASE CON POSTGIS Y PGROUTING</strong></p>
<p>Este es quizás el momento más excitante de todos, puesto que vamos a crear una base de datos con datos ya normalizados para ser explotado con las utilidades de PgRouting.</p>
<p>El proceso siempre es el mismo:</p>
<ol>
<li>Crear la base de datos</li>
<li>Añadirle la funcionalidad de PostGIS</li>
<li>Añadirle la funcionalidad de PgRouting</li>
<li>Cargar datos desde OSM a la base de datos (osm2pgsql)</li>
<li>Crear topología</li>
<li>Explotar la base de datos</li>
</ol>
<p><strong>Creación de una plantilla de base de datos</strong></p>
<p>Es una buena práctica tener creada una plantilla de base de datos con todas las extensiones ya incluidas para que podamos utilizarla en cualquier geodatabase que creemos.</p>
<p>Puesto que estamos intentando cargar datos desde OSM es conveniente utilizar una codificación de caracteres que albergue todas las posibilidades multilenguaje que se pueden dar (alfabetización árabe, cirílica, etc)</p>
<ol>
<li>Sín más preámbulos creamos la base de datos</li>
</ol>
<p>Sintaxis:</p>
<p>$ createdb –h &lt;host&gt; –U &lt;user&gt; -p &lt;puerto&gt; -E &lt;código codificación &lt;nombre base de datos&gt;</p>
<p>En nuestro caso este es el resultado</p>
<p>$ createdb -U postgres -E UTF8 routing</p>
<ol>
<li>PostGIS exige que la base de datos tenga cargado el lenguaje procedural Pl/PgSql. De hecho la gran mayoría de las funciones de PostGIS y PgRouting están en este lenguaje:</li>
</ol>
<p>$ createlang -U postgres plpgsql &lt;nombre base de datos&gt;</p>
<p>$ createlang -U postgres plpgsql routing</p>
<ol>
<li>Añadir la funcionalidad PostGIS</li>
</ol>
<p>Ahora necesitamos saber donde ha instalado Postgis los ficheros SQL necesarios para crear la geodatabase. Recomendamos utilizar el comando find para encontrarlos</p>
<p>Para las versiones &lt; 1.4</p>
<p>$ find /usr/ -name lwpostgis.sql</p>
<p>Para versiones &gt;= 1.4</p>
<p>$ find /usr/ -name postgis.sql</p>
<p>/usr/share/lwpostgis.sql</p>
<p>Lo mismo para las referencias espacials</p>
<p>$ find /usr/ -name spatial_ref_sys.sql</p>
<p>/usr/share/spatial_ref_sys.sql</p>
<p>Ahora sólo queda cargar el fichero de funcionalidades en la base de datos:</p>
<p>Para la versión 1.3.x</p>
<p>$ psql -U postgres -f /usr/share/lwpostgis.sql routing</p>
<p>$ psql -U postgres -f /usr/share/spatial_ref_sys.sql routing</p>
<p>Para la version 1.4</p>
<p>$ psql -U postgres -f /usr/share/pgsql/contrib/postgis.sql routing</p>
<p>$ psql -U postgres -f /usr/share/pgsql/contrib/spatial_ref_sys.sql routing</p>
<ol>
<li>Añadir la funcionalidad PgRouting</li>
</ol>
<p>Más de lo mismo. Primero añadimos la funcionalidad básica:</p>
<p>$ psql -U postgres -f /usr/share/postlbs/routing_core.sql routing</p>
<p>$ psql -U postgres -f /usr/share/postlbs/routing_core_wrappers.sql routing</p>
<p>$ psql -U postgres -f /usr/share/postlbs/routing_topology.sql routing</p>
<ol>
<li>Luego la funcionalidad para el algoritmo TSP (opcional)</li>
</ol>
<p>$ psql -U postgres -f /usr/share/postlbs/routing_tsp.sql routing</p>
<p>$ psql -U postgres -f /usr/share/postlbs/routing_tsp_wrappers.sql routing</p>
<ol>
<li>Por ultimo la funcionalidad para el algoritmo “Driving Distance”</li>
</ol>
<p>$ psql -U postgres -f /usr/share/postlbs/routing_dd.sql routing</p>
<p>$ psql -U postgres -f /usr/share/postlbs/routing_dd_wrappers.sql routing</p>
<ol>
<li>Vamos a comprobar que todo está bien.</li>
</ol>
<p>Accedemos a la base de datos creada:</p>
<p>$ psql -U postgres routing</p>
<p>routing=# <strong>select postgis_full_version();</strong></p>
<p>Devolverá:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">postgis_full_version&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-POSTGIS=&#8221;1.4.0&#8243; GEOS=&#8221;3.1.1-CAPI-1.6.0&#8243; PROJ=&#8221;Rel. 4.7.1, 23 September 2009&#8243; USE_STATS(1 row)</td>
</tr>
</tbody>
</table>
<ol>
<li>Últimos retoques:</li>
</ol>
<p>Con el objetivo de utilizar en el futuro OpenLayers, y con el fin de arbitrar un sistema de proyección que sea común para el uso de varios proveedores de datos (Google Maps, Yahoo Maps, Microsoft Live Maps, etc), vamos a incluir un nuevo registro en la tabla spatial_ref_sys, para añadir la denominada proyección esférica de Mercator, a veces conocida como “proyección Google”, por ser ésta la que se utiliza en en Google Maps. Lo interesante de esta proyección, a diferencia del sistema geodésico mundial con datum WGS84 es que las unidades están en metros, lo que facilita la compresión de los cálculos de distancias, en contraposición a la medición en grados decimales de arco de circunferencia. Más información aquí:</p>
<p><a href="http://trac.openlayers.org/wiki/SphericalMercator">http://trac.openlayers.org/wiki/SphericalMercator</a></p>
<p>En este enlace tienes una imagen de gran formato de la tierra con esta proyección: <a href="http://designintelligences.files.wordpress.com/2009/03/mercator-projection1.jpg">http://designintelligences.files.wordpress.com/2009/03/mercator-projection1.jpg</a></p>
<p>En definitiva, sólo tenemos que añadir este registro:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">routing=#  INSERT into spatial_ref_sys (srid, auth_name, auth_srid, srtext, proj4text) values (900913 ,&#8217;EPSG&#8217;,900913,&#8217;GEOGCS["WGS 84", DATUM["World Geodetic System1984", SPHEROID["WGS 84", 6378137.0, 298.257223563,AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], NIT["degree",0.017453292519943295], AXIS["Longitude", EAST], AXIS["Latitude", NORTH],AUTHORITY["EPSG","4326"]], PROJECTION["Mercator_1SP"],PARAMETER["semi_minor", 6378137.0],PARAMETER["latitude_of_origin",0.0], PARAMETER["central_meridian", 0.0], PARAMETER["scale_factor",1.0], PARAMETER["false_easting", 0.0], PARAMETER["false_northing", 0.0],UNIT["m", 1.0], AXIS["x", EAST], AXIS["y", NORTH],AUTHORITY["EPSG","900913"]] |&#8217;,'+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs&#8217;);</td>
</tr>
</tbody>
</table>
<p>La proyección esférica de Mercator tiene el código 900913, según el European Petroleum Survey Group (EPSG) mientras que OpenStreetMap utiliza como proyección global  predeterminada el geodésico mundial con datum WGS84, cuyo código es 4326.</p>
<p>Ya nos podemos salir de la consola de Postgresql</p>
<p>routing=# \q</p>
<ol>
<li>Crear una geodatabase a partir de la plantilla creada</li>
</ol>
<p>Bueno ya está hecho todo el trabajo de la plantilla, ahora el proceso de crear una nueva base de datos con todo ya preparado es sólo una línea;</p>
<p>createdb -U &lt;usuario&gt; -T &lt;plantilla&gt; &lt;nueva bd&gt;</p>
<p>En nuestro ejemplo sería</p>
<p>createdb -U postgres -T routing osmtest</p>
<p><strong>Truco del día:</strong></p>
<p>Sí tu servidor no tienes un sistema gráfico funcionando y necesitas llevar un fichero desde tu ordenador al servidor utiliza el comando “scp”. Es muy práctico</p>
<p>Sintaxis:</p>
<p>$ scp &lt;fichero de tu ordenador&gt;@&lt;hostname o IP&gt;:&lt;directorio del servidor donde copiar el fichero&gt;</p>
<p>Ejemplo:</p>
<p>$ scp OSM/alicante_30_09_2009.osm jose@www.gisandchips.org:/home/jose/compilar/osm2pgrouting</p>
<p><strong>DESCARGAR DATOS DE OPENSTREETMAP</strong></p>
<p>Esto ya va tomando color. Queda lo más bonito. ¡Paciencia!</p>
<p>Tenemos 2 opciones:</p>
<p>a)     Descargar un fichero OSM ya creado en cualquiera de los portales web que hay a tal efecto (Geofabrik (<a href="http://download.geofabrik.de/osm/">http://download.geofabrik.de/osm/</a>) , CloudMade (<a href="http://downloads.cloudmade.com/">http://downloads.cloudmade.com/</a>) , etc)</p>
<p>Ejemplo:</p>
<p>Descargar OSM de España (69 Mb)<span> </span></p>
<p>$ wget <a href="http://download.geofabrik.de/osm/europe/spain.osm.bz2">http://download.geofabrik.de/osm/europe/spain.osm.bz2</a></p>
<p>Descomprimir</p>
<p>$ tar -xjvf spain.osm.bz2</p>
<p>a)     Recortar una zona del planet.osm con Osmosis (<a href="http://wiki.openstreetmap.org/wiki/Osmosis">http://wiki.openstreetmap.org/wiki/Osmosis</a>)</p>
<p>$ wget <a href="http://dev.openstreetmap.org/~bretth/osmosis-build/osmosis-latest-bin.tar.gz">http://dev.openstreetmap.org/~bretth/osmosis-build/osmosis-latest-bin.tar.gz</a></p>
<p>$ tar xzvf osmosis-latest-bin.tar.gz</p>
<p>$ cd osmosis-0.31/ bin/</p>
<p>La sintaxis básica es la siguiente:</p>
<p>$./osmosis &#8211;read-xml &lt;fichero osm matriz&gt; &#8211;bb left=&lt;coord oeste&gt; right&lt;coord este&gt; top=&lt;coord norte&gt; bottom=&lt;coord sur&gt; &#8211;write-xml &lt;nombre fichero a crear extraido de matriz&gt;</p>
<p>Por supuesto las coordenadas deben de estar en grados decimales del WGS84. Pero, ¿de dónde las saco?</p>
<p>Esta vez viene en nuestra ayuda el portal <a href="http://www.openstreetmap.org/">www.openstreetmap.org</a> que viene con una utilidad (pestaña “Exportar”) para proporcionarnos información sobre la caja que estamos visualizando  en el mapa</p>
<p><img class="alignnone size-full wp-image-287" src="http://www.gisandchips.org/wp-content/osm_box.png" alt="osm_box" width="483" height="343" /></p>
<p>Ejemplo práctico a un barrio de Alicante</p>
<p>$./osmosis &#8211;read-xml /home/jose/OSM/alicante_30_09_2009.osm &#8211;bb left=-0.4359 right=-0.42006 top=38.37225 bottom=38.36192 &#8211;write-xml mibarrio.osm</p>
<p><strong>IMPORTAR UN OSM EN LA GEODATABASE</strong></p>
<p>Después de este tortuoso camino, ya queda lo más fácil importar el OSM, utilizando “osm2pgrouting”. La sintaxis es la siguiente:</p>
<p>$ ./osm2pgrouting -file &lt;fichero osm&gt; -conf &lt;fichero configuración&gt;  -dbname &lt;base de datos&gt; -user &lt;usuario&gt;</p>
<p>Ló único extraño aquí es el fichero de configuración, que es un XML donde se incluyen las tipologías de la vías  que queremos cargar a la base de datos (según OSM: motorway, trunk, primary, secondary, tertiary, residential, etc.). En las fuentes aparece un XML de ejemplo que nos puede servir. Debemos de tener en cuenta que en función de nuestros objetivos utilizaremos unas vías u otras. Por ejemplo, sí sólo queremos las grandes vías nos quedaremos con motorway y trunks. Sí sólo nos interesa el tema caminos rurales y rutas ciclistas nos toca trabajar el XML.</p>
<p>Ejemplo:</p>
<p>./osm2pgrouting -file ./alicante_30_09_2009.osm -conf ./mapconfig.xml -dbname osmtest -user postgres</p>
<p>NOTA: Este proceso suele ser bastante largo, y estará en función del tamaño del OSM. Como ejemplo, el área metropolitana de Alicante tardó unos 5 minutos, en un ordenador bien dotado. Toda España nos llevaría unas cuantas horas.</p>
<p>Tras un periodo de tiempo verás este mensaje</p>
<table border="1" cellspacing="0" cellpadding="0" width="100%">
<col span="1" width="256"></col>
<tbody>
<tr>
<td width="100%" valign="top">Ways table created<br />
<span style="background-color: #ffffff">Types table created<br />
Classes table created<br />
http://wiki.openstreetmap.org/wiki/Osmosis</span>create topology</p>
<p>#########################</p>
<p>size of streets: 4742</p>
<p>size of splitted ways : 12780</p>
<p>finished</td>
</tr>
</tbody>
</table>
<p>Para comprobar que tablas se han creado:</p>
<p>Entramos en la base de datos</p>
<p>psql -U postgres osmtest</p>
<p>Listamos las tablas:</p>
<p>osmtest=# \d</p>
<table border="1" cellspacing="0" cellpadding="0" width="1153">
<tbody>
<tr>
<td width="576" valign="top">List of relationsSchema | Name | Type | Owner</p>
<p>&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;-+&#8212;&#8212;&#8212;-</p>
<p>public | classes | table | postgres</p>
<p>public | geometry_columns | table | postgres</p>
<p>public | nodes | table | postgres</p>
<p>public | spatial_ref_sys | table | postgres</p>
<p>public | types | table | postgres</p>
<p>public | ways | table | postgres</p>
<p>(6 rows)</td>
<td width="576" valign="top"></td>
</tr>
</tbody>
</table>
<p>La tabla que contiene la geometría es ways;</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">osmtest=# select * from geometry_columns ;f_table_catalog | f_table_schema | f_table_name | f_geometry_column | coord_dimension | srid | type</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>| public | ways | the_geom | 2 | 4326 | MULTILINESTRING</p>
<p>(1 row)</p>
<p>osmtest=# select srid, f_geometry_column as geometria from geometry_columns;</p>
<p>srid | geometria</p>
<p>&#8212;&#8212;+&#8212;&#8212;&#8212;&#8211;</p>
<p>4326 | the_geom</p>
<p>(1 row)</td>
</tr>
</tbody>
</table>
<h2>CREACIÓN DE TOPOLOGÍA DE RED</h2>
<p>Si nos fijamos la tabla ways tiene vacíos los campos <em>source</em> y <em>target</em>, que son los identificadores de nodo. Es necesario crear topología. Para ello recurrimos a una función topológica de pgrouting: <em>“assign_vertex_id”</em></p>
<p>Lo único que tenemos es un identificador de arco (gid)</p>
<p>Para el caso de datos procedentes de OSM, al estar los datos en grados decimales y la proyección en geodésica (4326) la tolerancia a aplicar es muy pequeña. 0.00001</p>
<p>SELECT assign_vertex_id(&#8216;ways&#8217;, 0.00001, &#8216;the_geom&#8217;, &#8216;gid&#8217;);</p>
<p>Listado de tablas</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">osmtest=# \dList of relationsSchema | Name | Type | Owner</p>
<p>&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;-</p>
<p>public | classes | table | postgres</p>
<p>public | geometry_columns | table | postgres</p>
<p>public | nodes | table | postgres</p>
<p>public | spatial_ref_sys | table | postgres</p>
<p>public | types | table | postgres</p>
<p>public | vertices_tmp | table | postgres</p>
<p>public | vertices_tmp_id_seq | sequence | postgres</p>
<p>public | ways | table | postgres</p>
<p>(8 rows)</td>
</tr>
</tbody>
</table>
<p>Ahora la tabla ways está preparada para topología.</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="576" valign="top">osmtest=# select gid,source,target from ways;gid | source | target</p>
<p>&#8212;&#8212;-+&#8212;&#8212;&#8211;+&#8212;&#8212;&#8211;</p>
<p>46 | 46 | 47</p>
<p>187 | 190 | 191</p>
<p>213 | 215 | 216</p>
<p>309 | 308 | 309</p>
<p>327 | 325 | 240</p>
<p>447 | 437 | 438</p>
<p>564 | 554 | 555</p>
<p>649 | 635 | 636</p>
<p>711 | 700 | 701</p>
<p>832 | 814 | 815</p>
<p>882 | 863 | 864</p>
<p>927 | 906 | 907</td>
</tr>
</tbody>
</table>
<p>Con este extenso post queda por finalizada la primera parte sobre PgRouting con OpenStreetMap. Nos esperan dos nuevos artículos que espero sean de vuestro interés:</p>
<ol>
<li>Explotación de una geodatabase con OpenStreetMap y PgRouting</li>
<li>Diseño de una interfaz web con OpenLayers para el análisis de redes.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2009/10/03/analisis-de-redes-con-openstreetmap-y-pgrouting-en-un-ambiente-web/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Hola Mundo con gvSIG 2.0 (y con Eclipse)</title>
		<link>http://www.gisandchips.org/2009/10/01/hola-mundo-con-gvsig-2-0-y-con-eclipse/</link>
		<comments>http://www.gisandchips.org/2009/10/01/hola-mundo-con-gvsig-2-0-y-con-eclipse/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 11:52:22 +0000</pubDate>
		<dc:creator>jpiera</dc:creator>
				<category><![CDATA[Análisis]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[gvSIG]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=210</guid>
		<description><![CDATA[Este tutorial es una guía para desarrollar el famoso &#8220;Hola Mundo&#8221; en gvSIG 2.0. Se va a partir de un sistema operativo en el que se ha instalado previamente el entorno de desarrollo Eclipse con el plugin para SVN Subversive y a partir de este entorno, se va a describir paso por paso las acciones [...]]]></description>
			<content:encoded><![CDATA[<p>Este tutorial es una guía para desarrollar el famoso &#8220;Hola Mundo&#8221; en <a href="http://www.gvsig.gva.es">gvSIG</a> 2.0. Se va a partir de un sistema operativo en el que se ha instalado previamente el entorno de desarrollo <a href="http://www.eclipse.org/">Eclipse</a> con el plugin para SVN <a href="http://www.eclipse.org/subversive/">Subversive</a> y a partir de este entorno, se va a describir paso por paso las acciones que se tienen que realizar para añadir una opción en el menú &#8220;Ayuda&#8221; de gvSIG llama &#8220;Saludo&#8221; que al pulsar sobre ella abrirá una ventana con el clásico &#8220;Hola Mundo&#8221;.</p>
<p>Este documento no pretende ser una guía de desarrollo de gvSIG 2.0.  Si se quiere disponer de toda la información de desarrollo es aconsejable visitar la <a href="http://www.gvsig.org">web de documentación del proyecto</a>.<span id="more-210"></span></p>
<p>El primer paso es crear una carpeta en nuestro sistema donde vamos a situar todos los proyectos que nos van a hacer falta, que serán tanto nuestro proyecto del Hola Mundo como todos los proyectos mínimos necesarios para poder generar un gvSIG 2.0. Otra opción que no está contemplada en este tutoria es la de poder instalar nuestra extensión en una versión de gvSIG previemente instalada desde un instalador.</p>
<p>Una vez creada la carpeta hay que abrir el Eclipse e indicarle establecer la carpeta que hemos creado como workspace. Para ello tendremos que ir a la opción &#8220;File-&gt;Switch Workspace-&gt;Other&#8221; y seleccionar la carpeta que hemos creado anteriormente.</p>
<p>El siguiente paso será descargarnos el proyecto &#8220;build&#8221; desde el repositorio de gvSIG. Este proyecto es necesario para poder construir nuestro sistema y es el único proyecto que hay que bajar manualmente. Para ello hay que abrir la vista de SVN del Eclipse seleccionando la opción &#8220;Window -&gt; Open Perspective -&gt; Other&#8221; y hay que seleccionar la opción &#8220;SVN Repository Exploring&#8221;. Si no aparece esta opción es porque no se ha instalado ningún plugin de SVN.</p>
<p style="text-align: center"><a href="http://www.gisandchips.org/wp-content/svn.png"><img class="size-large wp-image-212 aligncenter" src="http://www.gisandchips.org/wp-content/svn-1024x604.png" alt="Abrir la vista de SVN" width="500" height="300" /></a></p>
<p>A continuación se tiene que añadir manualmente el repositorio de gvSIG desde el que hay que descargar el proyecto &#8220;build&#8221;. Para ello hay que pulsar con el botón derecho del ratón sobre la ventana &#8220;SVN Repositories&#8221; y se abrirá una nueva ventana donde hay que introducir la dirección del repositorio de gvSIG (http://subversion.gvsig.org/gvSIG). Pulsaremos en &#8220;Finish&#8221; y si todo ha funcionado correctamente deberá aparecer el repositorio en la lista de servidores.</p>
<p>La lista de servidores es una lista en forma de árbol que podremos ir desplegando haciendo un doble &#8220;click&#8221; en cada uno de los nodos del árbol. Hay que abrir el servidor que hemos añadido y tendremos que buscar la ruta &#8220;<img src="///tmp/moz-screenshot.jpg" alt="" />branches -&gt; v2_0_0_prep -&gt; build&#8221;. Una vez estemos en ella, pulsamos con el botón derecho del ratón sobre la carpeta y seleccionamos la opción &#8220;Check Out&#8221; que descargará el proyecto en nuestro workspace.</p>
<p><a href="http://www.gisandchips.org/wp-content/chechout.png"><img class="aligncenter size-full wp-image-218" src="http://www.gisandchips.org/wp-content/chechout.png" alt="Check Out del proyecto build" width="500" height="300" /></a></p>
<p>Ahora hay que ir a la vista de Java para poder ver el proyecto que acabamos de bajar. Para ello hay que seleccionar la opción &#8220;Window -&gt; Open Perspective -&gt; Java&#8221;. Si todo ha ido bien el proyecto &#8220;build&#8221; se encontrará en la vista &#8220;Package&#8221;.</p>
<p>A continuación vamos a abrir la vista de Ant desde la cual vamos a poder ejecutar algunos objetivos automáticamente. Para ello hay que ir al menú &#8220;Window -&gt; Show View -&gt; Ant&#8221; y se abrirá una ventana nueva llamada &#8220;Ant&#8221;. El proyecto build tiene en su carpeta raíz un fichero llamado &#8220;build.xml&#8221; que contiene todos los objetivos que podemos ejecutar. Si pulsamos sobre ese fichero y sin soltar lo arrastramos y lo dejamos caer sobre la ventana de &#8220;Ant&#8221; automáticamente aparecerán los objetivos definidos en el fichero.</p>
<p style="text-align: center"><a href="http://www.gisandchips.org/wp-content/ant.png"><img class="aligncenter size-full wp-image-219" src="http://www.gisandchips.org/wp-content/ant.png" alt="Obetivos de Ant" width="500" height="300" /></a></p>
<p style="text-align: left">Lo primero que tenemos que hacer es modificar la configuración del Eclipse con algunos parámetros que necesitamos. Se puede hacer manualmente, pero para facilitar la configuración se ha creado un objetivo de Ant que lo hace todo por nosotros. Para ello tenemos que ir a la ventana de Ant y hacer un doble &#8220;click&#8221; en la opción &#8220;mvn-configure-eclipse-workspace&#8221;. Si todo ha funcionado correctamente se abrirá una ventana donde tendremos que escribir la ruta donde se encuentra el workspace que queremos configurar, que por defecto será el workspace actual. Pulsaremos en OK y esperaremos a que se ejecute el comando con éxito utilizando para ello la vista &#8220;Console&#8221;.</p>
<p style="text-align: left">Una vez que ya tenemos el workspace configurado correctamente vamos a bajarnos los fuentes del gvSIG. Para ello debemos desplegar el proyecto &#8220;build&#8221; e ir a la carpeta &#8220;projects&#8221; donde veremos unas cuantas carpetas que se corresponden a grupos de proyectos de gvSIG. Nosotros necesitamos lo mínimo para poder arrancar un gvSIG, así que tendremos que desplegar la carpeta &#8220;gvsig-base&#8221;, pinchar con el botón izquierdo del ratón sobre el archivo &#8220;build.xml&#8221; y arrastrarlo hasta la vista de Ant.</p>
<p style="text-align: left">Ahora tendremos en la vista de Ant dos configuraciones diferentes (gvsig-build-config y gvsig-group-base), por lo que hay que ir con precaución a la hora de seleccionar un objetivo. Seleccionaremos gvsig-group-base y a continuación haremos un doble &#8220;click&#8221; en el objetivo &#8220;svm.checkout.all&#8221;. Se abrirá una ventana que servirá para poder configurar el servidor desde el que vamos a descargar los fuentes. Por defecto no hay que modificar nada, salvo la versión del conector de SVN que tenemos instalada en el Eclipse. Si no se conoce  la versión, se puede consultar en &#8220;Window -&gt; Preferences -&gt; Team -&gt; SVN -&gt; SVN Connector&#8221;.</p>
<p style="text-align: left"><a href="http://www.gisandchips.org/wp-content/checkout.png"><img class="aligncenter size-full wp-image-237" src="http://www.gisandchips.org/wp-content/checkout.png" alt="checkout" width="500" height="300" /></a></p>
<p style="text-align: left">Pulsamos en &#8220;Ok&#8221; y si todo ha funcionado correctamente veremos en la ventana &#8220;Console&#8221; como la aplicación empieza a descargarse diversos proyectos. Una vez que haya terminado tendremos que importar los proyectos descargados. Para ello tenemos que pulsar con el botón derecho sobre la ventana de &#8220;Package&#8221; y seleccionar la opción &#8220;Import&#8221;. A continuación debemos seleccionar &#8220;General -&gt; Existing Projects into Workspace&#8221; y pulsa en &#8220;Next&#8221;. Seleccionamos la carpeta de nuestro workspace y veremos como aparece una lista de proyectos en la ventana. Pulsamos en &#8220;Finish&#8221; y automáticamente aparecen todos los proyectos que forman el gvSIG base en la ventana &#8220;Package&#8221;.</p>
<p>Ahora vamos a compilar todos los fuentes y vamos a arrancar gvSIG. Para ello hay que ir a la vista de Ant y seleccionando &#8220;gvSIG-group-base&#8221; ejecutaremos el objetivo &#8220;mvn-install&#8221;. Este objetivo compilará todos los proyectos que nos hemos bajado y creará una instalación de gvSIG en la carpeta &#8220;build -&gt; product&#8221;. En la ventana &#8220;console&#8221; podremos ver el progreso de la compilación. En la actualidad gvSIG 2.0 está en fase de desarrollo y es posible que el comando anterior falle porque ha fallado alguno de los tests unitarios. Si es el caso hay que repetir el proceso anterior pero ejecutando &#8220;mv-install-without-tests&#8221;, que hace lo mismo que el install pero sin generar ni ejecutar los tests unitarios.</p>
<p>Si todo ha funcionado correctamente ya estamos en disposición de poder ejecutar gvSIG 2.0 desde el Eclipse. Para eso tenemos que seleccionar la opción &#8220;Run -&gt; Debug Configurations -&gt; Java Application&#8221;  y seleccionar el lanzador de nuestro sistema operativo. Al pulsar en &#8220;Debug&#8221; debería arrancar gvSIG. Si no lo hace y sale un mensaje diciendo que no se encuentra alguna librería, es porque Eclipse &#8220;no se ha dado cuenta&#8221; de que se ha instalado la versión de gvSIG en la carpeta &#8220;build/product&#8221;. Refrescamos esta carpeta y volvemos a arrancar la aplicación.</p>
<p style="text-align: center"><a href="http://www.gisandchips.org/wp-content/run.png"><img class="aligncenter size-full wp-image-262" src="http://www.gisandchips.org/wp-content/run.png" alt="run" width="500" height="300" /></a></p>
<p>Ahora que ya tenemos la aplicación vamos a crear nuestra extensión para gvSIG. Primero, deberemos decidir si lo que vamos a crear es una librería o una extensión. La diferencia principalmente es que las librerías no tienen interfaz de usuario y no dependen de Andami mientras que las extensiones sí que dependen de Andami. Nuestra idea es mostrar el &#8220;Hola Mundo&#8221; en una nueva ventana por lo que vamos a generar una extensión.</p>
<p>Para ellos seleccionamos la opción &#8220;Run -&gt; External Tools -&gt; External Tools configurations&#8221;  y en la opción &#8220;Ant Build&#8221; seleccionamos y ejecutamos &#8220;create extension&#8221;. Se abrirá una ventana dónde tendremos que insertar algunos de los parámetros de configuración de &#8220;Maven&#8221;. El único que nos interesa en estos momentos en el &#8220;Maven artifactid&#8221;, cuyo valor corresponderá con el nombre del proyecto de Eclipse que se va a crear. en nuestro caso escribiremos &#8220;org.gvsig.holamundo&#8221; y pulsaremos el botón &#8220;OK&#8221;. En la ventana &#8220;Console&#8221; podremos seguir el proceso de creación del nuevo proyecto.</p>
<p>Una vez que tenemos el proyecto creado hay que importarlo del mismo modo que importamos anteriormente todos los proyectos que nos bajamos del repositorio. El proyecto que se ha creado ha tomado como base la extensión de centrar una vista en un punto por lo que tiene algunas clases que no vamos a utilizar. Podemos eliminar todas las clases del proyecto.</p>
<p>Ahora vamos a crear una clase llamada &#8220;HolaMundoExtension&#8221; que herede de &#8220;org.gvsig.andami.plugins.Extension&#8221; en el paquete &#8220;org.gvsig.holamundo&#8221; que será nuestro punto de entrada cuando el usuario seleccione la opción de menú &#8220;Hola Mundo&#8221; desde la aplicación.  Tendremos que hacer que los métodos &#8220;isVisible&#8221; e &#8220;isEnabled&#8221; devuelvan &#8220;true&#8221; y en el método &#8220;execute&#8221;pondremos el código que muestre una ventana con un &#8220;Hola Mundo&#8221;. La clase quedará del siguiente modo:</p>
<pre class="brush: java; title: ; notranslate">

import java.awt.Component;
import javax.swing.JOptionPane;
import org.gvsig.andami.PluginServices;
import org.gvsig.andami.plugins.Extension;

public class HolaMundoExtension extends Extension {

public void execute(String actionCommand) {
JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(), &quot;Hola Mundo&quot;);
}

public void initialize() {

}

public boolean isEnabled() {
return true;
}

public boolean isVisible() {
return true;
}
}
</pre>
<p>Ahora tenemos que &#8220;enganchar&#8221; una opción de menú con nuestra clase editando el fichero &#8220;src/main/resources/config.xml&#8221; del modo que se muestra a continuación:</p>
<pre class="brush: xml; title: ; notranslate">

&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?&gt;
&lt;plugin-config&gt;
&lt;libraries library-dir=&quot;lib&quot;/&gt;
&lt;depends plugin-name=&quot;org.gvsig.app&quot;/&gt;
&lt;resourceBundle name=&quot;text&quot;/&gt;
&lt;extensions&gt;
&lt;extension class-name=&quot;org.gvsig.helloworld.HolaMundoExtension&quot;
description=&quot;Extensión que hace un hola mundo&quot;
active=&quot;true&quot;&gt;
&lt;menu text=&quot;Prueba/Hola Mundo&quot;
tooltip=&quot;Hola Mundo&quot;
action-command=&quot;&quot;/&gt;
&lt;/extension&gt;
&lt;/extensions&gt;
&lt;/plugin-config&gt;
</pre>
<p>Para poder probar nuestra extensión, antes debemos compilarla e instalarla en gvSIG. Para ello debemos de seleccionar nuestro proyecto y a continuación ejecutar el objetivo &#8220;mvn install&#8221; que encontraremos en &#8220;Run -&gt; External Tools -&gt; External Tools configurations -&gt; Ant Build&#8221;. Si todo funciona correctamente, deberemos arrancar gvSIG del mismo modo que lo habíamos hecho anteriormente y aparecerá una nueva entrada en la barra de menú llamana &#8220;Prueba&#8221; desde la que podremos ejecutar nuestra extensión.</p>
<p style="text-align: center"><a href="http://www.gisandchips.org/wp-content/helloworld.png"><img class="aligncenter size-full wp-image-263" src="http://www.gisandchips.org/wp-content/helloworld.png" alt="helloworld" width="500" height="300" /></a></p>
<p style="text-align: left">Si se quiere profundizar un poco más para entender qué contiene un fichero &#8220;config.xml&#8221; o cómo se crean extensiones más complejas se puede consultar la web de documentación del proyecto <a href="http://www.gvsig.org">gvSIG</a>.</p>
<p style="text-align: left">
<p style="text-align: left">
<p style="text-align: left">
<p style="text-align: left">
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2009/10/01/hola-mundo-con-gvsig-2-0-y-con-eclipse/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Integración de R en PostgreSQL. Mi primera función en pl/R.</title>
		<link>http://www.gisandchips.org/2009/09/24/integracion-de-r-en-postgresql-mi-primera-funcion-en-plr/</link>
		<comments>http://www.gisandchips.org/2009/09/24/integracion-de-r-en-postgresql-mi-primera-funcion-en-plr/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 08:49:58 +0000</pubDate>
		<dc:creator>benizar</dc:creator>
				<category><![CDATA[Análisis]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[pl/R]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[R]]></category>

		<guid isPermaLink="false">http://www.gisandchips.org/?p=165</guid>
		<description><![CDATA[En primer lugar, y para que ninguno de vosotros tenga impresión que no voy a hablar nunca de GIS, me gustaría tranquilizaros, y recordaros que en próximos artículos, yo o a quien le apetezca participar en este hilo, pasaremos a comentar usos de todo esto que estamos viendo orientado al tratamiento de la información espacial. [...]]]></description>
			<content:encoded><![CDATA[<p>En primer lugar, y para que ninguno de vosotros tenga impresión que no voy a hablar nunca de GIS, me gustaría tranquilizaros, y recordaros que en próximos artículos, yo o a quien le apetezca participar en este hilo, pasaremos a comentar usos de todo esto que estamos viendo orientado al tratamiento de la información espacial. Si hay alguien que quiera compartir sus experiencias con temas de R será bien recibido.</p>
<p>Este segundo artículo sobre tecnologías útiles para explotar toda la potencia de R se centra en el uso de R desde el PostgreSQL.</p>
<p>Como todos sabéis, tradicionalmente los Sistemas Gestores de Bases de Datos (SGBD), como PostgreSQL, Oracle, MySQL o Access han sido diseñados para guardar y gestionar gran cantidad de datos, por ello las posibilidades de análisis y salidas gráficas se han delegado mayormente en otros softwares como hojas de cálculo, paquetes estadísticos como SPSS, R o en nuestro caso en softwares SIG&#8230; pero eso se acabó  <img src='http://www.gisandchips.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />   .</p>
<p>pl/R es un lenguaje de programación procedural que permite contar con toda la potencia de cálculo y salidas gráficas del paquete estadístico R, así como de su lenguaje de programación desde dentro de funciones de PostgreSQL.</p>
<p><span id="more-165"></span></p>
<p>Los <span style="text-decoration: underline">requisitos básicos</span> para comenzar a trabajar con pl/R son, como no, tener instalado PostgreSQL (he trabajado sin demasiados problemas con las versiones 8.2 y 8.3), tener pl/R instalado, y crear una base de datos en PostgreSQL donde añadimos el nuevo lenguaje procedural.</p>
<p>Todo lo que necesitamos para iniciarnos lo podemos encontrar en la página WEB del creador de pl/R, <strong>Joe Conway</strong> (<a href="http://www.joeconway.com/plr/">http://www.joeconway.com/plr/</a> ), donde nos descargaremos los ficheros para la instalación tanto para Windows como para Linux. También hay documentación para dar los primeros pasos y unos cuantos más. Esta presentación os ayudará bastante (<a href="http://www.joeconway.com/oscon-pres-2003-1.pdf">http://www.joeconway.com/oscon-pres-2003-1.pdf</a> ). Os recomiendo leer todo lo que podáis, incluso su Curriculum que está en la página principal no tiene desperdicio.</p>
<p>Hay mucha documentación en Internet y ejemplos de funciones básicas. Nosotros para trabajar con algo que ya conocemos, volveremos a utilizar la función hist() de R para obtener el histograma de cualquier campo numérico que podamos tener en una tabla de nuestra base de datos.</p>
<p>Cualquiera que haya trabajado bien con R, bien con funciones de PostgreSQL en general encontrará rápidamente los primeros problemas o desventajas, si es que se pueden llamar así, de usar pl/R. En cualquiera de los dos casos, normalmente tendremos que aprender a usar una nueva herramienta (PostgreSQL o R), lo cual es un nuevo mundo. Depurar las funciones de pl/R puede ser engorroso si se hace directamente, y normalmente los procesos serán más lentos, proporcionalmente, que si trabajásemos solamente en uno de los dos lados del espejo.  Pero ahora os diré las ventajas que puedo destacar más rápidamente:</p>
<ul>
<li>Podemos ejecutar nuestras nuevas funciones mediante una      sencilla expresión de SQL,</li>
<li>las funciones estarán siempre junto con los datos      (acabando con la importación-exportación),</li>
<li>tenemos la posibilidad de usar las funciones desde PHP      y</li>
<li>un potente SGBD se encargará de gestionar el manejo de      los datos, lo cual es muy bueno cuando se trabaja con grandes volúmenes de      información.</li>
</ul>
<p>Hay más ventajas, pero creo que para empezar no está nada mal.</p>
<h3>Mi primera función en pl/R</h3>
<p>Una vez lo tenemos todo instalado, os recomiendo empezar probando que todo funciona bien desde el GUI de R, ya que desde pl/R nos será más complicada la depuración.</p>
<p>La función que paso a detallar está pensada para usarla en local y que la probéis con vuestros propios datos (numéricos; si no lo son veréis un mensaje de error). Se trata de crear un histograma y guardarlo como imagen.</p>
<p>Como os podéis dar cuenta parece una función de pl/pgSQL solo que cambiamos el lenguaje al final y metemos directamente código de R entre $BODYs o comillas simples, aunque resulta más práctico el $ por si dentro de la función necesitamos usar comillas de dos tipos.</p>
<p>Los comentarios de la función pueden ir con # igual que en R.</p>
<p>A continuación tenemos el código para crear la nueva función:</p>
<pre class="brush: sql; title: ; notranslate">

CREATE OR REPLACE FUNCTION _plr_hist(text, text)
RETURNS text AS
$BODY$
select = 'select '
campo = arg1
from = ' from '
tabla = arg2
selection = paste(select, campo, from, tabla, sep='');

## Ejecutamos la consulta y la almacenamos en el objeto &quot;sql&quot;;
sql &lt;- pg.spi.exec (selection);

## Lo que obtengamos a partir de aquí se imprimirá en un pdf...
dir='c:/temp/';
nam= arg1;
ext='.png';
newfile=paste(dir,nam,ext, sep='')
png(newfile);

hist(sql[,1], xlab = campo, ylab='frecuencias', main= campo, col='blue', ylim=c(0,20));

## Hasta aquí
dev.off();

## Si trabajamos en linux querremos hacer algo como lo siguiente
## para asignar privilegios de lectura a todos los usuarios de linux
##sys1='chmod go+r'
##sys2=paste(sys1, '', newfile)
##system(sys2)

## Esto devuelve un mensaje al terminar la función
print1='¡¡¡Ya está!!!, ¡¡¡mira que gráfico más chulo en'
print2=paste(print1, '', newfile, sep='')
print (print2);

$BODY$
LANGUAGE 'plr' VOLATILE
</pre>
<p>Dentro de la función hay que destacar el empleo de pg.spi.exec(),  para uso de los desarrolladores de PostgreSQL, que ejecuta una expresión dada.</p>
<p>Una vez creada nuestra función la podremos ejecutar de un modo muy sencillo. Fijaos que bueno que es esto  <img src='http://www.gisandchips.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />    :</p>
<pre class="brush: sql; title: ; notranslate">

select _plr_hist('un campo numérico', 'tabla');
</pre>
<p>Y obtenemos nuestra gráfica en la carpeta especificada.</p>
<h3>Algunos comentarios sobre todo esto:</h3>
<p>Viéndolo ya funcionar parece que nada “malo” pueda pasarnos. A este respecto, uno de los aspectos que más problemas me creó en su día es lo relacionado con los derechos del usuario Postgres en el SO, tanto en Linux como en Windows. La solución en linux viene dada y comentada en el código de más arriba. Con “chmod go+r” damos derechos de lectura a todos los usuarios. Lo que no me imaginaba nunca es que en Windows también iba a tener problemas. Resulta que el usuario que ejecuta el postmaster de Postgresql es “postgres”, que no dispone de derechos de escritura (no se si hay otros problemas) en “c:\”. Cuando se trata de crear una salida gráfica a c:\, el interprete de pl/R indica que no se puede iniciar el device(). Esto me llevó algún dolor de cabeza pues en Windows suelo hacer todas mis primeras pruebas directamente en c:\. En el ejemplo de antes trabajamos en un directorio creado a propósito. Sobre esto último podemos consultar en <a href="http://pgfoundry.org/pipermail/plr-general/2009-June/000264.html">http://pgfoundry.org/pipermail/plr-general/2009-June/000264.html</a> .</p>
<h3>Referencias:</h3>
<p>Solamente recordaros lo esencial de la página de Joe Conway (<a href="http://www.joeconway.com/plr/">http://www.joeconway.com/plr/</a> ). También os recomiendo entrar en <a href="http://www.bostongis.com/">http://www.bostongis.com/</a> donde hay un hilo de 3 artículos explicando distintos temas relacionados con pl/R. El primero es una introducción bastante detallada, el segundo es trata la creación de polígonos de Voronoi en PostgreSQL usando PostGIS y pl/R (muy recomendable, y avanzado), y el último es un ejemplo de uso de RGDAL.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>Si quereis contactar podeis enviarme un email (asunto: gisandchips):</p>
<p>Benito M. Zaragozí</p>
<p>benito.zaragozi@ua.es</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gisandchips.org/2009/09/24/integracion-de-r-en-postgresql-mi-primera-funcion-en-plr/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

