El protocolo utilizado para devolver los elementos de los datos geográficos se denomina Web Feature Service (WFS). Un servicio WFS permite guardar una copia de la fuente de datos (vectorial) en el disco duro local, siendo el acceso a los datos total.
Esto permite a los usuarios crear sus propios mapas y aplicaciones a partir de los datos de origen, convertir datos entre distintos formatos y ser capaz de manipular geográficamente en bruto los datos servidos.
Si quieres aprender a crear un servicio WFS con GeoServer pásate por este post: Construcción de un servicio WMS / WFS con GeoServer a partir de un shapefile.
En este artículo vamos a mostrarte cómo acceder a servicios WFS desde el cliente de mapas web OpenLayers 3. Añadiremos nuestra capa vectorial cities en OpenLayers desde GeoServer como un servicio WFS.
Una vez que tenemos un sencillo visor web creado con OpenLayers 3, vamos a añadir ahora una capa superpuesta de tipo vector.
En OpenLayers 3 las capas vectoriales se representan mediante la clase ol.layer.Vector y maneja la visualización de los datos vectoriales en el lado del cliente.
Dentro de nuestro script añadimos la capa base de OpenStreetMap en la variable raster y la añadimos al mapa:
<script> var raster = new ol.layer.Tile({ source: new ol.source.OSM() }); var map = new ol.Map({ layers: [raster], target: 'map', view: new ol.View({ center: [0, 0], zoom: 2 }) }); </script>
A continuación creamos el objeto vector (la capa vectorial) mediante la clase ol.layer.Vector:
var vector = new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: function(extent) { return 'http://localhost:8080/geoserver/earth/wfs?' + 'service=WFS&' + 'version=1.0.0&request=GetFeature&typename=cities&'+ 'outputFormat=application/json'; } }) });
Vamos a explicar más despacio qué es lo que hemos hecho.
La clase ol.layer.Vector requiere de forma obligatoria una fuente de datos (source) y opcionalmente una extensión, una resolución, la opacidad y un estilo para representar las capas (style). Si no se define éste último, se utilizará el estilo definido por defecto. Más adelante veremos cómo personalizarlo.
Hemos añadido la fuente de datos, que será una fuente de datos de tipo vectorial:
source: new ol.source.Vector({
La fuente de datos vectorial ol.source.Vector requiere al menos los parámetros format y url. Es decir el formato y la ubicación en la que se encuentra la capa vectorial.
En este ejemplo utilizamos como formato GeoJSON para su renderización en el navegador web y como url una función que nos devuelve la capa como servicio WFS de GeoServer:
format: new ol.format.GeoJSON(), url: function(extent) { return 'http://localhost:8080/geoserver/earth/wfs?' + 'service=WFS&' + 'version=1.0.0&request=GetFeature&typename=cities&'+ 'outputFormat=application/json'; }
Petición WFS GetFeature
Todas las versiones de WFS soportan las operación GetFeature. Esta operación devuelve una selección de objetos geográficos de la fuente de datos. Devuelve instancias de fenómenos (objetos individuales) en formato GML. Además, el cliente debe tener la posibilidad de solicitar las propiedades del fenómeno que desea y de realizar tanto consultas espaciales como no espaciales.
La url con la petición GetFeature de WFS que debemos especificar la podemos obtener directamente de nuestro servidor GeoServer.
Vamos a la interfaz de GeoServer, en la sección Datos > Previsualización de capas > y en la capa cities seleccionamos dentro de la sección WFS > GeoJSON, como se muestra en la siguiente imagen:
Haciendo clic, se abre el archivo cities en formato GeoJSON, siendo su enlace:
http://localhost:8080/geoserver/earth/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=earth:cities&maxFeatures=50&outputFormat=application%2Fjson
Ojo!, esta petición tiene un parámetro restrictivo por defecto:
maxFeatures=50
Eliminamos dicho parámetro y la url queda como en el código anterior, es decir:
http://localhost:8080/geoserver/earth/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=earth:cities&outputFormat=application%2Fjson
Vamos a ponerlo de nuevo todo junto:
var vector = new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: function(extent) { return 'http://localhost:8080/geoserver/earth/wfs?' + 'service=WFS&' + 'version=1.0.0&request=GetFeature&typename=cities&'+ 'outputFormat=application/json'; } }) });
En segundo lugar añadimos las dos capas al mapa: la capa raster de OSM y la vectorial:
var map = new ol.Map({ layers: [raster, vector], target: 'map', view: new ol.View({ center: [0 , 0], zoom: 2 }) });
Este es el resultado de la capa cities añadida como servicio WFS en OpenLayers.
Personalizando el estilo del WFS en OpenLayers
OpenLayers 3 viene con un conjunto de clases que nos ofrece un control bastante preciso de cómo representar nuestros objetos geográficos.
La clase principal es ol.style.Style
Para especificar el relleno, trazos, textos e imágenes tenemos las propiedades:
- El relleno – Fill (ol.syle.Fill)
- El trazo o contorno – Stroke (ol.style.Stroke)
- El texto – Text (ol.style.Text)
- Las imágenes – Image (ol.style.Image)
Cada una de las clases anteriores tiene sus propiedades. Que variarán dependiendo de nuestras necesidades.
ol.style.Fill: tiene la propiedad color. Solo necesita esta propiedad para especificar como rellenar una forma.
El código del relleno por defecto es:
var fill = new ol.style.Fill({ color: 'rgba(255,255,255,0.4)' });
ol.style.Stroke acepta:
- color
- width
El código del contorno por defecto es:
var stroke = new ol.style.Stroke({ color: '#3399CC', width: 1.25 });
Para representar los objetos geográficos como imágenes, OpenLayers 3 define dos clases: ol.style.Icon y ol.style.Circle que son herencias de la clase ol.style.Image.
- ol.style.Icon se ha diseñado para representar cualquier imagen especifica pasando una url a la propiedad image.
- ol.style.Circle. Se ha diseñado para representar circunferencias con buen rendimiento, por eso se usa para renderizar objetos vectoriales de tipo punto.
El código del por defecto es:
var styles = [ new ol.style.Style({ image: new ol.style.Circle({ fill: fill, stroke: stroke, radius: 5 }), fill: fill, stroke: stroke }) ];
Puedes verlo también en la documentación de la API: http://openlayers.org/en/latest/apidoc/ol.style.html
Vamos a actualizar la simbología de nuestra capa cities añadiendo la propiedad style y modificando el estilo predefinido por uno personalizado:
var vector = new ol.layer.Vector({ source: new ol.source.Vector({ format: new ol.format.GeoJSON(), url: 'http://localhost:8080/geoserver/earth/ows?'+ 'service=WFS&version=1.0.0&request=GetFeature&'+ 'typeName=earth:cities&'+ 'outputFormat=application%2Fjson' }), style: new ol.style.Style({ image: new ol.style.Circle({ radius: 3, fill: new ol.style.Fill({ color: 'orange'}) , stroke: new ol.style.Stroke({ color: 'black'}) }) }) });
Este es el resultado con nuestra capa vectorial con un radio de tamaño 3, un relleno en color naranja y un color de contorno en color negro:
Licenciado en Geografía. Máster en Sistemas de Información Geográfica. Consultor GIS desde el año 2004. En MappingGIS desde el año 2012 para ayudarte a impulsar tu perfil GIS y diferenciarte de la competencia. Echa un vistazo a todos nuestros cursos de SIG online.
Hola Aurelio:
Hay alguna forma de restringir la descarga del WFS a un solo registro?
Hola Reymar,
La operación GetFeature devuelve instancias de fenómenos (objetos individuales) en formato GML. Para restringir una solicitud GetFeature por atributo en lugar de elemento, utilizamos la clave propertyName en forma propertyName = atributo. Por ejemplo:
http://www.juntadeandalucia.es/medioambiente/mapwms/REDIAM_WFS_riesgos_naturales? SERVICE=wfs& VERSION=1.1.0& REQUEST=GetFeature& TYPENAME=zona_pel_incendios_se& COD_INE=zona_pel_incendios_se.41041
Saludos