From 5eaf1af6fb8026f362ce6ae0695b74ba1c8bf0fd Mon Sep 17 00:00:00 2001 From: Abhijith Sheheer Date: Fri, 11 Oct 2019 17:48:41 +0000 Subject: New upstream version 1.11.6 --- README.md | 36 ++++++++++++++++++------------------ package.json | 2 +- src/bounds.js | 3 +++ src/contains.js | 23 ++++++++++++++++++----- src/polygonContains.js | 15 +++++++++++---- test/bounds-test.js | 7 +++++++ test/contains-test.js | 30 ++++++++++++++++++++++++++++++ test/polygonContains-test.js | 8 ++++++++ 8 files changed, 96 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 8028a06..187831f 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ D3 uses [GeoJSON](http://geojson.org/geojson-spec.html) to represent geographic ## Installing -If you use NPM, `npm install d3-geo`. Otherwise, download the [latest release](https://github.com/d3/d3-geo/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-geo.v1.min.js) or as part of [D3 4.0](https://github.com/d3/d3). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3` global is exported: +If you use NPM, `npm install d3-geo`. Otherwise, download the [latest release](https://github.com/d3/d3-geo/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-geo.v1.min.js) or as part of [D3](https://github.com/d3/d3). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3` global is exported: ```html @@ -35,7 +35,7 @@ var projection = d3.geoEqualEarth(), ``` -[Try d3-geo in your browser.](https://tonicdev.com/npm/d3-geo) +[Try d3-geo in your browser.](https://observablehq.com/collection/@d3/d3-geo) ## API Reference @@ -236,35 +236,35 @@ Azimuthal projections project the sphere directly onto a plane. # d3.geoAzimuthalEqualArea() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/azimuthalEqualArea.js "Source")
# d3.geoAzimuthalEqualAreaRaw -[](https://bl.ocks.org/mbostock/3757101) +[](https://observablehq.com/@d3/azimuthal-equal-area) The azimuthal equal-area projection. # d3.geoAzimuthalEquidistant() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/azimuthalEquidistant.js "Source")
# d3.geoAzimuthalEquidistantRaw -[](https://bl.ocks.org/mbostock/3757110) +[](https://observablehq.com/@d3/azimuthal-equidistant) The azimuthal equidistant projection. # d3.geoGnomonic() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/gnomonic.js "Source")
# d3.geoGnomonicRaw -[](https://bl.ocks.org/mbostock/3757349) +[](https://observablehq.com/@d3/gnomonic) The gnomonic projection. # d3.geoOrthographic() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/orthographic.js "Source")
# d3.geoOrthographicRaw -[](https://bl.ocks.org/mbostock/3757125) +[](https://observablehq.com/@d3/orthographic) The orthographic projection. # d3.geoStereographic() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/stereographic.js "Source")
# d3.geoStereographicRaw -[](https://bl.ocks.org/mbostock/3757137) +[](https://observablehq.com/@d3/stereographic) The stereographic projection. @@ -273,7 +273,7 @@ The stereographic projection. # d3.geoEqualEarth() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/equalEarth.js "Source")
# d3.geoEqualEarthRaw -[](http://shadedrelief.com/ee_proj/) +[](https://observablehq.com/@d3/equal-earth) The Equal Earth projection, by Bojan Šavrič _et al._, 2018. @@ -283,7 +283,7 @@ Composite consist of several projections that are composed into a single display # d3.geoAlbersUsa() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/albersUsa.js "Source") -[](https://bl.ocks.org/mbostock/4090848) +[](https://observablehq.com/@d3/u-s-map) This is a U.S.-centric composite projection of three [d3.geoConicEqualArea](#geoConicEqualArea) projections: [d3.geoAlbers](#geoAlbers) is used for the lower forty-eight states, and separate conic equal-area projections are used for Alaska and Hawaii. Note that the scale for Alaska is diminished: it is projected at 0.35× its true relative area. This diagram by Philippe Rivière illustrates how this projection uses two rectangular insets for Alaska and Hawaii: @@ -301,60 +301,60 @@ The [two standard parallels](https://en.wikipedia.org/wiki/Map_projection#Conic) # d3.geoAlbers() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/albers.js "Source") -[](https://bl.ocks.org/mbostock/3734308) +[](https://observablehq.com/@d3/u-s-map) The Albers’ equal area-conic projection. This is a U.S.-centric configuration of [d3.geoConicEqualArea](#geoConicEqualArea). # d3.geoConicConformal() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicConformal.js "Source")
# d3.geoConicConformalRaw(phi0, phi1) [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicConformal.js "Source") -[](https://bl.ocks.org/mbostock/3734321) +[](https://observablehq.com/@d3/conic-conformal) The conic conformal projection. The parallels default to [30°, 30°] resulting in flat top. See also [*conic*.parallels](#conic_parallels). # d3.geoConicEqualArea() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicEqualArea.js "Source")
# d3.geoConicEqualAreaRaw(phi0, phi1) [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicEqualArea.js "Source") -[](https://bl.ocks.org/mbostock/3734308) +[](https://observablehq.com/@d3/conic-equal-area) The Albers’ equal-area conic projection. See also [*conic*.parallels](#conic_parallels). # d3.geoConicEquidistant() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicEquidistant.js "Source")
# d3.geoConicEquidistantRaw(phi0, phi1) [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicEquidistant.js "Source") -[](https://bl.ocks.org/mbostock/3734317) +[](https://observablehq.com/@d3/conic-equidistant) The conic equidistant projection. See also [*conic*.parallels](#conic_parallels). #### Cylindrical Projections -Cylindrical projections project the sphere onto a containing cylinder, and then unroll the cylinder onto the plane. [Pseudocylindrical projections](http://www.progonos.com/furuti/MapProj/Normal/ProjPCyl/projPCyl.html) are a generalization of cylindrical projections. +Cylindrical projections project the sphere onto a containing cylinder, and then unroll the cylinder onto the plane. [Pseudocylindrical projections](https://web.archive.org/web/20150928042327/http://www.progonos.com/furuti/MapProj/Normal/ProjPCyl/projPCyl.html) are a generalization of cylindrical projections. # d3.geoEquirectangular() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/equirectangular.js "Source")
# d3.geoEquirectangularRaw -[](https://bl.ocks.org/mbostock/3757119) +[](https://observablehq.com/@d3/equirectangular) The equirectangular (plate carrée) projection. # d3.geoMercator() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/mercator.js "Source")
# d3.geoMercatorRaw -[](https://bl.ocks.org/mbostock/3757132) +[](https://observablehq.com/@d3/mercator) The spherical Mercator projection. Defines a default [*projection*.clipExtent](#projection_clipExtent) such that the world is projected to a square, clipped to approximately ±85° latitude. # d3.geoTransverseMercator() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/transverseMercator.js "Source")
# d3.geoTransverseMercatorRaw -[](https://bl.ocks.org/mbostock/4695821) +[](https://observablehq.com/@d3/transverse-mercator) The transverse spherical Mercator projection. Defines a default [*projection*.clipExtent](#projection_clipExtent) such that the world is projected to a square, clipped to approximately ±85° latitude. # d3.geoNaturalEarth1() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/naturalEarth1.js "Source")
# d3.geoNaturalEarth1Raw -[](https://bl.ocks.org/mbostock/4479477) +[](https://observablehq.com/@d3/natural-earth) The [Natural Earth projection](http://www.shadedrelief.com/NE_proj/) is a pseudocylindrical projection designed by Tom Patterson. It is neither conformal nor equal-area, but appealing to the eye for small-scale maps of the whole world. diff --git a/package.json b/package.json index 4665576..11588f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "d3-geo", - "version": "1.11.3", + "version": "1.11.6", "description": "Shapes and calculators for spherical coordinates.", "keywords": [ "d3", diff --git a/src/bounds.js b/src/bounds.js index 5e1d29e..5defb99 100644 --- a/src/bounds.js +++ b/src/bounds.js @@ -32,6 +32,9 @@ var boundsStream = { else if (deltaSum > epsilon) phi1 = 90; else if (deltaSum < -epsilon) phi0 = -90; range[0] = lambda0, range[1] = lambda1; + }, + sphere: function() { + lambda0 = -(lambda1 = 180), phi0 = -(phi1 = 90); } }; diff --git a/src/contains.js b/src/contains.js index 952a62d..3b8e0c8 100644 --- a/src/contains.js +++ b/src/contains.js @@ -1,6 +1,6 @@ import {default as polygonContains} from "./polygonContains"; import {default as distance} from "./distance"; -import {epsilon, radians} from "./math"; +import {epsilon2, radians} from "./math"; var containsObjectType = { Feature: function(object, point) { @@ -59,10 +59,23 @@ function containsPoint(coordinates, point) { } function containsLine(coordinates, point) { - var ab = distance(coordinates[0], coordinates[1]), - ao = distance(coordinates[0], point), - ob = distance(point, coordinates[1]); - return ao + ob <= ab + epsilon; + var ao, bo, ab; + for (var i = 0, n = coordinates.length; i < n; i++) { + bo = distance(coordinates[i], point); + if (bo === 0) return true; + if (i > 0) { + ab = distance(coordinates[i], coordinates[i - 1]); + if ( + ab > 0 && + ao <= ab && + bo <= ab && + (ao + bo - ab) * (1 - Math.pow((ao - bo) / ab, 2)) < epsilon2 * ab + ) + return true; + } + ao = bo; + } + return false; } function containsPolygon(coordinates, point) { diff --git a/src/polygonContains.js b/src/polygonContains.js index dad70ea..b666cfb 100644 --- a/src/polygonContains.js +++ b/src/polygonContains.js @@ -1,11 +1,18 @@ import adder from "./adder"; import {cartesian, cartesianCross, cartesianNormalizeInPlace} from "./cartesian"; -import {asin, atan2, cos, epsilon, halfPi, pi, quarterPi, sin, tau} from "./math"; +import {abs, asin, atan2, cos, epsilon, halfPi, pi, quarterPi, sign, sin, tau} from "./math"; var sum = adder(); +function longitude(point) { + if (abs(point[0]) <= pi) + return point[0]; + else + return sign(point[0]) * ((abs(point[0]) + pi) % tau - pi); +} + export default function(polygon, point) { - var lambda = point[0], + var lambda = longitude(point), phi = point[1], sinPhi = sin(phi), normal = [sin(lambda), -cos(lambda), 0], @@ -22,14 +29,14 @@ export default function(polygon, point) { var ring, m, point0 = ring[m - 1], - lambda0 = point0[0], + lambda0 = longitude(point0), phi0 = point0[1] / 2 + quarterPi, sinPhi0 = sin(phi0), cosPhi0 = cos(phi0); for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) { var point1 = ring[j], - lambda1 = point1[0], + lambda1 = longitude(point1), phi1 = point1[1] / 2 + quarterPi, sinPhi1 = sin(phi1), cosPhi1 = cos(phi1), diff --git a/test/bounds-test.js b/test/bounds-test.js index b04e49b..41c2bf7 100644 --- a/test/bounds-test.js +++ b/test/bounds-test.js @@ -255,6 +255,13 @@ tape("bounds: Polygon - ring", function(test) { test.end(); }); +tape("bounds: Sphere", function(test) { + test.deepEqual(d3.geoBounds({ + type: "Sphere" + }), [[-180, -90], [180, 90]]); + test.end(); +}); + tape("bounds: NestedCollection", function(test) { test.deepEqual(d3.geoBounds({ type: "FeatureCollection", diff --git a/test/contains-test.js b/test/contains-test.js index 94f7c53..7864963 100644 --- a/test/contains-test.js +++ b/test/contains-test.js @@ -31,6 +31,35 @@ tape("a LineString contains any point on the Great Circle path", function(test) test.end(); }); +tape("a LineString with 2+ points contains those points", function(test) { + var points = [[0, 0], [1,2], [3, 4], [5, 6]]; + var feature = {type: "LineString", coordinates: points}; + points.forEach(point => { + test.equal(d3.geoContains(feature, point), true); + }); + test.end(); +}); + +tape("a LineString contains epsilon-distant points", function(test) { + var epsilon = 1e-6; + var line = [[0, 0], [0, 10], [10, 10], [10, 0]]; + var points = [[0, 5], [epsilon * 1, 5], [0, epsilon], [epsilon * 1, epsilon]]; + points.forEach(point => { + test.true(d3.geoContains({type:"LineString", coordinates: line}, point)); + }); + test.end(); +}); + +tape("a LineString does not contain 10*epsilon-distant points", function(test) { + var epsilon = 1e-6; + var line = [[0, 0], [0, 10], [10, 10], [10, 0]]; + var points = [[epsilon * 10, 5], [epsilon * 10, epsilon]]; + points.forEach(point => { + test.false(d3.geoContains({type:"LineString", coordinates: line}, point)); + }); + test.end(); +}); + tape("a MultiLineString contains any point on one of its components", function(test) { test.equal(d3.geoContains({type: "MultiLineString", coordinates: [[[0, 0], [1,2]], [[2, 3], [4,5]]]}, [2, 3]), true); test.equal(d3.geoContains({type: "MultiLineString", coordinates: [[[0, 0], [1,2]], [[2, 3], [4,5]]]}, [5, 6]), false); @@ -113,3 +142,4 @@ tape("null contains nothing", function(test) { test.equal(d3.geoContains(null, [0, 0]), false); test.end(); }); + diff --git a/test/polygonContains-test.js b/test/polygonContains-test.js index 586d4e8..0615905 100644 --- a/test/polygonContains-test.js +++ b/test/polygonContains-test.js @@ -30,6 +30,14 @@ rollup.rollup({input: "src/polygonContains.js"}) test.end(); }); + tape("geoPolygonContains wraps longitudes", function(test) { + var polygon = d3_geo.geoCircle().center([300, 0])().coordinates; + test.equal(polygonContains(polygon, [300, 0]), 1); + test.equal(polygonContains(polygon, [-60, 0]), 1); + test.equal(polygonContains(polygon, [-420, 0]), 1); + test.end(); + }); + tape("geoPolygonContains(southPole, point) returns the expected value", function(test) { var polygon = [[[-60, -80], [60, -80], [180, -80], [-60, -80]]]; test.equal(polygonContains(polygon, [0, 0]), 0); -- cgit v1.2.3