Skip to content

Instantly share code, notes, and snippets.

@mapsense-examples
Created June 20, 2015 00:24
Show Gist options
  • Save mapsense-examples/7cf20900aa789ad4c441 to your computer and use it in GitHub Desktop.
Save mapsense-examples/7cf20900aa789ad4c441 to your computer and use it in GitHub Desktop.
select OpenStreetMap points
html, body, #myMap {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
font: 14px 'Droid Sans', sans-serif;
color: #666;
}
.ms {
stroke-width: 1;
stroke: #ccc;
fill-opacity: 0.5;
mix-blend-mode: multiply;
/*
*/
}
circle {
vector-effect: non-scaling-stroke;
}
.A {
stroke: cyan;
fill: cyan;
}
.B {
stroke: magenta;
fill: magenta;
}
#selector_a {
outline: 13px solid rgba(0,255,255,0.6);
margin: 13px;
}
#selector_b {
outline: 13px solid rgba(255,0,255,0.6);
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;
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);
}
<!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;
}
</style>
</head>
<body>
<div id="myMap"></div>
<div id="ui">
<div id="control"></div>
<div id="legend">
</div>
</div>
<script>
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.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=amenity=='bar' OR amenity=='pub'",
'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=amenity=='bar'",
'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
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(whitelist) {
return function(s) {
applyColors(); // Update the colors based on the current global FIELD
s.attr("class", "ms"); // Assign a class (ms = mapsense)
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;
text += '<div class="detailCard"><table><tbody>';
if (whitelist.length > 0) { // if there's a whitelist, only show those fields
for (var i = 0; i < whitelist.length; i++) {
key = whitelist[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 whitelist, show all fields
for (var key in d.properties) {
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
// Finally, assign this function to the selection
// and request the values for name, population, and the currently selected field option
demographics_layer.selection(param_selection_function(['name',G.FIELD,'population']));
});
};
});
map = mapsense.map("#myMap"); // init the map
map.extent(G.home);
if (G.basemap) {
map.add(mapsense.basemap().apiKey(G.key).style(G.basemap));
}
/*
We want to use one overlay layer for both the queries
so we'll 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
)
.hosts(['a', 'b', 'c', 'd']))
.clip(false)
.selection(
function(d){
d.attr("class", function(f){
var classes = ['ms'];
classes.push(G.layers['overlay_a']['class']);
var whitelist = ['amenity','tourism'];
for (var i = 0; i < whitelist.length; i++) {
if (f.properties && f.properties[whitelist[i]]) {
classes.push(f.properties[whitelist[i]]);
if ( f.properties[whitelist[i]] == d3.select('#selector_a').node().value ) {
classes.push('A');
} else if ( f.properties[whitelist[i]] == d3.select('#selector_b').node().value ) {
classes.push('B');
}
}
};
return classes.join(' ');
})
}
);
map.add(G.layers['overlay_a'].ms_layer);
// 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
//$("#selector").val(G.FIELD).change(); // trigger the selector
}
function initSelect() {
// add a select element to the page
d3.select('#control').append('select')
.attr('id','selector_a')
.attr('class','selector A')
.selectAll('option') // there aren't any option elements yet, so we...
.data(G.selector_options) // bind the list of options...
.enter() // and when we enter the selection...
.append('option') // we append an option
.text(function(d){return d;})
;
d3.select('#control').append('select')
.attr('id','selector_b')
.attr('class','selector B')
.selectAll('option') // there aren't any option elements yet, so we...
.data(G.selector_options) // bind the list of options...
.enter() // and when we enter the selection...
.append('option') // we append an option
.text(function(d){return d;})
;
// When the user selects an option, update the class for those features
d3.selectAll('.selector')
.on('change', function() {
// update the query
var new_where = "&where=amenity=='" + d3.select('#selector_a').node().value + "' OR amenity=='" + d3.select('#selector_b').node().value + "'";
console.log(new_where);
var new_url = G.layers['overlay_a'].url + new_where;
// update the layer
G.layers['overlay_a'].ms_layer.url(
mapsense.url(new_url)
.hosts(['a','b','c','d'])
);
});
d3.select('#selector_b').node().value = 'pub';
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment