▶︎ Data source: 国営木曽三川公園Webサイト, 社会実情データ図録, Geocoding
Built with blockbuilder.org
Mapbox - Extruding circles (choropleth) | |
license: mit |
▶︎ Data source: 国営木曽三川公園Webサイト, 社会実情データ図録, Geocoding
Built with blockbuilder.org
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src='https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.js'></script> | |
<link href='https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.css' rel='stylesheet' /> | |
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@5/turf.min.js"></script> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<style> | |
#mapID { height: 700px; } | |
#position { | |
position:absolute; top: 0; height: 70px; width: 500px; | |
background-color: #fff; | |
padding: 30px; | |
margin: 10px; | |
font-family: 'Courier New', Courier, monospace; | |
} | |
h4 { | |
margin: 0 0 5px 0; | |
} | |
p { | |
margin: 0 0 5px 0; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="mapID"></div> | |
<script src="map.js"></script> | |
<div id="position"> | |
<h4>Visualize: Japanese towers with observation decks</h4> | |
<p>Let's touch the polygon, and check the tower info.</p> | |
<p style="color: grey;">(Other Ver. <a href="https://bl.ocks.org/hirosaji/04b37b81e05800f4531b8941da42eec1">simple</a>/<a href="https://bl.ocks.org/hirosaji/868b7f86af4b1fce305c5963684f29e6">stacked</a>/<a href="https://bl.ocks.org/hirosaji/adf6a4c8d1995c3b6276569dac760f78">gradient</a>)</p> | |
</body> |
(function () { | |
"use strict"; | |
mapboxgl.accessToken = 'pk.eyJ1IjoiaGlyb3NhamkiLCJhIjoiY2szOWlqZWNzMDJueTNjcWhyNjhqdXBnOSJ9._6mJT202QqpnMuK-jvMr3g'; | |
const mapObj = new mapboxgl.Map({ | |
container: 'mapID', | |
style: 'mapbox://styles/hirosaji/cklfggkyj4ytl17qhtxrp2qco', | |
center: [135.68380, 36.85676], | |
zoom: 5.2, | |
pitch: 60.00, | |
bearing: -17.60, | |
interactive: true | |
}); | |
const loadFiles = [ | |
d3.csv("tower_height.csv") | |
]; | |
let hoveredTowerId; | |
Promise.all(loadFiles).then(function (csv) { | |
const geojson = { | |
"type": "FeatureCollection", | |
"features": csv[0].map(function(d) { | |
return { | |
type: "Feature", | |
properties: { | |
name: d.name, | |
full_value: parseFloat(d.full_height), | |
observatory_value: parseFloat(d.observatory_height) | |
}, | |
geometry: { | |
type: "Point", | |
coordinates: [ | |
parseFloat(d.lng), | |
parseFloat(d.lat) | |
] | |
} | |
} | |
}) | |
} | |
const position = d3.select("#position"); | |
mapObj.on('load', function() { | |
mapObj.addLayer({ | |
'id': 'sky', | |
'type': 'sky', | |
'paint': { | |
'sky-type': 'atmosphere', | |
'sky-atmosphere-sun': [0.0, 0.0], | |
'sky-atmosphere-sun-intensity': 15 | |
} | |
}); | |
mapObj.addSource("data", { | |
type: "geojson", | |
data: geojson, | |
}); | |
mapObj.addLayer({ | |
'id': 'tower_points', | |
'type': 'circle', | |
'source': 'data', | |
'paint': { | |
'circle-opacity': 0 | |
} | |
}); | |
mapObj.addSource('extrusion_source', { | |
"type": "geojson", | |
"data": { | |
type: 'FeatureCollection', | |
features: [] | |
} | |
}); | |
mapObj.addLayer({ | |
'id': 'extrusion', | |
'type': 'fill-extrusion', | |
'source': 'extrusion_source', | |
'paint': { | |
'fill-extrusion-color': [ | |
'case', | |
['boolean', ['feature-state', 'hover'], false], | |
['get', 'hovered_color'], | |
['get', 'base_color'] | |
], | |
'fill-extrusion-height': ['get', 'height'], | |
'fill-extrusion-base': ['get', 'base'], | |
'fill-extrusion-opacity': 0.6 | |
} | |
}); | |
function update() { | |
const qfs = mapObj.queryRenderedFeatures({ | |
layers: ['tower_points'] | |
}); | |
const data = { | |
"type": "FeatureCollection", | |
"features": [] | |
}; | |
const radiusPX = 3; | |
qfs.forEach(function (object, i) { | |
const center = object.geometry.coordinates | |
let xy = mapObj.project(center); | |
xy.x += radiusPX; | |
let LL = mapObj.unproject(xy); | |
LL = turf.point([LL.lng, LL.lat]); | |
const radius = turf.distance(center, LL, { | |
units: 'meters' | |
}) + 0.00000001; | |
const bcolor = d3 | |
.scaleSequential(d3.interpolateYlOrRd) | |
// .scaleLinear() | |
// .range(["white", "blue"]) | |
.domain([50, 150]); | |
const hColor = d3 | |
.scaleSequential(d3.interpolateYlGnBu) | |
// .scaleLinear() | |
// .range(["white", "red"]) | |
.domain([50, 150]); | |
object.properties.height = object.properties.full_value * 600; | |
object.properties.base = 0; | |
object.properties.index = i; | |
object.properties.base_color = bcolor(object.properties.full_value); | |
object.properties.hovered_color = hColor(object.properties.full_value); | |
const options = { | |
steps: 16, | |
units: 'meters', | |
properties: object.properties | |
}; | |
const feature = turf.circle(center, radius, options); | |
feature.id = i; | |
data.features.push(feature); | |
}) | |
mapObj.getSource('extrusion_source').setData(data); | |
} | |
mapObj.on('data', function(e) { | |
if (e.sourceId !== 'data') return | |
update() | |
}) | |
}) | |
mapObj.on('mousemove', 'extrusion', function(e) { | |
mapObj.getCanvasContainer().style.cursor = 'pointer'; | |
if (hoveredTowerId) { | |
mapObj.setFeatureState( | |
{ source: 'extrusion_source', id: hoveredTowerId }, | |
{ hover: false } | |
); | |
} | |
hoveredTowerId = e.features[0].id; | |
mapObj.setFeatureState( | |
{ source: 'extrusion_source', id: hoveredTowerId }, | |
{ hover: true } | |
); | |
updatePosition(e.features[0].properties) | |
}); | |
mapObj.on('mouseleave', 'extrusion', function() { | |
mapObj.getCanvasContainer().style.cursor = 'default'; | |
mapObj.setFeatureState( | |
{ source: 'extrusion_source', id: hoveredTowerId }, | |
{ hover: false } | |
); | |
hoveredTowerId = null; | |
}); | |
const updatePosition = function(props) { | |
const info = | |
'<p>Name: ' + props.name + '</p>' + | |
'<p>Height of tower: ' + props.full_value + 'm</p>' + | |
'<p>Height of observatory: ' + props.observatory_value + 'm</p>'; | |
position.html(info); | |
}; | |
}) | |
})(); |
name | full_height | observatory_height | lat | lng | |
---|---|---|---|---|---|
東京スカイツリー | 634 | 451.2 | 35.70998 | 139.810643 | |
東京タワー | 332.6 | 250 | 35.658617 | 139.745552 | |
福岡タワー | 234 | 123 | 33.593331 | 130.351525 | |
名古屋テレビ塔 | 180 | 100 | 35.17155 | 136.907637 | |
梅田スカイビル | 173 | 170 | 34.705374 | 135.490524 | |
ゴールドタワー | 158 | 127 | 34.31177 | 133.808595 | |
海峡ゆめタワー | 153 | 143 | 33.95065 | 130.928888 | |
さっぽろテレビ塔 | 147.2 | 90.38 | 43.061132 | 141.35639 | |
秋田市ポートタワー | 143 | 100 | 39.75176 | 140.061947 | |
ツインアーチ138 | 138 | 100 | 35.357704 | 136.80906 | |
東山スカイタワー | 134 | 100 | 35.156694 | 136.97884 | |
瀬戸大橋タワー | 132 | 108 | 34.352083 | 133.825236 | |
千葉ポートタワー | 125 | 112 | 35.600432 | 140.097845 | |
クロスランドタワー | 118 | 100 | 36.656613 | 136.87863 | |
神戸ポートタワー | 108 | 90.8 | 34.684904 | 135.18552 | |
五稜郭タワー | 107 | 90 | 41.794766 | 140.754021 | |
横浜マリンタワー | 106 | 100 | 35.446179 | 139.635689 | |
通天閣 | 103 | 91 | 34.651962 | 135.506152 | |
別府タワー | 90 | 55 | 33.281325 | 131.506216 | |
銚子ポートタワー | 57.5 | 46.95 | 35.740915 | 140.862859 | |
東尋坊タワー | 55 | 52 | 36.166928 | 136.231465 | |
夢みなとタワー | 43 | 37 | 35.519779 | 133.259184 |