|
|
|
@ -2,8 +2,9 @@ import React, { useEffect, useState, useContext } from 'react'; |
|
|
|
|
import NodeEnvironment from 'jest-environment-node'; |
|
|
|
|
|
|
|
|
|
import { add_geo_area_to_store, get_geo_area_from_store } from './geo_store.js'; |
|
|
|
|
import * as turf from '@turf/turf' |
|
|
|
|
|
|
|
|
|
import pointsWithinPolygon from '@turf/points-within-polygon'; |
|
|
|
|
import KDBush from 'kdbush'; |
|
|
|
|
|
|
|
|
|
export async function sqljs_async_queries(sqljs_object, queries) { |
|
|
|
|
//var t0 = performance.now();
|
|
|
|
@ -109,37 +110,96 @@ export async function add_full_tag_info(db) { |
|
|
|
|
|
|
|
|
|
function polygons_benchmark(database) { |
|
|
|
|
var img_query = "SELECT Images.id, ImagePositions.latitudeNumber, ImagePositions.longitudeNumber FROM Images " |
|
|
|
|
+ "LEFT JOIN ImagePositions ON ImagePositions.imageid=Images.id GROUP BY Images.id;"; |
|
|
|
|
+ "LEFT JOIN ImagePositions ON ImagePositions.imageid=Images.id WHERE ImagePositions.latitudeNumber NOT NULL GROUP BY Images.id;"; |
|
|
|
|
|
|
|
|
|
sqljs_async_queries(database, [img_query]).then(res => { |
|
|
|
|
fetch("https://nominatim.openstreetmap.org/search?polygon_geojson=1&polygon_threshold=0.001&format=json&limit=5&q=Australia") |
|
|
|
|
fetch("https://nominatim.openstreetmap.org/search?polygon_geojson=1&polygon_threshold=0.001&format=json&limit=1&q=Australia") |
|
|
|
|
.then(res => res.json()) |
|
|
|
|
.then(jsonres => { |
|
|
|
|
var geojson; |
|
|
|
|
var polies; |
|
|
|
|
var points = []; |
|
|
|
|
|
|
|
|
|
console.log("Nominatim geo answer:", jsonres); |
|
|
|
|
|
|
|
|
|
if (Array.isArray(jsonres) && jsonres.length > 0) { |
|
|
|
|
geojson = jsonres[0].geojson; |
|
|
|
|
polies = jsonres[0].geojson; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (res && Array.isArray(res) && res.length > 0) { |
|
|
|
|
var cols = res[0].columns; |
|
|
|
|
var data = res[0].values; |
|
|
|
|
data.forEach(row => { |
|
|
|
|
points.push([row[cols.indexOf("longitudeNumber")], row[cols.indexOf("latitudeNumber")]]); |
|
|
|
|
points.push([parseFloat(row[cols.indexOf("longitudeNumber")]), parseFloat(row[cols.indexOf("latitudeNumber")])]); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
console.log("Points: ", points); |
|
|
|
|
console.log("GEOJSON: ", geojson); |
|
|
|
|
|
|
|
|
|
console.time("points within polygon"); |
|
|
|
|
var found = pointsWithinPolygon(points, geojson); |
|
|
|
|
console.timeEnd("points within polygon"); |
|
|
|
|
console.log("Nominatim GEOJSON: ", polies); |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
// Try Turf
|
|
|
|
|
const tpoints = turf.points(points); |
|
|
|
|
console.time("Turf points within polygon"); |
|
|
|
|
var found = turf.pointsWithinPolygon(tpoints, polies); |
|
|
|
|
console.timeEnd("Turf points within polygon"); |
|
|
|
|
console.log("Turf PointsWithinPolygon: ", found); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
console.log("PointsWithinPolygon: ", found); |
|
|
|
|
{ |
|
|
|
|
// Try KDBush
|
|
|
|
|
console.time("Build KDBush index"); |
|
|
|
|
const index = new KDBush(points, p => p[0], p => p[1], 16, Float64Array); |
|
|
|
|
console.timeEnd("Build KDBush index"); |
|
|
|
|
|
|
|
|
|
// Get bounding boxes for all subpolygons
|
|
|
|
|
var boxes = []; |
|
|
|
|
console.time("Build KDBush poly boxes"); |
|
|
|
|
for (let i = 0; i < polies.coordinates.length; i++) { |
|
|
|
|
const outerPoly = polies.coordinates[i][0]; |
|
|
|
|
var minx = Number.POSITIVE_INFINITY; |
|
|
|
|
var miny = Number.POSITIVE_INFINITY; |
|
|
|
|
var maxx = Number.NEGATIVE_INFINITY; |
|
|
|
|
var maxy = Number.NEGATIVE_INFINITY; |
|
|
|
|
for (let j = 0; j < outerPoly.length; j++) { |
|
|
|
|
minx = Math.min(minx, outerPoly[j][0]); |
|
|
|
|
miny = Math.min(miny, outerPoly[j][1]); |
|
|
|
|
maxx = Math.max(maxx, outerPoly[j][0]); |
|
|
|
|
maxy = Math.max(maxy, outerPoly[j][1]); |
|
|
|
|
} |
|
|
|
|
boxes.push([minx, miny, maxx, maxy]); |
|
|
|
|
} |
|
|
|
|
console.timeEnd("Build KDBush poly boxes"); |
|
|
|
|
console.log("KDBush boxes: ", boxes); |
|
|
|
|
|
|
|
|
|
// Test points in KD tree against each subpolygon bounding box
|
|
|
|
|
console.time("Find box points in KDBush"); |
|
|
|
|
let hits = new Set(); |
|
|
|
|
for (let i = 0; i < boxes.length; i++) { |
|
|
|
|
const ids = index.range(boxes[i][0], boxes[i][1], boxes[i][2], boxes[i][3]); |
|
|
|
|
ids.forEach(e => hits.add(e)); |
|
|
|
|
} |
|
|
|
|
console.timeEnd("Find box points in KDBush"); |
|
|
|
|
console.log("Hits: ", hits); |
|
|
|
|
|
|
|
|
|
// Test hit points exactly
|
|
|
|
|
console.time("Get exact hits after KDBush"); |
|
|
|
|
var realhits = []; |
|
|
|
|
var hitcache = {}; |
|
|
|
|
hits.forEach(hit => { |
|
|
|
|
const point = points[hit]; |
|
|
|
|
if(point in hitcache && hitcache[point]) { |
|
|
|
|
realhits.push(hit); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
const is_real_hit = turf.booleanPointInPolygon(turf.point(points[hit]), polies); |
|
|
|
|
hitcache[point] = is_real_hit; |
|
|
|
|
if(is_real_hit){ |
|
|
|
|
realhits.push(hit); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
console.log("Real: ", realhits); |
|
|
|
|
console.timeEnd("Get exact hits after KDBush"); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}) |
|
|
|
|
.catch(err => { throw err; }); |
|
|
|
|