GithubHelp home page GithubHelp logo

dpmcmlxxvi / de9im Goto Github PK

View Code? Open in Web Editor NEW
28.0 3.0 3.0 1019 KB

DE-9IM spatial predicate library implemented in Javascript.

Home Page: https://dpmcmlxxvi.github.io/de9im

License: MIT License

JavaScript 100.00%
de-9im spatial predicates javascript algorithm geospatial gis geojson

de9im's Introduction

build coverage npm code

de9im is a Javascript library that provides spatial predicate functions defined by the Dimensionally Extended Nine-Intersection Model (DE-9IM) and works with GeoJSON objects. It can test if two geometries have one of the following relationships: contains, coveredby, covers, crosses, disjoint, equals, intersects, overlaps, touches, within. It can be used client-side in a browser or server-side with Node.js.

See de9im examples for examples of geometries that satisfy the various predicates using de9im.

See pouchdb-geospatial for an example application that uses de9im to perform spatial querying of GeoJSON objects in a database.

GETTING STARTED

de9im depends on the Turf.js library for performing spatial operations which must be also included for client-side processing since Turf.js is not bundled with de9im.

In a browser

<script src="https://unpkg.com/@turf/turf" charset="utf-8"></script>
<script src="https://unpkg.com/de9im" charset="utf-8"></script>

In Node

npm install de9im
const de9im = require('de9im');

Then call a predicate function on two geometries

const line = {'type': 'LineString', 'coordinates': [[0, 0], [1, 1], [2, 2]]};
const point = {'type': 'Point', 'coordinates': [1, 1]};
de9im.contains(line, point);
// = true
de9im.disjoint(line, point);
// = false

USAGE

API

The de9im object has the following spatial predicate functions available:

contains
coveredby
covers
crosses
disjoint
equals
intersects
overlaps
touches
within

Each predicate takes two GeoJSON arguments and an optional boolean argument:

de9im.predicate(geojson1, geojson2, [error=true])

It returns true, false, or throws an exception if the geometry types provided are not supported. If the optional argument error is false then unsupported geometries return false instead of throwing an exception. Each predicate should be interpreted as the first argument operating on the second. For example,

de9im.contains(line, point)

should be read as

line contains point?

Data Types

The arguments for every predicate can be any GeoJSON type: Geometry, Feature, GeometryCollection, FeatureCollection. All geometry types are supported: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon. However, only homogenous geometries are supported in collections. For example, a FeatureCollection can have points but can not mix points and lines.

Argument Types

Each predicate has a unique combination of first and second argument geometries that it supports.

  • contains, covers

    1st / 2nd Point Line Polygon
    Point ✔️
    Line ✔️ ✔️
    Polygon ✔️ ✔️ ✔️
  • coveredby, within

    1st / 2nd Point Line Polygon
    Point ✔️ ✔️ ✔️
    Line ✔️ ✔️
    Polygon ✔️
  • crosses

    1st / 2nd Point Line Polygon
    Point ✔️ ✔️
    Line ✔️ ✔️ ✔️
    Polygon ✔️ ✔️
  • disjoint, intersects

    1st / 2nd Point Line Polygon
    Point ✔️ ✔️ ✔️
    Line ✔️ ✔️ ✔️
    Polygon ✔️ ✔️ ✔️
  • equals, overlaps

    1st / 2nd Point Line Polygon
    Point ✔️
    Line ✔️
    Polygon ✔️
  • touches

    1st / 2nd Point Line Polygon
    Point ✔️ ✔️
    Line ✔️ ✔️ ✔️
    Polygon ✔️ ✔️ ✔️

TIPS

The following are some best practices on using de9im:

  • Data is expected to be in WGS 84 coordinates as per the GeoJSON standard.

  • Data with the GeoJSON bbox attribute already defined will process faster.

  • Data with complex geometries (e.g., self-intersections, repeated coordinates) may produce invalid results.

  • Data coordinates should be truncated to avoid unrealistically high precision (more than 6 decimal places).

ALGORITHM NOTES

The de9im library uses a partition approach to determine if two geometries satisfy a given relation. This approach is different from the standard node/edge labeling used by most DE-9IM implementations. Labeling approaches are only defined for single geometries and not multi-geometries or collections and it is not clear how to extend them to cover those cases.

Instead, de9im partitions each input geometry into elementary facets, where each facet is either inside or outside the other geometry. For example, to test two (multi-) polygons, the first (multi-) polygon is triangulated. This triangulation gets intersected with the other (multi-) polygon's triangulation. This intersection gets re-triangulated to create a decomposition of the first (multi-) polygon such that each partition triangle (facet) is entirely inside or outside the second (multi-) polygon. Finally, the decision of whether the geometries satisfy the given predicate can be reduced to determining if the individual facets satisfy the relation. The same goes for lines using segments as the facets instead of triangles. This allows any geometry or collection type to be processed.

