Pubs in England: How to do it with Polymaps and GeoCommons Filters
August 2, 2011 at 12:25 pm | Posted in gis | 2 CommentsIn this post I will show one way to display and interact with data from GeoCommons, using the powerful “filters”, and all on the mapping library, PolyMaps. It will show a basic example showing points on a map based on a filter and a more advanced example with changeable filters and some basic interaction on the points.
Few weeks ago, I wrote about how to display data from GeoCommons quickly on an OpenLayers map. The resulting little map was not that interactive, but it showed how easy it was to get started using GeoCommons as a data source. PolyMaps is a bit different than other libraries – it’s very lightweight, fast and powerful, but in terms of bells and whistles, you have to roll your own, like with Jquery core and all the plugins. It follows JQuery in another way, in that it uses method chaining. Anyhow, here is a map of Green Map named pubs in England. The base dataset, of all (24 thousand or so) pubs in England, was from OpenStreetMap, and the data is cc-by-sa. http://geocommons.com/overlays/136549/ England pubs OSM july 2011 I added the data from an extract from geofabrik.de.
GeoCommons Filters
The GeoCommons API gives more information, but the filter we are using looks like this:
http://geocommons.com/overlays/136549/features.json?filter[name][][like]=green%20man
filter[string_col][][operator] = text
We can use things like equals, min and max for numeric and date type attributes, and equals and like for string. We can also add more than one filter to the query.
Green Map pubs in England
Filtered GeoCommons features on polymaps.
Most of the gubbings is in the pubs.js file. Lets see what’s going on here.
The first section sets up the map, and adds the Acetate basemap to it, and adds a control to it. Notice the method chain: ”map.add(po.image().url(po.url ” pretty nice, eh?
var po = org.polymaps;
var map_div = document.getElementById("map");
var map = po.map()
.container(map_div.appendChild(po.svg("svg")))
.zoom(5)
.center({"lat":54, "lon":-3})
.add(po.interact());
map.add(po.image().url(po.url("http://acetate.geoiq.com/tiles/terrain/{Z}/{X}/{Y}.png")))
The second section gets json from GeoCommons, based on a filter. A filter is like a search parameter. Then we can see that a layer is created and the features from the json are added to it. We have to get the json outside of polymaps as the json is not quite valid GeoJSON yet – (it doesn’t wrap the features array in a featureCollection) – but no matter, polymaps can handle it.
var url = "http://geocommons.com/overlays/136549/features.json?limit=100000"+
"&filter[name][][like]=green%20man";
url = "/cgi-bin/proxy.cgi?url=" + escape(url);
j = jQuery.getJSON(url, function(data){
map.add(po.geoJson().features(data))
});
Pretty basic, really, and not clickable, and the points are black. The points are SVG – and are default formatted.
Adding More Functionality
Search for any pub name, click on point gives the name.
This example lives at http://geothings.net/geoiq/any_pubs.htm and the key part of the javascript lives in http://geothings.net/geoiq/any_pubs.js
We will be building upon the last example a bit.
We have refactored the adding layer bit, because this time we are making several requests. We give it a reasonably random and throwaway id, which we assign to a global variable of the currentLayerId, so we can delete it in the future.
function addLayer(filterText){
if (currentLayerId){
element = document.getElementById(currentLayerId);
if (element) {
var parent = element.parentNode;
parent.removeChild(element);
}
}
var guid = Math.floor(Math.random()*3000);
currentLayerId = guid;
var url = "http://geocommons.com/overlays/136549/features.json?limit=10000"+
"&filter[name][][like]="+escape(filterText);
url = "/cgi-bin/proxy.cgi?url=" + escape(url);
j = jQuery.getJSON(url,
function(data){
map.add(po.geoJson().id(guid).features(data).on("load", setFeatures))
});
}
When the features are added, there is a callback method (setFeatures) which stuffs the name of the pub into the point’s SVG, gives it a CSS class so we can style it with pubs_styles.css, and add a mousedown event
function setFeatures(e){
for (var i = 0; i < e.features.length; i++) {
var feature = e.features[i];
feature.element.setAttribute("feat_name", feature.data.name); //give the element an id
feature.element.setAttribute("class", "pub_point"); //set css class for colours
feature.element.setAttribute("r", "5"); //radius of svg circle.
feature.element.addEventListener("mousedown", function(e){
clickFeature(this, e);
}, false);
}
}
pub_styles.css - the fill is purple, the stroke, white and the opacity 0.6 – we style the features using CSS!
.pub_point {
fill:rgb(148,0,211);
stroke: #fff;
fill-opacity: 0.6;
}
The click / mousedown event function gets the SVG feature and the event, and displays a div whose contents is made up from the feat_name attribute from the featrure. function setFeatures(e){
function clickFeature(f, evt){
var blurb = "<div class='info_blurb'>" + f.getAttribute("feat_name") + "</div>";
var infowin = document.getElementById('infowin')
infowin.style.width = "200px";
infowin.style.maxHeight = "200px";
infowin.style.overflow = "auto";
infowin.style.left = evt.clientX + "px";
infowin.style.top = evt.clientY + "px";
infowin.style.position = 'absolute';
infowin.style.display = 'block';
infowin.innerHTML = blurb;
}
So, wastefully using just bit of JQuery to handle to form, when text is entered in the box and the button pressed, the current layer is removed, and a new one is requested, give it a go!
It’s basic, in that if you change layer, the text label may still be there, and the labels don’t move when the map is panned, but hopefully you can see that you would have to roll your won stuff on top of polymaps to do this.
2 Comments »
RSS feed for comments on this post. TrackBack URI
Leave a Reply
Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.


[...] Hi, in this quick tutorial we will have a look at a new JavaScript mapping library, Leaflet using it to help load JSON features from a GeoCommons dataset. We will add our Acetate tile layer to the map, and use the cool API feature filtering functionalities to get just the features we want from the server, show them on a Leaflet map, add popups to the features, style the features according to what the feature is, and add some further interactivity. This blog follows up from two posts on my personal blog, showing GeoCommons features with OpenLayers and with Polymaps. [...]
Pingback by Leaflet & GeoCommons JSON | GeoIQ Developer— October 31, 2011 #
Hello,
I’ve been trying to test this example but the map at: http://geothings.net/geoiq/pubs.htm isn’t showing any points anymore and I can’t figure out why. Do you know what is going wrong as I’ve checked the data is still there and the query you use works fine: http://geocommons.com/overlays/136549/features.json?limit=100000&filternamelike=green%20man
Thanks,
Peter.
Comment by Peter— November 16, 2011 #