Skip to content

Instantly share code, notes, and snippets.

@strangerintheq
Last active October 30, 2018 19:01
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 strangerintheq/c28bfb385d9b6e5db7aa428815113099 to your computer and use it in GitHub Desktop.
Save strangerintheq/c28bfb385d9b6e5db7aa428815113099 to your computer and use it in GitHub Desktop.
d3 // antimeridian cuttted GeoJSON // leaflet
license: gpl-3.0
height: 500
scrolling: no
border: yes

this example shows how d3.js can help you with GeoJSON antimeridian cutting and use it in leaflet or other mapping service

<!DOCTYPE html>
<html>
<head>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css"/>
</head>
<body style="margin: 0">
<svg style="display: inline-block"></svg>
<div id="map" style="display: inline-block; width: 550px; height: 450px"></div>
<script>
var tileLayer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png');
var map = L.map('map').setView([0,0], 0).addLayer(tileLayer);
var bounds = [400, 450];
var colorGenerator = d3.scaleOrdinal(d3.schemeCategory10);
var projection = d3.geoMercator().translate([bounds[0] / 2, bounds[1] / 2]).scale(70);
var geoPath = d3.geoPath().projection(projection);
var geoCircle = d3.geoCircle();
var svg = d3.select('svg')
.attr("width", bounds[0])
.attr("height", bounds[1])
.attr("viewbox", "0 0 " + bounds[0] + " " + bounds[1])
.append('g');
svg.append("g")
.append("path")
.datum(d3.geoGraticule())
.attr("stroke", "gray")
.attr('d', geoPath);
function addCircle(center, radius, color) {
var g = svg.append("g");
var drag = d3.drag().on("drag", dragged);
var xy = projection(center);
var path = g.append("path")
.datum({
type: "Polygon",
coordinates: [[]],
x: xy[0],
y: xy[1]
})
.classed("zone", "true")
.attr("fill", color)
.attr("stroke", color)
.attr("fill-opacity", 0.3)
.call(drag);
update(path.datum());
function dragged(d) {
g.raise();
d.x = d3.event.x;
d.y = d3.event.y;
update(d)
}
function update(d) {
center = projection.invert([d.x, d.y]);
var poly = geoCircle.center(center).radius(radius)();
d.coordinates[0] = poly.coordinates[0];
path.attr('d', geoPath);
d.geojson && d.geojson.remove();
d.geojson = L.geoJSON(unproject(path.attr('d')), {
color: color,
}).addTo(map);
}
function unproject(d) {
var features = d.toLowerCase().split('z').join('').split('m');
features.shift();
var coords = features.map(function (feature) {
return feature.split('l').map(function (pt) {
var xy = pt.split(',');
return projection.invert([+xy[0], +xy[1]]);
});
});
return {
type: 'MultiPolygon',
coordinates: [coords]
}
}
}
d3.range(0, 4).forEach(function (i) {
addCircle([-120 + i * 60, 0], i * 10 + 10, colorGenerator(i));
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment