From f36dd96e2d8eb2a40b7d52ce7551c4d23d8f8bf1 Mon Sep 17 00:00:00 2001
From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com>
Date: Fri, 2 Oct 2020 15:44:07 +0200
Subject: [PATCH] feat(map): add map with Leaflet

---
 .gitignore                                |   3 ++
 angular.json                              |  12 ++++-
 package-lock.json                         |  25 ++++++++++
 package.json                              |   3 ++
 src/app/app.module.ts                     |   3 +-
 src/app/home/home.component.html          |   2 +-
 src/app/home/home.component.ts            |   9 ++--
 src/app/map/components/index.ts           |   6 +++
 src/app/map/components/map.component.html |   1 +
 src/app/map/components/map.component.scss |   3 ++
 src/app/map/components/map.component.ts   |  56 ++++++++++++++++++++++
 src/app/map/map.module.ts                 |  12 +++++
 src/app/map/models/map-options.ts         |   0
 src/app/map/services/map.service.spec.ts  |  16 +++++++
 src/app/map/services/map.service.ts       |   8 ++++
 src/assets/img/ic_marker.png              | Bin 0 -> 652 bytes
 src/index.html                            |  24 +++++-----
 src/main.ts                               |   5 +-
 18 files changed, 165 insertions(+), 23 deletions(-)
 create mode 100644 src/app/map/components/index.ts
 create mode 100644 src/app/map/components/map.component.html
 create mode 100644 src/app/map/components/map.component.scss
 create mode 100644 src/app/map/components/map.component.ts
 create mode 100644 src/app/map/map.module.ts
 create mode 100644 src/app/map/models/map-options.ts
 create mode 100644 src/app/map/services/map.service.spec.ts
 create mode 100644 src/app/map/services/map.service.ts
 create mode 100644 src/assets/img/ic_marker.png

diff --git a/.gitignore b/.gitignore
index 86d943a9b..dd7eaed51 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,6 @@ testem.log
 # System Files
 .DS_Store
 Thumbs.db
+
+#config
+.env
diff --git a/angular.json b/angular.json
index 79beada28..ed8667999 100644
--- a/angular.json
+++ b/angular.json
@@ -30,8 +30,16 @@
             "tsConfig": "tsconfig.app.json",
             "localize": true,
             "aot": true,
-            "assets": ["src/favicon.ico", "src/assets"],
-            "styles": ["src/styles.scss"],
+            "assets": [
+              "src/favicon.ico",
+              "src/assets",
+              {
+                "glob": "**/*",
+                "input": "./node_modules/leaflet/dist/images",
+                "output": "assets/"
+              }
+            ],
+            "styles": ["src/styles.scss", "./node_modules/leaflet/dist/leaflet.css"],
             "scripts": []
           },
           "configurations": {
diff --git a/package-lock.json b/package-lock.json
index 3cc3d6852..50b7ced9f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -773,6 +773,11 @@
         "tslib": "^2.0.0"
       }
     },
+    "@asymmetrik/ngx-leaflet": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@asymmetrik/ngx-leaflet/-/ngx-leaflet-8.1.0.tgz",
+      "integrity": "sha512-lq7LduBP/vXcaSEmKnx7mzCR8WsoYqh9pB6BNnq53yeCwsqRbG3GdKye1/i8VvoRzjDsmQBPQsIFZ9uclXrtgg=="
+    },
     "@babel/code-frame": {
       "version": "7.10.4",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
@@ -1973,6 +1978,12 @@
       "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
       "dev": true
     },
+    "@types/geojson": {
+      "version": "7946.0.7",
+      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz",
+      "integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==",
+      "dev": true
+    },
     "@types/glob": {
       "version": "7.1.3",
       "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
@@ -2004,6 +2015,15 @@
       "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
       "dev": true
     },
+    "@types/leaflet": {
+      "version": "1.5.17",
+      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.5.17.tgz",
+      "integrity": "sha512-2XYq9k6kNjhNI7PaTz8Rdxcc8Vzwu97OaS9CtcrTxnTSxFUGwjlGjTDvhTLJU+JRSfZ4lBwGcl0SjZHALdVr6g==",
+      "dev": true,
+      "requires": {
+        "@types/geojson": "*"
+      }
+    },
     "@types/minimatch": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@@ -8058,6 +8078,11 @@
       "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==",
       "dev": true
     },
