Last active
August 29, 2015 14:23
-
-
Save jhnklly/3ae6800eb8897fd2e359 to your computer and use it in GitHub Desktop.
osm2
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
html, body, #myMap { | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
overflow: hidden; | |
font: 11px 'Droid Sans', sans-serif; | |
color: #666; | |
} | |
* { box-sizing: border-box } | |
.ms { | |
stroke-width: 1; | |
stroke: #ccc; | |
stroke-opacity: 0.8; | |
fill-opacity: 0.5; | |
mix-blend-mode: multiply; | |
/* | |
*/ | |
} | |
circle { | |
vector-effect: non-scaling-stroke; | |
} | |
.A { | |
stroke: cyan; | |
fill: cyan; | |
/* | |
stroke-width: 0; | |
*/ | |
} | |
.B { | |
stroke: magenta; | |
fill: magenta; | |
/* | |
stroke-width: 0; | |
*/ | |
} | |
a.button { | |
display: inline-block; | |
padding: 5px 10px; | |
border: 2px solid #777; | |
font: 16px bold 'Droid Sans', sans-serif; | |
line-height: 37px; | |
color: #777; | |
height: 50px; | |
min-width: 50px; | |
vertical-align: top; | |
margin-left: 4px; | |
text-align: center; | |
cursor: pointer; | |
} | |
a.button:hover { | |
border: 2px solid #000; | |
color: #000; | |
} | |
input { | |
border: 0s; | |
font: 16px 'Droid Sans', sans-serif; | |
} | |
input:focus { | |
outline-offset: 0px; | |
} | |
#refresh { margin-top: 5px;} | |
#selector_a { | |
outline: 13px solid rgba(0,255,255,0.6); | |
mix-blend-mode: multiply; | |
margin: 13px; | |
} | |
#selector_b { | |
outline: 13px solid rgba(255,0,255,0.6); | |
mix-blend-mode: multiply; | |
margin: 13px; | |
margin-left: 0px; | |
} | |
#ui { | |
position: absolute; | |
z-index: 99; | |
margin: 0; | |
top: 0; | |
left: 0; | |
clear: both; | |
} | |
#selector { | |
font: 20px 'Droid Sans', sans-serif; | |
} | |
#legend { | |
background: rgba(255,255,255,0.8); | |
overflow: auto; | |
display: inline-block; | |
} | |
#color-chips, #color-values { | |
float: left; | |
margin-left: 5px; | |
} | |
#color-values{ | |
white-space: pre; | |
padding-right: 5px; | |
} | |
#color-values textarea { | |
overflow:hidden; | |
margin: 0; | |
border: none; | |
resize: none; | |
height: 100%; | |
} | |
.mouseinfo { | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
pointer-events: none; | |
max-width: 300px; | |
/*font: 20px 'Droid Sans', sans-serif;*/ | |
} | |
table { | |
border-collapse: collapse; | |
} | |
table, th, td { | |
border: 1px solid #ddd; | |
padding: 0 2px; | |
} | |
.detailKey { | |
background: #eee; | |
opacity: .8; | |
text-transform: uppercase; | |
font-weight: 600; | |
} | |
.detailVal { | |
background: rgba(255,255,255,0.8); | |
} |
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> | |
<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 type="text/css" href="index.css" rel="stylesheet"/> | |
<style> | |
circle { | |
vector-effect: non-scaling-stroke; | |
/*We leave them unpainted until they match a regex later*/ | |
stroke: none; | |
fill: none; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="myMap"></div> | |
<div id="ui"> | |
<div id="control"></div> | |
<div id="legend"> | |
</div> | |
</div> | |
<script> | |
function getBody() { | |
var doc, body, iframe, src; | |
body = d3.select('body'); | |
if (d3.select('iframe').node()) { | |
iframe = d3.select('iframe').node(); | |
src = d3.select(iframe).attr('src'); | |
if (src.slice(0,22) == '/mapsense-examples/raw') { | |
doc = iframe.contentDocument || iframe.contentWindow.document; | |
body = d3.select(doc).select('body'); | |
} | |
} | |
return body; | |
} | |
function readUrl() { | |
var body = getBody(); | |
var hash = location.hash.substring(1).split('/'); | |
console.log(hash, d3.select(body).node().select('#selector_a').node().value ); | |
d3.select(body).node().select('#selector_a').node().value = hash[0] || G.input_A; | |
d3.select(body).node().select('#selector_b').node().value = hash[1] || G.input_B; | |
} | |
function writeUrl() { | |
var body = getBody(); | |
var new_hash = '#' + d3.select(body).node().select('#selector_a').node().value + | |
'/' + d3.select(body).node().select('#selector_b').node().value; | |
window.location.hash = new_hash; | |
} | |
var G = {}; // A global object to store variables | |
G.key = 'key-2d5eacd8b924489c8ed5e8418bd883bc'; | |
G.simplify = '&ringSpan=10&lineSpan=10&s=10'; | |
G.home = [ // we'll set the map extent to these bounds | |
{lon: -125, lat: -60}, | |
{lon: 160, lat: 75} | |
]; | |
G.basemap = 'sketch'; | |
G.input_A = 'kitten'; | |
G.input_B = 'puppy'; | |
G.samples = [ | |
['kitten','puppy'], | |
['bar','pub'], | |
['soda','pop'], | |
['cafe','caffe'], | |
['church','mosque'], | |
['ice cream','gelato'], | |
['Martin Luther King','Jefferson Davis'], | |
['bicycle','motorcycle'], | |
['east','west'] | |
]; | |
G.samples_i = 0; | |
G.layers = { | |
'base': { 'url': '', 'default': false}, | |
'overlay_a': { | |
'url': 'https://{S}-api.mapsense.co/universes/mapsense.planet_osm_points/{Z}/{X}/{Y}.topojson?api-key=' + G.key, | |
'where': "&where=name=='"+G.input_A+"'", | |
'params': '&density=200', | |
'class': 'A', | |
'default': true | |
}, | |
'overlay_b': { | |
'url': 'https://{S}-api.mapsense.co/universes/mapsense.planet_osm_points/{Z}/{X}/{Y}.topojson?api-key=' + G.key, | |
'where': "&where=name=='"+G.input_B+"'", | |
'params': '&density=200', | |
'class': 'B', | |
'default': true | |
}, | |
'labels': { 'url': '', 'default': false} | |
}; | |
G.selector_options = ['place_of_worship','school','bench','restaurant','fast_food','cafe','bicycle_parking','pub','bar','swimming_pool','university','college']; | |
G.selector_options.sort(); | |
initSelect(); // initialize the selector UI | |
//readUrl(); | |
initMap(); // initialize the map | |
// Add a div to display info mouseover info | |
var mouseinfo = d3.select('body') | |
.append("div") | |
.attr("class","mouseinfo"); | |
function initMap() { | |
var param_selection_function = (function(show_list) { | |
return function(s) { | |
s.attr("r", 3); | |
s.attr("class", function(f){ | |
var classes = ['ms']; | |
classes.push(G.layers['overlay_a']['class']); | |
//var show_list = ['amenity','tourism','name']; | |
var show_list = ['name']; | |
for (var i = 0; i < show_list.length; i++) { | |
if (f.properties && f.properties[show_list[i]]) { | |
classes.push(f.properties[show_list[i]]); | |
var feature_value = f.properties[show_list[i]]; | |
var A_value = d3.select('#selector_a').node().value; | |
var B_value = d3.select('#selector_b').node().value; | |
var A_regex = new RegExp(escapeRegExp(A_value), "gi"); | |
var B_regex = new RegExp(escapeRegExp(B_value), "gi"); | |
// at this point, the line above is the same as: var regex = /#abc#/g; | |
if ( A_regex.test(feature_value) ) { | |
classes.push('A'); | |
} else if ( B_regex.test(feature_value) ) { | |
classes.push('B'); | |
} | |
} | |
}; | |
return classes.join(' '); | |
}) | |
s.on("mouseover", function(d) { // Bind a function to mouseover | |
// This will build a table to display the field names and values | |
var text = ""; | |
var value; | |
var no_list = ['DND_UUID']; | |
text += '<div class="detailCard"><table><tbody>'; | |
if (show_list.length > 0) { // if there's a show_list, only show those fields | |
for (var i = 0; i < show_list.length; i++) { | |
key = show_list[i]; | |
if (d.properties && d.properties[key]) { | |
value = d.properties[key]; | |
value = formatValue(value); | |
text += '<tr><td class="detailKey">' + key + '</td><td class="detailVal">' + value + '</td></tr>'; | |
} | |
} | |
} else { // if no show_list, show all fields | |
for (var key in d.properties) { | |
// except if it's in the no_list | |
if ( no_list.indexOf(key.toUpperCase()) == -1 ) { | |
text += '<tr><td class="detailKey">' + key + '</td><td class="detailVal">' + d.properties[key] + '</td></tr>'; | |
} | |
} | |
} | |
mouseinfo.html(text); // Update the mouseinfo div with the dynamic info | |
G.layers['overlay_a'].ms_layer.selection(param_selection_function([])); | |
}); | |
}; | |
}); | |
var param_selection_function_b = (function(show_list) { | |
return function(b) { | |
b.attr("r", 3); | |
console.log('psfb'); | |
console.log(b); | |
b.attr("class", "B"); | |
b.attr("class", function(f){ | |
console.log(f); | |
var classes = ['ms']; | |
classes.push(G.layers['overlay_b']['class']); | |
//var show_list = ['amenity','tourism','name']; | |
var show_list = ['name']; | |
for (var i = 0; i < show_list.length; i++) { | |
if (f.properties && f.properties[show_list[i]]) { | |
classes.push(f.properties[show_list[i]]); | |
var feature_value = f.properties[show_list[i]]; | |
var A_value = d3.select('#selector_a').node().value; | |
var B_value = d3.select('#selector_b').node().value; | |
var A_regex = new RegExp(escapeRegExp(A_value), "gi"); | |
var B_regex = new RegExp(escapeRegExp(B_value), "gi"); | |
// at this point, the line above is the same as: var regex = /#abc#/g; | |
if ( A_regex.test(feature_value) ) { | |
//classes.push('A'); | |
} else if ( B_regex.test(feature_value) ) { | |
classes.push('B'); | |
} | |
} | |
}; | |
return classes.join(' '); | |
}) | |
b.on("mouseover", function(d) { // Bind a function to mouseover | |
// This will build a table to display the field names and values | |
var text = ""; | |
var value; | |
var no_list = ['DND_UUID']; | |
text += '<div class="detailCard"><table><tbody>'; | |
if (show_list.length > 0) { // if there's a show_list, only show those fields | |
for (var i = 0; i < show_list.length; i++) { | |
key = show_list[i]; | |
if (d.properties && d.properties[key]) { | |
value = d.properties[key]; | |
value = formatValue(value); | |
text += '<tr><td class="detailKey">' + key + '</td><td class="detailVal">' + value + '</td></tr>'; | |
} | |
} | |
} else { // if no show_list, show all fields | |
for (var key in d.properties) { | |
// except if it's in the no_list | |
if ( no_list.indexOf(key.toUpperCase()) == -1 ) { | |
text += '<tr><td class="detailKey">' + key + '</td><td class="detailVal">' + d.properties[key] + '</td></tr>'; | |
} | |
} | |
} | |
mouseinfo.html(text); // Update the mouseinfo div with the dynamic info | |
G.layers['overlay_b'].ms_layer.selection(param_selection_function_b([])); | |
}); | |
}; | |
}); | |
map = mapsense.map("#myMap"); // init the map | |
map.extent(G.home); | |
if (G.basemap) { | |
map.add(mapsense.basemap().apiKey(G.key).style(G.basemap)); | |
} | |
/* | |
Using two layers (won't see their relative proportions). | |
We need to class them either A or B. | |
*/ | |
G.layers['overlay_a'].ms_layer = mapsense.topoJson() | |
.url(mapsense.url( | |
G.layers['overlay_a'].url + G.layers['overlay_a'].where + G.layers['overlay_a'].params | |
) | |
.hosts(['a', 'b', 'c', 'd'])) | |
.clip(false) | |
.scale('fixed') | |
.selection( | |
param_selection_function([]) | |
); | |
//map.add(G.layers['overlay_a'].ms_layer); | |
console.log(G.layers['overlay_b'].url + G.layers['overlay_b'].where + G.layers['overlay_b'].params); | |
G.layers['overlay_b'].ms_layer = mapsense.topoJson() | |
.url(mapsense.url( | |
G.layers['overlay_b'].url + G.layers['overlay_b'].where + G.layers['overlay_b'].params | |
) | |
.hosts(['a', 'b', 'c', 'd'])) | |
.clip(false) | |
.scale('fixed') | |
.selection( | |
param_selection_function_b([]) | |
); | |
console.log(G.layers['overlay_b'].ms_layer); | |
map.add(G.layers['overlay_b'].ms_layer); | |
updateQuery(); | |
// change map interaction so users can see the map update when they scroll through the selector fields | |
map.interact(false); | |
map.add(mapsense.drag()); | |
map.add(mapsense.wheel()); | |
map.add(mapsense.dblclick()); | |
map.add(mapsense.touch()); | |
//map.add(mapsense.hash()); | |
mapsense.compass().map(map); //enable shift zoom | |
d3.select('.compass').attr('style','display: none;') // but hide the compass graphic | |
} | |
function updateQuery() { | |
// update the query | |
var valu_A, valu_B, new_where, new_url; | |
var body = getBody(); | |
var valu_A = d3.select('#selector_a').node().value; | |
var valu_B = d3.select('#selector_b').node().value; | |
new_where = "&where=name=='" + valu_A + "'"; | |
new_url = G.layers['overlay_a'].url + new_where + G.layers['overlay_a'].params; | |
//console.log(new_url); | |
// update the layer | |
G.layers['overlay_a'].ms_layer.url( | |
mapsense.url(new_url) | |
.hosts(['a','b','c','d']) | |
); | |
new_where = "&where==name=='" + valu_B + "'"; | |
new_url_b = G.layers['overlay_b'].url + new_where + G.layers['overlay_b'].params; | |
//console.log(new_url_b); | |
// update the layer | |
G.layers['overlay_b'].ms_layer.url( | |
mapsense.url(new_url_b) | |
.hosts(['a','b','c','d']) | |
); | |
//writeUrl(); | |
} | |
function cycleQuery() { | |
// update the query | |
//var new_where = "&where=amenity=='" + d3.select('#selector_a').node().value + "' OR amenity=='" + d3.select('#selector_b').node().value + "'"; | |
if (G.samples_i < G.samples.length-1) { | |
G.samples_i += 1; | |
} else { | |
G.samples_i = 0; | |
} | |
var valu_A = G.samples[G.samples_i][0]; | |
var valu_B = G.samples[G.samples_i][1]; | |
var body = getBody(); | |
/* | |
d3.select('#selector_a').node().value = valu_A; | |
d3.select('#selector_b').node().value = valu_B; | |
*/ | |
d3.select(body).node().select('#selector_a').node().value = valu_A; | |
d3.select(body).node().select('#selector_b').node().value = valu_B; | |
d3.select('#enter').on('click')(); | |
} | |
function initSelect() { | |
// add a select element to the page | |
d3.select('#control').append('input') | |
.attr('id','selector_a') | |
.attr('class','selector A') | |
; | |
d3.select('#control').append('input') | |
.attr('id','selector_b') | |
.attr('class','selector B') | |
; | |
d3.select('#control').append('a') | |
.attr('id','enter') | |
.attr('class','button') | |
.text('Search') | |
; | |
d3.select('#control').append('br'); | |
d3.select('#control').append('a') | |
.attr('id','refresh') | |
.attr('class','button') | |
.html('Example') | |
; | |
// When the user selects an option, update the class for those features | |
d3.selectAll('.selector').on('change.query', updateQuery); | |
d3.selectAll('#enter').on('click', updateQuery); | |
d3.selectAll('#refresh').on('click', cycleQuery); | |
} | |
function escapeRegExp(stringToGoIntoTheRegex) { | |
return stringToGoIntoTheRegex.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment