Add workaround for turf.intersect which can't deal with touching polygons

This commit is contained in:
pietervdvn 2021-12-24 02:48:04 +01:00
parent d7d60da148
commit 92c63560ef
5 changed files with 2077 additions and 1827 deletions

View file

@ -357,7 +357,6 @@ export class GeoOperations {
* Returns null if the features are not intersecting * Returns null if the features are not intersecting
*/ */
private static calculateInstersection(feature, otherFeature, featureBBox: BBox, otherFeatureBBox?: BBox): number { private static calculateInstersection(feature, otherFeature, featureBBox: BBox, otherFeatureBBox?: BBox): number {
try {
if (feature.geometry.type === "LineString") { if (feature.geometry.type === "LineString") {
@ -427,19 +426,25 @@ export class GeoOperations {
return this.calculateInstersection(otherFeature, feature, otherFeatureBBox, featureBBox) return this.calculateInstersection(otherFeature, feature, otherFeatureBBox, featureBBox)
} }
try{
const intersection = turf.intersect(feature, otherFeature); const intersection = turf.intersect(feature, otherFeature);
if (intersection == null) { if (intersection == null) {
return null; return null;
} }
return turf.area(intersection); // in m² return turf.area(intersection); // in m²
}catch(e){
if(e.message === "Each LinearRing of a Polygon must have 4 or more Positions."){
// WORKAROUND TIME!
// See https://github.com/Turfjs/turf/pull/2238
return null;
}
throw e;
}
} }
throw "CalculateIntersection fallthrough: can not calculate an intersection between features"
} catch (exception) {
console.warn("EXCEPTION CAUGHT WHILE INTERSECTING: ", exception,"\nThe considered objects are",feature, otherFeature);
return undefined
}
return undefined;
} }
/** /**

3850
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -59,11 +59,11 @@
"license": "GPL", "license": "GPL",
"dependencies": { "dependencies": {
"@babel/preset-env": "7.13.8", "@babel/preset-env": "7.13.8",
"@turf/buffer": "^6.3.0", "@turf/buffer": "^6.5.0",
"@turf/collect": "^6.3.0", "@turf/collect": "^6.5.0",
"@turf/distance": "^6.3.0", "@turf/distance": "^6.5.0",
"@turf/length": "^6.3.0", "@turf/length": "^6.5.0",
"@turf/turf": "^6.3.0", "@turf/turf": "^6.5.0",
"@types/jquery": "^3.5.5", "@types/jquery": "^3.5.5",
"@types/leaflet-markercluster": "^1.0.3", "@types/leaflet-markercluster": "^1.0.3",
"@types/leaflet-providers": "^1.2.0", "@types/leaflet-providers": "^1.2.0",

View file

@ -3,6 +3,7 @@ import {equal} from "assert";
import T from "./TestHelper"; import T from "./TestHelper";
import {GeoOperations} from "../Logic/GeoOperations"; import {GeoOperations} from "../Logic/GeoOperations";
import {BBox} from "../Logic/BBox"; import {BBox} from "../Logic/BBox";
import * as turf from "@turf/turf"
export default class GeoOperationsSpec extends T { export default class GeoOperationsSpec extends T {
@ -187,7 +188,7 @@ export default class GeoOperationsSpec extends T {
], ],
["Regression test: intersection/overlap", () => { ["Regression test: intersection/overlap", () => {
const polyGrb ={ const polyGrb = {
"type": "Feature", "type": "Feature",
"properties": { "properties": {
"osm_id": "25189153", "osm_id": "25189153",
@ -351,10 +352,15 @@ export default class GeoOperationsSpec extends T {
} }
} }
const p0 = turf.polygon(polyGrb.geometry.coordinates)
Assert.notEqual(p0, null)
const p1 = turf.polygon(polyHouse.geometry.coordinates)
Assert.notEqual(p1, null)
const overlaps = GeoOperations.calculateOverlap(polyGrb, [polyHouse]) const overlaps = GeoOperations.calculateOverlap(polyGrb, [polyHouse])
Assert.equal(overlaps.length, 1) Assert.equal(overlaps.length, 0)
const overlapsRev= GeoOperations.calculateOverlap(polyHouse, [polyGrb]) const overlapsRev = GeoOperations.calculateOverlap(polyHouse, [polyGrb])
Assert.equal(overlaps.length, 1) Assert.equal(overlapsRev.length, 0)
}] }]
] ]

View file

@ -1,9 +1,9 @@
export default class T { export default class T {
public readonly name: string; public readonly name: string;
private readonly _tests: [string, (() => void)][]; private readonly _tests: [string, (() => (void | Promise<void>))][];
constructor(testsuite: string, tests: [string, () => void][]) { constructor(testsuite: string, tests: [string, () => (Promise<void> | void)][]) {
this.name = testsuite this.name = testsuite
this._tests = tests; this._tests = tests;
} }
@ -60,7 +60,14 @@ export default class T {
const failures: { testsuite: string, name: string, msg: string } [] = [] const failures: { testsuite: string, name: string, msg: string } [] = []
for (const [name, test] of this._tests) { for (const [name, test] of this._tests) {
try { try {
test(); const r = test()
if (r instanceof Promise) {
r.catch(e => {
console.log("ASYNC ERROR: ", e, e.stack)
failures.push({testsuite: this.name, name: name, msg: "" + e});
});
}
} catch (e) { } catch (e) {
console.log("ERROR: ", e, e.stack) console.log("ERROR: ", e, e.stack)
failures.push({testsuite: this.name, name: name, msg: "" + e}); failures.push({testsuite: this.name, name: name, msg: "" + e});