OSM BuildingsとTurf.jsを使ったサンプル。
Built with blockbuilder.org
<!DOCTYPE html>
<html>
<head>
<title>3D Hexbin Mapping</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#map {
width: 100%;
height: 100%;
}
.control {
position: absolute;
left: 0;
z-index: 1000;
}
.control.tilt {
top: 0;
}
.control.rotation {
top: 45px;
}
.control.zoom {
top: 90px;
}
.control.zoom button{
font-weight: normal;
}
.control button {
width: 30px;
height: 30px;
margin: 15px 0 0 15px;
border: 1px solid #999999;
background: #ffffff;
opacity: 0.6;
border-radius: 5px;
box-shadow: 0 0 5px #666666;
font-weight: bold;
text-align: center;
}
.control button:hover {
opacity: 1;
cursor: pointer;
}
</style>
<link rel="stylesheet" href="OSMBuildings.css">
<script src="OSMBuildings.js"></script>
<script src="https://npmcdn.com/@turf/turf/turf.min.js"></script>
</head>
<body>
<div id="map"></div>
<div class="control tilt">
<button class="dec">↙</button>
<button class="inc">↗</button>
</div>
<div class="control rotation">
<button class="inc">↶</button>
<button class="dec">↷</button>
</div>
<div class="control zoom">
<button class="dec">-</button>
<button class="inc">+</button>
</div>
<script>
!(function(){
'use strict';
var osmb = new OSMBuildings({
baseURL: '.',
tilt:45,
minZoom: 8,
maxZoom: 18,
position: { latitude:35.700912, longitude:139.752937 },
zoom: 14,
state: false, // stores map position/rotation in url
effects: ['shadows'],
attribution: '© 3D <a href="https://osmbuildings.org/copyright/">OSM Buildings</a>'
}).appendTo('map');
osmb.addMapTiles(
'//cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg',
{
attribution: '<a href="//maps.gsi.go.jp/development/ichiran.html">地理院タイル</a>'
}
);
var bbox = [
139.73150253295898,
35.69592230644545,
139.77343082427979,
35.67239331399702
];
var cellSize = 0.08;
var units = 'miles';
var hexgrid = turf.hexGrid(bbox, cellSize, units);
hexgrid.features.forEach(function(d){
d.properties.height = ~~(Math.random()*100);
if (d.properties.height > 75){
d.properties.color = "red";
d.properties.roofColor = "red";
}
else if (d.properties.height > 50){
d.properties.color = "orange";
d.properties.roofColor = "orange";
}
else if (d.properties.height > 25){
d.properties.color = "yellow";
d.properties.roofColor = "yellow";
}
});
osmb.addGeoJSON(hexgrid);
var controlButtons = document.querySelectorAll('.control button');
for (var i = 0, il = controlButtons.length; i < il; i++) {
controlButtons[i].addEventListener('click', function(e) {
var button = this;
var parentClassList = button.parentNode.classList;
var direction = button.classList.contains('inc') ? 1 : -1;
var increment;
var property;
if (parentClassList.contains('tilt')) {
property = 'Tilt';
increment = direction*10;
}
if (parentClassList.contains('rotation')) {
property = 'Rotation';
increment = direction*10;
}
if (parentClassList.contains('zoom')) {
property = 'Zoom';
increment = direction*1;
}
if (property) {
osmb['set'+ property](osmb['get'+ property]()+increment);
}
});
}
}());
</script>
</body>
</html>
.osmb {
}
.osmb-viewport {
position:absolute;
}
.osmb-attribution {
position:absolute;
right:0;
bottom:0;
padding:1px 3px;
background:rgba(255,255,255,0.5);
font:11px sans-serif;
z-index: 10;
}
.osmb-attribution a {
text-decoration:none;
color:#0078A8;
}
.osmb-attribution a:visited {
text-decoration:none;
color:#0078A8;
}
.osmb-attribution a:hover {
text-decoration:underline;
color:#0078A8;
}