99 lines
1.6 KiB
JavaScript
99 lines
1.6 KiB
JavaScript
// public/js/map/spatialIndex.js
|
|
// ===============================
|
|
// INDICE SPAZIALE FOTO (RBush)
|
|
// ===============================
|
|
|
|
(function () {
|
|
"use strict";
|
|
|
|
if (!window.GP) {
|
|
window.GP = {};
|
|
}
|
|
|
|
if (!window.GP.libs?.RBush) {
|
|
console.error("[spatialIndex] RBush non disponibile");
|
|
return;
|
|
}
|
|
|
|
const tree = new window.GP.libs.RBush();
|
|
|
|
let indexed = false;
|
|
let totalItems = 0;
|
|
|
|
function build(items) {
|
|
tree.clear();
|
|
|
|
const nodes = [];
|
|
|
|
for (const item of items) {
|
|
const lat = Number(item?.gps?.lat);
|
|
const lng = Number(item?.gps?.lng);
|
|
|
|
if (!Number.isFinite(lat) || !Number.isFinite(lng)) {
|
|
continue;
|
|
}
|
|
|
|
nodes.push({
|
|
minX: lng,
|
|
minY: lat,
|
|
maxX: lng,
|
|
maxY: lat,
|
|
|
|
id: item.id,
|
|
lat,
|
|
lng,
|
|
item,
|
|
});
|
|
}
|
|
|
|
tree.load(nodes);
|
|
|
|
indexed = true;
|
|
totalItems = nodes.length;
|
|
|
|
console.log("[spatialIndex] indicizzate", totalItems, "foto");
|
|
}
|
|
|
|
function search(bounds) {
|
|
if (!indexed) {
|
|
return [];
|
|
}
|
|
|
|
// ricerca globale
|
|
if (!bounds) {
|
|
return tree.all();
|
|
}
|
|
|
|
return tree.search({
|
|
minX: bounds.getWest(),
|
|
minY: bounds.getSouth(),
|
|
maxX: bounds.getEast(),
|
|
maxY: bounds.getNorth(),
|
|
});
|
|
}
|
|
|
|
function clear() {
|
|
tree.clear();
|
|
indexed = false;
|
|
totalItems = 0;
|
|
}
|
|
|
|
function stats() {
|
|
return {
|
|
indexed,
|
|
totalItems,
|
|
};
|
|
}
|
|
|
|
function isBuilt() {
|
|
return indexed;
|
|
}
|
|
|
|
window.MapSpatialIndex = {
|
|
build,
|
|
search,
|
|
clear,
|
|
stats,
|
|
isBuilt,
|
|
};
|
|
})();
|