Basic example of taking an output from our server and putting it on a map. As leaflet allows you to add geoJSON directly, we convert it from esri's JSON format to a more standard one.
Created
July 20, 2012 11:50
-
-
Save calvinmetcalf/3150329 to your computer and use it in GitHub Desktop.
Using ESRI JSON in Leaflet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset='utf-8'/> | |
<style> | |
html { height: 100% } | |
body { height: 100%; margin: 0; padding: 0;} | |
#map{ height: 100% } | |
</style> | |
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.3.1/leaflet.css" /> | |
<!--[if lte IE 8]> | |
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.3.1/leaflet.ie.css" /> | |
<![endif]--> | |
<script src="http://cdn.leafletjs.com/leaflet-0.3.1/leaflet.js"></script> | |
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> | |
<title> | |
Cameras | |
</title> | |
</head> | |
<body> | |
<div id="map"></div> | |
<script type="text/javascript" src="toGeoJSON.js"></script> | |
<script type="text/javascript" src="script.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//set the options | |
var center = new L.LatLng(42.3584308,-71.0597732); | |
var zoom = 8; | |
var url= "http://{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png"; | |
var options={ | |
subdomains:["otile1","otile2",/*"otile3",*/"otile4"],//we'd usually use all 4 but something is up with #3 at the moment | |
attribution:"Tiles Courtesy of <a href='http://www.mapquest.com/' target='_blank'>MapQuest</a> <img src='http://developer.mapquest.com/content/osm/mq_logo.png'>" | |
}; | |
//create the tiles | |
var tiles = new L.TileLayer(url,options); | |
//create the map | |
var m = new L.Map('map',{ | |
center:center, | |
zoom:zoom, | |
layers:[tiles] | |
}); | |
var gj = new L.GeoJSON(); | |
//create empty geojson object and add it to the map | |
m.addLayer(gj); | |
//create the popups | |
gj.on("featureparse", function (e) { | |
if (e.properties){ | |
e.layer.bindPopup(makePop(e.properties)); | |
} | |
}); | |
//get the current bounds | |
var bbox=m.getBounds().toBBoxString(); | |
//the url | |
var url = "http://services.massdot.state.ma.us/ArcGIS/rest/services/Assets/SmartCameras/MapServer/0/query?outFields=*&f=json&outSR=4326&inSR=4326&geometryType=esriGeometryEnvelope&geometry=" | |
//get the features | |
$.get(url+bbox,parseJSONP,"JSONP"); | |
//this is the call back from the jsonp ajax request | |
function parseJSONP(data){ | |
//we call the function to turn it into geoJSON and write a callback to add it to the geojson object | |
toGeoJSON(data, | |
function(d){ | |
gj.addGeoJSON(d) | |
} | |
); | |
} | |
//the function called earlier to make the popup, it goes through all the attributes and makes them into a nice key value list | |
function makePop(p){ | |
var a = []; | |
for(var key in p){ | |
a.push(key+": "+p[key]); | |
} | |
return a.join("<br/>"); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
fork me on github: http://github.com/calvinmetcalf/esri2geo | |
*/ | |
function toGeoJSON(data,cb){ | |
var outPut = { "type": "FeatureCollection", | |
"features": []}; | |
var fl = data.features.length; | |
var i = 0; | |
while(fl>i){ | |
var ft = data.features[i]; | |
/* as only ESRI based products care if all the features are the same type of geometry, check for geometry type at a feature level*/ | |
var outFT = { | |
"type": "Feature", | |
"properties":ft.attributes | |
}; | |
if(ft.geometry.x){ | |
//check if it's a point | |
outFT.geometry=point(ft.geometry); | |
}else if(ft.geometry.points){ | |
//check if it is a multipoint | |
outFT.geometry=points(ft.geometry); | |
}else if(ft.geometry.paths){ | |
//check if a line (or "ARC" in ESRI terms) | |
outFT.geometry=line(ft.geometry); | |
}else if(ft.geometry.rings){ | |
//check if a poly. | |
outFT.geometry=poly(ft.geometry); | |
} | |
outPut.features.push(outFT); | |
i++; | |
} | |
function point(geometry){ | |
//this one is easy | |
return {"type": "Point","coordinates": [geometry.x,geometry.y]}; | |
} | |
function points(geometry){ | |
//checks if the multipoint only has one point, if so exports as point instead | |
if(geometry.points.length===1){ | |
return {"type": "Point","coordinates": geometry.points[0]}; | |
}else{ | |
return { "type": "MultiPoint","coordinates":geometry.points}; | |
} | |
} | |
function line(geometry){ | |
//checks if their are multiple paths or just one | |
if(geometry.paths.length===1){ | |
return {"type": "LineString","coordinates": geometry.paths[0]}; | |
}else{ | |
return { "type": "MultiLineString","coordinates":geometry.paths}; | |
} | |
} | |
function poly(geometry){ | |
//first we check for some easy cases, like if their is only one ring | |
if(geometry.rings.length===1){ | |
return {"type": "Polygon","coordinates": geometry.rings}; | |
}else{ | |
/*if it isn't that easy then we have to start checking ring direction, basically the ring goes clockwise its part of the polygon, if it goes counterclockwise it is a hole in the polygon, but geojson does it by haveing an array with the first element be the polygons and the next elements being holes in it*/ | |
var ccc= dP(geometry.rings); | |
var d = ccc[0]; | |
var dd = ccc[1]; | |
var r=[]; | |
if(dd.length===0){ | |
/*if their are no holes we don't need to worry about this, but do need to stuck each ring inside its own array*/ | |
var l2 = d.length; | |
var i3 = 0; | |
while(l2>i3){ | |
r.push([d[i3]]); | |
} | |
return { "type": "MultiPolygon","coordinates":r}; | |
}else if(d.length===1){ | |
/*if their is only one clockwise ring then we know all holes are in that poly*/ | |
dd.unshift(d[0]); | |
return {"type": "Polygon","coordinates": dd}; | |
}else{ | |
/*if their are multiple rings and holes we have no way of knowing which belong to which without looking at it specially, so just dump the coordinates and add a hole field, this may cause errors*/ | |
return { "type": "MultiPolygon","coordinates":d, "holes":dd}; | |
} | |
} | |
} | |
function dP(a){ | |
//returns an array of 2 arrays, the first being all the clockwise ones, the second counter clockwise | |
var d = []; | |
var dd =[]; | |
var l = a.length; | |
var ii = 0; | |
while(l>ii){ | |
if(c(a[ii])){ | |
d.push(a[ii]); | |
}else{ | |
dd.push(a[ii]); | |
} | |
ii++; | |
} | |
return [d,dd]; | |
} | |
function c(a){ | |
//return true if clockwise | |
var l = a.length-1; | |
var i = 0; | |
var o=0; | |
while(l>i){ | |
o+=(a[i][0]*a[i+1][1]-a[i+1][0]*a[i][1]); | |
i++; | |
} | |
return o<=0; | |
} | |
if(cb){ | |
cb(outPut) | |
}else{ | |
return outPut; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment