Skip to content

Instantly share code, notes, and snippets.

@ampledata
Forked from samgehret/index.html
Last active Mar 1, 2019
Embed
What would you like to do?
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Display buildings in 3D</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.50.0/mapbox-gl.js'></script>
<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.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.eyJ1Ijoic2FtZ2VocmV0IiwiYSI6ImNqZWExcDdwNTAxYnEyeG1tZnQ4MTNsODkifQ.68r_UjBeRkubf5eUs4uw-g';
var map = new mapboxgl.Map({
//style: 'mapbox://styles/ealessandrini/cj3qdzuis003g2sp3q5k43fdp?fresh=true',
style: 'mapbox://styles/mapbox/dark-v9',
center: [-74.010962, 40.709779],
zoom: 15.5,
pitch: 45,
container: 'map'
});
// This object will hold the floor "discs"
var floors = {
"type": "FeatureCollection",
"features": []
}
var buildingTops = {
"type": "FeatureCollection",
"features": []
}
map.on('load', function () {
// Add a source and layer for the floor "discs"
map.addSource("floors", {
"type": "geojson",
"data": floors
});
map.addSource("buildingtops", {
"type": "geojson",
"data": buildingTops
});
// The 'building' layer in the mapbox-streets vector source contains building-height
// data from OpenStreetMap.
map.addSource("buildings", {
type: "vector",
url: "mapbox://mapbox.3d-buildings"
});
map.addLayer({
"id": "building-tops",
"type": "fill-extrusion",
"source": "buildingtops",
"paint": {
'fill-extrusion-color': "yellow",
'fill-extrusion-height': ['get','extrusion_height'],
'fill-extrusion-base': ['get','base_height'],
'fill-extrusion-opacity': 1,
}
});
map.addLayer({
'id': '3d-buildings',
'source': 'buildings',
'source-layer': 'building',
'type': 'fill-extrusion',
'minzoom': 10,
'paint': {
'fill-extrusion-color': ['case', ['==', ['feature-state', 'color'], 1], '#444',
'#ccc'
],
'fill-extrusion-height': ['get', 'height'],
'fill-extrusion-base': ['get', 'min_height'],
'fill-extrusion-opacity': 0.7
}
});
var url = "";
var coordinates = [];
var buildingIDList = [];
var building_id = "";
// Loop through the source GeoJSON
customerData.features.forEach(function (feature) {
// Set up the floor vizualization features
var floor = feature;
coordinates = feature.geometry.coordinates;
var buffered = turf.buffer(turf.point(coordinates), 0.00000001);
floor.geometry = buffered.geometry;
floors.features.push(floor);
// Query for which building footprints intersect them
url = "https://api.mapbox.com/v4/mapbox.3d-buildings/tilequery/" + coordinates +
".json?limit=50&radius=30&access_token=" + mapboxgl.accessToken;
fetch(url)
.then(data => {
return data.json()
})
.then(res => {
buildingFeatures = res.features
// console.log('building features', buildingFeatures)
buildingFeatures.forEach(function (buildingFeature) {
// console.log('builidngFEature', buildingFeature)
building_id = buildingFeature.id
buildingIDList.push(building_id);
if (buildingFeature.properties.height > 100) {
let newTop = {
"type": "Feature",
"properties": {
"base_height": "",
"extrusion_height": ""
}
}
coordinates = buildingFeature.geometry.coordinates
var bufferedPoint = turf.buffer(turf.point(coordinates),0.01)
newTop.geometry = bufferedPoint.geometry
newTop.properties.base_height = buildingFeature.properties.height / 2
newTop.properties.extrusion_height = buildingFeature.properties.height / 2 + 5
console.log('newtop', newTop)
buildingTops.features.push(newTop)
map.getSource("buildingtops").setData(buildingTops);
}
map.setFeatureState({
source: 'buildings',
sourceLayer: 'building',
id: building_id
}, {
'color': 0
})
})
})
.catch(function (error) {
console.log(error)
})
});
// Once the floor data is ready, update the source
map.getSource("floors").setData(floors);
});
// Code for auto-rotation - makes nice GIFS :-)
function rotateBy(current) {
var rotateNumber = current;
map.rotateTo(rotateNumber + 90, {
duration: 24000,
easing: function (t) {
return t;
}
});
}
map.on('click', function (e) {
rotateBy(map.getBearing());
});
// Source data for the rental floors
var customerData = {
"type": "FeatureCollection",
"name": "ss_building_sample",
"features": [
{
"type": "Feature",
"properties": {
"ID": 918400,
"PropertyID": 5011038,
"BuildingName": "3 World Trade Center",
"BuildingAddress": "175 Greenwich St",
"FloorAvail": 71,
"WeightedAverageRent": null,
"Estimated Rent": 55.76625,
"fl_height": 249,
"color": "yellow",
"fl_min_height": 245
},
"geometry": {
"type": "Point",
"coordinates": [-74.011608, 40.710893]
}
}
]
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment