forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			450 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			450 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import * as Assert from "assert";
 | 
						|
import {equal} from "assert";
 | 
						|
import T from "./TestHelper";
 | 
						|
import {GeoOperations} from "../Logic/GeoOperations";
 | 
						|
import {BBox} from "../Logic/BBox";
 | 
						|
import * as turf from "@turf/turf"
 | 
						|
 | 
						|
export default class GeoOperationsSpec extends T {
 | 
						|
 | 
						|
    private static polygon = {
 | 
						|
        "type": "Feature",
 | 
						|
        "properties": {},
 | 
						|
        "geometry": {
 | 
						|
            "type": "Polygon",
 | 
						|
            "coordinates": [
 | 
						|
                [
 | 
						|
                    [
 | 
						|
                        1.8017578124999998,
 | 
						|
                        50.401515322782366
 | 
						|
                    ],
 | 
						|
                    [
 | 
						|
                        -3.1640625,
 | 
						|
                        46.255846818480315
 | 
						|
                    ],
 | 
						|
                    [
 | 
						|
                        5.185546875,
 | 
						|
                        44.74673324024678
 | 
						|
                    ],
 | 
						|
                    [
 | 
						|
                        1.8017578124999998,
 | 
						|
                        50.401515322782366
 | 
						|
                    ]
 | 
						|
                ]
 | 
						|
            ]
 | 
						|
        }
 | 
						|
    };
 | 
						|
    private static multiPolygon = {
 | 
						|
        "type": "Feature",
 | 
						|
        "properties": {},
 | 
						|
        "geometry": {
 | 
						|
            "type": "MultiPolygon",
 | 
						|
            "coordinates": [[
 | 
						|
                [
 | 
						|
                    [
 | 
						|
                        1.8017578124999998,
 | 
						|
                        50.401515322782366
 | 
						|
                    ],
 | 
						|
                    [
 | 
						|
                        -3.1640625,
 | 
						|
                        46.255846818480315
 | 
						|
                    ],
 | 
						|
                    [
 | 
						|
                        5.185546875,
 | 
						|
                        44.74673324024678
 | 
						|
                    ],
 | 
						|
                    [
 | 
						|
                        1.8017578124999998,
 | 
						|
                        50.401515322782366
 | 
						|
                    ]
 | 
						|
                ],
 | 
						|
                [
 | 
						|
                    [
 | 
						|
                        1.0107421875,
 | 
						|
                        48.821332549646634
 | 
						|
                    ],
 | 
						|
                    [
 | 
						|
                        1.329345703125,
 | 
						|
                        48.25394114463431
 | 
						|
                    ],
 | 
						|
                    [
 | 
						|
                        1.988525390625,
 | 
						|
                        48.71271258145237
 | 
						|
                    ],
 | 
						|
                    [
 | 
						|
                        0.999755859375,
 | 
						|
                        48.86471476180277
 | 
						|
                    ],
 | 
						|
                    [
 | 
						|
                        1.0107421875,
 | 
						|
                        48.821332549646634
 | 
						|
                    ]
 | 
						|
                ]
 | 
						|
            ]]
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    private static inHole = [1.42822265625, 48.61838518688487]
 | 
						|
    private static inMultiPolygon = [2.515869140625, 47.37603463349758]
 | 
						|
    private static outsidePolygon = [4.02099609375, 47.81315451752768]
 | 
						|
 | 
						|
    constructor() {
 | 
						|
        super([
 | 
						|
                ["Point out of polygon", () => {
 | 
						|
                    GeoOperationsSpec.isFalse(GeoOperations.inside([
 | 
						|
                        3.779296875,
 | 
						|
                        48.777912755501845
 | 
						|
                    ], GeoOperationsSpec.polygon), "Point is outside of the polygon");
 | 
						|
                }
 | 
						|
 | 
						|
                ],
 | 
						|
                ["Point inside of polygon", () => {
 | 
						|
 | 
						|
                    GeoOperationsSpec.isTrue(GeoOperations.inside([
 | 
						|
                        1.23046875,
 | 
						|
                        47.60616304386874
 | 
						|
                    ], GeoOperationsSpec.polygon), "Point is inside of the polygon");
 | 
						|
                }
 | 
						|
                ],
 | 
						|
                ["MultiPolygonTest", () => {
 | 
						|
 | 
						|
                    const isTrue = GeoOperationsSpec.isTrue;
 | 
						|
                    const isFalse = GeoOperationsSpec.isFalse;
 | 
						|
 | 
						|
                    isFalse(GeoOperations.inside(GeoOperationsSpec.inHole, GeoOperationsSpec.multiPolygon), "InHole was detected as true");
 | 
						|
                    isTrue(GeoOperations.inside(GeoOperationsSpec.inMultiPolygon, GeoOperationsSpec.multiPolygon), "InMultiPolgyon was not detected as true");
 | 
						|
                    isFalse(GeoOperations.inside(GeoOperationsSpec.outsidePolygon, GeoOperationsSpec.multiPolygon), "OutsideOfPolygon was detected as true");
 | 
						|
 | 
						|
                }],
 | 
						|
                ["Intersection between a line and a polygon", () => {
 | 
						|
                    const line = {
 | 
						|
                        "type": "Feature",
 | 
						|
                        "properties": {},
 | 
						|
                        "geometry": {
 | 
						|
                            "type": "LineString",
 | 
						|
                            "coordinates": [
 | 
						|
                                [
 | 
						|
                                    3.779296875,
 | 
						|
                                    48.777912755501845
 | 
						|
                                ],
 | 
						|
                                [
 | 
						|
                                    1.23046875,
 | 
						|
                                    47.60616304386874
 | 
						|
                                ]
 | 
						|
                            ]
 | 
						|
                        }
 | 
						|
                    };
 | 
						|
 | 
						|
                    const overlap = GeoOperations.calculateOverlap(line, [GeoOperationsSpec.polygon]);
 | 
						|
                    Assert.equal(1, overlap.length)
 | 
						|
                }],
 | 
						|
                ["Fully enclosed", () => {
 | 
						|
                    const line = {
 | 
						|
                        "type": "Feature",
 | 
						|
                        "properties": {},
 | 
						|
                        "geometry": {
 | 
						|
                            "type": "LineString",
 | 
						|
                            "coordinates": [
 | 
						|
                                [
 | 
						|
                                    0.0439453125,
 | 
						|
                                    47.31648293428332
 | 
						|
                                ],
 | 
						|
                                [
 | 
						|
                                    0.6591796875,
 | 
						|
                                    46.77749276376827
 | 
						|
                                ]
 | 
						|
                            ]
 | 
						|
                        }
 | 
						|
                    };
 | 
						|
 | 
						|
                    const overlap = GeoOperations.calculateOverlap(line, [GeoOperationsSpec.polygon]);
 | 
						|
                    Assert.equal(1, overlap.length)
 | 
						|
                }],
 | 
						|
                ["overlapWith matches points too", () => {
 | 
						|
                    const point = {
 | 
						|
                        "type": "Feature",
 | 
						|
                        "properties": {},
 | 
						|
                        "geometry": {
 | 
						|
                            "type": "Point",
 | 
						|
                            "coordinates": [
 | 
						|
                                2.274169921875,
 | 
						|
                                46.76244305208004
 | 
						|
                            ]
 | 
						|
                        }
 | 
						|
                    };
 | 
						|
 | 
						|
                    const overlap = GeoOperations.calculateOverlap(point, [GeoOperationsSpec.polygon]);
 | 
						|
                    Assert.equal(1, overlap.length)
 | 
						|
                }],
 | 
						|
                ["bbox bounds test",
 | 
						|
                    () => {
 | 
						|
                        const bbox = BBox.fromTile(16, 32754, 21785)
 | 
						|
                        equal(-0.076904296875, bbox.minLon)
 | 
						|
                        equal(-0.0714111328125, bbox.maxLon)
 | 
						|
                        equal(51.5292513551899, bbox.minLat)
 | 
						|
                        equal(51.53266860674158, bbox.maxLat)
 | 
						|
                    }
 | 
						|
                ],
 | 
						|
                ["Regression test: intersection/overlap", () => {
 | 
						|
 | 
						|
                    const polyGrb = {
 | 
						|
                        "type": "Feature",
 | 
						|
                        "properties": {
 | 
						|
                            "osm_id": "25189153",
 | 
						|
                            "size_grb_building": "217.14",
 | 
						|
                            "addr:housenumber": "173",
 | 
						|
                            "addr:street": "Kortrijksestraat",
 | 
						|
                            "building": "house",
 | 
						|
                            "source:geometry:entity": "Gbg",
 | 
						|
                            "source:geometry:date": "2015/02/27",
 | 
						|
                            "source:geometry:oidn": "1729460",
 | 
						|
                            "source:geometry:uidn": "8713648",
 | 
						|
                            "H_DTM_MIN": "17.28",
 | 
						|
                            "H_DTM_GEM": "17.59",
 | 
						|
                            "H_DSM_MAX": "29.04",
 | 
						|
                            "H_DSM_P99": "28.63",
 | 
						|
                            "HN_MAX": "11.45",
 | 
						|
                            "HN_P99": "11.04",
 | 
						|
                            "detection_method": "from existing OSM building source: house ,hits (3)",
 | 
						|
                            "auto_building": "house",
 | 
						|
                            "size_shared": "210.68",
 | 
						|
                            "size_source_building": "212.63",
 | 
						|
                            "id": "https://betadata.grbosm.site/grb?bbox=360935.6475626023,6592540.815539878,361088.52161917265,6592693.689596449/37",
 | 
						|
                            "_lat": "50.83736194999996",
 | 
						|
                            "_lon": "3.2432137000000116",
 | 
						|
                            "_layer": "GRB",
 | 
						|
                            "_length": "48.51529464293261",
 | 
						|
                            "_length:km": "0.0",
 | 
						|
                            "_now:date": "2021-12-05",
 | 
						|
                            "_now:datetime": "2021-12-05 21:51:40",
 | 
						|
                            "_loaded:date": "2021-12-05",
 | 
						|
                            "_loaded:datetime": "2021-12-05 21:51:40"
 | 
						|
                        },
 | 
						|
                        "geometry": {
 | 
						|
                            "type": "Polygon",
 | 
						|
                            "coordinates": [
 | 
						|
                                [
 | 
						|
                                    [
 | 
						|
                                        3.2431059999999974,
 | 
						|
                                        50.83730270000021
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.243174299999987,
 | 
						|
                                        50.83728850000007
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.2432116000000173,
 | 
						|
                                        50.83736910000003
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.2433214000000254,
 | 
						|
                                        50.83740350000011
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.24329779999996,
 | 
						|
                                        50.837435399999855
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.2431881000000504,
 | 
						|
                                        50.83740090000025
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.243152699999997,
 | 
						|
                                        50.83738980000017
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.2431059999999974,
 | 
						|
                                        50.83730270000021
 | 
						|
                                    ]
 | 
						|
                                ]
 | 
						|
                            ]
 | 
						|
                        },
 | 
						|
                        "id": "https://betadata.grbosm.site/grb?bbox=360935.6475626023,6592540.815539878,361088.52161917265,6592693.689596449/37",
 | 
						|
                        "_lon": 3.2432137000000116,
 | 
						|
                        "_lat": 50.83736194999996,
 | 
						|
                        "bbox": {
 | 
						|
                            "maxLat": 50.837435399999855,
 | 
						|
                            "maxLon": 3.2433214000000254,
 | 
						|
                            "minLat": 50.83728850000007,
 | 
						|
                            "minLon": 3.2431059999999974
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    const polyHouse = {
 | 
						|
                        "type": "Feature",
 | 
						|
                        "id": "way/594963177",
 | 
						|
                        "properties": {
 | 
						|
                            "timestamp": "2021-12-05T04:04:55Z",
 | 
						|
                            "version": 3,
 | 
						|
                            "changeset": 114571409,
 | 
						|
                            "user": "Pieter Vander Vennet",
 | 
						|
                            "uid": 3818858,
 | 
						|
                            "addr:housenumber": "171",
 | 
						|
                            "addr:street": "Kortrijksestraat",
 | 
						|
                            "building": "house",
 | 
						|
                            "source:geometry:date": "2018-10-22",
 | 
						|
                            "source:geometry:ref": "Gbg/5096537",
 | 
						|
                            "_last_edit:contributor": "Pieter Vander Vennet",
 | 
						|
                            "_last_edit:contributor:uid": 3818858,
 | 
						|
                            "_last_edit:changeset": 114571409,
 | 
						|
                            "_last_edit:timestamp": "2021-12-05T04:04:55Z",
 | 
						|
                            "_version_number": 3,
 | 
						|
                            "id": "way/594963177",
 | 
						|
                            "_backend": "https://www.openstreetmap.org",
 | 
						|
                            "_lat": "50.83736395",
 | 
						|
                            "_lon": "3.2430937",
 | 
						|
                            "_layer": "OSM-buildings",
 | 
						|
                            "_length": "43.561938680928506",
 | 
						|
                            "_length:km": "0.0",
 | 
						|
                            "_now:date": "2021-12-05",
 | 
						|
                            "_now:datetime": "2021-12-05 21:51:40",
 | 
						|
                            "_loaded:date": "2021-12-05",
 | 
						|
                            "_loaded:datetime": "2021-12-05 21:51:39",
 | 
						|
                            "_surface": "93.32785810484549",
 | 
						|
                            "_surface:ha": "0"
 | 
						|
                        },
 | 
						|
                        "geometry": {
 | 
						|
                            "type": "Polygon",
 | 
						|
                            "coordinates": [
 | 
						|
                                [
 | 
						|
                                    [
 | 
						|
                                        3.2429993,
 | 
						|
                                        50.8373243
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.243106,
 | 
						|
                                        50.8373027
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.2431527,
 | 
						|
                                        50.8373898
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.2431881,
 | 
						|
                                        50.8374009
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.2431691,
 | 
						|
                                        50.8374252
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.2430936,
 | 
						|
                                        50.837401
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.243046,
 | 
						|
                                        50.8374112
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        3.2429993,
 | 
						|
                                        50.8373243
 | 
						|
                                    ]
 | 
						|
                                ]
 | 
						|
                            ]
 | 
						|
                        },
 | 
						|
                        "_lon": 3.2430937,
 | 
						|
                        "_lat": 50.83736395,
 | 
						|
                        "bbox": {
 | 
						|
                            "maxLat": 50.8374252,
 | 
						|
                            "maxLon": 3.2431881,
 | 
						|
                            "minLat": 50.8373027,
 | 
						|
                            "minLon": 3.2429993
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    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])
 | 
						|
                    Assert.equal(overlaps.length, 0)
 | 
						|
                    const overlapsRev = GeoOperations.calculateOverlap(polyHouse, [polyGrb])
 | 
						|
                    Assert.equal(overlapsRev.length, 0)
 | 
						|
 | 
						|
                }],
 | 
						|
                ["Overnode removal test", () => {
 | 
						|
 | 
						|
                    const feature = {
 | 
						|
                        "geometry": {
 | 
						|
                            "type": "Polygon",
 | 
						|
                            "coordinates": [
 | 
						|
                                [
 | 
						|
                                    [
 | 
						|
                                        4.477944199999975,
 | 
						|
                                        51.02783550000022
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        4.477987899999996,
 | 
						|
                                        51.027818800000034
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        4.478004500000021,
 | 
						|
                                        51.02783399999988
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        4.478025499999962,
 | 
						|
                                        51.02782489999994
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        4.478079099999993,
 | 
						|
                                        51.027873899999896
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        4.47801040000006,
 | 
						|
                                        51.027903799999955
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        4.477964799999972,
 | 
						|
                                        51.02785709999982
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        4.477964699999964,
 | 
						|
                                        51.02785690000006
 | 
						|
                                    ],
 | 
						|
                                    [
 | 
						|
                                        4.477944199999975,
 | 
						|
                                        51.02783550000022
 | 
						|
                                    ]
 | 
						|
                                ]
 | 
						|
                            ]
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    const copy = GeoOperations.removeOvernoding(feature)
 | 
						|
                    Assert.equal(copy.geometry.coordinates[0].length, 7)
 | 
						|
                    T.listIdentical([
 | 
						|
                        [
 | 
						|
                            4.477944199999975,
 | 
						|
                            51.02783550000022
 | 
						|
                        ],
 | 
						|
                        [
 | 
						|
                            4.477987899999996,
 | 
						|
                            51.027818800000034
 | 
						|
                        ],
 | 
						|
                        [
 | 
						|
                            4.478004500000021,
 | 
						|
                            51.02783399999988
 | 
						|
                        ],
 | 
						|
                        [
 | 
						|
                            4.478025499999962,
 | 
						|
                            51.02782489999994
 | 
						|
                        ],
 | 
						|
                        [
 | 
						|
                            4.478079099999993,
 | 
						|
                            51.027873899999896
 | 
						|
                        ],
 | 
						|
                        [
 | 
						|
                            4.47801040000006,
 | 
						|
                            51.027903799999955
 | 
						|
                        ],
 | 
						|
                        [
 | 
						|
                            4.477944199999975,
 | 
						|
                            51.02783550000022
 | 
						|
                        ]
 | 
						|
                    ], copy.geometry.coordinates[0])
 | 
						|
                }]
 | 
						|
            ]
 | 
						|
        )
 | 
						|
 | 
						|
    }
 | 
						|
}
 |