From 23f22db20c725d6bb79db1d43d1ddd81c8a1d73b Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Sun, 9 Dec 2012 12:03:46 +0000 Subject: Add ability to display catchment areas Still a bit broken in some places... --- resources/leaflet | 2 +- resources/map.js | 62 +++++++++++++++++++++++++++++++++++++++- resources/op2geojson.js | 75 ++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 127 insertions(+), 12 deletions(-) (limited to 'resources') diff --git a/resources/leaflet b/resources/leaflet index 8d4d347..88dac5d 160000 --- a/resources/leaflet +++ b/resources/leaflet @@ -1 +1 @@ -Subproject commit 8d4d347ec942bf3e1bf0b28ce2d697ca2d9dbd30 +Subproject commit 88dac5d77c2780930dff4546d08d3bc873471c1f diff --git a/resources/map.js b/resources/map.js index 6077643..3cd271b 100644 --- a/resources/map.js +++ b/resources/map.js @@ -33,7 +33,7 @@ $(document).ready(function() { var map = L.map( 'map', { zoom: 12, layers: [self.tileLayer], - }).setView([51.505, -0.09], 13); + }).setView([12.4822, -11.9463], 11); // TODO: Not sure why the above call to setView is needed GlobalMap = map; @@ -50,6 +50,7 @@ $(document).ready(function() { "(node[amenity=hospital]("+ bbox +");way[amenity=hospital]("+ bbox +");node(w););" + "(node[amenity=doctors]("+ bbox +");way[amenity=doctors]("+ bbox +");node(w););" + "(node[amenity=dentist]("+ bbox +");way[amenity=dentist]("+ bbox +");node(w););" + + "(node(" + bbox + ");relation[type=boundary][boundary=catchment_area];way(r);node(w););" + ");out;"; } @@ -100,16 +101,75 @@ $(document).ready(function() { map.addLayer(self.amenityLayers[amenity]); self.layersControl.addOverlay(self.amenityLayers[amenity], self.amenities[i]); }); + + // Now deal with the catchment areas + self.catchmentAreaLayer = L.geoJson(data, { + style: function(feature) { + return {fillColor: 'red', + weight: 2, + opacity: 1, + color: 'white', + dashArray: '3', + fillOpacity: 0.7}; + }, + onEachFeature: function(feature, layer) { + layer.on({ + mouseover: highlightFeature, + mouseout: resetHighlight, + click: zoomToFeature + }); + /*var center; + if (feature.geometry.type === "Point") { + center = feature.geometry.coordinates; + } else { + center = feature.geometry.coordinates[0]; + } + + layer.bindPopup(self.popupTemplate({ properties: feature.properties, coordinate: center }));*/ + }, + filter: function(feature, layer) { + return _.contains(_.values(feature.properties), "catchment_area"); + } + }); + map.addLayer(self.catchmentAreaLayer); + self.layersControl.addOverlay(self.catchmentAreaLayer, "Catchment Areas"); } else { _.each(self.amenities, function(amenity, i) { // Update the data for each amenity layer self.amenityLayers[amenity].clearLayers(); self.amenityLayers[amenity].addData(data); }); + + self.catchmentAreaLayer.clearLayers(); + self.catchmentAreaLayer.addData(data); } }); }) + function highlightFeature(e) { + var layer = e.target; + + layer.setStyle({ + weight: 5, + color: '#666', + dashArray: '', + fillOpacity: 0.7 + }); + + if (!L.Browser.ie && !L.Browser.opera) { + layer.bringToFront(); + } + } + + function resetHighlight(e) { + var geojsonLayer = self.catchmentAreaLayer; + self.catchmentAreaLayer.resetStyle(e.target); + } + + function zoomToFeature(e) { + map.fitBounds(e.target.getBounds()); + } + function onLocationFound(e) { self.currentLocation = e.latlng; var radius = e.accuracy / 2; diff --git a/resources/op2geojson.js b/resources/op2geojson.js index 4e4de16..cff2dea 100644 --- a/resources/op2geojson.js +++ b/resources/op2geojson.js @@ -8,24 +8,45 @@ op2geojson = function() { instance.fetch = function(url, data, callback) { $.post(url, data, function(data) { - // List all of the returned nodes - var nodes = []; + // Add nodes and ways to the layer + var features = []; + + // Process the data + var nodes = {}; + var ways = {}; + var relations = {}; $.each(data.elements, function(i, item) { if (item.type === 'node') { nodes[item.id] = item; - } - }); - // Add nodes and ways to the layer - var features = []; - $.each(data.elements, function(i, item) { - if( item.type === 'node' && item.tags != undefined + // As the nodes do not relate to other bits, + // they can be added here + if (item.type === 'node' + && item.tags != undefined && item.tags['amenity'] != undefined) { - features.push( instance.point(item) ); + + features.push( instance.point(item) ); + } } else if (item.type === 'way') { - features.push( instance.lineString(item, nodes) ); + ways[item.id] = item; + } else if (item.type === 'relation') { + relations[item.id] = item; } }); + + $.each(ways, function(i, way) { + features.push( instance.lineString(way, nodes) ); + }); + + $.each(relations, function(i, relation) { + if (relation.tags != undefined && + relation.tags['type'] == 'boundary' && + relation.tags['boundary'] == 'catchment_area') { + + features.push( instance.polygon(relation, ways, nodes) ); + } + }); + geojson = instance.featureCollection(features); callback(geojson); } @@ -76,6 +97,40 @@ op2geojson = function() { return collection; } + instance.polygon = function(relation, ways, nodes) { + polyCoordinates = []; + + $.each(relation.members, function(i, member) { + if (member.role == "outer") { + var way = ways[member.ref]; + var wayCoordinates = instance.lineString(way, nodes).geometry.coordinates; + if (polyCoordinates.length != 0) { + // If this way is backward + if (polyCoordinates[polyCoordinates.length - 1][0] != wayCoordinates[0][0] || + polyCoordinates[polyCoordinates.length - 1][1] != wayCoordinates[0][1]) { + wayCoordinates.reverse(); + } + } + polyCoordinates.shift(); + polyCoordinates = polyCoordinates.concat( wayCoordinates ); + } + }); + + var poly = { + "type" : "Feature", + "geometry" : { + "type" : "Polygon", + "coordinates" : [polyCoordinates] + }, + "properties" : {} + }; + + // Add the tags + _.extend(poly.properties, relation.tags); + + return poly; + } + return instance; }; -- cgit v1.2.3