Commit 1c7639fe authored by Thomas Frion's avatar Thomas Frion

[COMMENT] Comments for MapComponent

parent d84d3d67
import { Component, OnInit } from '@angular/core';
import { HttpClient } from "@angular/common/http";
import * as L from 'leaflet';
import * as models from 'src/app/pghm-api/api/models/models';
import { ServiceService } from 'src/app/pghm-api/api/clients/service.service';
import { GendUnitService } from 'src/app/pghm-api/api/clients/gendunit.service';
import { AuthGuard } from '../services/auth-guard.service';
import { environment } from '../../environments/environment';
/**
......@@ -18,12 +16,6 @@ import { environment } from '../../environments/environment';
styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {
//<img style="height: 25px; width: 25px;" title="Institut national de l\'information géographique et forestière" src="http://wxs.ign.fr/static/logos/IGN/IGN.gif">
private readonly attributions = {
ign: 'Choucas | <a href="http://www.ign.fr/" target="_blank">IGN-F/Geoportail</a>',
osm: '&copy; <a href="http://www.openstreetmap.org/copyright" target="_blank"> OpenStreetMap</a> contributors | Choucas',
otm: '&copy; <a href="http://garmin.opentopomap.org/#right">OpentTopoMap</a> | Choucas'
};
private unit : models.UnitModel;
private map; // The map it self
......@@ -37,12 +29,11 @@ export class MapComponent implements OnInit {
constructor(
private auth : AuthGuard,
private serviceApi : ServiceService,
private gendApi : GendUnitService,
private http : HttpClient
private serviceApi : ServiceService, // Client to load from api services (OSM, OTM, IGN, ...)
private gendApi : GendUnitService, // Client to load the unit of Gendarmerie
)
{
// Here we define the PGHM Logo as a Leaflet icon. We will use it for the marker of the user's unit
this.pghmIcon = L.icon({
iconUrl: 'assets/img/pghm.png',
shadowUrl: '',
......@@ -53,6 +44,7 @@ export class MapComponent implements OnInit {
popupAnchor: [0, 0] // point from which the popup should open relative to the iconAnchor
});
// Here we define the Gendarmerie flame as a Leaflet icon. We will use it for the markers of the gendarmerie units
this.gendarmerieIcon = L.icon({
iconUrl: 'assets/img/gendarmerie.png',
shadowUrl: '',
......@@ -63,21 +55,26 @@ export class MapComponent implements OnInit {
popupAnchor: [-10, 0] // point from which the popup should open relative to the iconAnchor
});
// We get the user's unit from local storage
this.unit = new models.UnitModel(
JSON.parse(localStorage.getItem(environment.localStorage.unit))
);
// We get the coordinates of the user's unit in a format which be understanbale by Leaflet
let coordinates = this.getCoor(this.unit.geom);
// We position the marker of the user's unit and we add to it a popup we some information
this.marker = L.marker(coordinates, {icon: this.pghmIcon});
this.marker.bindPopup("<b>" + this.unit.name + "</b> (" + this.unit.code + ") <br>"+
"<a href='mailto:" + this.unit.email + "'>" + this.unit.email + "</a><br><br>" +
MapComponent.ddToDMS(coordinates[0],coordinates[1]) + "<br>" +
"<b>Lat: </b>"+ coordinates[0] +", <b>Lon: </b>" + coordinates[1]);
"<b>Lat: </b>"+ coordinates[0] +", <b>Lng: </b>" + coordinates[1]);
}
ngOnInit(): void {
this.baseMap = {};
// We load all map services as Leaflet layers
this.serviceApi.all().then((res) => {
res.forEach((elem) => {
let setting = new models.Service(elem);
......@@ -98,6 +95,7 @@ export class MapComponent implements OnInit {
// }
});
// We define the map itself
this.map = L.map('map', {
center: this.getCoor(this.unit.geom),
zoom: this.unit.getSetting(models.UnitSetting.SettingName.Zoom).value,
......@@ -107,17 +105,23 @@ export class MapComponent implements OnInit {
layers: [this.baseMap['OTM']]
});
// We bind move and zoom events with MapComponent context
this.map.on("moveend", this.getGendarmeries.bind(this));
this.map.on("zoomend", this.getGendarmeries.bind(this));
// We add layers defined earlier to the map
L.control.layers(this.baseMap).addTo(this.map);
// We add the marke of the user's unit and we open the popup
this.marker.addTo(this.map);
this.marker.openPopup();
// Coordinates
/// The code below is to add information boxes such as coordinates or the scale
// We get coordinates in two formats: DD and DMS
let info = L.control({position: 'bottomright'});
info.onAdd = function (map) {
info.onAdd = function (map) { // We set the css of the box
this._div = L.DomUtil.create('div', 'infoControl');
this._div.style.background = "#fff";
this._div.style.padding = "10px";
......@@ -127,29 +131,37 @@ export class MapComponent implements OnInit {
return this._div;
};
info.update = function (lat, lon) {
info.update = function (lat, lon) { // Callback when we update the coordinates
this._div.innerHTML = '<p style="margin:0;">DMS &nbsp;&nbsp; ' + MapComponent.ddToDMS(lat,lon) + '</p>'+
'<p style="margin:0;">DD &nbsp;&nbsp;<b>Lat:</b> ' + lat + '&nbsp;&nbsp;<b>Lon:</b> '+ lon+'</p>';
'<p style="margin:0;">DD &nbsp;&nbsp;<b>Lat:</b> ' + lat + '&nbsp;&nbsp;<b>Lng:</b> '+ lon+'</p>';
};
info.addTo(this.map);
info.addTo(this.map); // We add the box to the map
// We bind the mouse motion event to get the coordinates
this.map.addEventListener('mousemove', function(e){
info.update(e.latlng.lat, e.latlng.lng);
});
// We add the box of the scale
L.control.scale().addTo(this.map);
});
}
/**
* We extract the coordinates from the string returned by the API.
* Basically the string has the following format "SRID=...; POINT(lng lat)"
* @param geom String contains the information about the coordinates
*/
private getCoor(geom : string) : number[] {
let parts = geom.split(';');
let center = [ 45.21811, 5.85113 ];
let center = [ 45.21811, 5.85113 ]; // Value by default (just in case)
if(parts.length == 2){
parts = parts.pop().split(' ');
parts = parts.pop().split(' '); // We get the part "(lng lat)" and we split it (using space character)
if(parts.length == 3){
center = [
Number(parts[2].substr(0,parts[2].length -1)),
Number(parts[1].substr(1)),
Number(parts[2].substr(0,parts[2].length -1)), // We remove the )
Number(parts[1].substr(1)), // We remove the (
];
}
}
......@@ -157,15 +169,24 @@ export class MapComponent implements OnInit {
return center;
}
/**
* This methods mains to convert coordinates as DD format into DMS format
* @param lat The Latitude
* @param lon The Longitude
*/
private static ddToDMS(lat: number, lon: number,) : string{
let latitude = this.toDegreesMinutesAndSeconds(lat);
let longitude = this.toDegreesMinutesAndSeconds(lon);
let latCad = lat >= 0 ? "N" : "S";
let lonCad = lat >= 0 ? "E" : "O";
return "<b>Lat: </b>"+ latCad + " " + latitude + "&nbsp;&nbsp;<b>Lon: </b>"+ lonCad + " " + longitude ;
return "<b>Lat: </b>"+ latCad + " " + latitude + "&nbsp;&nbsp;<b>Lng: </b>"+ lonCad + " " + longitude ;
}
/**
* This methods compute the DMS format from DD input
* @param coor The DD coordinates
*/
private static toDegreesMinutesAndSeconds(coor : number) : string {
let abs = Math.abs(coor);
let deg = Math.floor(abs);
......@@ -176,7 +197,12 @@ export class MapComponent implements OnInit {
return deg + "° " + min + "' " + sec+"''";
}
/**
* This method aims to get all Gendarmerie units inside of the current map bounds
* @param e Event
*/
getGendarmeries(e) : void {
// If the zoom is lower or equal at 11 we remove the GendUnit overlay if the map has it owerwise we do nothing
if (this.map.getZoom() <= 11) {
if(this.map.hasLayer(this.gendarmeries)){
this.map.removeLayer(this.gendarmeries);
......@@ -184,9 +210,12 @@ export class MapComponent implements OnInit {
return;
}
// If the map already has the overlay, then we remove it to start off on the right foot.
if(this.map.hasLayer(this.gendarmeries)){
this.map.removeLayer(this.gendarmeries);
}
// The two lines below aims to get the current map bounds and format them for the API.
const mapBounds = this.map.getBounds();
const bounds = {
x_min: mapBounds.getSouthWest().lng,
......@@ -194,15 +223,15 @@ export class MapComponent implements OnInit {
x_max: mapBounds.getNorthEast().lng,
y_max: mapBounds.getNorthEast().lat,
}
this.gendarmeries = L.layerGroup([]);
this.gendApi.getInBoundaries(bounds).then(
this.gendarmeries = L.layerGroup([]); // We reset the overlay
this.gendApi.getInBoundaries(bounds).then( // We call the API to get all units inside of the current map bounds
(res) => {
res.forEach(e => {
res.forEach(e => { // We create a marker with our custom icon for each units and add it to the overlay
let marker = L.marker(this.getCoor(e.geom), {icon:this.gendarmerieIcon});
marker.bindPopup("<b>"+e.name+"</b><br><br>"+e.addr+"<br>"+e.phone);
this.gendarmeries.addLayer(marker)
this.gendarmeries.addLayer(marker)
});
this.map.addLayer(this.gendarmeries);
this.map.addLayer(this.gendarmeries); // We add the overlay to the map
},
(err) => {console.log(err);}
);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment