268 Different Colourful Tiles – Plain Tile Maker

Plain Tile Maker was my weekend project – a mapping tile service that serves one colour tiles as a tile basemap.
There are about 268 colours to choose from – basically anything that the underlying library (Imagemagick) supports.
It was developed for me to play around on the Heroku platform, and as a response to a GeoCommons.com user question, where the user wanted a way to show just a plain one colour background.
This solution is more flexible, and really easy.

 

 

 

 

 

The format is

http://plaintiles.herokuapp.com/colorname/X/Y/Z.png

So for example,

http://plaintiles.herokuapp.com/DodgerBlue/0/0/0.png

http://plaintiles.herokuapp.com/bisque/12/3/32.png

And in return you get a 256×256 sized image of that colour.

DodgerBlue

bisque

You can use it in your mapping libraries, for example: With OpenLayers:

var colourTile = new OpenLayers.Layer.XYZ(
 "Plain Colour Tile",
 "http://plaintiles.herokuapp.com/colourName/${z}/${x}/${y}.png", 
 { sphericalMercator: true,
 buffer: 1,
 numZoomLevels: 17
 }
);

And with Leaflet:

new L.TileLayer('http://plaintiles.herokuapp.com/colourName/{x}/{y}/{z}.png', {maxZoom: 18});


Or you can add them to GeoCommons quite easily. Add

http://plaintiles.herokuapp.com/colorName/{X}/{Y}/{Z}.png

in the Add a URL link, choosing Map Tile URL from the format, and  then give it a nice name when prompted.

Here’s the Bisque tiles in GeoCommons.

I’ve used the in a map it to give a ghosting effect over the basemap, and to just show my own boundaries. http://geocommons.com/maps/181231  is a map made with some World Boundaries over the plain bisque map we had just added. I’ve also overlaid the Acetate Labels layer on top for context.

Want to know more? The code for this is on github.

Why companies are moving away from Google Maps to OpenStreetMap – switch2osm.org

At Leeds digitial networking event LSxCafe this Tuesday, I talked about how companies, such as Geocaching.com and Foursquare.com are moving away from Google Maps and choosing OpenStreetMap. The slides are below.

Today the twitterverse and blogosphere were abuzz with the discovery that Apple had made the switch to use OpenStreetMap in their iPhoto application. At the moment, it appears to be so, but there’s no attribution yet. Compare for yourselves : http://ivan.sanchezortega.es/leaflet-apple.php  But take it from me, I have personally surveyed using a GPS unit and mapped paths in woods which are not on any map anywhere else (not legal footpaths) which appear on Apples map.

Pubs in England: How to do it with Polymaps and GeoCommons Filters

UPDATE: now using 27,416 pubs from Aug 2012 http://geocommons.com/overlays/270943

In 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.

GeoCommons GeoJSON in OpenLayers

So, with GeoCommons you can export all the features from a dataset in GeoJSON format. This is very useful. Then can it be displayed in Openlayers? Why yes it can!

I use the following strategy, wrapping the response with a little bit extra so that the GeoJSON format can read it properly.

var url = "http://geocommons.com/overlays/128725/features.json?limit=100";

var p = new OpenLayers.Format.GeoJSON();

OpenLayers.loadURL(url, {}, null, function (response) {
 var gformat = new OpenLayers.Format.GeoJSON();
 gg = '{"type":"FeatureCollection", "features":' +
      response.responseText + '}';
 var feats = gformat.read(gg);

 vector_layer.addFeatures(feats);
});

Have a look a the live demo of this example of loading points from a Geocommons dataset straight into an OpenLayers map
(Note that I am using an OpenLayers.ProxyHost proxy to make it work in FF)

It is of course very basic in terms of styling, but it’s a start!

Incidentally the points are from “CARMA, India Power Plant Emissions, India, 2000/ 2007/Future” (carbon monitoring)

JSON prettifier for gedit

Just a quick note for those of you that use gedit and want to format json so that it goes from something like this:

