Building a Geospatial Application with Cloudant to Show Colorado Ski Areas

The aim of this post is to provide the building blocks to query and present geospatial data from Cloudant in third-party applications. Specifically, we will discuss how to integrate Leaflet with Cloudant to build this site. Leaflet is an open-source JavaScript library for mobile-friendly interactive maps.
Building Blocks
The site is built using Leaflet Vector Layers and Leaflet Draw. You can find all the code here. Leaflet Vector Layers pulls vector features from geo web service providers including ArcGIS Server, Arc2Earth, CartoDB, and Geocommons. Leaflet Draw is a vector drawing and editing plugin for Leaflet.
We used the existing dataset from GeoIQ, which includes GeoJSON data for ski areas in the Colorado area of the Rocky Mountains:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
{ "type": "Feature", "id": 11, "properties": { "Name": "Breckenridge Ski Area", "Status": "Open", "XCOORD": -106.079136, "YCOORD": 39.459103 }, "geometry": { "type": "Point", "coordinates": [ -106.07913649885852, 39.45910306740733, 0 ] } } |
After updating the data to Cloudant, create the database through the Cloudant administration user interface. (Note: If new to Cloudant, register and let support@cloudant.com know that you want to be on the geospatial cluster.)
We use the following Cloudant design document to index the GeoJSON as an R*Tree secondary spatial index.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "_id": "_design/SpatialView", "indexes": { "ski_areas": { "index": "function(doc){ if (doc.geometry) { st_index(doc.geometry);}}" } } } |
The design document above is created within Cloudant with an HTTP POST request:
1 2 3 |
curl -X POST -d @designDoc.json https://username:password@cloudant.com/colorado_skiing -H "Content-Type: application/json" |
I used a simple Python script to load the remaining GeoJSON feature collection for Colorado ski areas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import json import requests headers = {"content-type": "application/json"} # parse json feature collection json_data = open(areas) data = json.load(json_data) for feature in data["features"]: Id = feature["id"] # delete feature type and duplicate id del feature[“id”] requests.post(dbUrl, data=json.dumps(feature), headers=headers) json_data.close() |
The script above uses the Python requests to pull a GeoJSON feature collection and parse it as individual documents to be indexed in the Cloudant Spatial Index.
The Cloudant Geo OpenSearch API wrapped within Leaflet Vector Layers adds a datasource that is comparable to editing index.html to set up a region of interest.
Leaflet Vector Layers will provide radius, bounding box, and polygon queries of your data.
Norman Barker is the Director of Geo at Cloudant, an IBM Company. He has been developing geospatial programs for more than 10 years and leads the development of distributed geospatial indexes for Cloudant. His primary interest is in how to use unstructured geospatial data.
Feature image via Flickr Creative Commons.