Wednesday, September 29, 2010

Participating with OneGeology: Experience, Lessons Learned and Other Tidbits

I recently had the opportunity to "stand up" a WMS representing a 1:5,000,000 scale geologic map of North America for integration into a platform called OneGeology.




OneGeology, whos mission statement is to:

"Make web-accessible the best available geological map data worldwide at a scale of about 1: 1 million, as a geological survey contribution to the International Year of Planet Earth." (see: http://onegeology.org/what_is/mission.html)

 aims to:
  • create dynamic digital geological map data for the world.
  • make existing geological map data accessible in whatever digital format is available in each country. The target scale is 1:1 million but the project will be pragmatic and accept a range of scales and the best available data.
  • transfer know-how to those who need it, adopting an approach that recognises that different nations have differing abilities to participate.
  • the initiative is truly multilateral and multinational and will be carried out under the umbrella of several global organisations.   (see:  http://onegeology.org/what_is/objective.html)

The process for contributing to this worthy effort was pretty interesting and I wanted to share this experience a bit.

To begin with, the map we were submitting was actually a replacement for an existing geologic map of North America which only covered the southern portion.  The previous WMS was served using Map Server while our new one was being powered with ArcGIS Server 9.3.1.  This was quite the test for AGS given the outstanding performance of Map Server with regard to WMS serving.  In an effort to boost performance without doing a bunch of map authoring and data processing, we performed a couple of interesting tricks that I outlined in some detail in a previous post.

Basically, participation with the OneGeology platform can occur at several tiers, each basically correlated to functionality.  Our participation was of the first tier, that being simply contributing a WMS.  This experience was not trivial.  Even though WMS is technically a "standard," there is still enough wiggle in the spec that a specific implementation is needed to ensure interoperability.  The folks at OneGeology have done a outstanding job with this and have documented, in detail, requirements for how WMS services need to be configured for integration into their system.  Our specific instances are here:

http://certmapper.cr.usgs.gov/arcgis/rest/services/one_geology_wms/USGS_Geologic_Map_of_North_America/MapServer -- raster one

http://certmapper.cr.usgs.gov/arcgis/rest/services/one_geology_wms/USGS_Geologic_Map_of_North_America_GFI/MapServer -- vector one for getFeatureInfo requests only

And finally the portal.  It is a really nice application and serves as a great demonstration of "mashing up" distributed data services that originate throughout the globe.  It is really pretty astonishing, given the wide range of participating organizations.
OneGeology Portal Depicting Geologic Map of North America






Tuesday, September 7, 2010

WMS GetFeatureInfo Request Rewrite with Apache mod_rewrite (ArcGIS Server, Performance)

We had an interesting issue to deal with with regard to a WMS getFeatureInfo request with a particular WMS webmap service using ArcGIS server.  This issue had to due with performance.  The map service was of the Geologic Map of North America which contained very complicated geometries, cartography, etc so you can image the performance of dynamically generating images for WMS getMap requests from this bad boy.
View of Geologic Map of North America WMS Service in GAIA 3.4

We could have done a whole bunch of data processing such as scale dependent rendering, generalizing layers, etc (which would have been the right thing to do) but didn't really have the time or resources to do so.  Another solution you may be thinking was to cache the service but I am not convinced that ArcGIS Server caches work for WMS getMap requests given the bounding box geometry for the getMap requests are dynamic and may not match the scale and dimensions of the cache but that should be left to an entirely different discussion.

The next best thing was to rasterize the data and basically serve getMap requests based on a rasterized version of the data (in the map document itself).  This helped with performance dramatically but introduced a new issue.  Given that is was based on rasterized data, attribute data was now absent eliminating the ability to serve getFeatureInfo requests.  Our solution for this was to simply serve getFeatureInfo requests with a different service than that which serviced getMap requests.  Two services responding to different requests.  The WMS getCapabilities spec implements this capability by allowing you to simply specify an alternative OnlineResource xlink:type="" value for getFeatureInfo requests.  This works great for most clients but some don't adhere to this so we were forced to forward getFeatureInfo requests made to the original WMS service (containing the rasterized version of the data) to the new service.  Given this scenario, the base URI's for each service were:

http://certmapper.cr.usgs.gov/arcgis/rest/services/one_geology_wms/USGS_Geologic_Map_of_North_America/MapServer -- raster one

http://certmapper.cr.usgs.gov/arcgis/rest/services/one_geology_wms/USGS_Geologic_Map_of_North_America_GFI/MapServer -- vector one for getFeatureInfo requests only

To do this, we used apache mod_rewrite.  Now apache mod_rewrite is not for the faint of heart.  It is powerful but takes some time to work through.  Oh, and get your favorite regular expression cheatsheet ready because you will need it.

Anyway, here is the syntax we used to solve our problem:
The RewriteCond statement sets the stage.  In limits the scope of the following RewriteRule.  In this case, it looks for a query string variable that contains a value of "GetFeatureInfo" (we had to do some pattern matching stuff to account for caps or nocaps and to make is more explicit but that is too much for this post).  The RewriteRule then matches the first statement and replaces it with the second.  In our case, it tries to match:

/arcgis/services/one_geology_wms/USGS_Geologic_Map_of_North_America/MapServer/WMSServer 

and replace it with

http://certmapper.cr.usgs.gov/arcgis/services/one_geology_wms/USGS_Geologic_Map_of_North_America_GFI/MapServer/WMSServer. 

We actually used regular expression stuff to match it but this does the same thing and is easier to understand.  The final thing you will notice is the [P] modifier.  The replacement statement is actually mapped to a local file system location.  In our case, we needed to forward explicitly to a reverse proxy server so a fully qualified URI with the [P] does this.

Thanks to @GISBrett and @jasonbirch for suggestions and moral support on coming up with this solution :-)