Skip to content

Instantly share code, notes, and snippets.

@shimizu
Last active March 29, 2019 02:15
Show Gist options
  • 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment