Last active
August 29, 2015 14:27
-
-
Save mapsense-examples/9a63fed6a923aaf9d208 to your computer and use it in GitHub Desktop.
Drag & drop geojson to map
This file contains hidden or 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
// Hat tip Mike Bostock: https://github.com/mbostock/polymaps/blob/master/examples/bounds/bounds.js | |
function bounds(features) { | |
var i = -1, | |
n = features.length, | |
geometry, | |
bounds = [{lon: Infinity, lat: Infinity}, {lon: -Infinity, lat: -Infinity}]; | |
while (++i < n) { | |
//geometry = features[i].data.geometry; | |
geometry = features[i].geometry; | |
boundGeometry[geometry.type](bounds, geometry.coordinates); | |
} | |
return bounds; | |
} | |
function boundPoint(bounds, coordinate) { | |
var x = coordinate[0], y = coordinate[1]; | |
if (x < bounds[0].lon) bounds[0].lon = x; | |
if (x > bounds[1].lon) bounds[1].lon = x; | |
if (y < bounds[0].lat) bounds[0].lat = y; | |
if (y > bounds[1].lat) bounds[1].lat = y; | |
} | |
function boundPoints(bounds, coordinates) { | |
var i = -1, n = coordinates.length; | |
while (++i < n) boundPoint(bounds, coordinates[i]); | |
} | |
function boundMultiPoints(bounds, coordinates) { | |
var i = -1, n = coordinates.length; | |
while (++i < n) boundPoints(bounds, coordinates[i]); | |
} | |
var boundGeometry = { | |
Point: boundPoint, | |
MultiPoint: boundPoints, | |
LineString: boundPoints, | |
MultiLineString: boundMultiPoints, | |
Polygon: function(bounds, coordinates) { | |
boundPoints(bounds, coordinates[0]); // exterior ring | |
}, | |
MultiPolygon: function(bounds, coordinates) { | |
var i = -1, n = coordinates.length; | |
while (++i < n) boundPoints(bounds, coordinates[i][0]); | |
} | |
}; |
This file contains hidden or 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
document.addEventListener("DOMContentLoaded", function(event) { | |
var dropzone = document.querySelector('#myMap'); | |
var dragzone = document.querySelector('#myMap'); | |
var filelist; | |
dropzone.addEventListener('drop', function(event) { | |
if (event.preventDefault) { | |
event.preventDefault(); | |
} | |
var types = event.dataTransfer.types; | |
filelist = event.dataTransfer.files; | |
var file = event.dataTransfer.files[0]; | |
/*if (file.type !== 'application/json') { | |
alert('Uploaded file must be a compliant JSON file'); | |
return false; | |
}*/ | |
// Init file reader | |
var fileReader = new FileReader(); | |
fileReader.onload = function (e) { | |
processGJ(JSON.parse(fileReader.result)); | |
}; | |
fileReader.onerror = function (e) { | |
throw 'Error reading JSON file'; | |
}; | |
// Start reading file | |
fileReader.readAsText(file); | |
return false; | |
}, false); | |
dragzone.addEventListener('dragstart', function(event) { | |
return true; | |
}, true); | |
dragzone.addEventListener('dragend', function(event) { | |
return true; | |
}, true); | |
dropzone.addEventListener('dragenter', function(event) { | |
if (event.preventDefault) event.preventDefault(); | |
return false; | |
}, false); | |
dropzone.addEventListener('dragover', function(event) { | |
if (event.preventDefault) event.preventDefault(); // allows us to drop | |
}, false); | |
dropzone.addEventListener('dragleave', function(event) { | |
if (event.preventDefault) event.preventDefault(); // allows us to drop | |
return false; | |
}, false); | |
}); |
This file contains hidden or 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> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<script src="http://d3js.org/topojson.v1.min.js" charset="utf-8"></script> | |
<script src="https://developer.mapsense.co/mapsense.js" charset="utf-8"></script> | |
<link type="text/css" href="https://developer.mapsense.co/mapsense.css" rel="stylesheet"/> | |
<link rel="stylesheet" href="https://developer.mapsense.co/stylesheets/bootstrap.min.css" media="screen" type="text/css"> | |
<link rel="stylesheet" href="local.css" media="screen" type="text/css"> | |
<style> | |
</style> | |
</head> | |
<body> | |
<div id="myMap"></div> | |
<div class="lede"> | |
<!-- <div class="lede"> --> | |
<p>Have geojson? | |
<br/>Drag it onto the map!</p> | |
<p class="faint">No geojson file handy? <a href="polygons_countries.geojson">Sample here.</a></p> | |
</div> | |
<div id="info"></div> | |
<!-- Modal --> | |
<div id="fieldModal" class="modal fade"> | |
<div class="modal-dialog"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | |
<h4 class="modal-title">Pick fields</h4> | |
</div> | |
<div id="pickfields" class="modal-body"> | |
</div> | |
<div class="modal-footer"> | |
<button type="button" class="btn" data-dismiss="modal">Close</button> | |
<button type="button" class="btn" id="fields_picked">Map!</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- /Modal --> | |
<script src='http://code.jquery.com/jquery-1.11.0.min.js' type="text/javascript"></script> | |
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js' type="text/javascript"></script> | |
<script src='dragdrop_geojson.js' type="text/javascript"></script> | |
<script src='bounds.js' type="text/javascript"></script> | |
<script> | |
var my_key = "key-2d5eacd8b924489c8ed5e8418bd883bc"; | |
var home = [{ | |
lon: -130, | |
lat: 20 | |
}, { | |
lon: -60, | |
lat: 55 | |
}]; | |
var map = mapsense.map("#myMap"); //tell it where to go | |
map.add( | |
mapsense.basemap() | |
.apiKey(my_key) | |
.style("sketch") | |
) | |
.extent(home); | |
var GJ_LAYER; | |
// Add custom attribution | |
var attribution = mapsense.attribution('<a target="_blank" href="https://developer.mapsense.co/tileViewer/?tileset=mapsense.earth">©Mapsense ©OpenStreetMap</a>'); | |
attribution.map(map); | |
// Process GJ | |
var processGJ = function(GJData) { | |
GJ_LAYER = mapsense.geoJson() | |
.features(GJData.features) | |
.selection(selection_function); | |
map.add(GJ_LAYER); | |
//.on("load", zoomBounds) | |
zoomBounds(GJData); | |
} | |
function zoomBounds(e) { | |
map.extent(bounds(e.features)).zoomBy(-0.1); | |
} | |
var tooltip = d3.select('body') | |
.append("div") | |
.attr("class", "popup"); | |
function isFloat(n) { | |
var r = Number(n) && n % 1 !== 0; | |
return r; | |
} | |
var selection_function = (function() { | |
var whitelist = []; | |
var id_field = 'gid'; | |
//whitelist = ['population','female','male','hhi','layer','poverty','unemployment','uninsured','postal_code']; | |
/* The id of the previously hovered-over feature. */ | |
var hoverId = null; | |
return function(s) { | |
s.attr("r", function(d) { | |
return d.properties.radius || 10; | |
}) | |
.attr("class", function(d) { | |
var classes = ["mapFeatures"], | |
props = d.properties; | |
if (props) { | |
if (props.layer) classes.push(props.layer); | |
if (props.sub_layer) classes.push(props.sub_layer); | |
} | |
if (d.properties[id_field] !== null && hoverId !== null && d.properties[id_field] == hoverId) { | |
console.log(d.properties[id_field], hoverId); | |
classes.push("hoverFeature"); | |
} | |
return classes.join(' '); | |
}) | |
.on("mouseover", function(d) { | |
console.log(d); | |
//if ( d.properties.minz >= 5 ) { | |
d3.select(this).classed("selected", true); | |
//} | |
var text = ""; | |
var value; | |
text += '<div class="detailCard"><table><tbody>'; | |
if (whitelist.length > 0) { | |
for (var i = 0; i < whitelist.length; i++) { | |
key = whitelist[i]; | |
if (d.properties && d.properties[key]) { | |
value = d.properties[key]; | |
value = isFloat(value) ? value.toFixed(4) : value; | |
text += '<tr><td class="detailKey">' + key + '</td><td class="detailVal">' + value + '</td></tr>'; | |
} | |
} | |
} else { | |
for (var key in d.properties) { | |
text += '<tr><td class="detailKey">' + key + '</td><td class="detailVal">' + d.properties[key] + '</td></tr>'; | |
} | |
} | |
tooltip.html(text); | |
d3.select('#info').html(text); | |
if (d.properties[id_field] !== hoverId) { | |
hoverId = d.properties[id_field]; | |
GJ_LAYER.selection(selection_function); | |
} | |
//return tooltip.style("visibility", "visible"); | |
}) | |
.on("mousemove", function() { | |
//return tooltip.style("top", (d3.event.pageY - 0) + "px").style("left", (d3.event.pageX + 20) + "px"); | |
}) | |
.on("mouseout", function(d) { | |
d3.select(this).classed("selected", false); | |
return tooltip.style("visibility", "hidden"); | |
}); | |
}; | |
})(); | |
</script> | |
</body> | |
</html> |
This file contains hidden or 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
html, body, #myMap{ | |
height: 100%; | |
width: 100%; | |
margin: 0; padding: 0; | |
font-family: sans-serif; | |
overflow: hidden; | |
} | |
#myMap { | |
position: absolute; | |
top: 0; right: 0; bottom: 0; left: 0; | |
} | |
circle { | |
fill: rgba(68, 167, 228, 0.5); /*blue*/ | |
stroke: none; | |
} | |
.faint { color: #555; } | |
.top-left { | |
position: absolute; | |
top: 5px; | |
left: 5px; | |
} | |
.btn { | |
background-color: rgba(255,255,255,0.8); | |
outline: 1px solid rgba(0,0,0,0.3); | |
min-width: 60px; | |
padding: 2px 4px; | |
margin: 2px; | |
display: inline-block; | |
} | |
.csv_point, | |
circle { | |
fill: rgba(152, 78, 163, 0.2); | |
stroke: rgba(152, 78, 163, 1); | |
stroke-width: 1; | |
} | |
.modal-dialog { | |
width: 400px; | |
text-align: center; | |
font-size: 20px; | |
} | |
.modal-body { | |
margin: 0 auto; | |
text-align: right; | |
width: 270px; | |
} | |
.lede { | |
position: absolute; | |
top: 0; | |
left: 0; | |
padding: 5px 10px; | |
background: rgba(255,255,255,0.5); | |
width: 100%; | |
} | |
.mapsense-attribution { | |
/* adjusted for less contrast */ | |
background-color: rgba(255, 255, 255, 0.5); | |
color: #777; | |
position: absolute; | |
bottom: 0; | |
right: 0; | |
font-size: 12px; | |
font-family: sans-serif; | |
padding: 2px; | |
line-height: 1.2em; | |
text-decoration: none; | |
user-select: none; | |
cursor: default; | |
} | |
.mapsense-attribution a { | |
text-decoration: none; | |
color: #777; | |
} | |
.mapsense-attribution a:hover { | |
text-decoration: none; | |
color: #444; | |
} | |
.hoverFeature { | |
stroke-width: 2; | |
} | |
.popup { | |
position: absolute; | |
font-family: sans-serif; | |
font-size: 11px; | |
color: #666; | |
visibility: hidden; | |
border-radius: 3px; | |
pointer-events: none; | |
border: 1px solid #bbb; | |
padding: 8px; | |
background-color: rgba(255, 255, 255, .95); | |
max-height: 500px; | |
overflow: normal; | |
} | |
table { | |
border-collapse: collapse; | |
} | |
table, th, td { | |
font-size: 12px; | |
border: 1px solid #ddd; | |
padding: 1px; | |
} | |
.detailKey { | |
background: #eee; | |
opacity: .8; | |
text-transform: uppercase; | |
font-weight: 600; | |
} | |
.detailVal { | |
background: rgba(255,255,255,0.8); | |
} | |
.mapFeatures { | |
vector-effect: non-scaling-stroke; | |
stroke-linejoin: round; | |
stroke-linecap: round; | |
stroke: orange; | |
fill: rgba(0,0,0,0); | |
} | |
#info { | |
position: absolute; | |
bottom: 0px; | |
right: 0px; | |
max-width: 300px; | |
border: 1px solid #ccc; | |
overflow: scroll; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment