Saturday, December 08, 2012

Vooruitblik op GEO in 2013


De afgelopen jaren is het op een aantal terreinen hard gegaan met de ontwikkelingen in het ruimtelijke software veld. Google maps, OpenLayers hebben projecten als Mapbuilder en Chameleon (op zich hele leuke projecten) verdreven. En binnenkort zullen de html-5 viewers het stokje overnemen (leafletjs). Niemand durft meer een kaartje in Flash op te zetten en iedere website moet opeens weer leesbaar zijn op een 300*500 schermpje (of voldoen aan de webrichtlijnen). QGis heeft heel wat gebruikers overgenomen van de gevestigde partijen als ze niet al naar een WebClient overgestapt waren. Als u in 2005 echter zoals velen gekozen heeft voor OGC services als basis voor uw geo infrastructuur, dan is dat een duurzame keuze gebleken en de verwachting is dat dat ook nog wel zal blijven. Nog zo'n trouwe metgezel is mapserver, nog steeds de meest betrouwbare opensource kaartmotor die ik ken. Hieronder wat overpeinzingen over de afgelopen periode, ter inspiratie voor 2013...

Belangrijke recente ontwikkelingen zijn de ontwikkelingen rond de diverse portalen (PDOK, PGR, WGR) die in een grote mate voorzien in allerlei datasets met webservices ontsloten vanuit de bron (Kadastraal, BRT, BAG, Luchtfoto's, CBS, NWB). Hierdoor zal men steeds minder zelf tot aanschaf en opslag van door derden verzamelde gegevens over hoeven te gaan. Al bevatten de momenteel beschikbare services in veel gevallen nog niet een volledige historie. Voor ArcGIS en QGis zijn extensies beschikbaar die het gebruik van bijvoorbeeld de PDOK services vergemakkelijken.

De portalen en daarmee gepaard gaande regelgeving (Inspire, Basisregistraties) stellen wel vrij hoge eisen aan de dataleveranciers Dit speelt op diverse niveaus: ondersteuning van een datamodel, volledigheid van de metadata, voldoen aan de standaarden tot beschikbaarheidseisen van de webservices.

Als Geocat ondersteunen we overheden en bedrijven bij het publiceren van geografische datasets (op intra, extra en internet). Ons belangrijkste product is de opensource catalogus Geonetwork, de lijm in iedere spatial data infrastructure (SDI). Het terrein van metadata in combinatie met hoge eisen die Inspire/geonovum aan de metadata stelt maakt dit aspect voor velen vrij lastig. Geonetwork is geen eenvoudig product, echter door optimale inrichting van de templates, geautomatiseerde ETL processen en een losse catalog ontsluiting is het gebruik van de catalog binnen een organisatie wel degelijk te optimaliseren, zodat bijvoorbeeld ook niet-geo-gebruikers er goed mee aan de slag kunnen. Een portaal met een eenvoudigere interface (maar waarmee Inspire compatibiliteit weer lastiger te realiseren is) is bijvoorbeeld Geonode met daarin pyCSW.

Als voorbeeld, via de CSW extensie kan vanuit ArcGIS (maar ook arcgis explorer en QGis kennen een CSW extensie) direct gezocht worden in een catalog. De gevonden resultaten zijn direct aan de kaart toe te voegen. Ook Openlayers kent CSW-zoekopties.

Omdat het publiceren van metadata door velen als lastig ervaren wordt hebben we als geocat het initiatief genomen een "bridge" product te ontwikkelen dat publicatie van ArcGiS projecten naar een Open SDI tot het drukken op een knop reduceert. De data, styling, metadata en/of context wordt gepubliceeerd als kaartlagen in Geoserver of Mapserver, de metadata in geonetwork, waarbij zorg gedragen wordt dat alle wederzijdse koppelingen tussen service, dataset en metadata geautomatiseerd gelegd worden. Een context bestand is de OGC:variant van een themakaart. Een set lagen, een inzoom-extent en een titel met een omschrijving erbij. Optimaal inzetbaar als interactief kaartje bij een webpagina, email of bij netcentrisch werken, waarbij een specialist een kaart voorbereid en deze onder een community verspreid om een ruimtelijk probleem te duiden.


En wat komt er verder nog op ons af... Sensor services, 3D, Big data/Open data, authorisatie, WPS...

  • Steeds meer bedrijven en overheden hebben sensoren hangen/drijven, waarvan men de data stroom in sommige gevallen wil/moet delen met politie, waterschap, gemeente enz. Dan komt de OGC standaard SWE (sensor web enablement) om de hoek kijken. Deze ontwikkelingen zijn relatief nieuw, maar het is al vrij zeker dat bijvoorbeeld Inspire SWE op zal nemen in haar requirements voor bepaalde dataset-publicatie vormen. In geonetwork is SWE in de basis aanwezig, maar ik verwacht daar de komende tijd veel ontwikkeling rond. De meest gebruikte open source sensor server software is momenteel 52 north. 
  • 3D is nog altijd lastig om te visualiseren. Er zijn nauwelijks open source GIS pakketten die een goede 3D weergave hebben. De kaartserver deegree heeft een vrij groot pallet aan opslag mogelijkheden voor 3D data en ondersteuning voor de web perspective view service en 3D CityGML (via WFS). Maar er zijn nog nauwelijks clients die daar gebruik van kunnen maken.
  • 2012 staat onder andere in het teken van open data, door de overheid gestimuleerd is het vliegwiel gaan draaien, wekelijks wordt weer een nieuwe dataset gepubliceerd als open data (PDOK, RDW, RCE, Waterschappen). Altijd goed om de data licenties goed op een rijtje te hebben, sommigen dienen altijd vergezeld te gaan van auteurs vermeldingen (attribution), anderen mogen niet commercieel uitgebaat worden. De andere veelgehoorde term was big data. Met name de vele sensoren die we hebben genereren sneller data dan we kunnen verwerken. Een goede strategie in opslag en verwerking is dus onmisbaar.
  • In tegenstelling tot het punt hierboven wordt ook het aspect van authenticatie voor ruimtelijke services steeds belangrijker. Steeds meer processen lopen via het internet, de data komt overal vandaan. Men wil voorkomen dat niet geautoriseerde mensen bij de gevoelige data kunnen, maar tegelijkertijd ook niet steeds opnieuw een (afwijkend) wachtwoord in toetsen (single sign-on). En hoe dwing je een fair-use policy af?
  • WPS (Web Processing Services) gaan verder waar WMS en WFS ophouden. Analyses, route berekeningen, processen starten/volgen, alles is mogelijk met deze standaard die eigenlijk alleen een standaard biedt voor het formaat van de in- en output parameters. Met een product als taverna zijn dit soort services te combineren tot een workflow, alleen wordt alles remote uitgevoerd.

Een keuze voor Open Source?
In de praktijk blijkt dat de Open Source producten goed aan de OGC standaarden voldoen en qua functionaliteit niet onder doen voor de gesloten alternatieven. Ze passen dus goed in een architectuur gebaseerd op Open standaarden. Een eventueel nadeel is de bundeling van een aantal verschillende producten tot een SDI. Ik zie dat echter als een voordeel, met een Suite van een leverancier heeft men niet de mogelijkheid er een slecht presterende component uit te halen en te vervangen voor een beter alternatief. Een ander groot voordeel is dat als er wat mis is, men relatief eenvoudig op zoek kan naar de oorzaak. Rond Open Source producten zijn grote communities actief die actief op gebruikersvragen reageren. Er zijn ondertussen voldoende bedrijven die professionele dienstverlening hebben rond open source software, zoals OpenGeoGroep, B3Partners, Aris, GeoCat. Zij ondersteunen bij installatie, configuratie, aanpassingen, nieuwbouw, onderhoud en storingen.

Ik hoop u hierbij wat aanknopingspunten gegeven om uw visie rond geo verder uit te diepen.

Ik was dit verhaal aan het typen aan een potentiĆ«le klant, op basis van een advies aanvraag en dacht waarom niet op de blog. Anderen vinden het misschien ook interessant, zo'n compact overzicht.


Wednesday, November 07, 2012

Apply combined fill on multiple fields in geoserver SLD

Imagine you want to add a style to a map layer where the style is applied based on values of two attribute fields. Implementation like below seems quite logical if you see it, but I was quite surprised it works out of the box in geoserver... (Alternative would be to add the layer twice or have 10*10 rules, each field 1 value times each field 2 value)

The use case is a polygon fill based on crop cultivar as background-fill color and association (other crop that is mixed in) represented as a hash-pattern on top of the fill.

In geoserver you can add two featurestyles to a layer user style, the first implementing the background fill based on field A and a second style based on field B

<StyledLayerDescriptor> 
<NamedLayer>
<UserStyle>
<Name>test_style</Name>
<FeatureTypeStyle> ...</FeatureTypeStyle>
<FeatureTypeStyle>... </FeatureTypeStyle>
</UserStyle> 
</NamedLayer>
<StyledLayerDescriptor>

In featuretypestyle 1 now define the backgroundfill based on field 1
...
<Rule>
<Name>Cavendish</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>cultivar_type</ogc:PropertyName>
<ogc:Literal><![CDATA[1]]></ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<PolygonSymbolizer>
<Fill><CssParameter name="fill">#FF0000</CssParameter></Fill>
</PolygonSymbolizer>
</Rule>
....
And in featuretypestyle 2 define the hash-pattern based on field 2

...
<Rule>
<Name>Associated with established perennial crops</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>association</ogc:PropertyName>
 <ogc:Literal><![CDATA[1]]></ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<PolygonSymbolizer>
<PolygonSymbolizer>
<Fill>
<GraphicFill>
<Graphic>
<Mark>
<WellKnownName>shape://vertline</WellKnownName>
<Stroke><CssParameter name="stroke">#000000</CssParameter></Stroke>
</Mark>
</Graphic>
</GraphicFill>
</Fill>
<Stroke><CssParameter name="stroke">#6E6E6E</CssParameter><CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</PolygonSymbolizer>
</Rule>
...





This will result in a combined style as follows



A potential challenge here is the legend-display, but the two featurestyles are nicely placed after each other...



Monday, October 15, 2012

why THE spatial metadata usecase not always succeeds

So what's THE spatial metadata usecase? Imagine you're looking for a nice map on butterflies in the Alpes region France. You open up your favourite map editor (be it ArcMap, QGis or an Openlayers webclient), be sure a metadata search plug-in is installed (http://webhelp.esri.com/geoportal_extension/9.3.1/index.htm#ext_csw_clnts.htm, http://nextgis.ru/en/blog/cswclient, http://gxp.opengeo.org/master/examples/catalogue.html). Imagine you already have the url for the french metadata portal (or to some portal harvesting all european/global datasets), be it http://www.geocatalogue.fr

Now when looking for keyword 'butterfly' and pointing to Alpes, in most cases you'll find a nice set of results, thanx to the CSW standard. But as soon as you want to add those datasets to a map the troubles start... Apparantly the standards (and/or implementations) are unfortunately not totally clear in describing the full use case. Here is a list of items which you'll encounter researching this use case in several implementations:

- CSW uses the Dublin Core standard to describe dataset metadata. There is however no clear way specified in DC how to put webservice (be it WMS, WFS or WMTS) information (like url, protocol) in the document. Apparantly a group of enthousast invented in 2006 a dclite4g profile on top of DC which introduced a key DC:Uri and DC:format http://wiki.osgeo.org/wiki/DCLite4G. Geonetwork still uses this DC:Uri. However without refering to the DCLite4G profile, resulting in a non-conformant DC-record. Inside the DC:Uri element attributes like protocol, name and description (from iso onlineresource) are available, which enables addition of the dataset-service to the map. The Geonode team recently proposed to solve the add2map challange by in stead of using a DC:Uri element, to use a DCT:references element (which is available in the DC Terms schema). The dct:references however has only one attribute, the attribute 'schema'. To be able to have parameters like protocal, name and url, they proposed to add a json object containing these values into the schema attribute (http://dev.geonode.org/trac/wiki/pycsw#MetadataLinks). Let's keep interoperability in mind while designing these standards-additions...

- A next challenge in this usecase is in the ISO online resource definition. Apparantly the standard doesn't describe where the layername is stored which presents the actual dataset. This results for example in ArcGIS CSW-client that all layers of a service are added to the map. Within the metadata community people have come to some form of an agreement to put the layername in the name element, and you'll see most of the current implementations use this agreement. For example the dutch government has put this agreement in their metadata profile (http://www.geonovum.nl/sites/default/files/nederlands_metadata_profiel_op_iso_19115_voor_geografie_-_v1.3.pdf).


I guess that's the reason they've put an option to choose your favourite flavour
of CSW 202 in ArcMAP CSW client

- Recent ISO standards offer more specified guidelines for creating these types of links. This approach however has quite some overhead, so won't get popular very soon, I haven't seen any client implemenation so far (besides the ones in Geonetwork and ArcGIS Portal). ISO proposed to add to each metadata for dataset record (iso:19115) a link to a number of metadata for service (iso:19119) records in which a layer presenting this data is available (WMS/WFS/WMTS). To get from metadata for dataset to the URL-properties one needs an additional CSW request.

- Apparantly the amount of requests needed to add a layer to the map needs to be minimised to keep up performance, especially in browser based applications like GeoExt. I saw some comments in the GeoExt/GXP code, that a Catalogue search implementation should not include a getcapabilities request to the actual mapserver. Probably because this is a very costly request taking quite some browser memory. But there is some information in that getcapabilities request you'll need for a seemless user experience: For WMS the projections are only in the getcapabilities, but also the available image formats and feature-info formats. One'll need to check them before being able to add the service to a map (which could have a different  projection/image format). This is especially true when adding a WMTS service (the tiling scheme is only available in getcapabilities). Getcapabilities request can turn really big as soon as 100's of layers are grouped in 1 service. So keep your services small. Latest Geoserver (2.2) supports splitting up the main service into multiple smaller services using workspaces. Or we might endorse OGC and the server vendors to also allow a layer parameter in a getcapabilities request. So you get a capabilities response for only the single layer you're interested in.

JeroenT, BartvdE, TomK, FrancoisXP, MarceldR Thanx for sharing these insights

Wednesday, October 03, 2012

Using comboboxes in an ExtJS PropertyGrid

When viewing/editing a database record in a PropertyGrid, you often encounter integer-foreign-keys referring to other tables containing lookup-labels. In the propertygrid you would want to display the lookup-label in stead of the integer. You could get the label with a json-ajax-request, but since you might need these values multiple time It's probaly better to have them cache in an ArrayStore.

var store = new Ext.data.ArrayStore({
fields: ["id", "label"],
data :  {"lookup":[[1,"blue"],[2,"red"],[3,"green"],[4,"yellow"]]}
});
Now you can reference the correct label from the ArrayStore in the customRenderer configuration of the PropertyGrid (ExtJS 3.4 implementation http://dev.sencha.com/deploy/ext-3.4.0).
 new ext.grid.PropertyGrid({
                            customRenderers: {
                                  //get the lookup label
                                'color': function(v){ return getLookup(store,v) }
                            },
                            propertyNames: {
                                'color':'Couleur' //set a localised property header
                            },
                            source: aRecordStore.record[0].data
                        })
function getLookup(store,id){
           if (store.find('id',id)==-1) return "-";
           else return store.getAt(store.find('id',id)).get('label');
}

Using a store here to retrieve a single label is not very optimal, but the store will come in handy when you want to edit the propertygrid. In the case of the foreign key, you would want to present the user with a dropdown (combobox) of available values:

new ext.grid.PropertyGrid({
                            customRenderers: {
                                'color': function(v){ return getLookup(store,v) } //get the lookup label
                            },
                            customEditors: {
                                //you don't want people to edit the id-field
                                'id': new Ext.grid.GridEditor(new Ext.form.TextField ({disabled : true})),
                                //get a combobox editor filled with lookup values to edit the color field
                               'color': new Ext.grid.GridEditor(new Ext.form.ComboBox({
                        store: store,
                    mode: 'local',
                    forceSelection: true,
                    triggerAction: 'all',
                    editable: false,
                    valueField: 'id',
                    displayField: 'label',
                }
            )
        ),
                            propertyNames: {
                                'color':'Couleur' //set a localised property header
                            },
                            source: aRecordStore.record[0].data
                        })

In case you want people to only be able to edit the propertygrid when a certain condition is met (is authenticated/edit button has been activated), use the beforeedit event:

listeners: {"beforeedit": function() {
                if(!readOnly) {
                    return true;
                } else {
                    return false;
                }
            }
}

Monday, September 24, 2012

Add dutch gridset to Geoserver 2.2

This weekend geoserver 2.2 got released. Besides the obvious novalties, like WFS2 support, new authentication system, able to connect to ldap, a nice feature has been added; the possibility to separate the workspaces as separate endpoints, each having it's own parameters (like title, abstract, point of contact, styles). To get the capabilities for just 1 workspace visit the url http://..../geoserver/workspace_name/wms?request.... To set individual parameters on a workspace check the 'settings' box in the workspace edit form.

Also new is the ability to create a gridset from within the geoserver admin interface, before only the gridsets epsg:4326 and epsg:900913 were available. Now you can easily create a gridset for any projection. The gridset is saved in the geowebcache.xml. For example the gridset for the dutch projection epsg:28992 would look like this (copy paste them in geowebcache.xml), according to the dutch tiling guidelines (by geonovum)

 <gridSet>
      <name>RD_NEW</name>
      <description>Scales indicated by geonovum in nederlandse richtlijn tiling v1.0 from june 2010</description>
      <srs>
        <number>28992</number>
      </srs>
      <extent>
        <coords>
          <double>-285401.92</double>
          <double>22598.08</double>
          <double>595401.92</double>
          <double>903401.92</double>
        </coords>
      </extent>
      <alignTopLeft>false</alignTopLeft>
      <resolutions>
        <double>3440.64</double>
        <double>1720.32</double>
        <double>860.16</double>
        <double>430.08</double>
        <double>215.04</double>
        <double>107.52</double>
        <double>53.76</double>
        <double>26.88</double>
        <double>13.44</double>
        <double>6.72</double>
        <double>3.36</double>
        <double>1.68</double>
        <double>0.84</double>
        <double>0.42</double>
        <double>0.21</double>
      </resolutions>
      <metersPerUnit>1.0</metersPerUnit>
      <pixelSize>2.8E-4</pixelSize>
      <scaleNames>
        <string>0</string>
        <string>1</string>
        <string>2</string>
        <string>3</string>
        <string>4</string>
        <string>5</string>
        <string>6</string>
        <string>7</string>
        <string>8</string>
        <string>9</string>
        <string>10</string>
        <string>11</string>
        <string>12</string>
        <string>13</string>
        <string>14</string>
      </scaleNames>
      <tileHeight>256</tileHeight>
      <tileWidth>256</tileWidth>
      <yCoordinateFirst>false</yCoordinateFirst>
    </gridSet>