diff options
author | Abhijith Sheheer <abhijithsheheer@gmail.com> | 2019-10-11 17:48:41 +0000 |
---|---|---|
committer | Abhijith Sheheer <abhijithsheheer@gmail.com> | 2019-10-11 17:48:41 +0000 |
commit | 5eaf1af6fb8026f362ce6ae0695b74ba1c8bf0fd (patch) | |
tree | 1dca96f9204b4c41f7bf22327c44ca1df07a1e42 | |
parent | 036b4ce8c034a72c94b1c5d23ee033909fd71d0f (diff) |
New upstream version 1.11.6
-rw-r--r-- | README.md | 36 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/bounds.js | 3 | ||||
-rw-r--r-- | src/contains.js | 23 | ||||
-rw-r--r-- | src/polygonContains.js | 15 | ||||
-rw-r--r-- | test/bounds-test.js | 7 | ||||
-rw-r--r-- | test/contains-test.js | 30 | ||||
-rw-r--r-- | test/polygonContains-test.js | 8 |
8 files changed, 96 insertions, 28 deletions
@@ -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 <script src="https://d3js.org/d3-array.v1.min.js"></script> @@ -35,7 +35,7 @@ var projection = d3.geoEqualEarth(), </script> ``` -[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. <a href="#geoAzimuthalEqualArea" name="geoAzimuthalEqualArea">#</a> d3.<b>geoAzimuthalEqualArea</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/azimuthalEqualArea.js "Source") <br><a href="#geoAzimuthalEqualAreaRaw" name="geoAzimuthalEqualAreaRaw">#</a> d3.<b>geoAzimuthalEqualAreaRaw</b> -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/azimuthalEqualArea.png" width="480" height="250">](https://bl.ocks.org/mbostock/3757101) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/azimuthalEqualArea.png" width="480" height="250">](https://observablehq.com/@d3/azimuthal-equal-area) The azimuthal equal-area projection. <a href="#geoAzimuthalEquidistant" name="geoAzimuthalEquidistant">#</a> d3.<b>geoAzimuthalEquidistant</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/azimuthalEquidistant.js "Source") <br><a href="#geoAzimuthalEquidistantRaw" name="geoAzimuthalEquidistantRaw">#</a> d3.<b>geoAzimuthalEquidistantRaw</b> -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/azimuthalEquidistant.png" width="480" height="250">](https://bl.ocks.org/mbostock/3757110) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/azimuthalEquidistant.png" width="480" height="250">](https://observablehq.com/@d3/azimuthal-equidistant) The azimuthal equidistant projection. <a href="#geoGnomonic" name="geoGnomonic">#</a> d3.<b>geoGnomonic</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/gnomonic.js "Source") <br><a href="#geoGnomonicRaw" name="geoGnomonicRaw">#</a> d3.<b>geoGnomonicRaw</b> -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/gnomonic.png" width="480" height="250">](https://bl.ocks.org/mbostock/3757349) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/gnomonic.png" width="480" height="250">](https://observablehq.com/@d3/gnomonic) The gnomonic projection. <a href="#geoOrthographic" name="geoOrthographic">#</a> d3.<b>geoOrthographic</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/orthographic.js "Source") <br><a href="#geoOrthographicRaw" name="geoOrthographicRaw">#</a> d3.<b>geoOrthographicRaw</b> -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/orthographic.png" width="480" height="250">](https://bl.ocks.org/mbostock/3757125) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/orthographic.png" width="480" height="250">](https://observablehq.com/@d3/orthographic) The orthographic projection. <a href="#geoStereographic" name="geoStereographic">#</a> d3.<b>geoStereographic</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/stereographic.js "Source") <br><a href="#geoStereographicRaw" name="geoStereographicRaw">#</a> d3.<b>geoStereographicRaw</b> -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/stereographic.png" width="480" height="250">](https://bl.ocks.org/mbostock/3757137) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/stereographic.png" width="480" height="250">](https://observablehq.com/@d3/stereographic) The stereographic projection. @@ -273,7 +273,7 @@ The stereographic projection. <a href="#geoEqualEarth" name="geoEqualEarth">#</a> d3.<b>geoEqualEarth</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/equalEarth.js "Source") <br><a href="#geoEqualEarthRaw" name="geoEqualEarthRaw">#</a> d3.<b>geoEqualEarthRaw</b> -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/equalEarth.png" width="480" height="250">](http://shadedrelief.com/ee_proj/) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/equalEarth.png" width="480" height="250">](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 <a href="#geoAlbersUsa" name="geoAlbersUsa">#</a> d3.<b>geoAlbersUsa</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/albersUsa.js "Source") -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/albersUsa.png" width="480" height="250">](https://bl.ocks.org/mbostock/4090848) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/albersUsa.png" width="480" height="250">](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) <a href="#geoAlbers" name="geoAlbers">#</a> d3.<b>geoAlbers</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/albers.js "Source") -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/albers.png" width="480" height="250">](https://bl.ocks.org/mbostock/3734308) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/albers.png" width="480" height="250">](https://observablehq.com/@d3/u-s-map) The Albers’ equal area-conic projection. This is a U.S.-centric configuration of [d3.geoConicEqualArea](#geoConicEqualArea). <a href="#geoConicConformal" name="geoConicConformal">#</a> d3.<b>geoConicConformal</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicConformal.js "Source") <br><a href="#geoConicConformalRaw" name="geoConicConformalRaw">#</a> d3.<b>geoConicConformalRaw</b>(<i>phi0</i>, <i>phi1</i>) [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicConformal.js "Source") -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/conicConformal.png" width="480" height="250">](https://bl.ocks.org/mbostock/3734321) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/conicConformal.png" width="480" height="250">](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). <a href="#geoConicEqualArea" name="geoConicEqualArea">#</a> d3.<b>geoConicEqualArea</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicEqualArea.js "Source") <br><a href="#geoConicEqualAreaRaw" name="geoConicEqualAreaRaw">#</a> d3.<b>geoConicEqualAreaRaw</b>(<i>phi0</i>, <i>phi1</i>) [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicEqualArea.js "Source") -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/conicEqualArea.png" width="480" height="250">](https://bl.ocks.org/mbostock/3734308) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/conicEqualArea.png" width="480" height="250">](https://observablehq.com/@d3/conic-equal-area) The Albers’ equal-area conic projection. See also [*conic*.parallels](#conic_parallels). <a href="#geoConicEquidistant" name="geoConicEquidistant">#</a> d3.<b>geoConicEquidistant</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicEquidistant.js "Source") <br><a href="#geoConicEquidistantRaw" name="geoConicEquidistantRaw">#</a> d3.<b>geoConicEquidistantRaw</b>(<i>phi0</i>, <i>phi1</i>) [<>](https://github.com/d3/d3-geo/blob/master/src/projection/conicEquidistant.js "Source") -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/conicEquidistant.png" width="480" height="250">](https://bl.ocks.org/mbostock/3734317) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/conicEquidistant.png" width="480" height="250">](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. <a href="#geoEquirectangular" name="geoEquirectangular">#</a> d3.<b>geoEquirectangular</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/equirectangular.js "Source") <br><a href="#geoEquirectangularRaw" name="geoEquirectangularRaw">#</a> d3.<b>geoEquirectangularRaw</b> -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/equirectangular.png" width="480" height="250">](https://bl.ocks.org/mbostock/3757119) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/equirectangular.png" width="480" height="250">](https://observablehq.com/@d3/equirectangular) The equirectangular (plate carrée) projection. <a href="#geoMercator" name="geoMercator">#</a> d3.<b>geoMercator</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/mercator.js "Source") <br><a href="#geoMercatorRaw" name="geoMercatorRaw">#</a> d3.<b>geoMercatorRaw</b> -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/mercator.png" width="480" height="250">](https://bl.ocks.org/mbostock/3757132) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/mercator.png" width="480" height="250">](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. <a href="#geoTransverseMercator" name="geoTransverseMercator">#</a> d3.<b>geoTransverseMercator</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/transverseMercator.js "Source") <br><a href="#geoTransverseMercatorRaw" name="geoTransverseMercatorRaw">#</a> d3.<b>geoTransverseMercatorRaw</b> -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/transverseMercator.png" width="480" height="250">](https://bl.ocks.org/mbostock/4695821) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/transverseMercator.png" width="480" height="250">](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. <a href="#geoNaturalEarth1" name="geoNaturalEarth1">#</a> d3.<b>geoNaturalEarth1</b>() [<>](https://github.com/d3/d3-geo/blob/master/src/projection/naturalEarth1.js "Source") <br><a href="#geoNaturalEarth1Raw" name="geoNaturalEarth1Raw">#</a> d3.<b>geoNaturalEarth1Raw</b> -[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/naturalEarth1.png" width="480" height="250">](https://bl.ocks.org/mbostock/4479477) +[<img src="https://raw.githubusercontent.com/d3/d3-geo/master/img/naturalEarth1.png" width="480" height="250">](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); |