import “../core/true”; import “../math/trigonometry”; import “clip”; import “point-in-polygon”;
var d3_geo_clipAntimeridian = d3_geo_clip(
d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, d3_geo_clipAntimeridianPolygonContains);
// Takes a line and cuts into visible segments. Return values: // 0: there were intersections or the line was empty. // 1: no intersections. // 2: there were intersections, and the first and last segments should be // rejoined. function d3_geo_clipAntimeridianLine(listener) {
var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; // no intersections return { lineStart: function() { listener.lineStart(); clean = 1; }, point: function(λ1, φ1) { var sλ1 = λ1 > 0 ? π : -π, dλ = Math.abs(λ1 - λ0); if (Math.abs(dλ - π) < ε) { // line crosses a pole listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? π / 2 : -π / 2); listener.point(sλ0, φ0); listener.lineEnd(); listener.lineStart(); listener.point(sλ1, φ0); listener.point( λ1, φ0); clean = 0; } else if (sλ0 !== sλ1 && dλ >= π) { // line crosses antimeridian // handle degeneracies if (Math.abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; if (Math.abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); listener.point(sλ0, φ0); listener.lineEnd(); listener.lineStart(); listener.point(sλ1, φ0); clean = 0; } listener.point(λ0 = λ1, φ0 = φ1); sλ0 = sλ1; }, lineEnd: function() { listener.lineEnd(); λ0 = φ0 = NaN; }, // if there are intersections, we always rejoin the first and last segments. clean: function() { return 2 - clean; } };
}
function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) {
var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); return Math.abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2;
}
function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) {
var φ; if (from == null) { φ = direction * π / 2; listener.point(-π, φ); listener.point( 0, φ); listener.point( π, φ); listener.point( π, 0); listener.point( π, -φ); listener.point( 0, -φ); listener.point(-π, -φ); listener.point(-π, 0); listener.point(-π, φ); } else if (Math.abs(from[0] - to[0]) > ε) { var s = (from[0] < to[0] ? 1 : -1) * π; φ = direction * s / 2; listener.point(-s, φ); listener.point( 0, φ); listener.point( s, φ); } else { listener.point(to[0], to[1]); }
}
var d3_geo_clipAntimeridianPoint = [-π, 0];
function d3_geo_clipAntimeridianPolygonContains(polygon) {
return d3_geo_pointInPolygon(d3_geo_clipAntimeridianPoint, polygon);
}