+    "leaflet": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz",
+      "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw=="
+    },
     "less": {
       "version": "3.12.2",
       "resolved": "https://registry.npmjs.org/less/-/less-3.12.2.tgz",
diff --git a/package.json b/package.json
index 5a8956c0f..90b8efc60 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,8 @@
     "@angular/platform-browser": "~10.1.3",
     "@angular/platform-browser-dynamic": "~10.1.3",
     "@angular/router": "~10.1.3",
+    "@asymmetrik/ngx-leaflet": "^8.1.0",
+    "leaflet": "^1.7.1",
     "rxjs": "~6.6.0",
     "tslib": "^2.0.0",
     "zone.js": "~0.10.2"
@@ -35,6 +37,7 @@
     "@angular/localize": "^10.1.3",
     "@types/jasmine": "~3.5.0",
     "@types/jasminewd2": "~2.0.3",
+    "@types/leaflet": "^1.5.17",
     "@types/node": "^12.12.62",
     "codelyzer": "^6.0.0",
     "jasmine-core": "~3.6.0",
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 4ad3e8861..00278763f 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -11,10 +11,11 @@ import { StructureListComponent } from './structure-list/structure-list.componen
 import { FooterComponent } from './footer/footer.component';
 import { HeaderComponent } from './header/header.component';
 import { SharedModule } from './shared/shared.module';
+import { MapModule } from './map/map.module';
 
 @NgModule({
   declarations: [AppComponent, HeaderComponent, FooterComponent, HomeComponent, StructureListComponent],
-  imports: [BrowserModule, AppRoutingModule, FlexLayoutModule, SharedModule],
+  imports: [BrowserModule, AppRoutingModule, FlexLayoutModule, SharedModule, MapModule],
   providers: [{ provide: LOCALE_ID, useValue: 'fr' }, CustomBreakPointsProvider],
   bootstrap: [AppComponent],
 })
diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html
index 4f2ba48bc..56147e48a 100644
--- a/src/app/home/home.component.html
+++ b/src/app/home/home.component.html
@@ -1,5 +1,5 @@
 <div class="content-container">
   <div class="section-container">
-    <p>Home works!</p>
+    <app-map></app-map>
   </div>
 </div>
diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts
index 73acf06f0..98af51905 100644
--- a/src/app/home/home.component.ts
+++ b/src/app/home/home.component.ts
@@ -3,13 +3,10 @@ import { Component, OnInit } from '@angular/core';
 @Component({
   selector: 'app-home',
   templateUrl: './home.component.html',
-  styleUrls: ['./home.component.scss']
+  styleUrls: ['./home.component.scss'],
 })
 export class HomeComponent implements OnInit {
+  constructor() {}
 
-  constructor() { }
-
-  ngOnInit(): void {
-  }
-
+  ngOnInit(): void {}
 }
diff --git a/src/app/map/components/index.ts b/src/app/map/components/index.ts
new file mode 100644
index 000000000..45941a73c
--- /dev/null
+++ b/src/app/map/components/index.ts
@@ -0,0 +1,6 @@
+import { MapComponent } from './map.component';
+
+export { MapComponent };
+
+// tslint:disable-next-line:variable-name
+export const MapComponents = [MapComponent];
diff --git a/src/app/map/components/map.component.html b/src/app/map/components/map.component.html
new file mode 100644
index 000000000..de076413c
--- /dev/null
+++ b/src/app/map/components/map.component.html
@@ -0,0 +1 @@
+<div id="map" leaflet [leafletOptions]="mapOptions" (leafletMapReady)="onMapReady($event)"></div>
diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss
new file mode 100644
index 000000000..4bbcec030
--- /dev/null
+++ b/src/app/map/components/map.component.scss
@@ -0,0 +1,3 @@
+#map {
+  height: 600px;
+}
diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts
new file mode 100644
index 000000000..704918cd7
--- /dev/null
+++ b/src/app/map/components/map.component.ts
@@ -0,0 +1,56 @@
+import { Component, OnInit } from '@angular/core';
+import { latLng, MapOptions, tileLayer, Map, Marker, icon } from 'leaflet';
+
+declare var ol: any;
+@Component({
+  selector: 'app-map',
+  templateUrl: './map.component.html',
+  styleUrls: ['./map.component.scss'],
+})
+export class MapComponent implements OnInit {
+  public map: Map;
+  public mapOptions: MapOptions;
+
+  constructor() {}
+
+  ngOnInit(): void {
+    this.initializeMapOptions();
+  }
+
+  public onMapReady(map: Map): void {
+    this.map = map;
+    this.addSampleMarker();
+  }
+
+  private initializeMapOptions(): void {
+    this.mapOptions = {
+      center: latLng(45.764043, 4.835659),
+      zoom: 12,
+      layers: [
+        tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+          maxZoom: 18,
+          attribution: 'Map data © OpenStreetMap contributors',
+        }),
+      ],
+    };
+  }
+
+  private addSampleMarker(): void {
+    const marker = new Marker([45.764043, 4.835659]).setIcon(
+      icon({
+        iconSize: [25, 41],
+        iconAnchor: [13, 41],
+        iconUrl: '../../../assets/img/ic_marker.png',
+      })
+    );
+    marker.addTo(this.map);
+    const marker2 = new Marker([45.764043, 4.935659]).setIcon(
+      icon({
+        iconSize: [25, 41],
+        iconAnchor: [13, 41],
+        iconUrl: '../../../assets/img/ic_marker.png',
+      })
+    );
+    marker2.addTo(this.map);
+  }
+}
diff --git a/src/app/map/map.module.ts b/src/app/map/map.module.ts
new file mode 100644
index 000000000..d52d49db8
--- /dev/null
+++ b/src/app/map/map.module.ts
@@ -0,0 +1,12 @@
+import { NgModule } from '@angular/core';
+import { CommonModule, DatePipe } from '@angular/common';
+import { SharedModule } from '../shared/shared.module';
+import { MapComponents } from './components';
+import { LeafletModule } from '@asymmetrik/ngx-leaflet';
+@NgModule({
+  imports: [CommonModule, SharedModule, LeafletModule],
+  declarations: [MapComponents],
+  providers: [DatePipe],
+  exports: [MapComponents],
+})
+export class MapModule {}
diff --git a/src/app/map/models/map-options.ts b/src/app/map/models/map-options.ts
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/app/map/services/map.service.spec.ts b/src/app/map/services/map.service.spec.ts
new file mode 100644
index 000000000..9a1a1ec53
--- /dev/null
+++ b/src/app/map/services/map.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { MapService } from './map.service';
+
+describe('MapService', () => {
+  let service: MapService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(MapService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts
new file mode 100644
index 000000000..81ce8c87d
--- /dev/null
+++ b/src/app/map/services/map.service.ts
@@ -0,0 +1,8 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class MapService {
+  constructor() {}
+}
diff --git a/src/assets/img/ic_marker.png b/src/assets/img/ic_marker.png
new file mode 100644
index 0000000000000000000000000000000000000000..0cee292f0cfac7648bf62b1d257936ffb4986ffc
GIT binary patch
literal 652
zcmeAS@N?(olHy`uVBq!ia0y~yU=U|uV36iuV_;yI{zBw70|NtRfk$L90|U1(2s1Lw
znj^u$z`$4><nF|<?wrg^1_lO}bVpxD28NCO+<y{T85o!pJzX3_Dj3&>-7UQ3An@;-
z->i?_KUXR&VZP+J;(#BknP`N>ADN0inQpEFqAIci;R(|n*qJ^(;F*-SS)IQnVJ=Tw
zK3mE5({<H%-qxu*an^m`bDm+Y<RMGL>nSmt%hYTpPUQdiH*?0nqN9_$r*yg{n0yf9
z2u_g**{A;a`nvEV|74jNzqJUsE>FC4b5pLs{U7~jG9Jy{a69zxw3?{1S7+T=_k$sc
zds4;e&GT-rKf1MEGt<pN$f#ho9{b--MZN1Sl(y)yHJ&=Xc8S)E%3}{4r@iW*YM}Ug
zOL6B+%bTtGVsTL=e<$XgTiSgi<;p7elb5&Y^Zi+NZH7nAT7zi@A(uGbIjflJC~ezN
zrY2|Q+-Q7ML4Bv^RS8vtmCwH!XRXrNA@_Ht+yi~}`gikcG(I19TxoMAWF0S`&dDv_
zO%E&YwVqZNG78Q4@Zc9?<N8O^`#<=kTs<4at7J1_tvm0m1HF=si%eqgU03#*-#ppv
z)lBX-&M=`EmfQT5zt30yTg=0EY3lz265)B1%jy=e-8nc>;gR`SBijv+=iKS?xp&FE
zAty0CbkXaeHEo&kw`x0>6?iRI+|jH5=e?!1@_Kj23$FJH>)KBLTekKC-`wwe_WjvA
zH#Nd*Q!wx3jN5+e8s-X1Z0Xi}9`woP;8ytwhhit{PftEH{nx(rVzWDT|B7+$H7mV6
zZT88Q8;ZxRCqL(Wk`y3i-*KTr@!Hz$BE|YgE`95sXTI@#Z1O**SO1?+IR1UX0tN;K
N22WQ%mvv4FO#n1*DI)*?

literal 0
HcmV?d00001

diff --git a/src/index.html b/src/index.html
index 761c288f2..3469415cc 100644
--- a/src/index.html
+++ b/src/index.html
@@ -1,13 +1,15 @@
-<!doctype html>
+<!DOCTYPE html>
 <html lang="en">
-<head>
-  <meta charset="utf-8">
-  <title>Pamn</title>
-  <base href="/">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <link rel="icon" type="image/x-icon" href="favicon.ico">
-</head>
-<body>
-  <app-root></app-root>
-</body>
+  <head>
+    <meta charset="utf-8" />
+    <title>Pamn</title>
+    <base href="/" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <link rel="icon" type="image/x-icon" href="favicon.ico" />
+    <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css" />
+    <script src="https://openlayers.org/en/v4.6.5/build/ol.js" type="text/javascript"></script>
+  </head>
+  <body>
+    <app-root></app-root>
+  </body>
 </html>
diff --git a/src/main.ts b/src/main.ts
index c7b673cf4..d9a2e7e4a 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -8,5 +8,6 @@ if (environment.production) {
   enableProdMode();
 }
 
-platformBrowserDynamic().bootstrapModule(AppModule)
-  .catch(err => console.error(err));
+platformBrowserDynamic()
+  .bootstrapModule(AppModule)
+  .catch((err) => console.error(err));
-- 
GitLab