File

src/app/GN2CommonModule/map/marker/marker.component.ts

Description

Ce composant permet d'afficher un marker au clic sur la carte ainsi qu'un controleur permettant d'afficher/désafficher le marker.

NB: Doit être utiliser à l'interieur d'une balise pnx-map

Metadata

selector pnx-marker
templateUrl marker.component.html

Inputs

coordinates
defaultEnable

Contrôle si le marker est activé par défaut au lancement du composant

Default value: true

zoomLevel

Niveau de zoom à partir du quel on peut ajouter un marker sur la carte

Type: number

zoomToLocationLevel

Type: number

Outputs

markerChanged $event type: EventEmitter

Constructor

constructor(mapservice: MapService, _commonService: CommonService, config: any)

Methods

setMarkerLegend
setMarkerLegend()
Returns: void
enableMarkerOnClick
enableMarkerOnClick()
Returns: void
generateMarkerAndEvent
generateMarkerAndEvent(x: any, y: any, withEvents: boolean, zoomOnLayer: boolean)
Returns: void
markerMoveEvent
markerMoveEvent(marker: any)
Returns: void
changeMarkerButtonColor
changeMarkerButtonColor(enable: any)
Returns: void
toggleEditing
toggleEditing(enable: boolean)
Returns: void
markerToGeojson
markerToGeojson(latLng: any)
Returns: void

Properties

Private _coordinates
_coordinates: any
config
config: any
coordinates
coordinates: any[]
Public map
map: any
mapservice
mapservice: MapService
Public previousCoord
previousCoord: any[]
import { Component, OnInit, Input, Output, EventEmitter, OnChanges } from '@angular/core';
import { Map, Marker, Icon } from 'leaflet';
import { BehaviorSubject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { MapService } from '../map.service';
import * as L from 'leaflet';
import { CommonService } from '../../service/common.service';
import { ConfigService } from '@geonature/services/config.service';

const iconRetinaUrl = './marker-icon-2x.png';
const iconUrl = './marker-icon.png';
const shadowUrl = './marker-shadow.png';

export const CustomMarkerIcon = Icon.extend({
  options: {
    iconRetinaUrl: iconRetinaUrl,
    iconUrl: iconUrl,
    shadowUrl: shadowUrl,
    iconSize: [25, 41],
    iconAnchor: [12, 41],
    popupAnchor: [1, -34],
    tooltipAnchor: [16, -28],
    shadowSize: [41, 41],
  },
});

/**
 * Ce composant permet d'afficher un marker au clic sur la carte ainsi qu'un controleur permettant d'afficher/désafficher le marker.
 *
 * NB: Doit être utiliser à l'interieur d'une balise ``pnx-map``
 */
@Component({
  selector: 'pnx-marker',
  templateUrl: 'marker.component.html',
})
export class MarkerComponent implements OnInit, OnChanges {
  public map: Map;
  public previousCoord: Array<any>;
  private _coordinates: BehaviorSubject<Array<any>> = new BehaviorSubject(null);
  get coordinates(): Array<any> {
    return this._coordinates.getValue();
  }
  @Input('coordinates') set coordinates(value: Array<any>) {
    this._coordinates.next(value);
  }
  @Input() zoomToLocationLevel: number;
  /** Niveau de zoom à partir du quel on peut ajouter un marker sur la carte*/
  @Input() zoomLevel: number;
  /** Contrôle si le marker est activé par défaut au lancement du composant */
  @Input() defaultEnable = true;
  @Output() markerChanged = new EventEmitter<any>();
  constructor(
    public mapservice: MapService,
    private _commonService: CommonService,
    public config: ConfigService
  ) {}

  ngOnInit() {
    this.map = this.mapservice.map;
    this.zoomLevel = this.zoomLevel || this.config.MAPCONFIG.ZOOM_LEVEL_RELEVE;

    this.setMarkerLegend();
    // activation or not of the marker
    if (this.defaultEnable) {
      this.enableMarkerOnClick();
    } else {
      this.changeMarkerButtonColor(false);
    }

    this.mapservice.isMarkerEditing$.subscribe((isEditing) => {
      this.toggleEditing(isEditing);
    });

    //Observable pour gérer de l'affichage du marker
    this._coordinates
      .pipe(filter((coords) => this.map !== undefined && coords != null))
      .subscribe((coords) => {
        this.previousCoord = coords;
        this.generateMarkerAndEvent(coords[0], coords[1], false, true);
      });
  }

  setMarkerLegend() {
    // Marker
    const MarkerLegend = this.mapservice.addCustomLegend(
      'topleft',
      'markerLegend',
      'url(assets/images/location-pointer.png)'
    );
    this.map.addControl(new MarkerLegend());
    // custom the marker
    document.getElementById('markerLegend').style.backgroundColor = '#c8c8cc';
    L.DomEvent.disableClickPropagation(document.getElementById('markerLegend'));
    document.getElementById('markerLegend').onclick = () => {
      this.toggleEditing(true);
    };
  }

  enableMarkerOnClick() {
    this.map.on('click', (e: any) => {
      // check zoom level
      if (this.map.getZoom() < this.zoomLevel) {
        this._commonService.translateToaster('warning', 'Map.ZoomWarning');
      } else {
        this.generateMarkerAndEvent(e.latlng.lng, e.latlng.lat, true);
      }
    });
  }
  generateMarkerAndEvent(x, y, withEvents = true, zoomOnLayer = false) {
    if (this.mapservice.marker !== undefined) {
      this.mapservice.marker.remove();
      this.mapservice.marker = this.mapservice.createMarker(x, y, true).addTo(this.map);
      this.previousCoord = [x, y];
      this.markerMoveEvent(this.mapservice.marker);
    } else {
      this.mapservice.marker = this.mapservice.createMarker(x, y, true).addTo(this.map);
      this.markerMoveEvent(this.mapservice.marker);
    }
    // observable to send geojson
    // this.mapservice.firstLayerFromMap = false;

    const geojsonMarker = this.markerToGeojson(this.mapservice.marker.getLatLng());
    if (withEvents) {
      this.mapservice.setGeojsonCoord(geojsonMarker);
      this.markerChanged.emit(geojsonMarker);
    }

    if (zoomOnLayer) {
      this.mapservice.zoomOnMarker([x, y]);
    }
  }

  markerMoveEvent(marker: Marker) {
    marker.on('moveend', (event: L.LeafletMouseEvent) => {
      if (this.map.getZoom() < this.zoomLevel) {
        this._commonService.translateToaster('warning', 'Map.ZoomWarning');
        this.mapservice.marker.remove();
        this.mapservice.marker = this.mapservice.createMarker(
          this.previousCoord[0],
          this.previousCoord[1],
          true
        );
        this.map.addLayer(this.mapservice.marker);
        this.markerMoveEvent(this.mapservice.marker);
      } else {
        const geojsonCoord = this.markerToGeojson(this.mapservice.marker.getLatLng());
        this.mapservice.setGeojsonCoord(geojsonCoord);
        this.markerChanged.emit(geojsonCoord);
      }
    });
  }

  changeMarkerButtonColor(enable) {
    document.getElementById('markerLegend').style.backgroundColor = enable ? '#c8c8cc' : 'white';
  }

  toggleEditing(enable: boolean) {
    this.mapservice.editingMarker = enable;
    this.changeMarkerButtonColor(this.mapservice.editingMarker);

    if (!this.mapservice.editingMarker) {
      // disable event
      this.mapservice.map.off('click');
      if (this.mapservice.marker !== undefined) {
        this.mapservice.marker.off('moveend');
        this.map.removeLayer(this.mapservice.marker);
      }
    } else {
      this.mapservice.removeAllLayers(this.map, this.mapservice.leafletDrawFeatureGroup);
      this.mapservice.removeAllLayers(this.map, this.mapservice.fileLayerFeatureGroup);
      this.enableMarkerOnClick();
    }
  }

  markerToGeojson(latLng) {
    return { geometry: { type: 'Point', coordinates: [latLng.lng, latLng.lat] } };
  }

  ngOnChanges(changes) {
    if (this.map && changes.coordinates && changes.coordinates.currentValue) {
      const coords = changes.coordinates.currentValue;
      this.coordinates = coords;
    }
  }
}

results matching ""

    No results matching ""