forked from MapComplete/MapComplete
More refactoring
This commit is contained in:
parent
5d0fe31c41
commit
41e6a2c760
147 changed files with 1540 additions and 1797 deletions
|
@ -1,12 +1,13 @@
|
|||
import { Store, UIEventSource } from "../UIEventSource"
|
||||
import Locale from "../../UI/i18n/Locale"
|
||||
import TagRenderingAnswer from "../../UI/Popup/TagRenderingAnswer"
|
||||
import Combine from "../../UI/Base/Combine"
|
||||
import { Utils } from "../../Utils"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import { Feature } from "geojson"
|
||||
import FeaturePropertiesStore from "../FeatureSource/Actors/FeaturePropertiesStore"
|
||||
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"
|
||||
import SvelteUIElement from "../../UI/Base/SvelteUIElement"
|
||||
import TagRenderingAnswer from "../../UI/Popup/TagRenderingAnswer.svelte"
|
||||
|
||||
export default class TitleHandler {
|
||||
constructor(
|
||||
|
@ -32,7 +33,7 @@ export default class TitleHandler {
|
|||
const tagsSource =
|
||||
allElements.getStore(tags.id) ??
|
||||
new UIEventSource<Record<string, string>>(tags)
|
||||
const title = new TagRenderingAnswer(tagsSource, layer.title, {})
|
||||
const title = new SvelteUIElement(TagRenderingAnswer, { tags: tagsSource })
|
||||
return (
|
||||
new Combine([defaultTitle, " | ", title]).ConstructElement()
|
||||
?.textContent ?? defaultTitle
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
import FeatureSource, { Tiled } from "../FeatureSource"
|
||||
import { Tiles } from "../../../Models/TileRange"
|
||||
import { IdbLocalStorage } from "../../Web/IdbLocalStorage"
|
||||
import { UIEventSource } from "../../UIEventSource"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
import { BBox } from "../../BBox"
|
||||
import SimpleFeatureSource from "../Sources/SimpleFeatureSource"
|
||||
import FilteredLayer from "../../../Models/FilteredLayer"
|
||||
import Loc from "../../../Models/Loc"
|
||||
import FeatureSource from "../FeatureSource"
|
||||
import { Feature } from "geojson"
|
||||
import TileLocalStorage from "./TileLocalStorage"
|
||||
import { GeoOperations } from "../../GeoOperations"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { UIEventSource } from "../../UIEventSource"
|
||||
import FilteredLayer from "../../../Models/FilteredLayer"
|
||||
import { FeatureSourceForLayer, Tiled } from "../FeatureSource"
|
||||
import { BBox } from "../../BBox"
|
||||
import { FeatureSourceForLayer } from "../FeatureSource"
|
||||
import { Feature } from "geojson"
|
||||
|
||||
export default class SimpleFeatureSource implements FeatureSourceForLayer {
|
||||
|
|
52
Logic/FeatureSource/Sources/SnappingFeatureSource.ts
Normal file
52
Logic/FeatureSource/Sources/SnappingFeatureSource.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import FeatureSource from "../FeatureSource"
|
||||
import { Store } from "../../UIEventSource"
|
||||
import { Feature, Point } from "geojson"
|
||||
import { GeoOperations } from "../../GeoOperations"
|
||||
|
||||
export interface SnappingOptions {
|
||||
/**
|
||||
* If the distance is bigger then this amount, don't snap.
|
||||
* In meter
|
||||
*/
|
||||
maxDistance?: number
|
||||
}
|
||||
|
||||
export default class SnappingFeatureSource implements FeatureSource {
|
||||
public readonly features: Store<Feature<Point>[]>
|
||||
|
||||
constructor(
|
||||
snapTo: FeatureSource,
|
||||
location: Store<{ lon: number; lat: number }>,
|
||||
options?: SnappingOptions
|
||||
) {
|
||||
const simplifiedFeatures = snapTo.features.mapD((features) =>
|
||||
features
|
||||
.filter((feature) => feature.geometry.type !== "Point")
|
||||
.map((f) => GeoOperations.forceLineString(<any>f))
|
||||
)
|
||||
|
||||
location.mapD(
|
||||
({ lon, lat }) => {
|
||||
const features = snapTo.features.data
|
||||
const loc: [number, number] = [lon, lat]
|
||||
const maxDistance = (options?.maxDistance ?? 1000) * 1000
|
||||
let bestSnap: Feature<Point, { "snapped-to": string; dist: number }> = undefined
|
||||
for (const feature of features) {
|
||||
const snapped = GeoOperations.nearestPoint(<any>feature, loc)
|
||||
if (snapped.properties.dist > maxDistance) {
|
||||
continue
|
||||
}
|
||||
if (
|
||||
bestSnap === undefined ||
|
||||
bestSnap.properties.dist > snapped.properties.dist
|
||||
) {
|
||||
snapped.properties["snapped-to"] = feature.properties.id
|
||||
bestSnap = <any>snapped
|
||||
}
|
||||
}
|
||||
return bestSnap
|
||||
},
|
||||
[snapTo.features]
|
||||
)
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ import FeatureSource, { FeatureSourceForLayer } from "../FeatureSource"
|
|||
import StaticFeatureSource from "./StaticFeatureSource"
|
||||
import { GeoOperations } from "../../GeoOperations"
|
||||
import { BBox } from "../../BBox"
|
||||
import exp from "constants"
|
||||
import FilteredLayer from "../../../Models/FilteredLayer"
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
GeoJSON,
|
||||
Geometry,
|
||||
LineString,
|
||||
MultiLineString,
|
||||
MultiPolygon,
|
||||
Point,
|
||||
Polygon,
|
||||
|
@ -272,17 +273,42 @@ export class GeoOperations {
|
|||
* @param point Point defined as [lon, lat]
|
||||
*/
|
||||
public static nearestPoint(
|
||||
way: Feature<LineString | Polygon>,
|
||||
way: Feature<LineString | MultiLineString | Polygon | MultiPolygon>,
|
||||
point: [number, number]
|
||||
): Feature<Point> {
|
||||
): Feature<
|
||||
Point,
|
||||
{
|
||||
index: number
|
||||
dist: number
|
||||
location: number
|
||||
}
|
||||
> {
|
||||
return <any>(
|
||||
turf.nearestPointOnLine(<Feature<LineString>>way, point, { units: "kilometers" })
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to reuse the coordinates of the way as LineString.
|
||||
* Mostly used as helper for 'nearestPoint'
|
||||
* @param way
|
||||
*/
|
||||
public static forceLineString(
|
||||
way: Feature<LineString | MultiLineString | Polygon | MultiPolygon>
|
||||
): Feature<LineString | MultiLineString> {
|
||||
if (way.geometry.type === "Polygon") {
|
||||
way = { ...way }
|
||||
way.geometry = { ...way.geometry }
|
||||
way.geometry.type = "LineString"
|
||||
way.geometry.coordinates = (<Polygon>way.geometry).coordinates[0]
|
||||
} else if (way.geometry.type === "MultiPolygon") {
|
||||
way = { ...way }
|
||||
way.geometry = { ...way.geometry }
|
||||
way.geometry.type = "MultiLineString"
|
||||
way.geometry.coordinates = (<MultiPolygon>way.geometry).coordinates[0]
|
||||
}
|
||||
|
||||
return turf.nearestPointOnLine(<Feature<LineString>>way, point, { units: "kilometers" })
|
||||
return <any>way
|
||||
}
|
||||
|
||||
public static toCSV(features: any[]): string {
|
||||
|
|
|
@ -5,6 +5,7 @@ import GenericImageProvider from "./GenericImageProvider"
|
|||
import { Store, UIEventSource } from "../UIEventSource"
|
||||
import ImageProvider, { ProvidedImage } from "./ImageProvider"
|
||||
import { WikidataImageProvider } from "./WikidataImageProvider"
|
||||
import { OsmTags } from "../../Models/OsmFeature"
|
||||
|
||||
/**
|
||||
* A generic 'from the interwebz' image picker, without attribution
|
||||
|
@ -44,7 +45,7 @@ export default class AllImageProviders {
|
|||
UIEventSource<ProvidedImage[]>
|
||||
>()
|
||||
|
||||
public static LoadImagesFor(tags: Store<any>, tagKey?: string[]): Store<ProvidedImage[]> {
|
||||
public static LoadImagesFor(tags: Store<OsmTags>, tagKey?: string[]): Store<ProvidedImage[]> {
|
||||
if (tags.data.id === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ export default class ChangeLocationAction extends OsmChangeAction {
|
|||
this._meta = meta
|
||||
}
|
||||
|
||||
protected async CreateChangeDescriptions(changes: Changes): Promise<ChangeDescription[]> {
|
||||
protected async CreateChangeDescriptions(): Promise<ChangeDescription[]> {
|
||||
const d: ChangeDescription = {
|
||||
changes: {
|
||||
lat: this._newLonLat[1],
|
||||
|
|
|
@ -71,7 +71,7 @@ export default class ChangeTagAction extends OsmChangeAction {
|
|||
return { k: key.trim(), v: value.trim() }
|
||||
}
|
||||
|
||||
async CreateChangeDescriptions(changes: Changes): Promise<ChangeDescription[]> {
|
||||
async CreateChangeDescriptions(): Promise<ChangeDescription[]> {
|
||||
const changedTags: { k: string; v: string }[] = this._tagsFilter
|
||||
.asChange(this._currentTags)
|
||||
.map(ChangeTagAction.checkChange)
|
||||
|
|
|
@ -3,7 +3,6 @@ import { OsmConnection } from "../Osm/OsmConnection"
|
|||
import { MangroveIdentity } from "../Web/MangroveReviews"
|
||||
import { Store, Stores, UIEventSource } from "../UIEventSource"
|
||||
import Locale from "../../UI/i18n/Locale"
|
||||
import { Changes } from "../Osm/Changes"
|
||||
import StaticFeatureSource from "../FeatureSource/Sources/StaticFeatureSource"
|
||||
import FeatureSource from "../FeatureSource/FeatureSource"
|
||||
import { Feature } from "geojson"
|
||||
|
|
|
@ -122,7 +122,7 @@ export class Tag extends TagsFilter {
|
|||
return [this]
|
||||
}
|
||||
|
||||
asChange(properties: any): { k: string; v: string }[] {
|
||||
asChange(): { k: string; v: string }[] {
|
||||
return [{ k: this.key, v: this.value }]
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue