forked from MapComplete/MapComplete
Further refactoring of the tests
This commit is contained in:
parent
3ab373f6ec
commit
2dac893bb3
31 changed files with 2498 additions and 2992 deletions
|
@ -64,6 +64,15 @@ export class BBox {
|
|||
return new BBox([[maxLon, maxLat], [minLon, minLat]])
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the BBox based on a slippy map tile number
|
||||
*
|
||||
* const bbox = BBox.fromTile(16, 32754, 21785)
|
||||
* bbox.minLon // => -0.076904296875
|
||||
* bbox.maxLon // => -0.0714111328125
|
||||
* bbox.minLat // => 51.5292513551899
|
||||
* bbox.maxLat // => 51.53266860674158
|
||||
*/
|
||||
static fromTile(z: number, x: number, y: number): BBox {
|
||||
return new BBox(Tiles.tile_bounds_lon_lat(z, x, y))
|
||||
}
|
||||
|
|
|
@ -50,6 +50,19 @@ export class GeoOperations {
|
|||
*
|
||||
* If 'feature' is a point, it will return every feature the point is embedded in. Overlap will be undefined
|
||||
*
|
||||
* const polygon = {"type": "Feature","properties": {},"geometry": {"type": "Polygon","coordinates": [[[1.8017578124999998,50.401515322782366],[-3.1640625,46.255846818480315],[5.185546875,44.74673324024678],[1.8017578124999998,50.401515322782366]]]}};
|
||||
* const point = {"type": "Feature", "properties": {}, "geometry": { "type": "Point", "coordinates": [2.274169921875, 46.76244305208004]}};
|
||||
* const overlap = GeoOperations.calculateOverlap(point, [polygon]);
|
||||
* overlap.length // => 1
|
||||
* overlap[0].feat == polygon // => true
|
||||
* const line = {"type": "Feature","properties": {},"geometry": {"type": "LineString","coordinates": [[3.779296875,48.777912755501845],[1.23046875,47.60616304386874]]}};
|
||||
* const lineOverlap = GeoOperations.calculateOverlap(line, [polygon]);
|
||||
* lineOverlap.length // => 1
|
||||
* lineOverlap[0].overlap // => 156745.3293320278
|
||||
* lineOverlap[0].feat == polygon // => true
|
||||
* const line0 = {"type": "Feature","properties": {},"geometry": {"type": "LineString","coordinates": [[0.0439453125,47.31648293428332],[0.6591796875,46.77749276376827]]}};
|
||||
* const overlap0 = GeoOperations.calculateOverlap(line0, [polygon]);
|
||||
* overlap.length // => 1
|
||||
*/
|
||||
static calculateOverlap(feature: any, otherFeatures: any[]): { feat: any, overlap: number }[] {
|
||||
|
||||
|
@ -138,6 +151,28 @@ export class GeoOperations {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect wether or not the given point is located in the feature
|
||||
*
|
||||
* // Should work with a normal polygon
|
||||
* const polygon = {"type": "Feature","properties": {},"geometry": {"type": "Polygon","coordinates": [[[1.8017578124999998,50.401515322782366],[-3.1640625,46.255846818480315],[5.185546875,44.74673324024678],[1.8017578124999998,50.401515322782366]]]}};
|
||||
* GeoOperations.inside([3.779296875, 48.777912755501845], polygon) // => false
|
||||
* GeoOperations.inside([1.23046875, 47.60616304386874], polygon) // => true
|
||||
*
|
||||
* // should work with a multipolygon and detect holes
|
||||
* const 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]]
|
||||
* ]]
|
||||
* }
|
||||
* };
|
||||
* GeoOperations.inside([2.515869140625, 47.37603463349758], multiPolygon) // => true
|
||||
* GeoOperations.inside([1.42822265625, 48.61838518688487], multiPolygon) // => false
|
||||
* GeoOperations.inside([4.02099609375, 47.81315451752768], multiPolygon) // => false
|
||||
*/
|
||||
public static inside(pointCoordinate, feature): boolean {
|
||||
// ray-casting algorithm based on
|
||||
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||
|
|
|
@ -158,10 +158,11 @@ export class UIEventSource<T> {
|
|||
)
|
||||
}
|
||||
|
||||
public AsPromise(): Promise<T> {
|
||||
public AsPromise(condition?: ((t: T )=> boolean)): Promise<T> {
|
||||
const self = this;
|
||||
condition = condition ?? (t => t !== undefined)
|
||||
return new Promise((resolve, reject) => {
|
||||
if (self.data !== undefined) {
|
||||
if (condition(self.data)) {
|
||||
resolve(self.data)
|
||||
} else {
|
||||
self.addCallbackD(data => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue