Web Mapping

Automatic detection of complex operations in a port using #AIS and #Drools

Prodevelop ha desarrollado un Procesador de Eventos Complejos (CEP) basado en reglas de Drools y alimentado con mensajes AIS, capaz de detectar eventos relevantes de un puerto, tales como atraques, desatraques, fondeos, infracciones de límites de velocidad, etc. Opcionalmente, es capaz de detectar operaciones más complejas que involucran a dos buques, como las operaciones de practicaje y remolcaje. Aquí hay un ejemplo de operación de practicaje detectada automáticamente en el puerto de La Coruña. El círculo verde marca el inicio, el círculo rojo marca el final de la operación: Prodevelop has implemented a Drools-based Complex Event Processor (CEP) which receives AIS messages and is able to automatically detect relevant port operations such as docking, undocking, anchoring, speed limit violations, etc. It also detects more complex operations involving two ships, such as pilot and towing operations. Here is an example of a pilot operation automatically detected in the port of A Coruña (NW Spain). Green circle is the start, red circle is the end of the operation:


Pinche para ampliar - Click to enlarge


Detalle del inicio - Detail of the start


n/d

Testing Leaflet + Markercluster and Arabic characters

Leaflet.markercluster es un plugin para Leaflet (librería Javascript para aplicaciones web de mapas) creado por Dave Leaver. En este pequeño vídeo estamos probándolo con topónimos en caracteres árabes: Leaflet.markercluster is a plugin for Leaflet (Javascript webmapping library) created by Dave Leaver. This short video shows a test with Arabic place-names:
En comparación con el uso de teselas vectoriales pre-calculadas que ha desarrollado Prodevelop, veo las siguientes ventajas:
  • Mayor facilidad de uso.
  • Mejores efectos gráficos.
Y estos inconvenientes:
  • El algoritmo de agrupación no está muy conseguido, ya que se intenta agrupar de manera incremental.
  • Es necesario cargar todos los puntos de interés al inicio (es decir se está descargando mucha información que probablemente no se va a usar)
Compared to Prodevelop's pre-cached vector tiles approach, I can see these advantages:
  • Easier to use.
  • Better graphic effects.
And these problems:
  • The clustering method is not working very well, probably because it tries to group the POIs as they come, which is a too simplified approach.
  • It is necessary to load all the POIs at the start, which means that a lot of unneeded data is being downloaded.

Fast estimation of distance/area from geodetic coordinates

Dado un par de coordenadas (lon, lat) en grados, obtenemos las coordenadas en Mercator Esférico con: Given the pair of coordinates (lon, lat) in degrees, we can get the Spherical Mercator coordinates with:
DEGREES_PER_RADIAN = 180.0 / Math.PI;
MERCATOR_EARTH_RADIUS = 6378137.0;
METERS_PER_EQUATOR_DEGREE = Math.PI * MERCATOR_EARTH_RADIUS / 180.0;

rlat = lat / DEGREES_PER_RADIAN;
y = 0.5 * Math.log((1 + Math.sin(rlat)) / (1 - Math.sin(rlat)));
merx = METERS_PER_EQUATOR_DEGREE * lon;
mery = METERS_PER_EQUATOR_DEGREE * DEGREES_PER_RADIAN * y;
Como es sabido, la proyección esférica de Mercator usada por Google (llamada EPSG:900913 o EPSG:3857) conserva ángulos y proporciones localmente, y todos los paralelos miden lo mismo: As we know, the Spherical Mercator projection known as EPSG:900913 and also EPSG:3857 is conformal (keeps angles and shapes locally) and all parallels have the same length E:
R = 6378137 m
E = 2 * pi * R = 40075016.686 m
Pero sabemos que realmente cada paralelo mide aproximadamente P = E * cos(lat) así que al medir distancias o perímetros directamente en esta proyección, es necesario normalizar el resultado, multiplicándolo por un factor f = cos(lat). En el caso de Estocolmo (Suecia) por ejemplo: But we know that the true length of each parallel is approximately P = E * cos(lat), so if one wishes to measure distances, perimeters or paths directly on a map in EPSG:3857, it’s necessary to multiply the result by a factor f = cos(lat). In the case of Stockholm (Sweden), for example, we have:
lat = 60
f = 0.5
Esto es una piscina olímpica en Barcelona en Google Maps. Su latitud es 41.36573: This is an olympic swimming pool in Barcelona on Google Maps. Latitude is 41.36573:
Si medimos su longitud directamente en esa proyección: If we measure its length directly in that projection:
Longitud verdadera: True length:
L = 66.57 * cos(41.36573) = 49.96 m
En el caso de áreas, podemos imaginar un polígono arbitrario (por ejemplo el perfil de la cara de un hombre) dividido en infinidad de pequeños cuadritos. Si reducimos la imagen con un factor de 0.6, el área de cada cuadrito resultante será 0.36 veces el del cuadrito original: For areas, we can think of an arbitrary polygon (for example, the outline of a man's face) divided into little squares. If we scale down the image by a factor of 0.6, each resulting little square is 0.36 times the size of the original square:
Por tanto, si la magnitud unidimensional (longitud) se escala en un factor f, la magnitud bidimensional (área) queda escalada en un factor f^2. Esto quiere decir que un área calculada usando coordenadas de Mercator esférico debe ser normalizada con el factor [cos(lat)]^2. So if the 1-dimensional magnitude (length) is scaled by f, then the 2-dimensional magnitude (area) gets scaled by f^2. This means that the area computed using Spherical Mercator coordinates must be normalized by a factor of [cos(lat)]^2.

Using regular patterns to check clustering method performance

Este pequeño vídeo muestra el comportamiento de la aplicación de clusterización (agrupamiento de elementos cercanos) realizada por Prodevelop para generar archivos KML enlazados, de manera que el rendimiento de los clientes web sea óptimo sin perder validez en la ubicación de los elementos. Los pasos mostrados en el vídeo son:
  1. Explorar y editar la tabla original con gvSIG 2.1.0.
  2. Ejecutar la aplicación de clusterización sobre la misma tabla.
  3. Copiar la carpeta de archivos KML generada en una carpeta pública accesible desde internet.
  4. Obtener la URL del archivo KML raíz y visualizar el resultado en Google Earth.
This short video shows the behavior of the clustering application created by Prodevelop to create nested KML files. This approach ensures optimum performance by web clients without losing geographic information, regardless of the map scale. The steps shown in the video are:
  1. Exploring/editing the source table with gvSIG 2.1.0.
  2. Running clustering application on the same table.
  3. Copying resulting files to target web folder.
  4. Getting URL of root KML file and browsing final result in Google Earth.
Este es el código con el que se calcula la ubicación de cada agrupación de elementos, como una media ponderada en función del peso de los subelementos: This is the Java code which computes coordinates of cluster as an weighted average of the coordinates of its sub-elements:

GeoStore: parametrized creation of vector tiles in JSON/KML format from PostgreSQL/Oracle/MySQL databases

Prodevelop ha desarrollado, en el ámbito del proyecto GEOSTORE, una aplicación para la creación parametrizada de teselas (tiles) vectoriales en formato JSON y KML, a partir de tablas de PostgreSQL, Oracle o MySQL. In the context of the GEOSTORE project, Prodevelop has provided an application to create vector tiles in various formats (KML, JSON) from different databases (Oracle, PostgreSQL, MySQL).
Todos los parámetros que controlan el proceso se encuentran en un archivo .properties en el que se detallan: parámetros de acceso a la BD en la que se encuentran los datos, campos de la tabla a utilizar, nombre del campo geométrico o campos (longitud, latitud) en los que se encuentran las coordenadas asociadas a cada registro; el tipo de BD y el formato de salida, así como otros parámetros para ajustar los métodos de clusterización (agrupación) y división de los datos (teselado). Esta imagen muestra solo los parámetros más importantes: All the parameters involved in the process are set in a properties file: database access parameters, table fields to be used, name of field (if geometry is available) or fields (if longitude and latitude are available) where coordinates are to be found; type of database (currently supports PostgreSQL, Oracle and MySQL); output format (KML or JSON) as well as other parameters which determine how the tiling and clustering processes will work. This image shows only the relevant parameters of a typical properties file:
Aquí puede apreciarse el resultado al acercarse a un mapa en el que se han desplegado los archivos KML generados. Los clusters se expanden a medida que la escala de visualización lo permite: This image illustrates what happens when the user zooms in after the generated KML files have been deployed on a map. Clusters are expanded as zoom scale allows it:
Los archivos forman en disco un árbol de directorios similar al que se usa con las teselas de imágenes (Google Maps, OpenStreetMap, etc): Files are generated in a tree-like structure, similar to the one used by Google Maps or OpenStreetMap for their image tiles:
Esta otra captura de pantalla muestra un ejemplo similar con teselas JSON. En este caso, el cliente web estará probablemente escrito en Javascript: This screenshot shows a similar example using JSON tiles. In this case, the web client will typically be written in Javascript:
Finalmente, este vídeo muestra la creación y el uso de teselas KML desde una tabla Oracle y teselas JSON desde una tabla MySQL: This video shows the creation and use of KML tiles from an Oracle table and JSON tiles from a MySQL table:

n/d

OpenLayers, thematics and browsers

I'm used to debug my javascript code in Google Chrome as it has cool developer tools and its javascript engine is superb, but today I've broken Google Chrome.

I was writting some javascript code in OpenLayers to automatically generate unique value and range thematic for vector layers fully loaded on the browser. Once the code was running and after a few pans Google Chrome broke, the same code worked on Firefox. At the moment I have no idea what the "bug" is but I've made some (non rigorous) tests on several browsers and these are the results.

My OpenLayers was loading:

120 scaled and rotate SVG graphics
120 polygons
111 lines
1127 thematic points
15 png from a WMS layer

BrowserStart memoryOL load memoryWorked
Chromium 1680 MB320 MBYes
Firefox 11127 MB340 MBYes
Safari 5.122 MB180 MBGraphic errors
Chrome 18140 MB330 MBNo
IE--LOL
Opera 1160 MB200 MBYes

So Opera seems the "best browser in the world" but at the moment I will continue with Chromium

Liberado olsocial. Integración de redes sociales en OpenLayers

Acabamos de liberar olsocial, la primera extensión de OpenLayers libre que aporta capas de redes sociales desarrollada por Prodevelop.

Esta librería permite añadir con una sola línea de código datos provenientes de Twitter, Flickr, LastFm, Yelp y muchísimos más a través de POIProxy.

Un par de detalles sobre la implementación. Hemos enviado un parche para corregir la clase OpenLayers.Protocol.Script de OpenLayers para que funcionase con el API de Twitter (ver ticket) y hemos creado un gestor de popups que ha desembocado en un nuevo proyecto OL-FeaturePopups.

El proyecto es perfectamente utilizable en la actualidad pero aún tiene mucho margen de mejora, de forma que no dudes en replicar el código de gitHub y mejorarlo.

Playing around with Leaflet and POIProxy

I've been some time following Leaflet and this weekend I've decided to write some code on it. So as Leaflet has no tiled GeoJSON layer I've coded a layer to load points from POIProxy, draw them over the map and show a popup.



Of course it can be improved, at the moment only loads points at zoom level 16, the layers are exclusive to avoid overload and there are several bugs… but as a proof of concept, it's not bad :P

About Leaflet, I like several things. Its API is simple and lightweight and that's the point, it's incredibly fast on mobile devices. Apart from this, there are several interesting layers such as CartoDB that look promising :)

By the way I've uploaded a POIProxy demo that runs on desktop and mobile :) and the code is at my Github
Distribuir contenido