{"published":"2011-06-23T11:04:37-04:00","title":"TNC's Ecoregional Portfolio (public)","data_type":"WMS","calculation_params":null,"contributor":"jrfishe1","state":"complete","geometry_types":null,"permissions":[{"permissions":{"download":true,"view":true},"group_id":"everyone"}],"link":"http://geocommons.com/overlays/128841.json","feature_count":0,"icon_link":null,"name":"TNC's Ecoregional Portfolio (public)","extent":[-180.0,-85.0511,180.0,85.0511],"process_notes":"EPSG:4326,EPSG:3857","is_raster":true,"description":"The Nature Conservancy's Ecoregional Portfolio (public version) represents our priority areas for conservation.","short_classification":"Y","author":"The Nature Conservancy","source":"http://maps.tnc.org/","url":"http://maps.tnc.org/ecadpubprodanon/services/portfolio_anon_WM/MapServer/WMSServer?request=GetCapabilities&service=WMS","data_attributes":null,"tags":"conservation,priorities,the nature conservancy,tnc","id":128841,"pagination":{"total":0,"sort":null,"start":0,"limit":1000000},"url_type":"wms","classification":null}

ergh! To something like this

{
  "short_classification": "Y",
  "name": "TNC's Ecoregional Portfolio (public)",
  "icon_link": null,
  "author": "The Nature Conservancy",
  "title": "TNC's Ecoregional Portfolio (public)",
  "url_type": "wms",
  "data_attributes": null,
  "extent": [
    -180.0,
    -85.0511,
    180.0,
    85.0511
  ],
  "published": "2011-06-23T11:04:37-04:00",
  "url": "http://maps.tnc.org/ecadpubprodanon/services/portfolio_anon_WM/MapServer/WMSServer?request=GetCapabilities&service=WMS",
....
  "source": "http://maps.tnc.org/",
  "process_notes": "EPSG:4326,EPSG:3857",
  "state": "complete"
}

How to

Have Ruby. Install json gem.

Enable the external tool plugin in Gedit

Open up Manage External Tools

Create a new item

in the box type

#!/bin/sh
ruby /usr/bin/prettify_json.rb

Voila!

To activate it, load up a json file, then select the new command under tools > external tools

 

 

 

 

WhereCampEU 2011 recap & berlin psychogeography

Last week in Berlin I was lucky enough to go to WhereCampEU – thanks to Gary and Chris for organising this wonderful unconference. The conference was held in a trendy hipster ish part of the city, but which had also, I heard, the highest number of young families and births. It was also in the former Eastern part of the city. It gave the area a nice appeal, overall.

photo by Chris Fleming

I did a couple of sessions, one on a preview of GeoCommons2.0  talked about in a previous post and the other a psychogeography session. For the psychogeography session I sent four teams out to explore the environs around the campus.

One team followed people around. They said “I’m amazed by how slowly some people moved” and “Well, often we followed someone and then they would wander into a book shop”  - revealing the nature of the people and the type of area, bohem style cafes and shops, lazily people.

Another group were sent to ask people to point to were the centre of Berlin was. I asked some people where they thought was the centre, and most of them scratched their chins, and pointed to the Mitte area of the city, usually on the map, or waved southwards. Part of a consequence of being a split city, really. The western bit, someone said, “looks and feels more like a CBD” – that is, big shops, tall towers etc. I did venture to the former western CBD centre, and came across a mile long car show. This area was where the money was.

The other group was sent to walk around the area according to the Game of Life algorithm, Left left Right where you walk and take the first left, then the second left, then the next right, and so on. It’s impossible to predict where you will end up. I joined this group. We had a good explore over a small area, really, but encountering a lot of different environments. Shared (private) gardens / courtyards in the middle of apartment blocks, churches, cafes, and shops.

The fourth team were given a secret mission, and so I cannot reveal to you what they did. However, they are all in good health, and saw the city in a new light.

Photo by Chris Fleming

Back to the unconference, and some of the highlights were:

* Playing the Skobbler game, treasure hunting for addresses in the neighbourhood.

* Seeing offmaps evolve over the year. I’ve not got an iPhone, but that app looked very nice.

* Spatial databases, and in particular CouchDb – and their spatial bits

* CASA did a few talks – I’m getting more and more fond of their work – if anything they really seem to love the stuff they are doing – they share the same vision as me as giving GI tools and benefits to as many people as possible.

* Peter Batty wore an ipad t-shirt – and gave a great presentation about essentially putting utilities information onto a Gmaps like interface and mobile map.

* Gary Gale gave a compelling reason for standardizing place. And it makes sense.

* Meeting the NomadLabs guys for the first time, and being able to say “Thank You” for their work on Ruby on Rails GIS Hacks that I found very useful 4 years ago!

* Corridor talk, beer and food