forked from MapComplete/MapComplete
		
	Add live updating of icons on the map
This commit is contained in:
		
							parent
							
								
									f2d9eb8992
								
							
						
					
					
						commit
						4f7c25766a
					
				
					 2 changed files with 35 additions and 22 deletions
				
			
		| 
						 | 
					@ -12,6 +12,8 @@ import {SubstitutedTranslation} from "../../UI/SpecialVisualizations";
 | 
				
			||||||
import {Utils} from "../../Utils";
 | 
					import {Utils} from "../../Utils";
 | 
				
			||||||
import Combine from "../../UI/Base/Combine";
 | 
					import Combine from "../../UI/Base/Combine";
 | 
				
			||||||
import {VariableUiElement} from "../../UI/Base/VariableUIElement";
 | 
					import {VariableUiElement} from "../../UI/Base/VariableUIElement";
 | 
				
			||||||
 | 
					import {UIElement} from "../../UI/UIElement";
 | 
				
			||||||
 | 
					import {UIEventSource} from "../../Logic/UIEventSource";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class LayerConfig {
 | 
					export default class LayerConfig {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -153,7 +155,7 @@ export default class LayerConfig {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public GenerateLeafletStyle(tags: any, clickable: boolean):
 | 
					    public GenerateLeafletStyle(tags: UIEventSource<any>, clickable: boolean):
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            color: string;
 | 
					            color: string;
 | 
				
			||||||
            icon: {
 | 
					            icon: {
 | 
				
			||||||
| 
						 | 
					@ -162,7 +164,6 @@ export default class LayerConfig {
 | 
				
			||||||
                iconAnchor: [number, number];
 | 
					                iconAnchor: [number, number];
 | 
				
			||||||
                iconSize: [number, number];
 | 
					                iconSize: [number, number];
 | 
				
			||||||
                html: string;
 | 
					                html: string;
 | 
				
			||||||
                rotation: string;
 | 
					 | 
				
			||||||
                className?: string;
 | 
					                className?: string;
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            weight: number; dashArray: number[]
 | 
					            weight: number; dashArray: number[]
 | 
				
			||||||
| 
						 | 
					@ -186,11 +187,10 @@ export default class LayerConfig {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        function render(tr: TagRenderingConfig, deflt?: string) {
 | 
					        function render(tr: TagRenderingConfig, deflt?: string) {
 | 
				
			||||||
            const str = (tr?.GetRenderValue(tags)?.txt ?? deflt);
 | 
					            const str = (tr?.GetRenderValue(tags.data)?.txt ?? deflt);
 | 
				
			||||||
            return SubstitutedTranslation.SubstituteKeys(str, tags);
 | 
					            return SubstitutedTranslation.SubstituteKeys(str, tags.data);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const iconUrl = render(this.icon);
 | 
					 | 
				
			||||||
        const iconSize = render(this.iconSize, "40,40,center").split(",");
 | 
					        const iconSize = render(this.iconSize, "40,40,center").split(",");
 | 
				
			||||||
        const dashArray = render(this.dashArray).split(" ").map(Number);
 | 
					        const dashArray = render(this.dashArray).split(" ").map(Number);
 | 
				
			||||||
        let color = render(this.color, "#00f");
 | 
					        let color = render(this.color, "#00f");
 | 
				
			||||||
| 
						 | 
					@ -200,8 +200,6 @@ export default class LayerConfig {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const weight = rendernum(this.width, 5);
 | 
					        const weight = rendernum(this.width, 5);
 | 
				
			||||||
        const rotation = render(this.rotation, "0deg");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const iconW = num(iconSize[0]);
 | 
					        const iconW = num(iconSize[0]);
 | 
				
			||||||
        const iconH = num(iconSize[1]);
 | 
					        const iconH = num(iconSize[1]);
 | 
				
			||||||
| 
						 | 
					@ -223,24 +221,35 @@ export default class LayerConfig {
 | 
				
			||||||
            anchorH = iconH;
 | 
					            anchorH = iconH;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const iconUrlStatic = render(this.icon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var mappedHtml = tags.map(_ => {
 | 
				
			||||||
 | 
					            // What do you mean, 'tags' is never read?
 | 
				
			||||||
 | 
					            // It is read implicitly in the 'render' method
 | 
				
			||||||
 | 
					            const iconUrl = render(this.icon);
 | 
				
			||||||
 | 
					            const rotation = render(this.rotation, "0deg");
 | 
				
			||||||
            let html = `<img src="${iconUrl}" style="width:100%;height:100%;rotate:${rotation};display:block;" />`;
 | 
					            let html = `<img src="${iconUrl}" style="width:100%;height:100%;rotate:${rotation};display:block;" />`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (iconUrl.startsWith(Utils.assets_path)) {
 | 
					            if (iconUrl.startsWith(Utils.assets_path)) {
 | 
				
			||||||
                const key = iconUrl.substr(Utils.assets_path.length);
 | 
					                const key = iconUrl.substr(Utils.assets_path.length);
 | 
				
			||||||
                html = new Combine([
 | 
					                html = new Combine([
 | 
				
			||||||
                    (Svg.All[key] as string).replace(/stop-color:#000000/g, 'stop-color:' + color)
 | 
					                    (Svg.All[key] as string).replace(/stop-color:#000000/g, 'stop-color:' + color)
 | 
				
			||||||
            ]).SetStyle(`width:100%;height:100%;rotate:${rotation};display:block;`).Render();
 | 
					                ]).SetStyle(`width:100%;height:100%;rotate:${rotation};display:block;`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    .Render();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            return html;
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            icon:
 | 
					            icon:
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    html: html,
 | 
					                    html: new VariableUiElement(mappedHtml).Render(),
 | 
				
			||||||
                    iconSize: [iconW, iconH],
 | 
					                    iconSize: [iconW, iconH],
 | 
				
			||||||
                    iconAnchor: [anchorW, anchorH],
 | 
					                    iconAnchor: [anchorW, anchorH],
 | 
				
			||||||
                    popupAnchor: [0, 3 - anchorH],
 | 
					                    popupAnchor: [0, 3 - anchorH],
 | 
				
			||||||
                    rotation: rotation,
 | 
					                    iconUrl: iconUrlStatic,
 | 
				
			||||||
                    iconUrl: iconUrl,
 | 
					 | 
				
			||||||
                    className: clickable ? "leaflet-div-icon" : "leaflet-div-icon unclickable"
 | 
					                    className: clickable ? "leaflet-div-icon" : "leaflet-div-icon unclickable"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            color: color,
 | 
					            color: color,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,13 +129,17 @@ export class FilteredLayer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let self = this;
 | 
					        let self = this;
 | 
				
			||||||
        this._geolayer = L.geoJSON(data, {
 | 
					        this._geolayer = L.geoJSON(data, {
 | 
				
			||||||
            style: feature =>
 | 
					            style: feature => {
 | 
				
			||||||
                self.layerDef.GenerateLeafletStyle(feature.properties, self._showOnPopup !== undefined),
 | 
					                const tagsSource = State.state.allElements.getElement(feature.properties.id);
 | 
				
			||||||
 | 
					                return self.layerDef.GenerateLeafletStyle(tagsSource, self._showOnPopup !== undefined);
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            pointToLayer: function (feature, latLng) {
 | 
					            pointToLayer: function (feature, latLng) {
 | 
				
			||||||
                // Point to layer converts the 'point' to a layer object - as the geojson layer natively cannot handle points
 | 
					                // Point to layer converts the 'point' to a layer object - as the geojson layer natively cannot handle points
 | 
				
			||||||
                // Click handling is done in the next step
 | 
					                // Click handling is done in the next step
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                const style = self.layerDef.GenerateLeafletStyle(feature.properties, self._showOnPopup !== undefined);
 | 
					                const tagSource = State.state.allElements.getElement(feature.properties.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                const style = self.layerDef.GenerateLeafletStyle(tagSource, self._showOnPopup !== undefined);
 | 
				
			||||||
                let marker;
 | 
					                let marker;
 | 
				
			||||||
                if (style.icon === undefined) {
 | 
					                if (style.icon === undefined) {
 | 
				
			||||||
                    marker = L.circle(latLng, {
 | 
					                    marker = L.circle(latLng, {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue