12&mobile&map&func5on,&geojson& serversideconnecon ·...
TRANSCRIPT
ITS488 – Geographic Informa5on System
Teerayut Horanont, PhD Sirindhorn Interna5onal Ins5tute of Technology (SIIT) Thammasat University E: [email protected]
12 Mobile map func5on, GeoJSON & Server-‐side Connec5on
2014 11 18
11/18/14 ITS488 1
Today outline
11/18/14 ITS488 2
• Leaflet on mobile • Server side connec5on • Leaflet-‐Postgis • GeoJson
Find your current loca5on
Preparing full-‐screen page
body { padding: 0; margin: 0; } html, body, #map { height: 100%; }
To make our map div element stretch to all available space (fullscreen), we can use the following CSS code:
Preparing full-‐screen page
<meta name="viewport" content="width=device-‐width, ini5al-‐scale=1.0, maximum-‐scale=1.0, user-‐scalable=no" />:
Also, we need to tell the mobile browser to disable unwanted scaling of the page and set it to its actual size by placing the following line in the head sec5on or our HTML page:
Ini5alizing the map
var map = L.map('map'); L.5leLayer('hfp://{s}.5les.mapbox.com/v3/MapID/997/256/{z}/{x}/{y}.png', { afribu5on: 'Map data © <a href="hfp://openstreetmap.org">OpenStreetMap</a> contributors, <a href="hfp://crea5vecommons.org/licenses/by-‐sa/2.0/">CC-‐BY-‐SA</a>, Imagery © <a href="hfp://mapbox.com">Mapbox</a>', maxZoom: 18 }).addTo(map);
Detect the current user loca5on
• Leaflet has a very handy shortcut for zooming the map view to the detected loca5on — locate method with the setView op5on, replacing the usual setView method in the code:
map.locate({setView: true, maxZoom: 16});
Detect the current user loca5on
• Leaflet has a very handy shortcut for zooming the map view to the detected loca5on — locate method with the setView op5on, replacing the usual setView method in the code: func5on onLoca5onFound(e) { var radius = e.accuracy / 2; L.marker(e.latlng).addTo(map) .bindPopup("You are within " + radius + " meters from this point").openPopup(); L.circle(e.latlng, radius).addTo(map); } map.on('loca5onfound', onLoca5onFound);
Detect the current user loca5on
• show an error message if the geoloca5on failed:
func5on onLoca5onError(e) { alert(e.message); } map.on('loca5onerror', onLoca5onError);
How find loca5on work
And then try it again on your mobile phone!!
Try to find your loca5on from your PC
11/18/14 KML Tutorial 11
Ref: hfp://geojson.org/
Introduce to GeoJSON • GeoJSON is an open standard format for encoding collec5ons of simple geographical features along with their non-‐spa5al afributes using JavaScript Object Nota5on.
• The features include points, line strings, polygons, and mul5-‐part collec5ons of these types.
• The GeoJSON format differs from other GIS standards in that it was wrifen and is maintained not by a formal standards organiza5on, but by an Internet working group of developers.
11/18/14 KML Tutorial 12
11/18/14 KML Tutorial 13
Geometry
Geometry
11/18/14 KML Tutorial 14
Mul5part geometries
11/18/14 KML Tutorial 15
Mul5part geometries
11/18/14 KML Tutorial 16
Widely use? Who support • GeoJSON is supported by numerous mapping and GIS
so{ware packages, including OpenLayers, Leaflet, MapServer,Geoforge so{ware, GeoServer, GeoDjango, GDAL, Safe So{ware FME, and CartoDB. It is also possible to use GeoJSON with PostGIS and Mapnik, both of which handle the format via the GDAL OGR conversion library. Bing Maps, Yahoo! and Google also support GeoJSON in their API services.
• The Google Maps Javascript API v3 directly supports the integra5on of GeoJSON data layers as of March 19, 2014.
11/18/14 KML Tutorial 17
Adding GeoJSON to Leaflet
Using GeoJSON with Leaflet • Leaflet supports all of the GeoJSON types above, but Features
and FeatureCollec5ons work best as they allow you to describe features with a set of proper5es. For example:
var geojsonFeature = { "type": "Feature", "proper5es": { "name": "Coors Field", "amenity": "Baseball Stadium", "popupContent": "This is where the Rockies play!" }, "geometry": { "type": "Point", "coordinates": [-‐104.99404, 39.75621] } };
The GeoJSON layer • GeoJSON objects are added to the map through a GeoJSON
layer.
• Alterna5vely, we could create an empty GeoJSON layer and assign it to a variable so that we can add more features to it later.
L.geoJson(geojsonFeature).addTo(map);
var myLayer = L.geoJson().addTo(map); myLayer.addData(geojsonFeature);
Style • The style op5on can
be used to style features two different ways. First, we can pass a simple object that styles all paths (polylines and polygons) the same way:
var myLines = [{ "type": "LineString", "coordinates": [[-‐100, 40], [-‐105, 45], [-‐110, 55]] }, { "type": "LineString", "coordinates": [[-‐105, 40], [-‐110, 45], [-‐115, 55]] }]; var myStyle = { "color": "#ff7800", "weight": 5, "opacity": 0.65 }; L.geoJson(myLines, { style: myStyle }).addTo(map);
Style • Alterna5vely, we can
pass a func5on that styles individual features based on their proper5es. In the example below we check the "party" property and style our polygons accordingly:
var states = [{ "type": "Feature", "proper5es": {"party": "Republican"}, "geometry": { "type": "Polygon", "coordinates": [[ [-‐104.05, 48.99], [-‐97.22, 48.98], [-‐96.58, 45.94], [-‐104.03, 45.94], [-‐104.05, 48.99] ]] } }]; L.geoJson(states, { style: func5on(feature) { switch (feature.proper5es.party) { case 'Republican': return {color: "#ff0000"}; case 'Democrat': return {color: "#0000ff"}; } } }).addTo(map);
pointToLayer • Points are handled differently than polylines and polygons. By
default simple markers are drawn for GeoJSON Points. We can alter this by passing a pointToLayer func5on
var geojsonMarkerOp5ons = { radius: 8, fillColor: "#ff7800", color: "#000", weight: 1, opacity: 1, fillOpacity: 0.8 }; L.geoJson(someGeojsonFeature, { pointToLayer: func5on (feature, latlng) { return L.circleMarker(latlng, geojsonMarkerOp5ons); } }).addTo(map);
onEachFeature • The onEachFeature op5on is a func5on that gets called on
each feature before adding it to a GeoJSON layer. A common reason to use this op5on is to afach a popup to features when they are clicked.
onEachFeature func5on onEachFeature(feature, layer) { // does this feature have a property named popupContent? if (feature.proper5es && feature.proper5es.popupContent) { layer.bindPopup(feature.proper5es.popupContent); } } var geojsonFeature = { "type": "Feature", "proper5es": { "name": "Coors Field", "amenity": "Baseball Stadium", "popupContent": "This is where the Rockies play!" }, "geometry": { "type": "Point", "coordinates": [-‐104.99404, 39.75621] } }; L.geoJson(geojsonFeature, { onEachFeature: onEachFeature }).addTo(map);
filter • The filter op5on can be used
to control the visibility of GeoJSON features.
var someFeatures = [{ "type": "Feature", "proper5es": { "name": "Coors Field", "show_on_map": true }, "geometry": { "type": "Point", "coordinates": [-‐104.99404, 39.75621] } }, { "type": "Feature", "proper5es": { "name": "Busch Field", "show_on_map": false }, "geometry": { "type": "Point", "coordinates": [-‐104.98404, 39.74621] } }];
L.geoJson(someFeatures, { filter: func5on(feature, layer) { return feature.proper5es.show_on_map; } }).addTo(map);
Connect with Server side and Database
Add dynamic objects from database
• Server-‐side script -‐ postgis_geojson.php Server-‐side scrip5ng is a technique used in website design which involves
embedding scripts in an HTML source code which results in a user's (client's) request to the server website being handled by a script running on the server-‐side before the server responds to the client's request.
Server-‐side script
PostGIS
Server-‐side script
if (empty($_GET['geotable'])) { echo "missing required parameter: <i>geotable</i>"; exit; } else $geotable = $_GET['geotable']; if (empty($_GET['geomfield'])) { echo "missing required parameter: <i>geomfield</i>"; exit; } else $geomfield = $_GET['geomfield'];
Retrive URL variables
Server-‐side script
$conn = pg_connect("dbname='test' user='postgres' password='Ai3@2304' host='localhost'"); if (!$conn) { echo "Not connected : " . pg_error(); exit; }
Connect to Database
Next Build SQL SELECT statement and return the geometry as a GeoJSON element
See provided “postgis_geojson.php” for reference
getJSON • Define a map
$.getJSON("hfp://gis.siit.tu.ac.th/lab/postgis_geojson.php?geotable=bldg_jj&geomfield=geom&limit=200", func5on(data) { var geojson = L.geoJson(data, { onEachFeature: func5on (feature, layer) { layer.bindPopup(feature.proper5es.bl_name); } }); var map = L.map('cupcake-‐map').fitBounds(geojson.getBounds()); cupcakeTiles.addTo(map); geojson.addTo(map); });
var cupcakeTiles = L.5leLayer('hfp://a.5les.mapbox.com/v3/lyzidiamond.map-‐ietb6srb/{z}/{x}/{y}.png', { maxZoom: 18 });
Leaflet: Other visuliza5on
• jQuery + Leaflet = powerful map JS lib
What is jQuery • jQuery is a fast, small, and feature-‐rich JavaScript library. • With jQuery, Ajax much simpler with an easy-‐to-‐use API that
works across a mul5tude of browsers.
$(document).ready( createMap ); func5on createMap() { // Code goes here... };
Within the file, we will use jQuery to detect when the web page has loaded before execu5ng our code.
jQuery + Leaflet
• Within the createMap func5on, we will first define some ini5al parameters:
var loc = {'lat': 40.754531, 'lon': -‐73.993113}, zoomLevel = 3, maxZoom = 15, mapID = 'map';
jQuery + Leaflet
• We next use Leaflet to create a new map object in which we set the current view to a specified loca5on.
var map = L.map('map').setView( [loc.lat, loc.lon], zoomLevel );
jQuery + Leaflet
• Use leaflet add Open Street Maps (OSM) layer.
L.5leLayer('hfp://{s}.5le.osm.org/{z}/{x}/{y}.png', { 'maxZoom': maxZoom, 'afribu5on': 'Map data © OpenStreetMap, under CC BY SA' }).addTo(map);
Then test load your map!
Try something beau5ful
var watercolor = new L.StamenTileLayer("watercolor") .addTo(map);
• A Stamen Design is a design and technology studio who provide various style layers for use with mapping libraries.
<script src="hfp://maps.stamen.com/js/5le.stamen.js?v1.2.1"></script>
First add:
Then:
Again, try to load data from server side and build your own map with
different style map. • Toner
• watercolor
watercolor
toner
Ques5on?
• Mini project discussion