Skip to content

Instantly share code, notes, and snippets.

@sansumbrella
Last active June 21, 2019 21:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sansumbrella/df940b1e6575e56f360b88c3b3cd976b to your computer and use it in GitHub Desktop.
Save sansumbrella/df940b1e6575e56f360b88c3b3cd976b to your computer and use it in GitHub Desktop.
Pickable 3D buildings with feature state and buildings plus
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Highlight 3D Building By ID</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.js"></script>
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.css" rel="stylesheet" />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
mapboxgl.accessToken =
"pk.eyJ1IjoiZGF2aWQtd2lja3MiLCJhIjoiY2p4Nmx3cjhzMDEybjN4c3gzbzh3cTZncyJ9.PTQf1HJSLa-qzXCeY-NIHw";
var map = new mapboxgl.Map({
style: "mapbox://styles/david-wicks/cjsgl6i5b43cc1frlz1o4uolc",
center: [-74.0066, 40.7135],
zoom: 15.5,
pitch: 45,
bearing: -17.6,
container: "map",
hash: true
});
// The 'building' layer in the mapbox-streets vector source contains building-height
// data from OpenStreetMap.
map.on("load", function() {
// Insert the layer beneath any symbol layer.
var layers = map.getStyle().layers;
var labelLayerId;
for (var i = 0; i < layers.length; i++) {
if (layers[i].type === "symbol" && layers[i].layout["text-field"]) {
labelLayerId = layers[i].id;
break;
}
}
map.addLayer(
{
id: "3d-buildings",
source: "composite",
"source-layer": "buildings_plus",
filter: ["==", "extrude", "true"],
type: "fill-extrusion",
minzoom: 14,
paint: {
// color based on feature state
"fill-extrusion-color": ["match", ["feature-state", "highlight"], "true", "#F0F", "#09F"],
// use an 'interpolate' expression to add a smooth transition effect to the
// buildings as the user zooms in
"fill-extrusion-height": ["interpolate", ["linear"], ["zoom"], 15, 0, 15.05, ["get", "height"]],
"fill-extrusion-base": ["interpolate", ["linear"], ["zoom"], 15, 0, 15.05, ["get", "min_height"]],
"fill-extrusion-opacity": 0.6
}
},
labelLayerId
);
map.on("click", e => {
const features = map.queryRenderedFeatures(e.point, { layers: ["3d-buildings"] });
const feature = features[0];
if (feature) {
selectFeature(feature.id);
}
});
const selectFeature = (() => {
let previous;
return id => {
if (id !== previous && previous !== undefined) {
map.setFeatureState(
{ source: "composite", sourceLayer: "buildings_plus", id: previous },
{ highlight: "false" }
);
}
previous = id;
map.setFeatureState({ source: "composite", sourceLayer: "buildings_plus", id }, { highlight: "true" });
};
})();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment