Merge develop
This commit is contained in:
commit
15e6fde194
275 changed files with 786405 additions and 39150 deletions
|
@ -8,7 +8,7 @@ import {BBox} from "../BBox";
|
|||
import Constants from "../../Models/Constants";
|
||||
import SimpleFeatureSource from "../FeatureSource/Sources/SimpleFeatureSource";
|
||||
|
||||
export interface GeoLocationPointProperties {
|
||||
export interface GeoLocationPointProperties {
|
||||
id: "gps",
|
||||
"user:location": "yes",
|
||||
"date": string,
|
||||
|
|
|
@ -24,6 +24,7 @@ import FullNodeDatabaseSource from "./TiledFeatureSource/FullNodeDatabaseSource"
|
|||
import MapState from "../State/MapState";
|
||||
import {ElementStorage} from "../ElementStorage";
|
||||
import {Feature, Geometry} from "@turf/turf";
|
||||
import {OsmFeature} from "../../Models/OsmFeature";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -338,15 +339,19 @@ export default class FeaturePipeline {
|
|||
|
||||
}
|
||||
|
||||
public GetAllFeaturesWithin(bbox: BBox): Feature<Geometry, {id: string}>[][] {
|
||||
public GetAllFeaturesWithin(bbox: BBox): OsmFeature[][] {
|
||||
const self = this
|
||||
const tiles = []
|
||||
const tiles: OsmFeature[][] = []
|
||||
Array.from(this.perLayerHierarchy.keys())
|
||||
.forEach(key => tiles.push(...self.GetFeaturesWithin(key, bbox)))
|
||||
.forEach(key => {
|
||||
const fetched : OsmFeature[][] = self.GetFeaturesWithin(key, bbox)
|
||||
tiles.push(...fetched);
|
||||
})
|
||||
return tiles;
|
||||
}
|
||||
|
||||
public GetAllFeaturesAndMetaWithin(bbox: BBox, layerIdWhitelist?: Set<string>): {features: any[], layer: string}[] {
|
||||
public GetAllFeaturesAndMetaWithin(bbox: BBox, layerIdWhitelist?: Set<string>):
|
||||
{features: OsmFeature[], layer: string}[] {
|
||||
const self = this
|
||||
const tiles :{features: any[], layer: string}[]= []
|
||||
Array.from(this.perLayerHierarchy.keys())
|
||||
|
@ -362,7 +367,11 @@ export default class FeaturePipeline {
|
|||
return tiles;
|
||||
}
|
||||
|
||||
public GetFeaturesWithin(layerId: string, bbox: BBox): any[][] {
|
||||
/**
|
||||
* Gets all the tiles which overlap with the given BBOX.
|
||||
* This might imply that extra features might be shown
|
||||
*/
|
||||
public GetFeaturesWithin(layerId: string, bbox: BBox): OsmFeature[][] {
|
||||
if (layerId === "*") {
|
||||
return this.GetAllFeaturesWithin(bbox)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import {Store, UIEventSource} from "../UIEventSource";
|
||||
import FilteredLayer from "../../Models/FilteredLayer";
|
||||
import {BBox} from "../BBox";
|
||||
import {Feature, Geometry} from "@turf/turf";
|
||||
import {OsmFeature} from "../../Models/OsmFeature";
|
||||
|
||||
export default interface FeatureSource {
|
||||
features: Store<{ feature: any, freshness: Date }[]>;
|
||||
features: Store<{ feature: OsmFeature, freshness: Date }[]>;
|
||||
/**
|
||||
* Mainly used for debuging
|
||||
*/
|
||||
|
@ -28,12 +30,3 @@ export interface FeatureSourceForLayer extends FeatureSource {
|
|||
export interface IndexedFeatureSource extends FeatureSource {
|
||||
readonly containedIds: Store<Set<string>>
|
||||
}
|
||||
|
||||
/**
|
||||
* A feature source which has some extra data about it's state
|
||||
*/
|
||||
export interface FeatureSourceState {
|
||||
readonly sufficientlyZoomed: Store<boolean>;
|
||||
readonly runningQuery: Store<boolean>;
|
||||
readonly timeout: Store<number>;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import {FeatureSourceForLayer, Tiled} from "../FeatureSource";
|
|||
import {BBox} from "../../BBox";
|
||||
import {ElementStorage} from "../../ElementStorage";
|
||||
import {TagsFilter} from "../../Tags/TagsFilter";
|
||||
import {tag} from "@turf/turf";
|
||||
import {OsmFeature} from "../../../Models/OsmFeature";
|
||||
|
||||
export default class FilteringFeatureSource implements FeatureSourceForLayer, Tiled {
|
||||
public features: UIEventSource<{ feature: any; freshness: Date }[]> =
|
||||
|
@ -65,21 +67,16 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
|
|||
private update() {
|
||||
const self = this;
|
||||
const layer = this.upstream.layer;
|
||||
const features: { feature: any; freshness: Date }[] = (this.upstream.features.data ?? []);
|
||||
const features: { feature: OsmFeature; freshness: Date }[] = (this.upstream.features.data ?? []);
|
||||
const includedFeatureIds = new Set<string>();
|
||||
const newFeatures = (features ?? []).filter((f) => {
|
||||
|
||||
self.registerCallback(f.feature)
|
||||
|
||||
const isShown = layer.layerDef.isShown;
|
||||
const isShown: TagsFilter = layer.layerDef.isShown;
|
||||
const tags = f.feature.properties;
|
||||
if (isShown.IsKnown(tags)) {
|
||||
const result = layer.layerDef.isShown.GetRenderValue(
|
||||
f.feature.properties
|
||||
).txt;
|
||||
if (result !== "yes") {
|
||||
return false;
|
||||
}
|
||||
if (isShown !== undefined && !isShown.matchesProperties(tags) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const tagsFilter = Array.from(layer.appliedFilters?.data?.values() ?? [])
|
||||
|
|
|
@ -13,7 +13,7 @@ export default interface TileHierarchy<T extends FeatureSource & Tiled> {
|
|||
export class TileHierarchyTools {
|
||||
|
||||
public static getTiles<T extends FeatureSource & Tiled>(hierarchy: TileHierarchy<T>, bbox: BBox): T[] {
|
||||
const result = []
|
||||
const result: T[] = []
|
||||
hierarchy.loadedTiles.forEach((tile) => {
|
||||
if (tile.bbox.overlapsWith(bbox)) {
|
||||
result.push(tile)
|
||||
|
|
|
@ -3,7 +3,7 @@ import {BBox} from "./BBox";
|
|||
import togpx from "togpx"
|
||||
import Constants from "../Models/Constants";
|
||||
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
|
||||
import {booleanWithin, Coord, Feature, Geometry, MultiPolygon, Polygon, Properties} from "@turf/turf";
|
||||
import {AllGeoJSON, booleanWithin, Coord, Feature, Geometry, MultiPolygon, Polygon, Properties} from "@turf/turf";
|
||||
|
||||
export class GeoOperations {
|
||||
|
||||
|
@ -29,7 +29,7 @@ export class GeoOperations {
|
|||
* Returns [lon,lat] coordinates
|
||||
* @param feature
|
||||
*/
|
||||
static centerpointCoordinates(feature: any): [number, number] {
|
||||
static centerpointCoordinates(feature: AllGeoJSON): [number, number] {
|
||||
return <[number, number]>turf.center(feature).geometry.coordinates;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ export class Imgur extends ImageProvider {
|
|||
for (const tag of descr.split("\n")) {
|
||||
const kv = tag.split(":");
|
||||
const k = kv[0];
|
||||
data[k] = kv[1]?.replace("\r", "");
|
||||
data[k] = kv[1]?.replace(/\r/g, "");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ export class Changes {
|
|||
const recentLocationPoints = locations.map(ff => ff.feature)
|
||||
.filter(feat => feat.geometry.type === "Point")
|
||||
.filter(feat => {
|
||||
const visitTime = new Date((<GeoLocationPointProperties>feat.properties).date)
|
||||
const visitTime = new Date((<GeoLocationPointProperties><any>feat.properties).date)
|
||||
// In seconds
|
||||
const diff = (now.getTime() - visitTime.getTime()) / 1000
|
||||
return diff < Constants.nearbyVisitTime;
|
||||
|
|
|
@ -13,7 +13,7 @@ export class Tag extends TagsFilter {
|
|||
throw "Invalid key: undefined or empty";
|
||||
}
|
||||
if (value === undefined) {
|
||||
throw "Invalid value: value is undefined";
|
||||
throw `Invalid value while constructing a Tag with key '${key}': value is undefined`;
|
||||
}
|
||||
if (value === "*") {
|
||||
console.warn(`Got suspicious tag ${key}=* ; did you mean ${key}~* ?`)
|
||||
|
|
|
@ -6,12 +6,11 @@ import ComparingTag from "./ComparingTag";
|
|||
import {RegexTag} from "./RegexTag";
|
||||
import SubstitutingTag from "./SubstitutingTag";
|
||||
import {Or} from "./Or";
|
||||
import {AndOrTagConfigJson} from "../../Models/ThemeConfig/Json/TagConfigJson";
|
||||
import {TagConfigJson} from "../../Models/ThemeConfig/Json/TagConfigJson";
|
||||
import {isRegExp} from "util";
|
||||
import * as key_counts from "../../assets/key_totals.json"
|
||||
|
||||
type Tags = Record<string, string>
|
||||
type OsmTags = Tags & {id: string}
|
||||
|
||||
export class TagUtils {
|
||||
private static keyCounts: { keys: any, tags: any } = key_counts["default"] ?? key_counts
|
||||
|
@ -249,7 +248,7 @@ export class TagUtils {
|
|||
* // Must match case insensitive
|
||||
* TagUtils.Tag("name~i~somename").matchesProperties({name: "SoMeName"}) // => true
|
||||
*/
|
||||
public static Tag(json: AndOrTagConfigJson | string, context: string = ""): TagsFilter {
|
||||
public static Tag(json: TagConfigJson, context: string = ""): TagsFilter {
|
||||
try {
|
||||
return this.TagUnsafe(json, context);
|
||||
} catch (e) {
|
||||
|
@ -258,6 +257,20 @@ export class TagUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `.Tag`, except that this will return undefined if the json is undefined
|
||||
* @param json
|
||||
* @param context
|
||||
* @constructor
|
||||
*/
|
||||
public static TagD(json?: TagConfigJson, context: string = ""): TagsFilter | undefined {
|
||||
if(json === undefined){
|
||||
return undefined
|
||||
}
|
||||
return TagUtils.Tag(json, context)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* INLINE sort of the given list
|
||||
*/
|
||||
|
@ -308,22 +321,22 @@ export class TagUtils {
|
|||
return {key, value, invert: invert == "!", modifier: (modifier == "i~" ? "i" : "")};
|
||||
}
|
||||
|
||||
private static TagUnsafe(json: AndOrTagConfigJson | string, context: string = ""): TagsFilter {
|
||||
private static TagUnsafe(json: TagConfigJson, context: string = ""): TagsFilter {
|
||||
|
||||
if (json === undefined) {
|
||||
throw new Error(`Error while parsing a tag: 'json' is undefined in ${context}. Make sure all the tags are defined and at least one tag is present in a complex expression`)
|
||||
}
|
||||
if (typeof (json) != "string") {
|
||||
if (json.and !== undefined && json.or !== undefined) {
|
||||
if (json["and"] !== undefined && json["or"] !== undefined) {
|
||||
throw `Error while parsing a TagConfig: got an object where both 'and' and 'or' are defined`
|
||||
}
|
||||
if (json.and !== undefined) {
|
||||
return new And(json.and.map(t => TagUtils.Tag(t, context)));
|
||||
if (json["and"] !== undefined) {
|
||||
return new And(json["and"].map(t => TagUtils.Tag(t, context)));
|
||||
}
|
||||
if (json.or !== undefined) {
|
||||
return new Or(json.or.map(t => TagUtils.Tag(t, context)));
|
||||
if (json["or"] !== undefined) {
|
||||
return new Or(json["or"].map(t => TagUtils.Tag(t, context)));
|
||||
}
|
||||
throw "At " + context + ": unrecognized tag"
|
||||
throw `At ${context}: unrecognized tag: ${JSON.stringify(json)}`
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue