diff --git a/Logic/GeoOperations.ts b/Logic/GeoOperations.ts index 8bdc3c259..250e75182 100644 --- a/Logic/GeoOperations.ts +++ b/Logic/GeoOperations.ts @@ -701,6 +701,20 @@ export class GeoOperations { return turf.bearing(a, b) } + public static along(a: Coord, b: Coord, distanceMeter: number): Coord { + return turf.along( + { + type:"Feature", + geometry:{ + type:"LineString", + coordinates: [a, b] + } + }, distanceMeter, {units: "meters"} + + ).geometry.coordinates + } + + /** * Returns 'true' if one feature contains the other feature * diff --git a/Models/ThemeConfig/Json/LineRenderingConfigJson.ts b/Models/ThemeConfig/Json/LineRenderingConfigJson.ts index 6a359792b..d93c31215 100644 --- a/Models/ThemeConfig/Json/LineRenderingConfigJson.ts +++ b/Models/ThemeConfig/Json/LineRenderingConfigJson.ts @@ -31,14 +31,11 @@ export default interface LineRenderingConfigJson { */ lineCap?: "round" | "square" | "butt" | string | TagRenderingConfigJson - /** - * Whether or not to fill polygons - */ - fill?: "yes" | "no" | TagRenderingConfigJson /** * The color to fill a polygon with. - * If undefined, this will be slightly more opaque version of the stroke line + * If undefined, this will be slightly more opaque version of the stroke line. + * Use '#00000000' to make the fill invisible */ fillColor?: string | TagRenderingConfigJson diff --git a/UI/BigComponents/NewPointLocationInput.svelte b/UI/BigComponents/NewPointLocationInput.svelte index 054fe41fa..199c0ceca 100644 --- a/UI/BigComponents/NewPointLocationInput.svelte +++ b/UI/BigComponents/NewPointLocationInput.svelte @@ -8,7 +8,6 @@ import type {MapProperties} from "../../Models/MapProperties"; import ShowDataLayer from "../Map/ShowDataLayer"; import type {FeatureSource, FeatureSourceForLayer} from "../../Logic/FeatureSource/FeatureSource"; - import SnappingFeatureSource from "../../Logic/FeatureSource/Sources/SnappingFeatureSource"; import FeatureSourceMerger from "../../Logic/FeatureSource/Sources/FeatureSourceMerger"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; @@ -31,6 +30,7 @@ export let maxSnapDistance: number = undefined; export let snappedTo: UIEventSource; + export let value: UIEventSource<{ lon: number, lat: number }>; if (value.data === undefined) { value.setData(coordinate); @@ -39,7 +39,8 @@ let preciseLocation: UIEventSource<{ lon: number, lat: number }> = new UIEventSource<{ lon: number; lat: number - }>(coordinate); + }>(undefined); + const xyz = Tiles.embedded_tile(coordinate.lat, coordinate.lon, 16); const map: UIEventSource = new UIEventSource(undefined); let initialMapProperties: Partial = { @@ -52,14 +53,19 @@ bounds: new UIEventSource(undefined), allowMoving: new UIEventSource(true), allowZooming: new UIEventSource(true), - minzoom: new UIEventSource(18) + minzoom: new UIEventSource(18), + rasterLayer: UIEventSource.feedFrom(state.mapProperties.rasterLayer) }; - initialMapProperties.bounds.addCallbackAndRunD((bounds: BBox) => { - const max = bounds.pad(3).squarify(); - initialMapProperties.maxbounds.setData(max); - return true; // unregister - }); + + const featuresForLayer = state.perLayer.get(targetLayer.id) + if(featuresForLayer){ + new ShowDataLayer(map, { + layer: targetLayer, + features: featuresForLayer + }) + } + if (snapToLayers?.length > 0) { @@ -99,4 +105,4 @@ + value={preciseLocation} initialCoordinate={{...coordinate}} maxDistanceInMeters=50 /> diff --git a/UI/InputElement/Helpers/LocationInput.svelte b/UI/InputElement/Helpers/LocationInput.svelte index 9ff4adc56..15be7edd8 100644 --- a/UI/InputElement/Helpers/LocationInput.svelte +++ b/UI/InputElement/Helpers/LocationInput.svelte @@ -1,38 +1,82 @@
-
- -
+
+ +
-
- -
- - +
+ +
+ +
diff --git a/UI/Map/ShowDataLayer.ts b/UI/Map/ShowDataLayer.ts index a43ecdff8..6b25d9da0 100644 --- a/UI/Map/ShowDataLayer.ts +++ b/UI/Map/ShowDataLayer.ts @@ -228,30 +228,46 @@ class LineRenderingLayer { features.features.addCallbackAndRunD(() => self.update(features.features)) } + public destruct(): void { + this._map.removeLayer(this._layername + "_polygon") + } + + /** + * Calculate the feature-state for maplibre + * @param properties + * @private + */ private calculatePropsFor( properties: Record ): Partial> { - const calculatedProps = {} const config = this._config + const calculatedProps: Record = {} for (const key of LineRenderingLayer.lineConfigKeys) { calculatedProps[key] = config[key]?.GetRenderValue(properties)?.Subs(properties).txt } + calculatedProps.fillColor = calculatedProps.fillColor ?? calculatedProps.lineColor + for (const key of LineRenderingLayer.lineConfigKeysColor) { - let v = config[key]?.GetRenderValue(properties)?.Subs(properties).txt + let v = calculatedProps[key] if (v === undefined) { continue } if (v.length == 9 && v.startsWith("#")) { // This includes opacity - calculatedProps[key + "-opacity"] = parseInt(v.substring(7), 16) / 256 + calculatedProps[`${key}-opacity`] = parseInt(v.substring(7), 16) / 256 v = v.substring(0, 7) + if (v.length == 9 && v.startsWith("#")) { + // This includes opacity + calculatedProps[`${key}-opacity`] = parseInt(v.substring(7), 16) / 256 + v = v.substring(0, 7) + } } - calculatedProps[key] = v } + calculatedProps["fillColor-opacity"] = calculatedProps["fillColor-opacity"] ?? 0.1 + for (const key of LineRenderingLayer.lineConfigKeysNumber) { - const v = config[key]?.GetRenderValue(properties)?.Subs(properties).txt - calculatedProps[key] = Number(v) + calculatedProps[key] = Number(calculatedProps[key]) } return calculatedProps @@ -303,6 +319,7 @@ class LineRenderingLayer { this._onClick(e.features[0]) }) const polylayer = this._layername + "_polygon" + map.addLayer({ source: this._layername, id: polylayer, @@ -311,13 +328,15 @@ class LineRenderingLayer { layout: {}, paint: { "fill-color": ["feature-state", "fillColor"], - "fill-opacity": 0.1, + "fill-opacity": ["feature-state", "fillColor-opacity"], }, }) - map.on("click", polylayer, (e) => { - e.originalEvent["consumed"] = true - this._onClick(e.features[0]) - }) + if (this._onClick) { + map.on("click", polylayer, (e) => { + e.originalEvent["consumed"] = true + this._onClick(e.features[0]) + }) + } this._visibility?.addCallbackAndRunD((visible) => { try { @@ -388,6 +407,8 @@ export default class ShowDataLayer { drawLines?: true | boolean } + private onDestroy: (() => void)[] = [] + constructor( map: Store, options: ShowDataLayerOptions & { @@ -399,7 +420,7 @@ export default class ShowDataLayer { this._map = map this._options = options const self = this - map.addCallbackAndRunD((map) => self.initDrawFeatures(map)) + this.onDestroy.push(map.addCallbackAndRunD((map) => self.initDrawFeatures(map))) } public static showMultipleLayers( @@ -437,6 +458,10 @@ export default class ShowDataLayer { }) } + public destruct() { + + } + private zoomToCurrentFeatures(map: MlMap) { if (this._options.zoomToFeatures) { const features = this._options.features.features.data @@ -458,7 +483,7 @@ export default class ShowDataLayer { if (this._options.drawLines !== false) { for (let i = 0; i < this._options.layer.lineRendering.length; i++) { const lineRenderingConfig = this._options.layer.lineRendering[i] - new LineRenderingLayer( + const l = new LineRenderingLayer( map, features, this._options.layer.id + "_linerendering_" + i, @@ -467,6 +492,7 @@ export default class ShowDataLayer { fetchStore, onClick ) + this.onDestroy.push(l.destruct) } } if (this._options.drawMarkers !== false) { diff --git a/UI/Popup/AddNewPoint/AddNewPoint.svelte b/UI/Popup/AddNewPoint/AddNewPoint.svelte index b0f0acee7..9413fcd58 100644 --- a/UI/Popup/AddNewPoint/AddNewPoint.svelte +++ b/UI/Popup/AddNewPoint/AddNewPoint.svelte @@ -31,6 +31,7 @@ import BackButton from "../../Base/BackButton.svelte"; import ToSvelte from "../../Base/ToSvelte.svelte"; import Svg from "../../../Svg"; + import RasterLayerOverview from "../../Map/RasterLayerOverview.svelte"; export let coordinate: { lon: number, lat: number }; export let state: SpecialVisualizationState; @@ -281,6 +282,9 @@ + + + {:else} Creating point... {/if} diff --git a/assets/layers/last_click/last_click.json b/assets/layers/last_click/last_click.json index 4ba8033cf..32eddfd8a 100644 --- a/assets/layers/last_click/last_click.json +++ b/assets/layers/last_click/last_click.json @@ -77,7 +77,7 @@ ], "render": "
{renderings}{first_preset}
" }, - "labelCssClasses": "text-sm min-w-min pl-1 pr-1 rounded-3xl text-white opacity-65 whitespace-nowrap block-ruby", + "labelCssClasses": "text-sm min-w-min px-2 rounded-full text-white opacity-65 whitespace-nowrap block-ruby", "labelCss": "background: #00000088", "label": { "render": { diff --git a/public/css/index-tailwind-output.css b/public/css/index-tailwind-output.css index 7cad71e2f..8c85f7460 100644 --- a/public/css/index-tailwind-output.css +++ b/public/css/index-tailwind-output.css @@ -1245,10 +1245,6 @@ video { resize: both; } -.grid-cols-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); -} - .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }