forked from MapComplete/MapComplete
refactoring(maplibre): WIP
This commit is contained in:
parent
231d67361e
commit
4d48b1cf2b
89 changed files with 1166 additions and 3973 deletions
|
@ -1,4 +1,4 @@
|
|||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { ImmutableStore, UIEventSource } from "../../Logic/UIEventSource";
|
||||
import Combine from "../Base/Combine"
|
||||
import Translations from "../i18n/Translations"
|
||||
import { VariableUiElement } from "../Base/VariableUIElement"
|
||||
|
@ -24,13 +24,13 @@ export default class AddNewMarker extends Combine {
|
|||
for (const preset of filteredLayer.layerDef.presets) {
|
||||
const tags = TagUtils.KVtoProperties(preset.tags)
|
||||
const icon = layer.mapRendering[0]
|
||||
.GenerateLeafletStyle(new UIEventSource<any>(tags), false)
|
||||
.RenderIcon(new ImmutableStore<any>(tags), false)
|
||||
.html.SetClass("block relative")
|
||||
.SetStyle("width: 42px; height: 42px;")
|
||||
icons.push(icon)
|
||||
if (last === undefined) {
|
||||
last = layer.mapRendering[0]
|
||||
.GenerateLeafletStyle(new UIEventSource<any>(tags), false)
|
||||
.RenderIcon(new ImmutableStore<any>(tags), false)
|
||||
.html.SetClass("block relative")
|
||||
.SetStyle("width: 42px; height: 42px;")
|
||||
}
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
import Link from "../Base/Link"
|
||||
import Svg from "../../Svg"
|
||||
import Combine from "../Base/Combine"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import UserDetails from "../../Logic/Osm/OsmConnection"
|
||||
import Constants from "../../Models/Constants"
|
||||
import Loc from "../../Models/Loc"
|
||||
import { VariableUiElement } from "../Base/VariableUIElement"
|
||||
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"
|
||||
import { BBox } from "../../Logic/BBox"
|
||||
import { Utils } from "../../Utils"
|
||||
import Translations from "../i18n/Translations"
|
||||
|
||||
/**
|
||||
* The bottom right attribution panel in the leaflet map
|
||||
*/
|
||||
export default class Attribution extends Combine {
|
||||
constructor(
|
||||
location: UIEventSource<Loc>,
|
||||
userDetails: UIEventSource<UserDetails>,
|
||||
layoutToUse: LayoutConfig,
|
||||
currentBounds: UIEventSource<BBox>
|
||||
) {
|
||||
const mapComplete = new Link(
|
||||
`Mapcomplete ${Constants.vNumber}`,
|
||||
"https://github.com/pietervdvn/MapComplete",
|
||||
true
|
||||
)
|
||||
const reportBug = new Link(
|
||||
Svg.bug_ui().SetClass("small-image"),
|
||||
"https://github.com/pietervdvn/MapComplete/issues",
|
||||
true
|
||||
)
|
||||
|
||||
const layoutId = layoutToUse?.id
|
||||
const stats = new Link(
|
||||
Svg.statistics_ui().SetClass("small-image"),
|
||||
Utils.OsmChaLinkFor(31, layoutId),
|
||||
true
|
||||
)
|
||||
|
||||
const idLink = location.map(
|
||||
(location) =>
|
||||
`https://www.openstreetmap.org/edit?editor=id#map=${location?.zoom ?? 0}/${
|
||||
location?.lat ?? 0
|
||||
}/${location?.lon ?? 0}`
|
||||
)
|
||||
const editHere = new Link(Svg.pencil_ui().SetClass("small-image"), idLink, true)
|
||||
|
||||
const mapillaryLink = location.map(
|
||||
(location) =>
|
||||
`https://www.mapillary.com/app/?focus=map&lat=${location?.lat ?? 0}&lng=${
|
||||
location?.lon ?? 0
|
||||
}&z=${Math.max((location?.zoom ?? 2) - 1, 1)}`
|
||||
)
|
||||
const mapillary = new Link(
|
||||
Svg.mapillary_black_ui().SetClass("small-image"),
|
||||
mapillaryLink,
|
||||
true
|
||||
)
|
||||
|
||||
const mapDataByOsm = new Link(
|
||||
Translations.t.general.attribution.mapDataByOsm,
|
||||
"https://openstreetmap.org/copyright",
|
||||
true
|
||||
)
|
||||
|
||||
const editWithJosm = new VariableUiElement(
|
||||
userDetails.map(
|
||||
(userDetails) => {
|
||||
if (userDetails.csCount < Constants.userJourney.tagsVisibleAndWikiLinked) {
|
||||
return undefined
|
||||
}
|
||||
const bounds: any = currentBounds.data
|
||||
if (bounds === undefined) {
|
||||
return undefined
|
||||
}
|
||||
const top = bounds.getNorth()
|
||||
const bottom = bounds.getSouth()
|
||||
const right = bounds.getEast()
|
||||
const left = bounds.getWest()
|
||||
|
||||
const josmLink = `http://127.0.0.1:8111/load_and_zoom?left=${left}&right=${right}&top=${top}&bottom=${bottom}`
|
||||
return new Link(Svg.josm_logo_ui().SetClass("small-image"), josmLink, true)
|
||||
},
|
||||
[location, currentBounds]
|
||||
)
|
||||
)
|
||||
super([mapComplete, reportBug, stats, editHere, editWithJosm, mapillary, mapDataByOsm])
|
||||
this.SetClass("flex")
|
||||
}
|
||||
}
|
|
@ -1,25 +1,19 @@
|
|||
import { VariableUiElement } from "../Base/VariableUIElement"
|
||||
import Svg from "../../Svg"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import GeoLocationHandler from "../../Logic/Actors/GeoLocationHandler"
|
||||
import { BBox } from "../../Logic/BBox"
|
||||
import Loc from "../../Models/Loc"
|
||||
import Hotkeys from "../Base/Hotkeys"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Constants from "../../Models/Constants"
|
||||
import { MapProperties } from "../../Models/MapProperties"
|
||||
|
||||
/**
|
||||
* Displays an icon depending on the state of the geolocation.
|
||||
* Will set the 'lock' if clicked twice
|
||||
*/
|
||||
export class GeolocationControl extends VariableUiElement {
|
||||
constructor(
|
||||
geolocationHandler: GeoLocationHandler,
|
||||
state: {
|
||||
locationControl: UIEventSource<Loc>
|
||||
currentBounds: UIEventSource<BBox>
|
||||
}
|
||||
) {
|
||||
constructor(geolocationHandler: GeoLocationHandler, state: MapProperties) {
|
||||
const lastClick = new UIEventSource<Date>(undefined)
|
||||
lastClick.addCallbackD((date) => {
|
||||
geolocationHandler.geolocationState.requestMoment.setData(date)
|
||||
|
@ -48,7 +42,7 @@ export class GeolocationControl extends VariableUiElement {
|
|||
if (permission === "denied") {
|
||||
return Svg.location_refused_svg()
|
||||
}
|
||||
if (geolocationState.isLocked.data) {
|
||||
if (!geolocationState.allowMoving.data) {
|
||||
return Svg.location_locked_svg()
|
||||
}
|
||||
|
||||
|
@ -77,7 +71,7 @@ export class GeolocationControl extends VariableUiElement {
|
|||
},
|
||||
[
|
||||
geolocationState.currentGPSLocation,
|
||||
geolocationState.isLocked,
|
||||
geolocationState.allowMoving,
|
||||
geolocationHandler.mapHasMoved,
|
||||
lastClickWithinThreeSecs,
|
||||
lastRequestWithinTimeout,
|
||||
|
@ -95,9 +89,9 @@ export class GeolocationControl extends VariableUiElement {
|
|||
await geolocationState.requestPermission()
|
||||
}
|
||||
|
||||
if (geolocationState.isLocked.data === true) {
|
||||
if (geolocationState.allowMoving.data === false) {
|
||||
// Unlock
|
||||
geolocationState.isLocked.setData(false)
|
||||
geolocationState.allowMoving.setData(true)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -109,21 +103,17 @@ export class GeolocationControl extends VariableUiElement {
|
|||
|
||||
// A location _is_ known! Let's move to this location
|
||||
const currentLocation = geolocationState.currentGPSLocation.data
|
||||
const inBounds = state.currentBounds.data.contains([
|
||||
const inBounds = state.bounds.data.contains([
|
||||
currentLocation.longitude,
|
||||
currentLocation.latitude,
|
||||
])
|
||||
geolocationHandler.MoveMapToCurrentLocation()
|
||||
if (inBounds) {
|
||||
const lc = state.locationControl.data
|
||||
state.locationControl.setData({
|
||||
...lc,
|
||||
zoom: lc.zoom + 3,
|
||||
})
|
||||
state.zoom.update((z) => z + 3)
|
||||
}
|
||||
|
||||
if (lastClickWithinThreeSecs.data) {
|
||||
geolocationState.isLocked.setData(true)
|
||||
geolocationState.allowMoving.setData(false)
|
||||
lastClick.setData(undefined)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import BackgroundMapSwitch from "./BackgroundMapSwitch"
|
|||
import Lazy from "../Base/Lazy"
|
||||
import { VariableUiElement } from "../Base/VariableUIElement"
|
||||
import FeatureInfoBox from "../Popup/FeatureInfoBox"
|
||||
import CopyrightPanel from "./CopyrightPanel"
|
||||
import FeaturePipelineState from "../../Logic/State/FeaturePipelineState"
|
||||
import Hotkeys from "../Base/Hotkeys"
|
||||
import { DefaultGuiState } from "../DefaultGuiState"
|
||||
|
@ -21,7 +20,7 @@ export default class LeftControls extends Combine {
|
|||
const currentViewFL = state.currentView?.layer
|
||||
const currentViewAction = new Toggle(
|
||||
new Lazy(() => {
|
||||
const feature: Store<any> = state.currentView.features.map((ffs) => ffs[0]?.feature)
|
||||
const feature: Store<any> = state.currentView.features.map((ffs) => ffs[0])
|
||||
const icon = new VariableUiElement(
|
||||
feature.map((feature) => {
|
||||
const defaultIcon = Svg.checkbox_empty_svg()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import FloorLevelInputElement from "../Input/FloorLevelInputElement"
|
||||
import MapState, { GlobalFilter } from "../../Logic/State/MapState"
|
||||
import MapState from "../../Logic/State/MapState"
|
||||
import { TagsFilter } from "../../Logic/Tags/TagsFilter"
|
||||
import { RegexTag } from "../../Logic/Tags/RegexTag"
|
||||
import { Or } from "../../Logic/Tags/Or"
|
||||
|
@ -11,6 +11,7 @@ import { BBox } from "../../Logic/BBox"
|
|||
import { TagUtils } from "../../Logic/Tags/TagUtils"
|
||||
import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline"
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
import { GlobalFilter } from "../../Logic/State/GlobalFilter"
|
||||
|
||||
/***
|
||||
* The element responsible for the level input element and picking the right level, showing and hiding at the right time, ...
|
||||
|
|
|
@ -9,30 +9,9 @@ import LevelSelector from "./LevelSelector"
|
|||
import { GeolocationControl } from "./GeolocationControl"
|
||||
|
||||
export default class RightControls extends Combine {
|
||||
constructor(
|
||||
state: MapState & { featurePipeline: FeaturePipeline },
|
||||
geolocationHandler: GeoLocationHandler
|
||||
) {
|
||||
const geolocationButton = Toggle.If(state.featureSwitchGeolocation, () =>
|
||||
new MapControlButton(new GeolocationControl(geolocationHandler, state), {
|
||||
dontStyle: true,
|
||||
}).SetClass("p-1")
|
||||
)
|
||||
|
||||
const plus = new MapControlButton(Svg.plus_svg()).onClick(() => {
|
||||
state.locationControl.data.zoom++
|
||||
state.locationControl.ping()
|
||||
})
|
||||
|
||||
const min = new MapControlButton(Svg.min_svg()).onClick(() => {
|
||||
state.locationControl.data.zoom--
|
||||
state.locationControl.ping()
|
||||
})
|
||||
|
||||
constructor(state: MapState & { featurePipeline: FeaturePipeline }) {
|
||||
const levelSelector = new LevelSelector(state)
|
||||
super(
|
||||
[levelSelector, plus, min, geolocationButton].map((el) => el.SetClass("m-0.5 md:m-1"))
|
||||
)
|
||||
super([levelSelector].map((el) => el.SetClass("m-0.5 md:m-1")))
|
||||
this.SetClass("flex flex-col items-center")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Translation } from "../i18n/Translation"
|
||||
import Svg from "../../Svg"
|
||||
import { TextField } from "../Input/TextField"
|
||||
|
@ -7,10 +7,15 @@ import Translations from "../i18n/Translations"
|
|||
import Hash from "../../Logic/Web/Hash"
|
||||
import Combine from "../Base/Combine"
|
||||
import Locale from "../i18n/Locale"
|
||||
import { BBox } from "../../Logic/BBox"
|
||||
|
||||
export default class SearchAndGo extends Combine {
|
||||
private readonly _searchField: TextField
|
||||
constructor(state: { leafletMap: UIEventSource<any>; selectedElement?: UIEventSource<any> }) {
|
||||
constructor(state: {
|
||||
leafletMap: UIEventSource<any>
|
||||
selectedElement?: UIEventSource<any>
|
||||
bounds?: Store<BBox>
|
||||
}) {
|
||||
const goButton = Svg.search_ui().SetClass("w-8 h-8 full-rounded border-black float-right")
|
||||
|
||||
const placeholder = new UIEventSource<Translation>(Translations.t.general.search.search)
|
||||
|
@ -49,7 +54,7 @@ export default class SearchAndGo extends Combine {
|
|||
searchField.GetValue().setData("")
|
||||
placeholder.setData(Translations.t.general.search.searching)
|
||||
try {
|
||||
const result = await Geocoding.Search(searchString)
|
||||
const result = await Geocoding.Search(searchString, state.bounds.data)
|
||||
|
||||
console.log("Search result", result)
|
||||
if (result.length == 0) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Asks to add a feature at the last clicked location, at least if zoom is sufficient
|
||||
*/
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import Svg from "../../Svg"
|
||||
import { SubtleButton } from "../Base/SubtleButton"
|
||||
import Combine from "../Base/Combine"
|
||||
|
@ -22,13 +22,12 @@ import { Changes } from "../../Logic/Osm/Changes"
|
|||
import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline"
|
||||
import { ElementStorage } from "../../Logic/ElementStorage"
|
||||
import ConfirmLocationOfPoint from "../NewPoint/ConfirmLocationOfPoint"
|
||||
import BaseLayer from "../../Models/BaseLayer"
|
||||
import Loading from "../Base/Loading"
|
||||
import Hash from "../../Logic/Web/Hash"
|
||||
import { GlobalFilter } from "../../Logic/State/MapState"
|
||||
import { WayId } from "../../Models/OsmFeature"
|
||||
import { Tag } from "../../Logic/Tags/Tag"
|
||||
import { LoginToggle } from "../Popup/LoginButton"
|
||||
import { GlobalFilter } from "../../Models/GlobalFilter"
|
||||
|
||||
/*
|
||||
* The SimpleAddUI is a single panel, which can have multiple states:
|
||||
|
@ -288,7 +287,7 @@ export default class SimpleAddUI extends LoginToggle {
|
|||
const tags = TagUtils.KVtoProperties(preset.tags ?? [])
|
||||
let icon: () => BaseUIElement = () =>
|
||||
layer.layerDef.mapRendering[0]
|
||||
.GenerateLeafletStyle(new UIEventSource<any>(tags), false)
|
||||
.RenderIcon(new ImmutableStore<any>(tags), false)
|
||||
.html.SetClass("w-12 h-12 block relative")
|
||||
const presetInfo: PresetInfo = {
|
||||
layerToAddTo: layer,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue