Fixed update position new marker/polygon on resize in image-map
This commit is contained in:
		
							parent
							
								
									d547ba407a
								
							
						
					
					
						commit
						1e1d3a8257
					
				@ -30,6 +30,7 @@ import 'leaflet.markercluster/dist/leaflet.markercluster';
 | 
			
		||||
import {
 | 
			
		||||
  defaultSettings,
 | 
			
		||||
  FormattedData,
 | 
			
		||||
  MapProviders,
 | 
			
		||||
  MapSettings,
 | 
			
		||||
  MarkerSettings,
 | 
			
		||||
  PolygonSettings,
 | 
			
		||||
@ -74,6 +75,8 @@ export default abstract class LeafletMap {
 | 
			
		||||
    drawRoutes: boolean;
 | 
			
		||||
    showPolygon: boolean;
 | 
			
		||||
    updatePending = false;
 | 
			
		||||
    addMarkers: L.Marker[] = [];
 | 
			
		||||
    addPolygons: L.Polygon[] = [];
 | 
			
		||||
 | 
			
		||||
    protected constructor(public ctx: WidgetContext,
 | 
			
		||||
                          public $container: HTMLElement,
 | 
			
		||||
@ -133,6 +136,7 @@ export default abstract class LeafletMap {
 | 
			
		||||
                      shadowSize: [41, 41]
 | 
			
		||||
                    });
 | 
			
		||||
                    const newMarker = L.marker(mousePositionOnMap, { icon }).addTo(this.map);
 | 
			
		||||
                    this.addMarkers.push(newMarker);
 | 
			
		||||
                    const datasourcesList = document.createElement('div');
 | 
			
		||||
                    const customLatLng = this.convertToCustomFormat(mousePositionOnMap);
 | 
			
		||||
                    const header = document.createElement('p');
 | 
			
		||||
@ -147,6 +151,10 @@ export default abstract class LeafletMap {
 | 
			
		||||
                            const updatedEnttity = { ...ds, ...customLatLng };
 | 
			
		||||
                            this.saveMarkerLocation(updatedEnttity).subscribe(() => {
 | 
			
		||||
                              this.map.removeLayer(newMarker);
 | 
			
		||||
                              const markerIndex = this.addMarkers.indexOf(newMarker);
 | 
			
		||||
                              if (markerIndex > -1) {
 | 
			
		||||
                                this.addMarkers.splice(markerIndex, 1);
 | 
			
		||||
                              }
 | 
			
		||||
                              this.deleteMarker(ds.entityName);
 | 
			
		||||
                              this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options);
 | 
			
		||||
                            });
 | 
			
		||||
@ -158,6 +166,10 @@ export default abstract class LeafletMap {
 | 
			
		||||
                    deleteBtn.appendChild(document.createTextNode('Discard changes'));
 | 
			
		||||
                    deleteBtn.onclick = () => {
 | 
			
		||||
                        this.map.removeLayer(newMarker);
 | 
			
		||||
                        const markerIndex = this.addMarkers.indexOf(newMarker);
 | 
			
		||||
                        if (markerIndex > -1) {
 | 
			
		||||
                          this.addMarkers.splice(markerIndex, 1);
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
                    datasourcesList.append(deleteBtn);
 | 
			
		||||
                    const popup = L.popup();
 | 
			
		||||
@ -196,14 +208,16 @@ export default abstract class LeafletMap {
 | 
			
		||||
      let mousePositionOnMap: L.LatLng[];
 | 
			
		||||
      let addPolygon: L.Control;
 | 
			
		||||
      this.map.on('mousemove', (e: L.LeafletMouseEvent) => {
 | 
			
		||||
        const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01;
 | 
			
		||||
        const latlng1 = e.latlng;
 | 
			
		||||
        const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + 10);
 | 
			
		||||
        const latlng3 = L.latLng(e.latlng.lat - 10, e.latlng.lng);
 | 
			
		||||
        const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + polygonOffset);
 | 
			
		||||
        const latlng3 = L.latLng(e.latlng.lat - polygonOffset, e.latlng.lng);
 | 
			
		||||
        mousePositionOnMap = [latlng1, latlng2, latlng3];
 | 
			
		||||
      });
 | 
			
		||||
      const dragListener = (e: L.DragEndEvent) => {
 | 
			
		||||
        if (e.type === 'dragend' && mousePositionOnMap) {
 | 
			
		||||
          const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map);
 | 
			
		||||
          this.addPolygons.push(newPolygon);
 | 
			
		||||
          const datasourcesList = document.createElement('div');
 | 
			
		||||
          const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)};
 | 
			
		||||
          const header = document.createElement('p');
 | 
			
		||||
@ -218,6 +232,10 @@ export default abstract class LeafletMap {
 | 
			
		||||
              const updatedEnttity = { ...ds, ...customLatLng };
 | 
			
		||||
              this.savePolygonLocation(updatedEnttity).subscribe(() => {
 | 
			
		||||
                this.map.removeLayer(newPolygon);
 | 
			
		||||
                const polygonIndex = this.addPolygons.indexOf(newPolygon);
 | 
			
		||||
                if (polygonIndex > -1) {
 | 
			
		||||
                  this.addPolygons.splice(polygonIndex, 1);
 | 
			
		||||
                }
 | 
			
		||||
                this.deletePolygon(ds.entityName);
 | 
			
		||||
              });
 | 
			
		||||
            };
 | 
			
		||||
@ -228,6 +246,10 @@ export default abstract class LeafletMap {
 | 
			
		||||
          deleteBtn.appendChild(document.createTextNode('Discard changes'));
 | 
			
		||||
          deleteBtn.onclick = () => {
 | 
			
		||||
            this.map.removeLayer(newPolygon);
 | 
			
		||||
            const polygonIndex = this.addPolygons.indexOf(newPolygon);
 | 
			
		||||
            if (polygonIndex > -1) {
 | 
			
		||||
              this.addPolygons.splice(polygonIndex, 1);
 | 
			
		||||
            }
 | 
			
		||||
          };
 | 
			
		||||
          datasourcesList.append(deleteBtn);
 | 
			
		||||
          const popup = L.popup();
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
 | 
			
		||||
import { WidgetSubscriptionOptions } from '@core/api/widget-api.models';
 | 
			
		||||
import { isDefinedAndNotNull, isEmptyStr } from '@core/utils';
 | 
			
		||||
 | 
			
		||||
const maxZoom = 4;// ?
 | 
			
		||||
const maxZoom = 4; // ?
 | 
			
		||||
 | 
			
		||||
export class ImageMap extends LeafletMap {
 | 
			
		||||
 | 
			
		||||
@ -162,52 +162,64 @@ export class ImageMap extends LeafletMap {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onResize(updateImage?: boolean) {
 | 
			
		||||
        let width = this.$container.clientWidth;
 | 
			
		||||
        if (width > 0 && this.aspect) {
 | 
			
		||||
            let height = width / this.aspect;
 | 
			
		||||
            const imageMapHeight = this.$container.clientHeight;
 | 
			
		||||
            if (imageMapHeight > 0 && height > imageMapHeight) {
 | 
			
		||||
                height = imageMapHeight;
 | 
			
		||||
                width = height * this.aspect;
 | 
			
		||||
            }
 | 
			
		||||
            width *= maxZoom;
 | 
			
		||||
            const prevWidth = this.width;
 | 
			
		||||
            const prevHeight = this.height;
 | 
			
		||||
            if (this.width !== width || updateImage) {
 | 
			
		||||
                this.width = width;
 | 
			
		||||
                this.height = width / this.aspect;
 | 
			
		||||
                if (!this.map) {
 | 
			
		||||
                    this.initMap(updateImage);
 | 
			
		||||
                } else {
 | 
			
		||||
                    const lastCenterPos = this.latLngToPoint(this.map.getCenter());
 | 
			
		||||
                    lastCenterPos.x /= prevWidth;
 | 
			
		||||
                    lastCenterPos.y /= prevHeight;
 | 
			
		||||
                    this.updateBounds(updateImage, lastCenterPos);
 | 
			
		||||
                    this.map.invalidateSize(true);
 | 
			
		||||
                    this.updateMarkers(this.markersData);
 | 
			
		||||
                    this.updatePolygons(this.polygonsData);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
      let width = this.$container.clientWidth;
 | 
			
		||||
      if (width > 0 && this.aspect) {
 | 
			
		||||
        let height = width / this.aspect;
 | 
			
		||||
        const imageMapHeight = this.$container.clientHeight;
 | 
			
		||||
        if (imageMapHeight > 0 && height > imageMapHeight) {
 | 
			
		||||
          height = imageMapHeight;
 | 
			
		||||
          width = height * this.aspect;
 | 
			
		||||
        }
 | 
			
		||||
        width *= maxZoom;
 | 
			
		||||
        const prevWidth = this.width;
 | 
			
		||||
        const prevHeight = this.height;
 | 
			
		||||
        if (this.width !== width || updateImage) {
 | 
			
		||||
          this.width = width;
 | 
			
		||||
          this.height = width / this.aspect;
 | 
			
		||||
          if (!this.map) {
 | 
			
		||||
            this.initMap(updateImage);
 | 
			
		||||
          } else {
 | 
			
		||||
            const lastCenterPos = this.latLngToPoint(this.map.getCenter());
 | 
			
		||||
            lastCenterPos.x /= prevWidth;
 | 
			
		||||
            lastCenterPos.y /= prevHeight;
 | 
			
		||||
            this.updateBounds(updateImage, lastCenterPos);
 | 
			
		||||
            this.map.invalidateSize(true);
 | 
			
		||||
            this.updateMarkers(this.markersData);
 | 
			
		||||
            if (this.options.draggableMarker && this.addMarkers.length) {
 | 
			
		||||
              this.addMarkers.forEach((marker) => {
 | 
			
		||||
                const prevPoint = this.convertToCustomFormat(marker.getLatLng(), prevWidth, prevHeight);
 | 
			
		||||
                marker.setLatLng(this.convertPosition(prevPoint));
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
            this.updatePolygons(this.polygonsData);
 | 
			
		||||
            if (this.options.showPolygon && this.options.editablePolygon && this.addPolygons.length) {
 | 
			
		||||
              this.addPolygons.forEach((polygon) => {
 | 
			
		||||
                const prevPolygonPoint = this.convertToPolygonFormat(polygon.getLatLngs(), prevWidth, prevHeight);
 | 
			
		||||
                polygon.setLatLngs(this.convertPositionPolygon(prevPolygonPoint));
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fitBounds(bounds: LatLngBounds, padding?: LatLngTuple) { }
 | 
			
		||||
 | 
			
		||||
    initMap(updateImage?: boolean) {
 | 
			
		||||
        if (!this.map && this.aspect > 0) {
 | 
			
		||||
            const center = this.pointToLatLng(this.width / 2, this.height / 2);
 | 
			
		||||
          this.map = L.map(this.$container, {
 | 
			
		||||
                minZoom: 1,
 | 
			
		||||
                maxZoom,
 | 
			
		||||
                scrollWheelZoom: !this.options.disableScrollZooming,
 | 
			
		||||
                center,
 | 
			
		||||
                zoom: 1,
 | 
			
		||||
                crs: L.CRS.Simple,
 | 
			
		||||
                attributionControl: false,
 | 
			
		||||
                editable: !!this.options.editablePolygon
 | 
			
		||||
            });
 | 
			
		||||
            this.updateBounds(updateImage);
 | 
			
		||||
        }
 | 
			
		||||
      if (!this.map && this.aspect > 0) {
 | 
			
		||||
        const center = this.pointToLatLng(this.width / 2, this.height / 2);
 | 
			
		||||
        this.map = L.map(this.$container, {
 | 
			
		||||
          minZoom: 1,
 | 
			
		||||
          maxZoom,
 | 
			
		||||
          scrollWheelZoom: !this.options.disableScrollZooming,
 | 
			
		||||
          center,
 | 
			
		||||
          zoom: 1,
 | 
			
		||||
          crs: L.CRS.Simple,
 | 
			
		||||
          attributionControl: false,
 | 
			
		||||
          editable: !!this.options.editablePolygon
 | 
			
		||||
        });
 | 
			
		||||
        this.updateBounds(updateImage);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    convertPosition(expression): L.LatLng {
 | 
			
		||||
@ -227,13 +239,14 @@ export class ImageMap extends LeafletMap {
 | 
			
		||||
        if (!Array.isArray(el[0]) && !Array.isArray(el[1]) && el.length === 2) {
 | 
			
		||||
          return this.pointToLatLng(
 | 
			
		||||
            el[0] * this.width,
 | 
			
		||||
            el[1] * this.height)
 | 
			
		||||
            el[1] * this.height
 | 
			
		||||
          );
 | 
			
		||||
        } else if (Array.isArray(el) && el.length) {
 | 
			
		||||
          return this.convertPositionPolygon(el as LatLngTuple[] | LatLngTuple[][]);
 | 
			
		||||
        } else {
 | 
			
		||||
          return null;
 | 
			
		||||
        }
 | 
			
		||||
      }).filter(el => !!el)
 | 
			
		||||
      }).filter(el => !!el);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pointToLatLng(x, y): L.LatLng {
 | 
			
		||||
@ -244,32 +257,32 @@ export class ImageMap extends LeafletMap {
 | 
			
		||||
        return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    convertToCustomFormat(position: L.LatLng): object {
 | 
			
		||||
        const point = this.latLngToPoint(position);
 | 
			
		||||
        return {
 | 
			
		||||
            [this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, this.width),
 | 
			
		||||
            [this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, this.height)
 | 
			
		||||
        }
 | 
			
		||||
    convertToCustomFormat(position: L.LatLng, width = this.width, height = this.height): object {
 | 
			
		||||
      const point = this.latLngToPoint(position);
 | 
			
		||||
      return {
 | 
			
		||||
        [this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, width),
 | 
			
		||||
        [this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, height)
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    convertToPolygonFormat(points: Array<any>): Array<any> {
 | 
			
		||||
    convertToPolygonFormat(points: Array<any>, width = this.width, height = this.height): Array<any> {
 | 
			
		||||
      if (points.length) {
 | 
			
		||||
        return points.map(point=> {
 | 
			
		||||
        return points.map(point => {
 | 
			
		||||
          if (point.length) {
 | 
			
		||||
            return this.convertToPolygonFormat(point);
 | 
			
		||||
            return this.convertToPolygonFormat(point, width, height);
 | 
			
		||||
          } else {
 | 
			
		||||
            const pos = this.latLngToPoint(point);
 | 
			
		||||
            return [calculateNewPointCoordinate(pos.x, this.width), calculateNewPointCoordinate(pos.y, this.height)];
 | 
			
		||||
            return [calculateNewPointCoordinate(pos.x, width), calculateNewPointCoordinate(pos.y, height)];
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
        });
 | 
			
		||||
      } else {
 | 
			
		||||
        return []
 | 
			
		||||
        return [];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    convertPolygonToCustomFormat(expression: any[][]): object {
 | 
			
		||||
      return {
 | 
			
		||||
        [this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
 | 
			
		||||
      }
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user