diff --git a/Logic/Actors/UpdateFromOverpass.ts b/Logic/Actors/UpdateFromOverpass.ts index d7b470a210..c75239a939 100644 --- a/Logic/Actors/UpdateFromOverpass.ts +++ b/Logic/Actors/UpdateFromOverpass.ts @@ -1,12 +1,12 @@ import {UIEventSource} from "../UIEventSource"; import Loc from "../../Models/Loc"; -import {Or} from "../Or"; +import {Or} from "../Tags/Or"; import LayoutConfig from "../../Customizations/JSON/LayoutConfig"; import {Overpass} from "../Osm/Overpass"; import Bounds from "../../Models/Bounds"; import FeatureSource from "../FeatureSource/FeatureSource"; import {Utils} from "../../Utils"; -import {TagsFilter} from "../TagsFilter"; +import {TagsFilter} from "../Tags/TagsFilter"; export default class UpdateFromOverpass implements FeatureSource { diff --git a/Logic/ExtraFunction.ts b/Logic/ExtraFunction.ts index 432a5494f0..e286d1d266 100644 --- a/Logic/ExtraFunction.ts +++ b/Logic/ExtraFunction.ts @@ -61,13 +61,60 @@ Some advanced functions are available on feat as well: "Calculates the distance between the feature and a specified point", ["longitude", "latitude"], (featuresPerLayer, feature) => { - return (lon, lat) => { - // Feature._lon and ._lat is conveniently place by one of the other metatags - return GeoOperations.distanceBetween([lon, lat], [feature._lon, feature._lat]); + return (arg0, lat) => { + if(typeof arg0 === "number"){ + const lon = arg0 + // Feature._lon and ._lat is conveniently place by one of the other metatags + return GeoOperations.distanceBetween([lon, lat], [feature._lon, feature._lat]); + }else{ + // arg0 is probably a feature + return GeoOperations.distanceBetween(GeoOperations.centerpointCoordinates(arg0),[feature._lon, feature._lat]) + } + } } ) - private static readonly allFuncs: ExtraFunction[] = [ExtraFunction.DistanceToFunc, ExtraFunction.OverlapFunc]; + + private static ClosestObjectFunc = new ExtraFunction( + "closest", + "Given either a list of geojson features or a single layer name, gives the single object which is nearest to the feature. In the case of ways/polygons, only the centerpoint is considered.", + ["list of features"], + (featuresPerLayer, feature) => { + return (features) => { + if (typeof features === "string") { + features = featuresPerLayer.get(features) + } + let closestFeature = undefined; + let closestDistance = undefined; + for (const otherFeature of features) { + if(otherFeature == feature){ + continue; // We ignore self + } + let distance = undefined; + if (otherFeature._lon !== undefined && otherFeature._lat !== undefined) { + distance = GeoOperations.distanceBetween([otherFeature._lon, otherFeature._lat], [feature._lon, feature._lat]); + } else { + distance = GeoOperations.distanceBetween( + GeoOperations.centerpointCoordinates(otherFeature), + [feature._lon, feature._lat] + ) + } + if(distance === undefined){ + throw "Undefined distance!" + } + if(closestFeature === undefined || distance < closestDistance){ + console.log("Distance between ", feature.properties.id, "and", otherFeature.properties.id, "is", distance) + closestFeature = otherFeature + closestDistance = distance; + } + } + return closestFeature; + } + } + ) + + + private static readonly allFuncs: ExtraFunction[] = [ExtraFunction.DistanceToFunc, ExtraFunction.OverlapFunc, ExtraFunction.ClosestObjectFunc]; private readonly _name: string; private readonly _args: string[]; private readonly _doc: string; @@ -91,10 +138,10 @@ Some advanced functions are available on feat as well: return new Combine([ ExtraFunction.intro, "