Skip to content

Instantly share code, notes, and snippets.

@shimizu
Last active March 29, 2019 02:15
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 shimizu/fb1323d5d1e6dd8566a6c5046d30946a to your computer and use it in GitHub Desktop.
Save shimizu/fb1323d5d1e6dd8566a6c5046d30946a to your computer and use it in GitHub Desktop.
D3 v4 - Smooth path
license: mit

D3のInterpolation機能を使って、地図上のパスを滑らかに補完する。

Smooth pathのD3 ver.4版

Built with blockbuilder.org

<!DOCTYPE html>
<html>
<head>
<title>Smooth path</title>
<style type="text/css">
html, body {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
#map1{
float: right;
width: 50%;
height: 100%;
}
#map2{
float: left;
width: 50%;
height: 100%;
}
.SvgOverlay {
position: relative;
width: 500px;
height: 500px;
}
.SvgOverlay svg {
position: absolute;
top: -4000px;
left: -4000px;
width: 8000px;
height: 8000px;
}
</style>
</head>
<body>
<div id="map1"></div>
<div id="map2"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA8X-e3Naz_Pu50cP8bdDQUZukKrXMqDGs&libraries=visualization"></script>
<script src="//unpkg.com/d3@4.12.2/build/d3.min.js"></script>
<script src="index.js"></script>
</body>
</html>
//Gmap スタイル指定
const style_array_from_above_here = [
{
featureType: 'water',
elementType: 'all',
stylers: [ { hue: '#e9ebed' }, { saturation: -78 }, { lightness: 67 }, { visibility: 'simplified' } ]
},
{
featureType: 'landscape',
elementType: 'all',
stylers: [ { hue: '#ffffff' }, { saturation: -100 }, { lightness: 100 }, { visibility: 'simplified' } ]
},
{
featureType: 'road',
elementType: 'geometry',
stylers: [ { hue: '#bbc0c4' }, { saturation: -93 }, { lightness: 31 }, { visibility: 'simplified' } ]
},
{
featureType: 'poi',
elementType: 'all',
stylers: [ { hue: '#ffffff' }, { saturation: -100 }, { lightness: 100 }, { visibility: 'off' } ]
},
{
featureType: 'road.local',
elementType: 'geometry',
stylers: [ { hue: '#e9ebed' }, { saturation: -90 }, { lightness: -8 }, { visibility: 'simplified' } ]
},
{
featureType: 'transit',
elementType: 'all',
stylers: [ { hue: '#e9ebed' }, { saturation: 10 }, { lightness: 69 }, { visibility: 'on' } ]
},
{
featureType: 'administrative.locality',
elementType: 'all',
stylers: [ { hue: '#2c2e33' }, { saturation: 7 }, { lightness: 19 }, { visibility: 'on' } ]
},
{
featureType: 'road',
elementType: 'labels',
stylers: [ { hue: '#bbc0c4' }, { saturation: -93 }, { lightness: 31 }, { visibility: 'on' } ]
},
{
featureType: 'road.arterial',
elementType: 'labels',
stylers: [ { hue: '#bbc0c4' }, { saturation: -93 }, { lightness: -2 }, { visibility: 'simplified' } ]
}
];
//Google Map 初期化
const mapOpotion = {
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP,
styles: style_array_from_above_here,
center: new google.maps.LatLng(24.3408621, 124.1614194)
};
const map1 = new google.maps.Map(document.getElementById('map1'), mapOpotion);
const map2 = new google.maps.Map(document.getElementById('map2'), mapOpotion);
//データセット読み込み
d3.json('line.geojson', main);
function main(data) {
const drawAction = function() {
//オーバーレイ設定
const layer = d3.select(this.getPanes().overlayLayer).append('div').attr('class', 'SvgOverlay');
const svg = layer.append('svg');
const layergroup = svg.append('g').attr('class', 'd3maplayear');
const markerOverlay = this;
const overlayProjection = markerOverlay.getProjection();
//Google Projection作成
const googleMapProjection = d3.geoTransform({
point: function(x, y) {
const d = overlayProjection.fromLatLngToDivPixel(new google.maps.LatLng(y, x));
this.stream.point(d.x + 4000, d.y + 4000);
}
});
//パスジェネレーター作成
const path = d3.geoPath().projection(googleMapProjection);
const interpolate = d3.line().x((d) => d[0]).y((d) => d[1]).curve(d3.curveBasis);
const smoothPath = (pstr) => {
const sp = path(pstr).replace(/M|Z/, '').split('L').map((d) => d.split(','));
return interpolate(sp);
};
//オーバーレイ描画イベント
this.draw = draw;
function draw() {
const currentMap = this.getMap();
const line = layergroup.selectAll('path').data(data.features);
line.attr('d', (d) => {
if (currentMap == map2) return smoothPath(d);
return path(d);
});
const enter = line.enter().append('path');
line
.merge(enter)
.attr('d', (d) => {
if (currentMap == map2) return smoothPath(d);
return path(d);
})
.attr('stroke', 'orange')
.attr('stroke-width', 4)
.attr('fill', 'none');
}
};
const overlay1 = new google.maps.OverlayView(); //OverLayオブジェクトの作成
const overlay2 = new google.maps.OverlayView(); //OverLayオブジェクトの作成
overlay1.onAdd = drawAction;
overlay2.onAdd = drawAction;
//作成したSVGを地図にオーバーレイする
overlay1.setMap(map1);
overlay2.setMap(map2);
}
Display the source blob
Display the rendered blob
Raw
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
140.80078125,
45.644768217751924
],
[
134.47265625,
41.96765920367816
],
[
138.25195312499997,
40.84706035607122
],
[
131.66015625,
38.34165619279595
],
[
134.12109375,
37.37015718405753
],
[
125.33203125,
31.57853542647338
],
[
130.166015625,
27.371767300523047
],
[
125.94726562499999,
18.646245142670608
],
[
134.560546875,
12.039320557540584
],
[
141.85546875,
14.008696370634658
],
[
150.29296875,
20.632784250388028
],
[
148.0078125,
14.093957177836236
],
[
152.138671875,
16.804541076383455
],
[
151.34765625,
13.239945499286312
],
[
153.193359375,
14.264383087562662
],
[
153.6328125,
11.78132529611229
]
]
}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment