import { FilterParams, PagingParams, DataPage } from "pip-services3-commons-nodex"; import { IdentifiableMemoryPersistence } from "pip-services3-data-nodex"; import { FireMapTileBlockV1, FireMapTileV1 } from "../data/version1"; import { IFireMapPersistence } from "./IFireMapPersistence"; export class FireMapMemoryPersistence extends IdentifiableMemoryPersistence implements IFireMapPersistence { private composeFilter(filter: FilterParams): any { filter = filter || new FilterParams(); let locations = []; let flng = filter.getAsNullableFloat('flng'); let flat = filter.getAsNullableFloat('flat'); let tlng = filter.getAsNullableFloat('tlng'); let tlat = filter.getAsNullableFloat('tlat'); let zoom = filter.getAsNullableInteger('zoom'); let coordinates = filter.getAsObject('coordinates'); if (typeof coordinates === "string") { coordinates = coordinates.split(','); } else { coordinates = null; } // get blocks for coordinates if (coordinates != null) { for (let location of coordinates) { let lat, long; [lat, long] = location.split(','); lat = parseFloat(lat); lat = parseFloat(long); locations.push({lat: lat, long: long}); } } let flngM: number = null; let tlngM: number = null; // round to the next tile for current zoom if ([flng, flat, tlng, tlat].every((el) => el != null)) { // if coordinates is left top and right bottom corners if (flat > tlat) { [flat, tlat] = [tlat, flat]; } // if coordinates pass through the last meridian if (flng > tlng) { flngM = -180; tlngM = tlng; tlng = 180; } } return (item: FireMapTileV1) => { // if item inside flng, flat, tlng, tlat coordinates let notInRange = (flng1, tlng1, flng2, tlng2) => (flng2 != null && tlng2 != null && !(flng1 <= tlng2 && flng1 >= flng2 || tlng1 <= tlng2 && tlng1 >= flng2)); if (notInRange(item.flng, item.tlng, flng, tlng) && ((flngM == null && tlngM == null) || notInRange(item.flng, item.tlng, flngM, tlngM))) return false; if (notInRange(item.flat, item.tlat, flat, tlat)) return false; if (zoom != null && zoom != item.zoom) return false; if (locations.length > 0) { for (let location of locations) { if (item.flng <= location.long && location.long <= item.tlng && item.flat >= location.lat && location.lat >= item.tlat) { return true; } } return false; } return true; }; } public async getTileBlocksByFilter(correlationId: string, filter: FilterParams, paging: PagingParams): Promise> { // get blocks in passed coordinates let page = this.getPageByFilter(correlationId, this.composeFilter(filter), paging, null, null); return page; } public async updateTileBlocks(correlationId: string, updates: FireMapTileBlockV1[]): Promise { if (updates == null) { return; } for (let update of updates) { this.set(correlationId, update); } this._logger.trace(correlationId, "Updated %s firemap blocks", updates.length); } }