Monday, 10 February 2014

Cool things to do with the mapguide-rest API: Part 1

Rather than give a verbatim overview of everything that is provided by the REST API in mapguide-rest (because a blog post that is just raw API documentation doesn't exactly sound like thrilling content to read), I'm going to approach this from a different angle.

For this series of posts, I'm going to specifically focus on some of the cool things you can do through the REST API that is either:

  1. Not possible through the mapagent
  2. Is possible through the mapagent, but is really unintuitive or returns content in an undesirable format
For anything else, I'd figure you could either just figure it out from the URLs provided by the various HTML representations available:
  • Site Repository: http://servername/mapguide/rest/library/list.html
  • Coordinate System Catalog: http://servername/mapguide/rest/coordsys/categories.html
  • FDO Provider Registry: http://servername/mapguide/rest/providers.html

Querying Features

Querying data from Feature Sources is possible using the SELECTFEATURES operation in the mapagent, but has some issues that make it difficult for client applications to use:
  • The operation is very verbose and requires lots of parameters to set up.
  • The operation returns MapGuide-specific XML data, and its JSON response is a direct 1:1 conversion of the XML format.
Querying data from Feature Sources through our REST API on the other hand is a simple and intuitive affair. This is because most of the base information is in the URL itself with optional parameters specified in the query string. For example, returning all data from the feature source Library://Samples/Sheboygan/Data/Parcels.FeatureSource is simply issuing the following GET request:

GET http://servername/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/features.xml/SHP_Schema/Parcels

This will return everything from the Parcels Feature Source under the SHP_Schema:Parcels feature class in XML format.

From this basic request, you can apply all sorts of extra parameters in various permutations to shape the response to your liking

Want to filter the data? Pass a filter parameter with your URL-encoded FDO filter string

GET http://servername/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/features.xml/SHP_Schema/Parcels?filter=RNAME%20LIKE%20'SCHMITT%25'

Where (RNAME%20LIKE%20'SCHMITT%25') is the URL-encoded form of (RNAME LIKE 'SCHMITT%')

Want to filter the same data by bounding box instead? Pass a bbox parameter with an x1,y1,x2,y2 quartet.

GET http://servername/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/features.xml/SHP_Schema/Parcels?bbox=-87.6,43.7,-87.7,43.8

Want to cap the results to 500 features maximum? Pass a maxfeatures parameter

GET http://servername/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/features.xml/SHP_Schema/Parcels?maxfeatures=500

Want the geometry data transformed to a different coordinate system (eg. Web Mercator)? Pass a transformto parameter

GET http://servername/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/features.xml/SHP_Schema/Parcels?transformto=WGS84.PseudoMercator

And here's possibly the best one of the lot, want the data in a more usable format than XML like GeoJSON? Sure you can!

GET http://servername/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/features.geojson/SHP_Schema/Parcels

Aggregating data

Unlike the feature querying capabilities, the aggregation capabilities of the REST API are much more simplified and is focused around 3 key common scenarios:
  • Counting the number of features
  • Getting the bounding box of a feature class
  • Getting the distinct list of values for a given property
So using the same Parcels feature source, here's how you can count the number of features

GET http://servername/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/aggregates.xml/count/SHP_Schema/Parcels

Here's how you get a bounding box

GET http://servername/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/aggregates.xml/bbox/SHP_Schema/Parcels

Want it in a different coordinate system? Pass a transformto parameter.

GET http://servername/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/aggregates.xml/bbox/SHP_Schema/Parcels?transformto=WGS84.PseudoMercator

Here's how you can get a distinct set of RTYPE property values

GET http://servername/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/aggregates.xml/distinctvalues/SHP_Schema/Parcels?property=RTYPE

And finally, if you want this in JSON instead of XML, just use aggregates.json in the URL instead of aggregates.xml

Transforming Coordinates

Here's something you definitely can't do through the mapagent. 

With the rise of HTML5 and powerful client-side web applications, probably the greatest irony about MapGuide as a web mapping solution is that we have one of the most powerful Coordinate System libraries with comprehensive support for every coordinate system on this planet you could imagine but ... we can't even tap into this library on the client-side in the web browser where it probably matters the most! It's why Fusion, OpenLayers, etc use libraries like Proj4js for its coordinate transformation needs because nothing better exists.

While I can't say that the REST API solves this problem (we're not exactly giving you csmap.js here), we do try make the issue of transforming spatial data as minimal as possible in the REST API:
  • All data with spatial/geometric components whether queried in the above fashion or published via our GeoREST-style framework (which I'll elaborate in a future post) have transform-ability built-in as an option.
  • For everything else, we provide an endpoint for transforming a batch of coordinates from one coordinate system to another. Read on to find out how.
To transform a set of coordinates from one CS to another, you simply make a POST request like so:

POST http://servername/mapguide/rest/services/transformcoords
from = "LL84"
to = "WGS84.PseudoMercator"
coords = "-87.1 43.2,-87.2 43.3,-87.4 43.1"

This will give you a response which looks like this.

More cool stuff

If this post got you excited, then stay tuned because there's more where that came from in the next part.


ChrisGo said...

Very cool! Can we get an example of how to make selection and trigger zooms. On the other hand get selection and query selection data from map. More real world example lesson set would very, very helpful?

Amatya Gupta said...

I want to add features in Map using WFS using MapGuide Maestro? Can i acheive it?