Map Widget Maker

Brian Timoney’s post How the Public Actually Uses Local Government Web Maps: Metrics from Denver really got me thinking about things I could be doing differently with web maps. One of them was creating easily embedded, single-topic web maps, which will go great with our newly redesigned open data portal, should that actually happen (damn you giant-pile-of-crap-on-my-desk). You can view the prototype here or check out the code on Github. It isn’t done, but it (mostly) works and since I’ll be sitting on it for a while I figured I’d go ahead and release the code in case anybody finds it useful. It’s using Leaflet and Twitter Bootstrap.

Yes, I picked that title font. Yes, I kind of regret it now.

Basically it creates iframe embed code for a map, ala YouTube video embeds. You give it a config.json file like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"basemaps":
{
"osm": {
"title": "Open Street Map",
"url": "http://tile.openstreetmap.org/{z}/{x}/{y}.png",
"options": { "attribution": "Open Street Map"}
},
"mecklenburg": {
"title": "Mecklenburg County GIS",
"url" : "http://maps.co.mecklenburg.nc.us/mbtiles/mbtiles-server.php?db=meckbase.mbtiles&z={z}&x={x}&y={y}",
"options": { "attribution": "Mecklenburg County GIS"}
}
},
"wmsurl": "http://maps.co.mecklenburg.nc.us/geoserver/wms",
"wmsnamespace": "postgis",
"wmsfilter": "postgis:",
"attribution": "Mecklenburg County GIS",
"defaultlayer": "",
"center": [35.270, -80.837],
"zoom": 9,
"search": false
}

You’re giving it some options for base maps (tiled zxy stuff). Then you’re giving it a WMS server to connect to and a few other options like attribution and default map center/zoom. Pretty straight-forward. Then your users can make their iframe embed code and plop it on their page in a quick and easy 3-step process. Ideally your WMS layer info is better than mine so you’ll get clean WMS layer names and info instead of “Generated from postgis”, though we both know it isn’t.

The really cool part? The widget map builder builds the map widget you see in the widget map builder with the widget map builder. It’s recursive! Hah! Er…hah? Guess you had to be there.

Caveat emptor:

  • There were two ways to go here: iframe or javascript widget. I went iframe. They're sandboxed, avoid javascript collisions, offer greater security and privacy for the host, and are generally easier for people to actually use/embed. You don't get CSS inheritance from the parent, which isn't a problem with an embedded map, and parent/child communication is possible via window.postMessage.
  • There is a tiny amount of server-side code - wmsproxy.php. Without a proxy any client-side GetFeatureInfo/GetCapabilities will smack face-first into a cross domain security violation. But it's very simple code to replicate in Ruby/Python/.NET if PHP isn't your thing.
  • It assumes the One True Projection. You could probably hack it to take your favorite local projection should you be possessed by that (bad) idea.
  • No search box yet. That'll be custom code though - everybody will be doing that differently.
  • The overlays are only WMS image - no GeoJSON etc. yet.
  • There are some odd styling/alignment issues on Firefox with the form elements. It's my first foray into Twitter Bootstrap (like), and I'm probably doing it wrong (don't like). I haven't even looked at it in IE yet.

Edit: Gads! I forgot to give credit where credit is due - Bryan McBride’s GetFeatureInfo Leaflet example was a big help in getting the identify function working.