Finally, while de9im has turf as a dependency, it does not use its DE-9IM functions since it has only limited functionality and only covers a small subset of all possible geometry and predicate combinations. The goal of de9im is to cover all possible combinations. The turf library is only used for basic spatial processing and geometry utility functions.

BUILD

To build and test the library locally:

npm install
npm test

BENCHMARK

Benchmark timing results can be found at bench.md.

LICENSE

Copyright (c) 2019 Daniel Pulido mailto:[email protected]

Source code is released under the MIT License.

de9im's People

Contributors

dpmcmlxxvi avatar greenkeeper[bot] avatar snyk-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

de9im's Issues

An in-range update of rollup is breaking the build 🚨

The devDependency rollup was updated from 1.27.9 to 1.27.10.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

rollup is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes for v1.27.10

2019-12-11

Bug Fixes

  • Keep track of function return values in more situations (#3278)

Pull Requests

Commits

The new version differs by 3 commits.

  • a562ec5 1.27.10
  • 6a2b3f8 Update changelog
  • 31747e3 Avoid some unnecessary value tracking deoptimizations (#3278)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of eslint is breaking the build 🚨

The devDependency eslint was updated from 6.6.0 to 6.7.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

eslint is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes for v6.7.0
  • 312a88f New: Add grouped-accessor-pairs rule (fixes #12277) (#12331) (Milos Djermanovic)
  • 5c68f5f Update: Add 'lexicalBindings' to no-implicit-globals and change messages (#11996) (Milos Djermanovic)
  • 6eaad96 New: Add suggestions API (#12384) (Will Douglas)
  • b336fbe Fix: indent rule with JSX spread props (#12581) (Nathan Woltman)
  • 97c745d Update: Report assignment expression location in no-cond-assign (#12465) (Milos Djermanovic)
  • 0f01f3d Update: Check member expressions with this in operator-assignment (#12495) (Milos Djermanovic)
  • 62c7038 Fix: invalid token checking in computed-property-spacing (fixes #12198) (#12533) (YeonJuan)
  • 4f8a1ee Update: Add enforceForClassMembers option to no-useless-computed-key (#12110) (ark120202)
  • 1a2eb99 New: new rule no-constructor-return (fixes #12481) (#12529) (Pig Fang)
  • ca3b2a6 New: ignorePatterns in config files (refs eslint/rfcs#22) (#12274) (Toru Nagashima)
  • 60204a3 Docs: Added another Textmate 2 bundle. (#12580) (Ryan Fitzer)
  • 62623f9 Fix: preserve whitespace in multiline-comment-style (fixes #12312) (#12316) (Kai Cataldo)
  • 17a8849 New: Add no-dupe-else-if rule (fixes #12469) (#12504) (Milos Djermanovic)
  • 41a78fd Update: improve location for semi and comma-dangle (#12380) (Chiawen Chen)
  • 0a480f8 Docs: Change "Code Conventions" link in pull-requests.md (#12401) (Denis Sikuler)
  • fed20bb Fix: require-await crash on global await (#12571) (Brad Zacher)
  • b8030fc Update: deprecate personal config (fixes #11914, refs eslint/rfcs#32) (#12426) (Toru Nagashima)
  • 40c8c32 Fix: improve report location for object-curly-spacing (#12563) (Milos Djermanovic)
  • 1110045 Fix: ignore marker-only comments in spaced-comment (fixes #12036) (#12558) (Milos Djermanovic)
  • 6503cb8 Update: Fix uglified object align in key-spacing (fixes #11414) (#12472) (YeonJuan)
  • 40791af Docs: clarify ignoreDestructuring option in the camelcase rule (#12553) (Milos Djermanovic)
  • 07d398d Chore: Add GitHub organization to Sponsor button (#12562) (Brandon Mills)
  • a477707 Chore: Format style guide links so they can be clicked (#12189) (Ivan V)
  • 0f7edef Update: add react plugin config for eslint init (#12446) (Ibrahim Rouis)
  • 448ff1e Update: Report '\08' and '\09' in no-octal-escape (fixes #12080) (#12526) (Milos Djermanovic)
  • 45aa6a3 New: Add no-setter-return rule (fixes #12285) (#12346) (Milos Djermanovic)
  • 0afb518 Fix: invalid autofix in function-call-argument-newline (fixes #12454) (#12539) (YeonJuan)
  • 90305e0 Update: Depcrecate isSpaceBetweenTokens() (#12519) (Kai Cataldo)
  • 41b1e43 New: add option for camelcase (fixes #12527) (#12528) (Pig Fang)
  • f49f1e0 Upgrade: upgrade optionator to avoid license issue (fixes #11536) (#12537) (Pig Fang)
  • 0286b57 Docs: Clean up Getting Started Guide (#12544) (Nicholas C. Zakas)
  • 575a98d Chore: Add funding field to package.json (#12543) (Nicholas C. Zakas)
  • 9e29e18 Fix: sourceCode#isSpaceBetweenTokens() checks non-adjacent tokens (#12491) (Kai Cataldo)
  • 5868550 Docs: add notice about function keyword in keyword-spacing (#12524) (Pig Fang)
  • bb556d5 Fix: curly multi reports single lexical declarations (fixes #11908) (#12513) (Milos Djermanovic)
  • ac60621 Fix: unexpected autofix in prefer-const (fixes #12514) (#12521) (YeonJuan)
  • 990065e Update: curly multi-or-nest flagging semis on next line (fixes #12370) (#12378) (cherryblossom000)
  • 084a8a6 Fix: no-cond-assign with always option reports switch case clauses (#12470) (Milos Djermanovic)
  • 7e41355 Update: improve report location for space-infix-ops (#12324) (Chiawen Chen)
  • 94ff921 Update: Add capIsConstructor option to no-invalid-this (fixes #12271) (#12308) (Milos Djermanovic)
  • de65de6 New: Add prefer-exponentiation-operator rule (fixes #10482) (#12360) (Milos Djermanovic)
  • c78f4a7 Update: Allow JSX exception in no-inline-comments (fixes #11270) (#12388) (Milos Djermanovic)
  • e17fb90 New: allowAfterThisConstructor for no-underscore-dangle (fixes #11488) (#11489) (sripberger)
  • 287ca56 Build: update CI for Node.js 13 (#12496) (Toru Nagashima)
  • 98e1d50 Upgrade: globals to v12.1.0 (#12296) (Tony Brix)
  • 8ac71a3 Sponsors: Sync README with website (ESLint Jenkins)
  • 4e142ea Docs: Update README team and sponsors (ESLint Jenkins)
Commits

The new version differs by 49 commits.

  • 61848b4 6.7.0
  • 9162db9 Build: changelog update for 6.7.0
  • 312a88f New: Add grouped-accessor-pairs rule (fixes #12277) (#12331)
  • 5c68f5f Update: Add 'lexicalBindings' to no-implicit-globals and change messages (#11996)
  • 6eaad96 New: Add suggestions API (#12384)
  • b336fbe Fix: indent rule with JSX spread props (#12581)
  • 97c745d Update: Report assignment expression location in no-cond-assign (#12465)
  • 0f01f3d Update: Check member expressions with this in operator-assignment (#12495)
  • 62c7038 Fix: invalid token checking in computed-property-spacing (fixes #12198) (#12533)
  • 4f8a1ee Update: Add enforceForClassMembers option to no-useless-computed-key (#12110)
  • 1a2eb99 New: new rule no-constructor-return (fixes #12481) (#12529)
  • ca3b2a6 New: ignorePatterns in config files (refs eslint/rfcs#22) (#12274)
  • 60204a3 Docs: Added another Textmate 2 bundle. (#12580)
  • 62623f9 Fix: preserve whitespace in multiline-comment-style (fixes #12312) (#12316)
  • 17a8849 New: Add no-dupe-else-if rule (fixes #12469) (#12504)

There are 49 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Clean up build packaging

Keep in source control only what is needed and standardized the build files.

  • Remove the build files in lib from VCS.
  • Build a debug and release version (de9im.js and de9im.min.js).
  • Add a files property to keep only relevant files for an npm install user.

Allow 3D bbox.

helpers.disjoint assumes bboxes are 2D. Need to allow for 3D case and possibly mixed case.

Add browser test.

Current build supports a browser script but there is no actual test it. All testing is currently node only. Add a manual or automated headless browser test.

An in-range update of rollup is breaking the build 🚨


☝️ Important announcement: Greenkeeper will be saying goodbye 👋 and passing the torch to Snyk on June 3rd, 2020! Find out how to migrate to Snyk and more at greenkeeper.io


The devDependency rollup was updated from 2.3.1 to 2.3.2.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

rollup is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes for v2.3.2

2020-03-31

Bug Fixes

  • Only warn but do not fail build when a namespace is called as a function (#3475)
  • Make sure pre-existing sourcemap comments are also removed when rebuilding using the cache (#3476)

Pull Requests

Commits

The new version differs by 5 commits.

  • 85c59ba 2.3.2
  • 0580f82 Update changelog
  • 36cea37 Store locations for removed comments in cache (#3476)
  • c69c41b feat: Call namespace error as a warning (#3475)
  • 5eb01fb Fix documentation

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Extend docs to show edge cases of each method

I will quickly copy my testcase here in case someone else comes along and wonders about this.

My Question: How do the different methods handle cases where

  • a line is within an area
    vs.
  • a line is both in and out of an area

Conclusion: In my case, I want to use intersects which returns true for lines intersecting with the area.

image

contains:

de9im.contains(area, lineFullyWithinArea)) // ==> true
de9im.contains(area, lineInAndOutOfArea)) // ==> false

coveredby:

de9im.coveredby(lineFullyWithinArea, area)) // ==> true
de9im.coveredby(lineInAndOutOfArea, area)) // ==> false

crosses:

de9im.crosses(area, lineFullyWithinArea)) // ==> false
de9im.crosses(area, lineInAndOutOfArea)) // ==> true

intersects:

de9im.intersects(area, lineFullyWithinArea)) // ==> true
de9im.intersects(area, lineInAndOutOfArea)) // ==> true

within:

de9im.within(lineFullyWithinArea, area)) // ==> true
de9im.within(lineInAndOutOfArea, area)) // ==> false

The methods not listed here do not support this szenario.

Full test file
const area = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      properties: {},
      geometry: {
        type: "Polygon",
        coordinates: [
          [
            [13.587512969970701, 52.3013410761489],
            [13.619956970214844, 52.3013410761489],
            [13.619956970214844, 52.31141727938367],
            [13.587512969970701, 52.31141727938367],
            [13.587512969970701, 52.3013410761489],
          ],
        ],
      },
    },
  ],
}

const lineFullyWithinArea = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      properties: {},
      geometry: {
        type: "LineString",
        coordinates: [
          [13.594036102294922, 52.30595962063293],
          [13.613433837890625, 52.30784888634275],
        ],
      },
    },
  ],
}

const lineInAndOutOfArea = {
  type: "Feature",
  properties: {},
  geometry: {
    type: "LineString",
    coordinates: [
      [13.5955810546875, 52.30889844356715],
      [13.5955810546875, 52.313935971877584],
    ],
  },
}

import de9im from "de9im"

console.log(
  "de9im.contains(area, lineFullyWithinArea))",
  de9im.contains(area, lineFullyWithinArea)
)
console.log(
  "de9im.contains(area, lineInAndOutOfArea))",
  de9im.contains(area, lineInAndOutOfArea)
)
console.log(
  "de9im.coveredby(lineFullyWithinArea, area))",
  de9im.coveredby(lineFullyWithinArea, area)
)
console.log(
  "de9im.coveredby(lineInAndOutOfArea, area))",
  de9im.coveredby(lineInAndOutOfArea, area)
)
console.log(
  "de9im.crosses(area, lineFullyWithinArea))",
  de9im.crosses(area, lineFullyWithinArea)
)
console.log(
  "de9im.crosses(area, lineInAndOutOfArea))",
  de9im.crosses(area, lineInAndOutOfArea)
)
console.log(
  "de9im.intersects(area, lineFullyWithinArea))",
  de9im.intersects(area, lineFullyWithinArea)
)
console.log(
  "de9im.intersects(area, lineInAndOutOfArea))",
  de9im.intersects(area, lineInAndOutOfArea)
)
console.log(
  "de9im.within(lineFullyWithinArea, area))",
  de9im.within(lineFullyWithinArea, area)
)
console.log(
  "de9im.within(lineInAndOutOfArea, area))",
  de9im.within(lineInAndOutOfArea, area)
)

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

An in-range update of rollup is breaking the build 🚨

The devDependency rollup was updated from 1.18.0 to 1.19.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

rollup is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Commits

The new version differs by 6 commits.

  • 9af119d 1.19.0
  • b3f361c Update changelog
  • 456f4d2 Avoid variable from empty module name be empty (#3026)
  • 17eaa43 Use id of last module in chunk as name base for auto-generated chunks (#3025)
  • 871bfa0 Switch to a code-splitting build and update dependencies (#3020)
  • 2443783 Unified file emission api (#2999)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Use labeling algorithm for single shape geometries.

The current implementation uses a partition approach to determine relations between geometries. For example, a polygon gets an earcut triangulation which gets intersected with another polygon's triangulation to create a partition.

This partition is re-triangulated to create a decomposition of the original polygon such that each partition triangle is entirely inside or outside the other polygon. Same goes for lines using segments instead of triangles. This allows any geometry or collection type to be processed.

However, this may prove inefficient for simple shapes. So, a standard node/edge labeling approach to build the 9-intersection matrix may be faster for single-shape cases like Polygon/Polygon geometries.

An in-range update of rollup is breaking the build 🚨

The devDependency rollup was updated from 1.27.6 to 1.27.7.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

rollup is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes for v1.27.7

2019-12-01

Bug Fixes

  • Fix a scenario where a reassignments to computed properties were not tracked (#3267)

Pull Requests

Commits

The new version differs by 4 commits.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.