Permalink
Browse files

Initial commit of working map client/server.

  • Loading branch information...
0 parents commit 3c930ac89d965c1c882ad67495f9ca1511d55eb1 @talltom committed Nov 25, 2012
Showing with 204 additions and 0 deletions.
  1. +50 −0 get_geojson.py
  2. +40 −0 getdata.py
  3. +114 −0 map.htm
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+
+# get_geojson.py - CGI script to get UKMap building geom/heights from PostGIS and return as GeoJson strings.
+# Tested with lighttpd.
+
+# Note: this is just a test script, it would be more efficient to implement this in a real web framework (i.e. GeoDjango) in WSGI format.
+
+# Copyright Tom Holderness 2012.
+# Released under BSD license (see LICENSE.txt)
+# https://github.com/talltom/
+
+__author__='Tom Holderness'
+__year__='2012'
+__version__ = "0.1"
+
+import cgi
+import cgitb; cgitb.enable() # for troubleshooting
+import json
+import psycopg2
+
+# Get bbox coords from URL query, with a little minimal error checking
+fs = cgi.FieldStorage()
+if 'bbox_wkt' not in fs:
+ print "Content-type: text/html"
+ print
+ print "<h1>Error</h1>"
+ print "bbox_wkt was not found in URL query string."
+else:
+ bbox_wkt = fs['bbox_wkt'].value
+
+# Database connection
+conn = psycopg2.connect("dbname=ukmap_london user=postgres password=postgres")
+
+# Database cursor
+cur = conn.cursor()
+
+# Query
+cur.execute('SELECT row_to_json(fc) FROM ( SELECT \'FeatureCollection\' As type, array_to_json(array_agg(f)) As features FROM (SELECT \'Feature\' As type, ST_AsGeoJSON(ST_Transform(lg.the_geom,4326))::json As geometry, row_to_json((SELECT l FROM (SELECT height) As l)) As properties FROM "3DLondon" As lg WHERE ST_Within(lg.the_geom, ST_Transform(ST_GeomFromText(%s,4326),27700)) LIMIT 100000 ) As f ) As fc;',[bbox_wkt])
+array = cur.fetchall()
+
+# Return data as GeoJSON
+print "Content-type: application/json\n"
+# Format JSON data
+jsondata = json.dumps(array[0])
+# Hack to remove Ptthon list brackets
+jsondata = jsondata[2:-2]
+# Remove escaped strings
+jsondata = jsondata.replace("\\","")
+# Print the data
+print jsondata
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+#http://mail.python.org/pipermail/tutor/2002-September/017255.html
+
+import cgi
+import cgitb; cgitb.enable() # for troubleshooting
+import json
+import psycopg2
+
+# Get bbox coords from URL query
+fs = cgi.FieldStorage()
+if 'bbox_wkt' not in fs:
+ print "Content-type: text/html"
+ print
+ print "<h1>Error</h1>"
+ print "bbox_wkt was not found in URL query string."
+else:
+ bbox_wkt = fs['bbox_wkt'].value
+
+# Database connection
+conn = psycopg2.connect("dbname=ukmap_london user=postgres password=postgres")
+
+# Database cursor
+cur = conn.cursor()
+
+# Query
+#cur.execute('SELECT row_to_json(fc) FROM ( SELECT \'FeatureCollection\' As type, array_to_json(array_agg(f)) As features FROM (SELECT \'Feature\' As type, ST_AsGeoJSON(ST_Transform(lg.the_geom,4326))::json As geometry, row_to_json((SELECT l FROM (SELECT height, "wallColor") As l)) As properties FROM "3DLondon" As lg WHERE ST_Within(lg.the_geom, ST_Transform(ST_GeomFromText(%s,4326),3857)) LIMIT 100000 ) As f ) As fc;',[bbox_wkt])
+cur.execute('SELECT row_to_json(fc) FROM ( SELECT \'FeatureCollection\' As type, array_to_json(array_agg(f)) As features FROM (SELECT \'Feature\' As type, ST_AsGeoJSON(ST_Transform(lg.the_geom,4326))::json As geometry, row_to_json((SELECT l FROM (SELECT height) As l)) As properties FROM "3DLondon" As lg WHERE ST_Within(lg.the_geom, ST_Transform(ST_GeomFromText(%s,4326),3857)) LIMIT 100000 ) As f ) As fc;',[bbox_wkt])
+array = cur.fetchall()
+
+# Return data as GeoJSON
+print "Content-type: application/json\n"
+#print 'callback(%s);' % (json.dumps(array[0]))
+jsondata = json.dumps(array[0])
+jsondata = jsondata[2:-2]
+jsondata = jsondata.replace("\\","")
+#print 'callback(' + jsondata + ');'
+
+print jsondata
+#print 'callback(%s);' % (jsondata)
114 map.htm
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>3DLondon</title>
+ <meta name="description" content="3D visualisations of buildings in London using UKMap data with leaflet and OSM Buildings.">
+ <meta name="author" content="Tom Holderness">
+ <meta name="version" content="0.1">
+
+ <!--JQuery library to handle JSON requests-->
+ <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
+ <!--JQuery extension to handle JSON requests using AJAX post request-->
+ <!--Credit to: http://forum.jquery.com/topic/getjson-using-post -->
+ <script>
+ jQuery.extend({
+ postJSON: function( url, data, callback) {
+ return jQuery.post(url, data, callback, "json");
+ }
+ });
+ </script>
+
+ <!--Leaflet map library (hosted version)-->
+ <script src="http://cdn.leafletjs.com/leaflet-0.4.5/leaflet.js"></script>
+
+ <!--OSM Buildings library for buildings (forked version to remove OSM attribution for buildings)-->
+ <script src="https://raw.github.com/talltom/osmbuildings/v0.1.7a/dist/L.BuildingsLayer-debug.js"></script>
+
+ <!--Styles and CSS-->
+ <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.5/leaflet.css" />
+ <!--[if lte IE 8]>
+ < link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.5/leaflet.ie.css" />
+ <![endif]-->
+
+ <style>
+ body {
+ padding: 0;
+ margin: 0;
+ }
+ html, body, #map {
+ height: 100%;
+ }
+ </script>
+ </style>
+</head>
+
+<body>
+ <div id="map"></div>
+ <script>
+ //Define functions to get building data
+
+ //Get current map view bounding box coords as WKT
+ function getBBoxWKT(){
+ var mbounds = map.getBounds().toBBoxString().split(',');
+ var bounds_wkt = 'POLYGON(('+mbounds[2]+' '+mbounds[1]+','+mbounds[0]+' '+mbounds[1]+','+mbounds[0]+' '+mbounds[3]+','+mbounds[2]+' '+mbounds[3]+','+mbounds[2]+' '+mbounds[1]+'))';
+ return bounds_wkt;
+ }
+
+
+ //Request data from GeoJson server and add to map
+ function getBuildings(bounds_wkt){
+ jQuery.postJSON('/3DLondon/getdata.py?bbox_wkt='+bounds_wkt, function(data){
+ build
+ .addTo(map)
+ .setStyle({ wallColor: 'rgb(200,190,180)', roofColor: 'null', strokeRoofs: true })
+ .geoJSON(data)
+ ;
+ });
+ };
+
+ //Create map, with center coordinates for St Paul's Cathedral-->
+ var latlon = new L.LatLng(51.513611, -0.098056);
+ var map = L.map('map').setView(latlon, 18);
+
+ //Canada Square (Canary Wharf)
+ //var latlon = new L.LatLng(51.505, -0.018589);
+
+ //Render London (may crash!)
+ //var latlon = new L.LatLng(51.505, -0.118589);
+ //var map = L.map('map').setView(latlon, 13);
+
+ //Add attribution
+ map.attributionControl.setPrefix('<a href="http://tomholderness.wordpress.com" target="_blank">3DLondon Map</a> | 3D Building data &copy the <a href="http://www.geoinformationgroup.co.uk/products/ukmap" target=_blank">GeoInformation Group</a> provided by <a href="http://www.landmap.ac.uk/" target="_blank">Landmap</a> | Basemap &copy <a href="http://www.openstreetmap.org/" target="_blank">OpenStreetMap</a> <a href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank">CC-BY-SA</a> & <a href="http://cloudmade.com/" target="_blank">Cloudmade</a>');
+
+ //Add a basemap using OSM data with Cloudmade styling
+ var basemap = new L.tileLayer('http://{s}.tile.cloudmade.com/deedc5cf90ae407885ec4a8678c85e0a/78326/256/{z}/{x}/{y}.png');
+ map.addLayer(basemap);
+
+ //Add scale bar to map
+ L.control.scale().addTo(map);
+
+ // Create a buildings layer instance
+ var build = new L.BuildingsLayer();
+ //map.removeLayer(build);
+
+ //Call get bounds and get buildings on page load
+ getBuildings(getBBoxWKT());
+
+ //Listen for map pan events and get new buildings data
+ map.on('moveend', function(e) {
+ getBuildings(getBBoxWKT());
+ });
+
+ //Listen for map zoom events and get new building data
+ var czoom = map.getZoom();
+ map.on('zoomend', function(e){
+ //If zoom out, get new data
+ if (map.getZoom() > czoom)
+ {
+ getBuildings(getBBoxWKT());
+ }
+ czoom = map.getZoom();
+ });
+
+</script>
+</body>

0 comments on commit 3c930ac

Please sign in to comment.