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 01/10] 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 zcmV;70(1R|P)<h;3K|Lk000e1NJLTq000*N000{Z1^@s6m*^DR00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP<VFdsH0wGC6K~#7FtybM} z+CUKg_D-7di}|S_qyy4HsK8DIHWgSH{2X|W9E%FT6(k)HS74Vw2Lkfo43ciMCl7>R zoeYL=26VT}etX>QekVc+e)qi30G%1aIWgB{T(fp2Jdu$P@%?F-{&K~Wi<F5*U^MU+ z2vcMjRK6$U*REH@{v87W_Jj~cr(x3BvTYFG_>atJ;+?SDRsEKHTFup(*sk~hVhfUZ z%d?)_uf?^0DQQMH5;AbBE(iUxa*eMzBD5_Afy&FRq$-$s#^6Dg>W`H$A^Ws*iJ3Xs zg)bIfT6F!9Y|f>N*kshIN6FK+FAn^s)|g0atuU4_RMH6ULnJjUBDS!0CLTINfiuM* zC%H-07$q>N=k_ydsw}u3{h1!%FDHNQo_r|t$3dw)%v7!o4lK#EOM>Bf-i6C25;9e6 z@ZkCZfv@5lzwk_C)y+~3B0P|-M-7_5jTwQWG+o};BTS!zlSb;93x)|+5?ln^4|)5~ zd;X&g4$_tXz!+C<lXiZf2He4sAmTU8GCi>4oZN~`-qJ^aY++|rqU%zuhG}2geTV}f z4LPXXE`R<@w1s)si-_n7?;x&*%l@XV@D82#yuSRson=@`vQrI{XxmP%fSnT<w2Ln1 zQt~{(wI7heU6C)BW5SpEzONRWh`ah+Lyb0d+m@TjgxDd+JCo-L<YG`7KZwwHA=a(8 m6mu`c()Np<H?hxMWBvl_|L2g$_n@Ev0000<MNUMnLSTY4ZYd)G 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 From 0daaf7c37063231735ac9896244c146f9aeebad6 Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Fri, 9 Oct 2020 15:23:04 +0200 Subject: [PATCH 02/10] feat(carto): first working verison of leafleat carto with wms from data.grandlyon --- angular.json | 6 +- package-lock.json | 77 ++++++++++++++++++-- package.json | 5 +- src/app/map/components/map.component.html | 13 +++- src/app/map/components/map.component.scss | 28 ++++++++ src/app/map/components/map.component.ts | 82 +++++++++++++++++++--- src/app/map/map.module.ts | 3 +- src/assets/img/ic_marker.png | Bin 652 -> 1274 bytes src/index.html | 4 ++ src/styles.scss | 1 + tsconfig.app.json | 2 + tsconfig.spec.json | 14 +--- 12 files changed, 204 insertions(+), 31 deletions(-) diff --git a/angular.json b/angular.json index ed8667999..9bc732dd2 100644 --- a/angular.json +++ b/angular.json @@ -39,7 +39,11 @@ "output": "assets/" } ], - "styles": ["src/styles.scss", "./node_modules/leaflet/dist/leaflet.css"], + "styles": [ + "src/styles.scss", + "./node_modules/leaflet/dist/leaflet.css", + "./node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css" + ], "scripts": [] }, "configurations": { diff --git a/package-lock.json b/package-lock.json index 50b7ced9f..5441d3080 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1945,6 +1945,28 @@ } } }, + "@runette/ngx-leaflet-locate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@runette/ngx-leaflet-locate/-/ngx-leaflet-locate-1.0.3.tgz", + "integrity": "sha512-U792/VO5PvQKok7H4CHJ+u3L7Vy3Pca3Iki32CXVqloVzUOO0VcNMcF07NoLcXkUHEXX7hJ5I7OGivTyMFcYpQ==", + "requires": { + "@types/leaflet.locatecontrol": "^0.60.7", + "leaflet.locatecontrol": "^0.68.0", + "tslib": "^1.9.0" + }, + "dependencies": { + "leaflet.locatecontrol": { + "version": "0.68.0", + "resolved": "https://registry.npmjs.org/leaflet.locatecontrol/-/leaflet.locatecontrol-0.68.0.tgz", + "integrity": "sha512-jXJCpBvkyH6shjPEOK/DWu/tKX/WdkNeO96jyPrnGelYp9u6wSDj4V1V4aX9+CMTIrEyVB4/4XuU+T7VTRpb6w==" + }, + "tslib": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", + "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" + } + } + }, "@schematics/angular": { "version": "10.1.3", "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-10.1.3.tgz", @@ -1981,8 +2003,7 @@ "@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 + "integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==" }, "@types/glob": { "version": "7.1.3", @@ -2019,11 +2040,18 @@ "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/leaflet.locatecontrol": { + "version": "0.60.7", + "resolved": "https://registry.npmjs.org/@types/leaflet.locatecontrol/-/leaflet.locatecontrol-0.60.7.tgz", + "integrity": "sha512-sac/MeK4gB+3XTJ3JzCe3HqLwKNHblIpZrxUJ6FapWK8uISZ0wcy8motVO7+v/yO47tQgsnYaobwFZ//beWHBQ==", + "requires": { + "@types/leaflet": "*" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -2037,9 +2065,9 @@ "dev": true }, "@types/node": { - "version": "12.12.62", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.62.tgz", - "integrity": "sha512-qAfo81CsD7yQIM9mVyh6B/U47li5g7cfpVQEDMfQeF8pSZVwzbhwU3crc0qG4DmpsebpJPR49AKOExQyJ05Cpg==", + "version": "12.12.67", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz", + "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==", "dev": true }, "@types/normalize-package-data": { @@ -6568,6 +6596,12 @@ "minimalistic-assert": "^1.0.1" } }, + "hat": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", + "integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=", + "dev": true + }, "hex-color-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", @@ -7687,6 +7721,12 @@ } } }, + "js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8014,6 +8054,20 @@ } } }, + "karma-browserify": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/karma-browserify/-/karma-browserify-7.0.0.tgz", + "integrity": "sha512-SLgh1dmF2eZEj3glrmTD2CMJRGZwEiKA6k2hBr2+2JDC4JMU1dlsvBKpV66Lvi/tbj3H9qA+Vl/FdIcfPRrJpA==", + "dev": true, + "requires": { + "convert-source-map": "^1.1.3", + "hat": "^0.0.3", + "js-string-escape": "^1.0.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.0", + "os-shim": "^0.1.3" + } + }, "karma-chrome-launcher": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz", @@ -8083,6 +8137,11 @@ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz", "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==" }, + "leaflet.locatecontrol": { + "version": "0.72.0", + "resolved": "https://registry.npmjs.org/leaflet.locatecontrol/-/leaflet.locatecontrol-0.72.0.tgz", + "integrity": "sha512-enAf10UG9Z1bV0siTP/+vG/ZVncDqSA3V8c6iZ3s6KWL5Ngkk4A4mk9Ssefj46ey98I9HSYWqoS+k2Y7EaKjwQ==" + }, "less": { "version": "3.12.2", "resolved": "https://registry.npmjs.org/less/-/less-3.12.2.tgz", @@ -9728,6 +9787,12 @@ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, + "os-shim": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", + "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", + "dev": true + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", diff --git a/package.json b/package.json index 90b8efc60..b463714e8 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,9 @@ "@angular/platform-browser-dynamic": "~10.1.3", "@angular/router": "~10.1.3", "@asymmetrik/ngx-leaflet": "^8.1.0", + "@runette/ngx-leaflet-locate": "^1.0.3", "leaflet": "^1.7.1", + "leaflet.locatecontrol": "^0.72.0", "rxjs": "~6.6.0", "tslib": "^2.0.0", "zone.js": "~0.10.2" @@ -38,11 +40,12 @@ "@types/jasmine": "~3.5.0", "@types/jasminewd2": "~2.0.3", "@types/leaflet": "^1.5.17", - "@types/node": "^12.12.62", + "@types/node": "^12.12.67", "codelyzer": "^6.0.0", "jasmine-core": "~3.6.0", "jasmine-spec-reporter": "~5.0.0", "karma": "~5.0.0", + "karma-browserify": "^7.0.0", "karma-chrome-launcher": "~3.1.0", "karma-coverage-istanbul-reporter": "~3.0.2", "karma-jasmine": "~4.0.0", diff --git a/src/app/map/components/map.component.html b/src/app/map/components/map.component.html index de076413c..7fa9fe594 100644 --- a/src/app/map/components/map.component.html +++ b/src/app/map/components/map.component.html @@ -1 +1,12 @@ -<div id="map" leaflet [leafletOptions]="mapOptions" (leafletMapReady)="onMapReady($event)"></div> +<div + id="map" + leaflet + [leafletOptions]="mapOptions" + [leafletLayersControl]="layersControl" + (leafletMapReady)="onMapReady($event)" +></div> +<leaflet-locate-control + [map]="map" + [options]="locateOptions" + (location$)="onNewLocation($event)" +></leaflet-locate-control> diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss index 4bbcec030..67c8eb237 100644 --- a/src/app/map/components/map.component.scss +++ b/src/app/map/components/map.component.scss @@ -1,3 +1,31 @@ +@import '../../../assets/scss/color'; + #map { height: 600px; } + +::ng-deep .fa-map-marker { + display: inline-block; + height: 0; + width: 0; + border-right: 5px solid transparent; + border-bottom: 12px solid red; + border-left: 7px solid transparent; +} + +::ng-deep .leaflet-control-locate-circle { + &.leaflet-interactive { + stroke: $white !important; + fill: $black !important; + stroke-width: 2px !important; + } +} + +::ng-deep .leaflet-marker-icon { + &.leaflet-interactive { + circle { + fill: $primary-color !important; + stroke-width: unset !important; + } + } +} diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts index 704918cd7..473f9d8fb 100644 --- a/src/app/map/components/map.component.ts +++ b/src/app/map/components/map.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; -import { latLng, MapOptions, tileLayer, Map, Marker, icon } from 'leaflet'; +import { latLng, MapOptions, tileLayer, Map, Marker, icon, CRS, TileLayer, LatLngBounds } from 'leaflet'; -declare var ol: any; +declare const L: any; // Leaflet @Component({ selector: 'app-map', templateUrl: './map.component.html', @@ -10,6 +10,16 @@ declare var ol: any; export class MapComponent implements OnInit { public map: Map; public mapOptions: MapOptions; + public layersControl = {}; + public locateOptions = { + flyTo: false, + keepCurrentZoomLevel: true, + locateOptions: { + enableHighAccuracy: true, + }, + icon: 'fa-map-marker', + clickBehavior: { inView: 'stop', outOfView: 'setView', inViewNotFollowing: 'setView' }, + }; constructor() {} @@ -22,23 +32,74 @@ export class MapComponent implements OnInit { this.addSampleMarker(); } + public onNewLocation(e: Location): void { + console.log(e); + } + private initializeMapOptions(): void { + const metroMaps = new TileLayer.WMS('https://download.data.grandlyon.com/wms/grandlyon', { + crs: CRS.EPSG4326, + transparent: true, + format: 'image/png', + attribution: 'Map data © OpenStreetMap contributors', + version: '1.3.0', + bounds: new LatLngBounds([45.437, 4.568], [46.03, 5.18]), + }); + metroMaps.wmsParams = { + format: 'image/png', + transparent: true, + version: '1.3.0', + layers: 'adr_voie_lieu.adrmetropole', + service: 'WMS', + request: 'GetMap', + width: 256, + height: 256, + }; + + const ignMaps = new TileLayer.WMS('https://data.grandlyon.com/api/query/map/ign', { + crs: CRS.EPSG4326, + transparent: true, + format: 'image/png', + attribution: 'Map data © OpenStreetMap contributors', + version: '1.1.1', + }); + ignMaps.wmsParams = { + format: 'image/png', + styles: 'normal', + transparent: true, + version: '1.1.1', + layers: 'ORTHOIMAGERY.ORTHOPHOTOS.BDORTHO', + service: 'WMS', + request: 'GetMap', + width: 512, + height: 512, + }; + + const carteLayer = tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + maxZoom: 18, + attribution: 'Map data © OpenStreetMap contributors', + }); + + this.layersControl = { + baseLayers: { + Carte: carteLayer, + Satellite: ignMaps, + }, + overlays: { + 'Contours métropole': metroMaps, + }, + }; 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', - }), - ], + layers: [carteLayer, metroMaps], }; } private addSampleMarker(): void { const marker = new Marker([45.764043, 4.835659]).setIcon( icon({ - iconSize: [25, 41], + iconSize: [35, 41], iconAnchor: [13, 41], iconUrl: '../../../assets/img/ic_marker.png', }) @@ -46,11 +107,12 @@ export class MapComponent implements OnInit { marker.addTo(this.map); const marker2 = new Marker([45.764043, 4.935659]).setIcon( icon({ - iconSize: [25, 41], + iconSize: [35, 41], iconAnchor: [13, 41], iconUrl: '../../../assets/img/ic_marker.png', }) ); marker2.addTo(this.map); + marker.bindTooltip('<p>Hello <br/>World !</p>'); } } diff --git a/src/app/map/map.module.ts b/src/app/map/map.module.ts index d52d49db8..3487eb49d 100644 --- a/src/app/map/map.module.ts +++ b/src/app/map/map.module.ts @@ -3,8 +3,9 @@ import { CommonModule, DatePipe } from '@angular/common'; import { SharedModule } from '../shared/shared.module'; import { MapComponents } from './components'; import { LeafletModule } from '@asymmetrik/ngx-leaflet'; +import { NgxLeafletLocateModule } from '@runette/ngx-leaflet-locate'; @NgModule({ - imports: [CommonModule, SharedModule, LeafletModule], + imports: [CommonModule, SharedModule, NgxLeafletLocateModule, LeafletModule], declarations: [MapComponents], providers: [DatePipe], exports: [MapComponents], diff --git a/src/assets/img/ic_marker.png b/src/assets/img/ic_marker.png index 0cee292f0cfac7648bf62b1d257936ffb4986ffc..f378d60ad21bd0bae4e7570e9b6cb9800fc8f0e9 100644 GIT binary patch delta 1240 zcmV;}1Sk891^NjgiBL{Q4GJ0x0000DNk~Le0000d0000k2nGNE0IRG3{gELwe*}+7 zL_t(|0nM2|OcX&B#@`Yvu(*QLlEn_9@r)X+<cy6L8VEL6s6-O1IHg305Ctm{Itvrg z#>z-+v@sl38cBd)ppqL({v^^sd%kaYvl*5<c6PY~zvSJ_-p=j*cr)|n&EQc26^q3b z7p-h(*|Kc7_N^vLY>sUjrRRByf2t{l%Cb!rlj##%Yn=CaE{y=i#Z%hxlGf7iCHnQ_ z7p)XlXnl2^Hr6(R_Vp*~DSa|c4UG+S@$yA#I^ASHPO-JIC+DKx>qS7N1nLp4x3{+G z%jYlJP<K`OL|Oy3-)Yx%(HPqhLvB)BI0o~%m}2vjLX}c`N4qwWV!K*ye>{3oVC!q^ z^t|smp{$hPz5bDY<3&{t(Ay6T<Lc$`%L99>lxpj0skg6}n$I+s1@uB-7-O>r>{;J4 zs<!%v`)$B;_86=QwZ-7qT?vmJhDJw5&5-fs{ec3{Neudgdaf&1(J>Y!jJ+4*FLYPa zPWR?fu|4++A0Iz_JXA0UfA2#i5Cz`TaN;%Hoq#(ESz#(GK|k<Z4j)Ou&>a^pU!az2 zEqZWUf!0|jmWs6Zj!Edq;$mrGiQ)(l-H*Dd`E>K1d*8o(k3B>HcjML#{IT#}swM#A z&=KcBST`|<1q{<a&o&_?UAcBe-$y%F!Fy_1naftdWl)>>G2{FYe|T(QWWda>Nw!9w zVVGr|C~?j94)@V6PB+i|3^+1?LrzAjpj>~i*G2)GV3@Y>;*Chpb|2tq*PZKjeKf5s zub65J;C$3JRyUk}jF+LyL_-nHJMn=@B7aPztkf$Nz`2e$|CDd4`KatxJet>lB_>TN zSsZ>1#Z-N|-c*(2e@}Ej)gE{AoUPb!TiaWvnsNMzo~}t&9l$A6TxS$wp+xeG#K^L; zW2iOI_f^BGAoM7}>6zv_U;$=@owpIq^?Hqf?3xqS)z$5Sn@3G@DkoWy-|WVG`#!Gm zJy%=fuGi-;oj28az~w_<MhY(+9S-uaEL(wLW(5?<Y60Jef7&?-YqV(6lkE2|+}_jG z6MI*MfNaG*Ej(lT+qCvroadqUkQuWO#2a<8DP54o!;)quO=p?{FzjQK>^rdOk$Cu+ z;l>PHmW!z*-m8@0{fD`Ss49}pj*fGZ7UwZzZ+G0L!<HEyq9L>L*g+WU;O6yP*Y}K} zY71ay56fT^f9CrDPH6Q)ez)sxtUT<XVB!qLcGbSOYx%+;<YHWJc%SqpO1I+(y<~Og z<8UIeXKm#MIJC)!jtnX;cnduw!Z@1@w<)*qx3SGt3(%UG25hiYyZug?5S$VJGL<~c zL05)6HdwB$%lVuJMC`-a2@VUBDs=p{FIXg;1v$aRe?8P+kH6MgMzz75;RJAyWV0K0 znZx+9VrQov%PInw1P~z!V3KJdZ)`J%G!=&vK!h5dM1KAJmEOO3PvyV{h6hY$tH|+? z`ap03n5CWLvee?jqCR7@lLgmf)v8IdT_l-B^+y$Z9`qDDZg%K$ZFSB3@1YR2&o~r7 z0CA|XF2QDx46GEOrCEuQM=yW~(EkNyB!FX;1p5albj*?`Xz`Q)0000<MNUMnLSTX# COJ6kr delta 613 zcmV-r0-F8$35*3HiBL{Q4GJ0x0000DNk~Le0000N0000R2nGNE0GH?#+mRtOe*z&% zL_t(|0j*ZuaoRu-{`O9q@r(JXAfyA*L8!n^1vV8}82lV~jvR{$z!fAN5LaNAKnDWy z;0%&(vnLOPV4VzxZw7R?%YJ*@?S3ah34Zsy&j6hn!Z|V5WL&d$COnam5ApqJnErCb zlZ%vzMqo7X76?;h7*xI|<JYcNf5iSB0|EAg5Jjh9(%G_Y5a0NZ%xL1Bu-jGrmV8>x z)tcC@_yA%Hl6cFrp4+d*wSOsTMmQ2OaH}o{{jze6uQ(#KEe3(g%dMm;n0dzFL6+)| zl`tXuv~!7>IoX9T7G7F({gG_WrHj~P)T&3x)3z@T{HE5JNNlYzmM~P(e+ceFBsDA| zwy<_49y&vTGsPe$xk=R+B`~Sy_A_d#EVv&1nI7OTCx7mqd?@qBL8&~<RIUvUEXlM> zg5i1Ih07-rGF5Ew;Q9f9ui_iO@JwXY%~A~_JdmwN4Vu7>8G)iSUEbFtOrL|3M(UXh zh6z>@Tm;(>dHc_M{-X>If6|rzz!+C<lXiZf2He4sAmTU8GCi>4oZN~`-qJ^aY++|r zqU%zuhG}2geTV}f4LPXXE`R<@w1s)si-_n7?;x&*%l@XV@D82#yuSRson=@`vQrI{ zXxmP%fSnT<w2Ln1Qt~{(wI7heU6C)BW5SpEzONRWh`ah+Lyb0dJKL6<$%NP;$2*hf z3FKl>8b658cp=uUw-j?P#M1VQo;R`2U1R<N>i_4E$M>M100000NkvXXu0mjf+fySZ diff --git a/src/index.html b/src/index.html index 3469415cc..e3de07cb0 100644 --- a/src/index.html +++ b/src/index.html @@ -7,6 +7,10 @@ <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" /> + <link + rel="stylesheet" + href="https://cdn.jsdelivr.net/npm/leaflet.locatecontrol@0.72.0/dist/L.Control.Locate.min.css" + /> <script src="https://openlayers.org/en/v4.6.5/build/ol.js" type="text/javascript"></script> </head> <body> diff --git a/src/styles.scss b/src/styles.scss index 96329efae..d62180f39 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -3,6 +3,7 @@ @import 'assets/scss/typography'; @import 'assets/scss/color'; @import 'assets/scss/breakpoint'; +@import '../node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css'; html, body { diff --git a/tsconfig.app.json b/tsconfig.app.json index 6bb6c9dac..789f1f58b 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -3,6 +3,8 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", + "fullTemplateTypeCheck": true, + "strictInjectionParameters": true, "types": ["node"] }, "files": ["src/main.ts", "src/polyfills.ts"], diff --git a/tsconfig.spec.json b/tsconfig.spec.json index 092345b02..1fde99220 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -3,16 +3,8 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", - "types": [ - "jasmine" - ] + "types": ["node", "jasmine"] }, - "files": [ - "src/test.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } -- GitLab From 5aa1038800f5b2eaa021040e0b5e3e33e124b4ae Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Tue, 13 Oct 2020 17:21:37 +0200 Subject: [PATCH 03/10] feat(map): clean code and remove ign map because of heavy loading --- src/app/home/home.component.html | 7 +- src/app/map/components/map.component.html | 14 +--- src/app/map/components/map.component.scss | 4 +- src/app/map/components/map.component.ts | 94 +++++++++-------------- src/app/map/services/map.service.ts | 29 +++++++ tsconfig.app.json | 2 - 6 files changed, 72 insertions(+), 78 deletions(-) diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html index 56147e48a..ca9398f41 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -1,5 +1,4 @@ -<div class="content-container"> - <div class="section-container"> - <app-map></app-map> - </div> +<div fxLayout="row"> + <p fxFlex="30%">temp</p> + <app-map fxFlex="70%" [toogleToolTipIds]="[1, 2]"></app-map> </div> diff --git a/src/app/map/components/map.component.html b/src/app/map/components/map.component.html index 7fa9fe594..4ed0d90d5 100644 --- a/src/app/map/components/map.component.html +++ b/src/app/map/components/map.component.html @@ -1,12 +1,2 @@ -<div - id="map" - leaflet - [leafletOptions]="mapOptions" - [leafletLayersControl]="layersControl" - (leafletMapReady)="onMapReady($event)" -></div> -<leaflet-locate-control - [map]="map" - [options]="locateOptions" - (location$)="onNewLocation($event)" -></leaflet-locate-control> +<div id="map" leaflet [leafletOptions]="mapOptions" (leafletMapReady)="onMapReady($event)"></div> +<leaflet-locate-control [map]="map" [options]="locateOptions"></leaflet-locate-control> diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss index 67c8eb237..e11a4d0aa 100644 --- a/src/app/map/components/map.component.scss +++ b/src/app/map/components/map.component.scss @@ -1,7 +1,9 @@ @import '../../../assets/scss/color'; +@import '../../../assets/scss/layout'; #map { - height: 600px; + height: calc(100vh - #{$header-height} - #{$footer-height}); + width: 100%; } ::ng-deep .fa-map-marker { diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts index 473f9d8fb..6121644a2 100644 --- a/src/app/map/components/map.component.ts +++ b/src/app/map/components/map.component.ts @@ -1,16 +1,17 @@ -import { Component, OnInit } from '@angular/core'; -import { latLng, MapOptions, tileLayer, Map, Marker, icon, CRS, TileLayer, LatLngBounds } from 'leaflet'; +import { Component, Input, OnInit } from '@angular/core'; +import { latLng, MapOptions, tileLayer, Map, CRS, TileLayer, LatLngBounds } from 'leaflet'; +import { MapService } from '../services/map.service'; -declare const L: any; // Leaflet @Component({ selector: 'app-map', templateUrl: './map.component.html', styleUrls: ['./map.component.scss'], }) export class MapComponent implements OnInit { + @Input() public toogleToolTipIds: Array<number> = []; public map: Map; public mapOptions: MapOptions; - public layersControl = {}; + // Init locate options public locateOptions = { flyTo: false, keepCurrentZoomLevel: true, @@ -21,22 +22,29 @@ export class MapComponent implements OnInit { clickBehavior: { inView: 'stop', outOfView: 'setView', inViewNotFollowing: 'setView' }, }; - constructor() {} + constructor(private mapService: MapService) {} ngOnInit(): void { this.initializeMapOptions(); } + /** + * Add marker when map is ready to be showned + * @param map + */ public onMapReady(map: Map): void { this.map = map; - this.addSampleMarker(); - } - - public onNewLocation(e: Location): void { - console.log(e); + this.addMarker(); + this.toggleToolTip(this.toogleToolTipIds); } + /** + * Init map options : + * - Metropole bounds based on a WMS service hosted by data.grandlyon.com + * - Map Layer based on open street maps + */ private initializeMapOptions(): void { + // Init WMS service with param from data.grandlyon.com const metroMaps = new TileLayer.WMS('https://download.data.grandlyon.com/wms/grandlyon', { crs: CRS.EPSG4326, transparent: true, @@ -55,64 +63,32 @@ export class MapComponent implements OnInit { width: 256, height: 256, }; - - const ignMaps = new TileLayer.WMS('https://data.grandlyon.com/api/query/map/ign', { - crs: CRS.EPSG4326, - transparent: true, - format: 'image/png', - attribution: 'Map data © OpenStreetMap contributors', - version: '1.1.1', - }); - ignMaps.wmsParams = { - format: 'image/png', - styles: 'normal', - transparent: true, - version: '1.1.1', - layers: 'ORTHOIMAGERY.ORTHOPHOTOS.BDORTHO', - service: 'WMS', - request: 'GetMap', - width: 512, - height: 512, - }; - const carteLayer = tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: 'Map data © OpenStreetMap contributors', }); - - this.layersControl = { - baseLayers: { - Carte: carteLayer, - Satellite: ignMaps, - }, - overlays: { - 'Contours métropole': metroMaps, - }, - }; + // Center is set on townhall + // Zoom is blocked on 11 to prevent people to zoom out from metropole this.mapOptions = { center: latLng(45.764043, 4.835659), - zoom: 12, + zoom: 11, + minZoom: 11, layers: [carteLayer, metroMaps], }; } - private addSampleMarker(): void { - const marker = new Marker([45.764043, 4.835659]).setIcon( - icon({ - iconSize: [35, 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: [35, 41], - iconAnchor: [13, 41], - iconUrl: '../../../assets/img/ic_marker.png', - }) - ); - marker2.addTo(this.map); - marker.bindTooltip('<p>Hello <br/>World !</p>'); + /** + * Toogle all tooltips given in parameters + */ + public toggleToolTip(ids: Array<number>): void { + ids.forEach((id) => { + this.mapService.toogleToolTip(id); + }); + } + + private addMarker(): void { + //TODO: Replace with real data + this.map = this.mapService.addMarker(this.map, 45.764043, 4.835659, 1); + this.map = this.mapService.addMarker(this.map, 45.764043, 4.935659, 2); } } diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts index 81ce8c87d..30aaad690 100644 --- a/src/app/map/services/map.service.ts +++ b/src/app/map/services/map.service.ts @@ -1,8 +1,37 @@ import { Injectable } from '@angular/core'; +import { icon, Marker, Map } from 'leaflet'; @Injectable({ providedIn: 'root', }) export class MapService { + private markersList = {}; constructor() {} + + public addMarker(map: Map, lat: number, lon: number, id: number): Map { + const marker = new Marker([lat, lon]).setIcon( + icon({ + iconSize: [35, 41], + iconAnchor: [13, 41], + iconUrl: '../../../assets/img/ic_marker.png', + }) + ); + + marker.bindTooltip('<p>Hello <br/>World !</p>'); //TODO: replace with real data + marker.addTo(map); + this.markersList[id] = marker; + return map; + } + + public toogleToolTip(id: number): void { + this.getMarker(id).toggleTooltip(); + } + + public setToolTip(id: number): void { + this.getMarker(id).bindTooltip('<p>Hello <br/>World 2!</p>'); + } + + public getMarker(id: number): Marker { + return this.markersList[id]; + } } diff --git a/tsconfig.app.json b/tsconfig.app.json index 789f1f58b..6bb6c9dac 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -3,8 +3,6 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", - "fullTemplateTypeCheck": true, - "strictInjectionParameters": true, "types": ["node"] }, "files": ["src/main.ts", "src/polyfills.ts"], -- GitLab From 6295b528092663fbadde388a192f29f8c64e44c1 Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Fri, 16 Oct 2020 17:15:28 +0200 Subject: [PATCH 04/10] feat(map): add TU and clean service --- package-lock.json | 26 +++++++++--------- src/app/home/home.component.html | 2 +- src/app/home/home.component.scss | 3 +++ src/app/map/components/map.component.scss | 29 +++++++++++++++----- src/app/map/components/map.component.ts | 16 +++++------ src/app/map/services/map.service.spec.ts | 33 +++++++++++++++++++++++ src/app/map/services/map.service.ts | 27 ++++++++++++++----- 7 files changed, 101 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 57bbd8dbf..ce5d413bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8047,17 +8047,17 @@ } } }, + "jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=" + }, "js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", "dev": true }, - "jju": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=" - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8671,6 +8671,14 @@ "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", "dev": true }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "requires": { + "package-json": "^6.3.0" + } + }, "leaflet": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz", @@ -8681,14 +8689,6 @@ "resolved": "https://registry.npmjs.org/leaflet.locatecontrol/-/leaflet.locatecontrol-0.72.0.tgz", "integrity": "sha512-enAf10UG9Z1bV0siTP/+vG/ZVncDqSA3V8c6iZ3s6KWL5Ngkk4A4mk9Ssefj46ey98I9HSYWqoS+k2Y7EaKjwQ==" }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "requires": { - "package-json": "^6.3.0" - } - }, "less": { "version": "3.12.2", "resolved": "https://registry.npmjs.org/less/-/less-3.12.2.tgz", diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html index cec915a85..030fee9dd 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -1,4 +1,4 @@ <div fxLayout="row"> - <app-structure-list fxFlex="30%"></app-structure-list> + <app-structure-list class="left-pane" fxFlex="30%"></app-structure-list> <app-map fxFlex="70%" [toogleToolTipIds]="[1, 2]"></app-map> </div> diff --git a/src/app/home/home.component.scss b/src/app/home/home.component.scss index e69de29bb..7d2eb86af 100644 --- a/src/app/home/home.component.scss +++ b/src/app/home/home.component.scss @@ -0,0 +1,3 @@ +.left-pane { + padding: 0 25px; +} diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss index e11a4d0aa..e40578ea2 100644 --- a/src/app/map/components/map.component.scss +++ b/src/app/map/components/map.component.scss @@ -7,12 +7,29 @@ } ::ng-deep .fa-map-marker { - display: inline-block; - height: 0; - width: 0; - border-right: 5px solid transparent; - border-bottom: 12px solid red; - border-left: 7px solid transparent; + color: $black; + position: absolute; + margin-left: 4px; + margin-top: 2px; + width: 12px; + height: 12px; + border: solid 1px currentColor; + border-radius: 7px 7px 7px 0; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + margin-left: -6px; + margin-top: 6px; +} + +::ng-deep .fa-map-marker:before { + content: ''; + position: absolute; + left: 3px; + top: 3px; + width: 4px; + height: 4px; + border: solid 1px currentColor; + border-radius: 3px; } ::ng-deep .leaflet-control-locate-circle { diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts index 6121644a2..f3e84b556 100644 --- a/src/app/map/components/map.component.ts +++ b/src/app/map/components/map.component.ts @@ -14,7 +14,7 @@ export class MapComponent implements OnInit { // Init locate options public locateOptions = { flyTo: false, - keepCurrentZoomLevel: true, + keepCurrentZoomLevel: false, locateOptions: { enableHighAccuracy: true, }, @@ -30,12 +30,11 @@ export class MapComponent implements OnInit { /** * Add marker when map is ready to be showned - * @param map + * @param map map */ public onMapReady(map: Map): void { this.map = map; this.addMarker(); - this.toggleToolTip(this.toogleToolTipIds); } /** @@ -64,15 +63,15 @@ export class MapComponent implements OnInit { height: 256, }; const carteLayer = tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - maxZoom: 18, + maxZoom: 20, attribution: 'Map data © OpenStreetMap contributors', }); // Center is set on townhall // Zoom is blocked on 11 to prevent people to zoom out from metropole this.mapOptions = { center: latLng(45.764043, 4.835659), - zoom: 11, - minZoom: 11, + zoom: 10, + minZoom: 10, layers: [carteLayer, metroMaps], }; } @@ -88,7 +87,8 @@ export class MapComponent implements OnInit { private addMarker(): void { //TODO: Replace with real data - this.map = this.mapService.addMarker(this.map, 45.764043, 4.835659, 1); - this.map = this.mapService.addMarker(this.map, 45.764043, 4.935659, 2); + this.mapService.createMarker(45.764043, 4.835659, 1, '<p>Hello <br/>World !</p>').addTo(this.map); + this.mapService.createMarker(45.764043, 4.935659, 2, '<p>Hello <br/>World 2!</p>').addTo(this.map); + this.mapService.createMarker(45.664043, 4.835659, 3).addTo(this.map); } } diff --git a/src/app/map/services/map.service.spec.ts b/src/app/map/services/map.service.spec.ts index 9a1a1ec53..3470f88c5 100644 --- a/src/app/map/services/map.service.spec.ts +++ b/src/app/map/services/map.service.spec.ts @@ -1,4 +1,5 @@ import { TestBed } from '@angular/core/testing'; +import { Map } from 'leaflet'; import { MapService } from './map.service'; @@ -13,4 +14,36 @@ describe('MapService', () => { it('should be created', () => { expect(service).toBeTruthy(); }); + + it('should create marke with coord {lat: 45.764043, lng: 4.835659}', () => { + const marker = service.createMarker(45.764043, 4.835659, 1); + + expect(marker.getLatLng().lat).toEqual(45.764043); + expect(marker.getLatLng().lng).toEqual(4.835659); + }); + it('should add marker to map with icon ic_marker.png', () => { + const marker = service.createMarker(45.764043, 4.835659, 1); + + expect(marker.getIcon().options.iconUrl).toEqual('../../../assets/img/ic_marker.png'); + expect(marker.getIcon().options.iconSize).toEqual([35, 41]); + expect(marker.getIcon().options.iconAnchor).toEqual([13, 41]); + }); + + it('should cerate marker with tooltip', () => { + const marker = service.createMarker(45.764043, 4.835659, 1, '<p>Hello <br/>World !</p>'); + + expect(marker.getTooltip().getContent()).toEqual('<p>Hello <br/>World !</p>'); + }); + + it('should get marker', () => { + const marker = service.createMarker(45.764043, 4.835659, 1, '<p>Hello <br/>World !</p>'); + expect(marker).toEqual(service.getMarker(1)); + }); + it('should not get marker, with missing id', () => { + service.createMarker(45.764043, 4.835659, 1, '<p>Hello <br/>World !</p>'); + expect(service.getMarker(2)).toEqual(null); + }); + it('should not get marker, empty', () => { + expect(service.getMarker(1)).toEqual(null); + }); }); diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts index 30aaad690..eb5eb8d4f 100644 --- a/src/app/map/services/map.service.ts +++ b/src/app/map/services/map.service.ts @@ -8,7 +8,7 @@ export class MapService { private markersList = {}; constructor() {} - public addMarker(map: Map, lat: number, lon: number, id: number): Map { + public createMarker(lat: number, lon: number, id: number, tooltip?: string): Marker { const marker = new Marker([lat, lon]).setIcon( icon({ iconSize: [35, 41], @@ -17,21 +17,34 @@ export class MapService { }) ); - marker.bindTooltip('<p>Hello <br/>World !</p>'); //TODO: replace with real data - marker.addTo(map); + if (tooltip) { + marker.bindTooltip(tooltip); + } this.markersList[id] = marker; - return map; + return marker; } + /** + * Toogle a tooltip + * @param id marker id + */ public toogleToolTip(id: number): void { this.getMarker(id).toggleTooltip(); } - public setToolTip(id: number): void { - this.getMarker(id).bindTooltip('<p>Hello <br/>World 2!</p>'); + /** + * Set a tooltip + * @param id markerId + * @param html html to display + */ + public setToolTip(id: number, html: string): void { + this.getMarker(id).bindTooltip(html); } + /** + * Get marker by id + */ public getMarker(id: number): Marker { - return this.markersList[id]; + return this.markersList[id] ? this.markersList[id] : null; } } -- GitLab From 397fb5f7c840a2fed513ef98cf5ebf8cc27fc2c7 Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Tue, 20 Oct 2020 13:19:44 +0200 Subject: [PATCH 05/10] feat(map): merge structre and map. Remove useless components and structure refacto --- package-lock.json | 8 +++ package.json | 7 +- proxy.conf.json | 12 ++++ src/app/app.module.ts | 21 ++++-- src/app/home/home.component.html | 4 +- src/app/home/home.component.ts | 15 +++- src/app/map/components/map.component.scss | 35 ++++++++++ src/app/map/components/map.component.ts | 70 +++++++++++++++---- src/app/map/models/address.model.ts | 16 +++++ src/app/map/models/addressGeometry.model.ts | 16 +++++ src/app/map/models/geojson.model.ts | 13 ++++ src/app/map/models/map-options.ts | 0 src/app/map/services/geojson.service.spec.ts | 31 ++++++++ src/app/map/services/geojson.service.ts | 33 +++++++++ src/app/map/services/map.service.ts | 3 + .../{structure-list => }/models/day.model.ts | 0 .../models/openingDay.model.ts | 0 .../models/structure.model.ts | 17 ++++- .../{structure-list => }/models/time.model.ts | 0 .../{structure-list => }/models/week.model.ts | 0 .../services/structure-list.service.spec.ts | 0 .../services/structure-list.service.ts | 8 +-- .../components/card/card.component.html | 1 - .../components/card/card.component.scss | 0 .../components/card/card.component.spec.ts | 25 ------- .../shared/components/card/card.component.ts | 15 ---- src/app/shared/components/index.ts | 6 +- .../components/card/card.component.html | 17 ++--- .../components/card/card.component.scss | 8 +-- .../components/card/card.component.ts | 18 ++--- .../structure-list.component.html | 3 +- .../structure-list.component.ts | 5 +- .../structure-list/structure-list.module.ts | 14 ---- src/app/structure-list/structure-list.scss | 10 +++ src/environments/environment.ts | 2 + 35 files changed, 308 insertions(+), 125 deletions(-) create mode 100644 src/app/map/models/address.model.ts create mode 100644 src/app/map/models/addressGeometry.model.ts create mode 100644 src/app/map/models/geojson.model.ts delete mode 100644 src/app/map/models/map-options.ts create mode 100644 src/app/map/services/geojson.service.spec.ts create mode 100644 src/app/map/services/geojson.service.ts rename src/app/{structure-list => }/models/day.model.ts (100%) rename src/app/{structure-list => }/models/openingDay.model.ts (100%) rename src/app/{structure-list => }/models/structure.model.ts (76%) rename src/app/{structure-list => }/models/time.model.ts (100%) rename src/app/{structure-list => }/models/week.model.ts (100%) rename src/app/{structure-list => }/services/structure-list.service.spec.ts (100%) rename src/app/{structure-list => }/services/structure-list.service.ts (97%) delete mode 100644 src/app/shared/components/card/card.component.html delete mode 100644 src/app/shared/components/card/card.component.scss delete mode 100644 src/app/shared/components/card/card.component.spec.ts delete mode 100644 src/app/shared/components/card/card.component.ts delete mode 100644 src/app/structure-list/structure-list.module.ts create mode 100644 src/app/structure-list/structure-list.scss diff --git a/package-lock.json b/package-lock.json index ce5d413bd..c141501b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1902,6 +1902,14 @@ "webpack-sources": "1.4.3" } }, + "@ngx-translate/core": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-13.0.0.tgz", + "integrity": "sha512-+tzEp8wlqEnw0Gc7jtVRAJ6RteUjXw6JJR4O65KlnxOmJrCGPI0xjV/lKRnQeU0w4i96PQs/jtpL921Wrb7PWg==", + "requires": { + "tslib": "^2.0.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", diff --git a/package.json b/package.json index b582075f7..4b09a880a 100644 --- a/package.json +++ b/package.json @@ -3,14 +3,14 @@ "version": "0.0.3", "scripts": { "ng": "ng", - "start": "ng serve --configuration=fr", + "start": "ng serve --configuration=fr --proxy-config proxy.conf.json", "build:prod": "ng build --configuration=production,fr --output-path=dist", "build:dev": "ng build --configuration=fr --output-path=dist", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", "release": "standard-version", - "translate": "ng xi18n --output-path src/locale --out-file messages.en.xlf", + "translate": "ng xi18n --ivy --output-path src/locale --out-file messages.en.xlf", "api": "json-server api/db.json --routes api/routes.json --no-cors=true" }, "private": true, @@ -26,10 +26,11 @@ "@angular/platform-browser-dynamic": "~10.1.3", "@angular/router": "~10.1.3", "@asymmetrik/ngx-leaflet": "^8.1.0", + "@ngx-translate/core": "^13.0.0", "@runette/ngx-leaflet-locate": "^1.0.3", + "json-server": "^0.16.2", "leaflet": "^1.7.1", "leaflet.locatecontrol": "^0.72.0", - "json-server": "^0.16.2", "luxon": "^1.25.0", "rxjs": "~6.6.0", "tslib": "^2.0.0", diff --git a/proxy.conf.json b/proxy.conf.json index c394a84fb..4cafc6d48 100644 --- a/proxy.conf.json +++ b/proxy.conf.json @@ -1,5 +1,17 @@ { "/api": { "target": "http://localhost:3000" + }, + "/base-adresse/base-adresse-nationale/streets": { + "target": "https://passerelle.formulaireextranet.grandlyon.com", + "secure": false, + "changeOrigin": true, + "logLevel": "info" + }, + "/geocoding/photon/api": { + "target": "https://download.data.grandlyon.com", + "secure": false, + "changeOrigin": true, + "logLevel": "info" } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 0a75ad24f..7cb7bc0d7 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,21 +1,32 @@ import { LOCALE_ID, NgModule } from '@angular/core'; - -import { AppRoutingModule } from './app-routing.module'; +import { HttpClientModule } from '@angular/common/http'; import { BrowserModule } from '@angular/platform-browser'; import { FlexLayoutModule } from '@angular/flex-layout'; +import { AppRoutingModule } from './app-routing.module'; + import { AppComponent } from './app.component'; import { HomeComponent } from './home/home.component'; import { CustomBreakPointsProvider } from './config/custom-breakpoint'; import { FooterComponent } from './footer/footer.component'; import { HeaderComponent } from './header/header.component'; import { SharedModule } from './shared/shared.module'; -import { StructureListModule } from './structure-list/structure-list.module'; import { MapModule } from './map/map.module'; +import { RechercheComponent } from './structure-list/components/recherche/recherche.component'; +import { StructureListComponent } from './structure-list/structure-list.component'; +import { CardComponent } from './structure-list/components/card/card.component'; @NgModule({ - declarations: [AppComponent, HeaderComponent, FooterComponent, HomeComponent], - imports: [BrowserModule, AppRoutingModule, FlexLayoutModule, SharedModule, StructureListModule, MapModule], + declarations: [ + AppComponent, + HeaderComponent, + FooterComponent, + HomeComponent, + StructureListComponent, + CardComponent, + RechercheComponent, + ], + imports: [BrowserModule, HttpClientModule, 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 030fee9dd..68c653d8b 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -1,4 +1,4 @@ <div fxLayout="row"> - <app-structure-list class="left-pane" fxFlex="30%"></app-structure-list> - <app-map fxFlex="70%" [toogleToolTipIds]="[1, 2]"></app-map> + <app-structure-list [structureList]="structures" class="left-pane" fxFlex="30%"></app-structure-list> + <app-map fxFlex="70%" [structures]="structures"></app-map> </div> diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index 98af51905..2264953e0 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -1,4 +1,8 @@ import { Component, OnInit } from '@angular/core'; +import { mergeMap } from 'rxjs/operators'; +import { Structure } from '../models/structure.model'; +import { StructureService } from '../services/structure-list.service'; +const { DateTime } = require('luxon'); @Component({ selector: 'app-home', @@ -6,7 +10,14 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./home.component.scss'], }) export class HomeComponent implements OnInit { - constructor() {} + public structures: Structure[] = []; + constructor(private structureService: StructureService) {} - ngOnInit(): void {} + ngOnInit(): void { + this.structureService.getStructures().subscribe((structures) => { + this.structures = structures.map((structure) => + this.structureService.updateOpeningStructure(structure, DateTime.local()) + ); + }); + } } diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss index e40578ea2..7c09074d9 100644 --- a/src/app/map/components/map.component.scss +++ b/src/app/map/components/map.component.scss @@ -1,5 +1,7 @@ @import '../../../assets/scss/color'; @import '../../../assets/scss/layout'; +@import '../../../assets/scss/icons'; +@import '../../../assets/scss/typography'; #map { height: calc(100vh - #{$header-height} - #{$footer-height}); @@ -48,3 +50,36 @@ } } } + +::ng-deep .leaflet-tooltip { + padding: 8px 10px 8px 10px; + h1 { + color: $purple; + @include cn-bold-20; + margin: 0; + } + p { + color: $grey-3; + @include cn-regular-16; + margin: 0 0 13px 0; + } + div { + align-items: center; + display: flex; + } + // Find somthing better than redeclare class. Mixins ? + .ico-dot-available { + height: 12px; + width: 12px; + background-color: $green; + border-radius: 50%; + margin-right: 8px; + } + .ico-dot-unavailable { + height: 12px; + width: 12px; + background-color: $grey; + border-radius: 50%; + margin-right: 8px; + } +} diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts index f3e84b556..e30ec0504 100644 --- a/src/app/map/components/map.component.ts +++ b/src/app/map/components/map.component.ts @@ -1,5 +1,10 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { latLng, MapOptions, tileLayer, Map, CRS, TileLayer, LatLngBounds } from 'leaflet'; +import { Observable } from 'rxjs'; +import { mergeMap } from 'rxjs/operators'; +import { Structure } from '../../models/structure.model'; +import { GeoJson } from '../models/geojson.model'; +import { GeojsonService } from '../services/geojson.service'; import { MapService } from '../services/map.service'; @Component({ @@ -7,7 +12,8 @@ import { MapService } from '../services/map.service'; templateUrl: './map.component.html', styleUrls: ['./map.component.scss'], }) -export class MapComponent implements OnInit { +export class MapComponent implements OnChanges { + @Input() public structures: Structure[] = []; @Input() public toogleToolTipIds: Array<number> = []; public map: Map; public mapOptions: MapOptions; @@ -22,19 +28,64 @@ export class MapComponent implements OnInit { clickBehavior: { inView: 'stop', outOfView: 'setView', inViewNotFollowing: 'setView' }, }; - constructor(private mapService: MapService) {} - - ngOnInit(): void { + constructor(private mapService: MapService, private geoJsonService: GeojsonService) { this.initializeMapOptions(); } + ngOnChanges(changes: SimpleChanges): void { + if (changes.structures) { + this.getStructurePosition(); + } + } + + /** + * Get structures positions and add marker corresponding to those positons on the map + */ + private getStructurePosition(): void { + this.structures.forEach((element: Structure) => { + this.getCoord(element.voie).subscribe((coord: GeoJson) => { + this.mapService + .createMarker(coord.geometry.getLon(), coord.geometry.getLat(), 1, this.buildToolTip(element)) + .addTo(this.map); + }); + }); + } + + /** + * Create tooltip for display + * @param structure Structure + */ + private buildToolTip(structure: Structure): string { + const cssAvailabilityClass = structure.isOpen ? 'available' : 'unavailable'; + return ( + '<h1>' + + structure.nomDeVotreStructure + + '</h1>' + + '<p>' + + structure.typeDeStructure + + '</p><div>' + + '<span class="ico-dot-' + + cssAvailabilityClass + + '"></span><span>' + + structure.openDisplay() + + '</span></div>' + ); + } + + /** + * Get coord with a street reference + * @param idVoie Street reference + */ + public getCoord(idVoie: number): Observable<GeoJson> { + return this.geoJsonService.getAddress(idVoie).pipe(mergeMap((res) => this.geoJsonService.getCoord(res))); + } + /** * Add marker when map is ready to be showned * @param map map */ public onMapReady(map: Map): void { this.map = map; - this.addMarker(); } /** @@ -84,11 +135,4 @@ export class MapComponent implements OnInit { this.mapService.toogleToolTip(id); }); } - - private addMarker(): void { - //TODO: Replace with real data - this.mapService.createMarker(45.764043, 4.835659, 1, '<p>Hello <br/>World !</p>').addTo(this.map); - this.mapService.createMarker(45.764043, 4.935659, 2, '<p>Hello <br/>World 2!</p>').addTo(this.map); - this.mapService.createMarker(45.664043, 4.835659, 3).addTo(this.map); - } } diff --git a/src/app/map/models/address.model.ts b/src/app/map/models/address.model.ts new file mode 100644 index 000000000..b91f488bb --- /dev/null +++ b/src/app/map/models/address.model.ts @@ -0,0 +1,16 @@ +export class Address { + public id: number; + public text: string; + public type: string; + public city: string; + public citycode: string; + public zipcode: string; + + constructor(obj?: any) { + Object.assign(this, obj); + } + + public queryString(): string { + return this.text + ' ' + this.citycode; + } +} diff --git a/src/app/map/models/addressGeometry.model.ts b/src/app/map/models/addressGeometry.model.ts new file mode 100644 index 000000000..71e1ce346 --- /dev/null +++ b/src/app/map/models/addressGeometry.model.ts @@ -0,0 +1,16 @@ +export class AddressGeometry { + public coordinates: Array<number>; + public type: string; + + constructor(obj?: any) { + Object.assign(this, obj); + } + + public getLat(): number { + return this.coordinates[0]; + } + + public getLon(): number { + return this.coordinates[1]; + } +} diff --git a/src/app/map/models/geojson.model.ts b/src/app/map/models/geojson.model.ts new file mode 100644 index 000000000..3407c70da --- /dev/null +++ b/src/app/map/models/geojson.model.ts @@ -0,0 +1,13 @@ +import { AddressGeometry } from './addressGeometry.model'; + +export class GeoJson { + public geometry: AddressGeometry; + public type: string; + public properties: object; + + constructor(obj?: any) { + Object.assign(this, obj, { + geometry: obj && obj.geometry ? new AddressGeometry(obj.geometry) : null, + }); + } +} diff --git a/src/app/map/models/map-options.ts b/src/app/map/models/map-options.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/app/map/services/geojson.service.spec.ts b/src/app/map/services/geojson.service.spec.ts new file mode 100644 index 000000000..0d9d5d0c6 --- /dev/null +++ b/src/app/map/services/geojson.service.spec.ts @@ -0,0 +1,31 @@ +import { TestBed } from '@angular/core/testing'; +import { Address } from '../models/address.model'; + +import { GeojsonService } from './geojson.service'; + +describe('GeojsonService', () => { + let service: GeojsonService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(GeojsonService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should get address for id 26061 ', () => { + service.getAddress(26061).subscribe((val) => { + expect(val.zipcode).toEqual('69800'); + expect(val.text).toEqual('13ème Rue Cité Berliet'); + }); + }); + + it('should get coord with query string avenue foch 69006 ', () => { + service.getCoord(new Address({ text: 'avenue foch', citycode: '69006' })).subscribe((val) => { + expect(val.geometry.getLat()).toEqual(4.8429024); + expect(val.geometry.getLon()).toEqual(45.7733884); + }); + }); +}); diff --git a/src/app/map/services/geojson.service.ts b/src/app/map/services/geojson.service.ts new file mode 100644 index 000000000..7af9e3481 --- /dev/null +++ b/src/app/map/services/geojson.service.ts @@ -0,0 +1,33 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { Address } from '../models/address.model'; +import { GeoJson } from '../models/geojson.model'; + +@Injectable({ + providedIn: 'root', +}) +export class GeojsonService { + constructor(private http: HttpClient) {} + + /** + * Retrive an address with a street national reference + * @param idVoie Number + */ + public getAddress(idVoie: number): Observable<Address> { + return this.http + .get('/base-adresse/base-adresse-nationale/streets' + '?id=' + idVoie) + .pipe(map((data: { data: any[]; err: number }) => new Address(data.data[0]))); + } + + /** + * Get GeoLocation with an address + * @param address Address + */ + public getCoord(address: Address): Observable<GeoJson> { + return this.http + .get('/geocoding/photon/api' + '?q=' + address.queryString()) + .pipe(map((data: { features: any[]; type: string }) => new GeoJson(data.features[0]))); + } +} diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts index eb5eb8d4f..77296375a 100644 --- a/src/app/map/services/map.service.ts +++ b/src/app/map/services/map.service.ts @@ -21,6 +21,9 @@ export class MapService { marker.bindTooltip(tooltip); } this.markersList[id] = marker; + console.log('marker lat', lat); + console.log('marker lon', lon); + console.log('marker', marker); return marker; } diff --git a/src/app/structure-list/models/day.model.ts b/src/app/models/day.model.ts similarity index 100% rename from src/app/structure-list/models/day.model.ts rename to src/app/models/day.model.ts diff --git a/src/app/structure-list/models/openingDay.model.ts b/src/app/models/openingDay.model.ts similarity index 100% rename from src/app/structure-list/models/openingDay.model.ts rename to src/app/models/openingDay.model.ts diff --git a/src/app/structure-list/models/structure.model.ts b/src/app/models/structure.model.ts similarity index 76% rename from src/app/structure-list/models/structure.model.ts rename to src/app/models/structure.model.ts index 92ceb326d..cd65a8ead 100644 --- a/src/app/structure-list/models/structure.model.ts +++ b/src/app/models/structure.model.ts @@ -1,6 +1,7 @@ +import { TranslateService } from '@ngx-translate/core'; +import { Weekday } from '../structure-list/enum/weekday.enum'; import { Day } from './day.model'; import { OpeningDay } from './openingDay.model'; -import { Weekday } from '../enum/weekday.enum'; import { Week } from './week.model'; export class Structure { @@ -13,7 +14,7 @@ export class Structure { public typeDeStructure: string; public description: string; public n: string; - public voie: string; + public voie: number; public telephone: string; public courriel: string; public siteWeb: string; @@ -32,7 +33,7 @@ export class Structure { public isOpen: boolean; public openedOn: OpeningDay; - constructor(obj?: any) { + constructor(obj?: any, private translateService: TranslateService) { Object.assign(this, obj, { hours: obj && obj.hours ? new Week(obj.hours) : null, }); @@ -58,4 +59,14 @@ export class Structure { return null; } } + + public openDisplay(): string { + if (this.isOpen) { + return 'Ouvert actuellement '; + } else if (this.openedOn.day) { + return 'Fermé - Ouvre ' + this.openedOn.day + ' à ' + this.openedOn.schedule; + } else { + return 'Fermé - Aucun horaire disponible '; + } + } } diff --git a/src/app/structure-list/models/time.model.ts b/src/app/models/time.model.ts similarity index 100% rename from src/app/structure-list/models/time.model.ts rename to src/app/models/time.model.ts diff --git a/src/app/structure-list/models/week.model.ts b/src/app/models/week.model.ts similarity index 100% rename from src/app/structure-list/models/week.model.ts rename to src/app/models/week.model.ts diff --git a/src/app/structure-list/services/structure-list.service.spec.ts b/src/app/services/structure-list.service.spec.ts similarity index 100% rename from src/app/structure-list/services/structure-list.service.spec.ts rename to src/app/services/structure-list.service.spec.ts diff --git a/src/app/structure-list/services/structure-list.service.ts b/src/app/services/structure-list.service.ts similarity index 97% rename from src/app/structure-list/services/structure-list.service.ts rename to src/app/services/structure-list.service.ts index 9394b38c1..82d06039c 100644 --- a/src/app/structure-list/services/structure-list.service.ts +++ b/src/app/services/structure-list.service.ts @@ -1,16 +1,14 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { WeekDay } from '@angular/common'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; -const { DateTime } = require('luxon'); +import { Structure } from '../models/structure.model'; import { Day } from '../models/day.model'; import { OpeningDay } from '../models/openingDay.model'; -import { Structure } from '../models/structure.model'; +import { Weekday } from '../structure-list/enum/weekday.enum'; import { Time } from '../models/time.model'; -import { Weekday } from '../enum/weekday.enum'; -import { Week } from '../models/week.model'; -import { WeekDay } from '@angular/common'; @Injectable({ providedIn: 'root', diff --git a/src/app/shared/components/card/card.component.html b/src/app/shared/components/card/card.component.html deleted file mode 100644 index f2fda252a..000000000 --- a/src/app/shared/components/card/card.component.html +++ /dev/null @@ -1 +0,0 @@ -<p>card works!</p> diff --git a/src/app/shared/components/card/card.component.scss b/src/app/shared/components/card/card.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/app/shared/components/card/card.component.spec.ts b/src/app/shared/components/card/card.component.spec.ts deleted file mode 100644 index 3093fd5a3..000000000 --- a/src/app/shared/components/card/card.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { CardComponent } from './card.component'; - -describe('CardComponent', () => { - let component: CardComponent; - let fixture: ComponentFixture<CardComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ CardComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(CardComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/shared/components/card/card.component.ts b/src/app/shared/components/card/card.component.ts deleted file mode 100644 index 07a9ab07e..000000000 --- a/src/app/shared/components/card/card.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-card', - templateUrl: './card.component.html', - styleUrls: ['./card.component.scss'] -}) -export class CardComponent implements OnInit { - - constructor() { } - - ngOnInit(): void { - } - -} diff --git a/src/app/shared/components/index.ts b/src/app/shared/components/index.ts index d8ec6de94..b86c35354 100644 --- a/src/app/shared/components/index.ts +++ b/src/app/shared/components/index.ts @@ -1,7 +1,7 @@ -import { CardComponent } from './card/card.component'; +// import { CardComponent } from './card/card.component'; // tslint:disable-next-line: max-line-length -export { CardComponent }; +// export { CardComponent }; // tslint:disable-next-line:variable-name -export const SharedComponents = [CardComponent]; +export const SharedComponents = []; diff --git a/src/app/structure-list/components/card/card.component.html b/src/app/structure-list/components/card/card.component.html index 490d59af8..b8d0c1dc5 100644 --- a/src/app/structure-list/components/card/card.component.html +++ b/src/app/structure-list/components/card/card.component.html @@ -1,6 +1,5 @@ -<span class="nbStructuresLabel">{{ structures.length }} structures</span> -<div class="structure" fxLayout="column" *ngFor="let structure of structures"> - <span class="nomStructure">{{ structure.nom }}</span> +<div class="structure" fxLayout="column"> + <span class="nomStructure">{{ structure.nomDeVotreStructure }}</span> <div class="headerStructure" fxLayout="row" fxLayoutAlign="space-between center"> <span class="typeStructure">{{ structure.typeDeStructure }}</span> @@ -8,18 +7,12 @@ </div> <br /> <div class="statusStructure" fxLayout="row" fxLayoutAlign="start center"> - <div *ngIf="structure.isOpen; else closed"> - <span class="ico-dot-available"></span> - <span>Ouvert actuellement</span> + <div> + <span *ngIf="structure.isOpen; else closed" class="ico-dot-available"></span> + <span>{{ structure.openDisplay() }}</span> </div> <ng-template #closed> <span class="ico-dot-unavailable"></span> - <span *ngIf="structure.openedOn.day; else noTime"> - Fermé - Ouvre {{ structure.openedOn.day }} à {{ structure.openedOn.schedule }}</span - > - </ng-template> - <ng-template #noTime> - <span> Fermé - Aucun horaire disponible</span> </ng-template> </div> </div> diff --git a/src/app/structure-list/components/card/card.component.scss b/src/app/structure-list/components/card/card.component.scss index 732c84c03..3fe9e2edd 100644 --- a/src/app/structure-list/components/card/card.component.scss +++ b/src/app/structure-list/components/card/card.component.scss @@ -2,15 +2,9 @@ @import '../../../../assets/scss/color'; @import '../../../../assets/scss/typography'; -.nbStructuresLabel { - color: $grey; - @include cn-regular-16; - display: flex; - align-items: center; -} .structure { padding: 12px 0 12px 0; - border-bottom: 1px dashed $grey; + border-bottom: 1px dashed $grey !important; .typeStructure { color: $grey; @include cn-regular-16; diff --git a/src/app/structure-list/components/card/card.component.ts b/src/app/structure-list/components/card/card.component.ts index 5594b507f..9049bcfa7 100644 --- a/src/app/structure-list/components/card/card.component.ts +++ b/src/app/structure-list/components/card/card.component.ts @@ -1,7 +1,5 @@ -import { Component, OnInit } from '@angular/core'; -import { Structure } from '../../models/structure.model'; -import { StructureService } from '../../services/structure-list.service'; -const { DateTime } = require('luxon'); +import { Component, Input, OnInit } from '@angular/core'; +import { Structure } from '../../../models/structure.model'; @Component({ selector: 'app-card', @@ -9,14 +7,8 @@ const { DateTime } = require('luxon'); styleUrls: ['./card.component.scss'], }) export class CardComponent implements OnInit { - structures: Structure[] = []; - constructor(private structureService: StructureService) {} + @Input() public structure: Structure; + constructor() {} - ngOnInit(): void { - this.structureService.getStructures().subscribe((structures) => { - structures.forEach((s: Structure) => { - this.structures.push(this.structureService.updateOpeningStructure(s, DateTime.local())); - }); - }); - } + ngOnInit(): void {} } diff --git a/src/app/structure-list/structure-list.component.html b/src/app/structure-list/structure-list.component.html index a6dbe19b7..017b98518 100644 --- a/src/app/structure-list/structure-list.component.html +++ b/src/app/structure-list/structure-list.component.html @@ -1,2 +1,3 @@ <app-recherche></app-recherche> -<app-card></app-card> +<span class="nbStructuresLabel">{{ structureList.length }} structures</span> +<app-card *ngFor="let structure of structureList" [structure]="structure"></app-card> diff --git a/src/app/structure-list/structure-list.component.ts b/src/app/structure-list/structure-list.component.ts index 276b325e4..37296692d 100644 --- a/src/app/structure-list/structure-list.component.ts +++ b/src/app/structure-list/structure-list.component.ts @@ -1,10 +1,13 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; +import { Structure } from '../models/structure.model'; @Component({ selector: 'app-structure-list', templateUrl: './structure-list.component.html', + styleUrls: ['./structure-list.scss'], }) export class StructureListComponent implements OnInit { + @Input() public structureList: Structure[]; constructor() {} ngOnInit(): void {} diff --git a/src/app/structure-list/structure-list.module.ts b/src/app/structure-list/structure-list.module.ts deleted file mode 100644 index 7067e0fef..000000000 --- a/src/app/structure-list/structure-list.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { StructureListComponent } from './structure-list.component'; -import { CardComponent } from './components/card/card.component'; -import { RechercheComponent } from './components/recherche/recherche.component'; -import { HttpClientModule } from '@angular/common/http'; -import { FlexLayoutModule } from '@angular/flex-layout'; - -@NgModule({ - declarations: [StructureListComponent, CardComponent, RechercheComponent], - imports: [CommonModule, HttpClientModule, FlexLayoutModule], - exports: [StructureListComponent], -}) -export class StructureListModule {} diff --git a/src/app/structure-list/structure-list.scss b/src/app/structure-list/structure-list.scss new file mode 100644 index 000000000..68c10dffe --- /dev/null +++ b/src/app/structure-list/structure-list.scss @@ -0,0 +1,10 @@ +@import '../../assets/scss/icons'; +@import '../../assets/scss/color'; +@import '../../assets/scss/typography'; + +.nbStructuresLabel { + color: $grey; + @include cn-regular-16; + display: flex; + align-items: center; +} diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 79b25c900..9ad8ed69b 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -5,6 +5,8 @@ export const environment = { production: false, registrationForm: 'https://services.formulaireextranet.grandlyon.com/saisie-fiche-structure', + addressApi: 'https://passerelle.formulaireextranet.grandlyon.com/base-adresse/base-adresse-nationale/streets', + geojsonApi: 'https://download.data.grandlyon.com/geocoding/photon/api', VERSION: require('../../package.json').version, }; -- GitLab From 7e53d3b9cc375036f47a0f3d7de137947fcaa65d Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Wed, 21 Oct 2020 10:10:54 +0200 Subject: [PATCH 06/10] fix: unit testing and remove console.log --- src/app/home/home.component.spec.ts | 8 +- src/app/map/services/geojson.service.spec.ts | 43 ++++- src/app/map/services/map.service.ts | 3 - src/app/models/structure.model.ts | 3 +- .../components/card/card.component.spec.ts | 151 ++++++++++++++++- .../structure-list.component.spec.ts | 156 +++++++++++++++++- src/locale/messages.en.xlf | 4 + 7 files changed, 347 insertions(+), 21 deletions(-) diff --git a/src/app/home/home.component.spec.ts b/src/app/home/home.component.spec.ts index 2c5a17268..8c0ce9e12 100644 --- a/src/app/home/home.component.spec.ts +++ b/src/app/home/home.component.spec.ts @@ -1,3 +1,5 @@ +import { HttpClientModule } from '@angular/common/http'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { HomeComponent } from './home.component'; @@ -8,9 +10,9 @@ describe('HomeComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ HomeComponent ] - }) - .compileComponents(); + declarations: [HomeComponent], + imports: [HttpClientTestingModule], + }).compileComponents(); }); beforeEach(() => { diff --git a/src/app/map/services/geojson.service.spec.ts b/src/app/map/services/geojson.service.spec.ts index 0d9d5d0c6..f25dadf4e 100644 --- a/src/app/map/services/geojson.service.spec.ts +++ b/src/app/map/services/geojson.service.spec.ts @@ -1,11 +1,19 @@ import { TestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { Address } from '../models/address.model'; import { GeojsonService } from './geojson.service'; +import { HttpClientModule } from '@angular/common/http'; describe('GeojsonService', () => { let service: GeojsonService; + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HttpClientModule], + }).compileComponents(); + }); + beforeEach(() => { TestBed.configureTestingModule({}); service = TestBed.inject(GeojsonService); @@ -15,17 +23,36 @@ describe('GeojsonService', () => { expect(service).toBeTruthy(); }); - it('should get address for id 26061 ', () => { - service.getAddress(26061).subscribe((val) => { - expect(val.zipcode).toEqual('69800'); - expect(val.text).toEqual('13ème Rue Cité Berliet'); + it('should get address for id 26061 ', async () => { + await new Promise((resolve) => { + service.getAddress(26061).subscribe( + (val) => { + console.log(val); + expect(val.zipcode).toEqual('69800'); + expect(val.text).toEqual('13ème Rue Cité Berliet'); + resolve(); + }, + (err) => { + console.log(err); + resolve(); + } + ); }); }); - it('should get coord with query string avenue foch 69006 ', () => { - service.getCoord(new Address({ text: 'avenue foch', citycode: '69006' })).subscribe((val) => { - expect(val.geometry.getLat()).toEqual(4.8429024); - expect(val.geometry.getLon()).toEqual(45.7733884); + it('should get coord with query string avenue foch 69006 ', async () => { + await new Promise((resolve) => { + service.getCoord(new Address({ text: 'avenue foch', citycode: '69006' })).subscribe( + (val) => { + expect(val.geometry.getLat()).toEqual(4.8429024); + expect(val.geometry.getLon()).toEqual(45.7733884); + resolve(); + }, + (err) => { + console.log(err); + resolve(); + } + ); }); }); }); diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts index 77296375a..eb5eb8d4f 100644 --- a/src/app/map/services/map.service.ts +++ b/src/app/map/services/map.service.ts @@ -21,9 +21,6 @@ export class MapService { marker.bindTooltip(tooltip); } this.markersList[id] = marker; - console.log('marker lat', lat); - console.log('marker lon', lon); - console.log('marker', marker); return marker; } diff --git a/src/app/models/structure.model.ts b/src/app/models/structure.model.ts index cd65a8ead..191917321 100644 --- a/src/app/models/structure.model.ts +++ b/src/app/models/structure.model.ts @@ -1,4 +1,3 @@ -import { TranslateService } from '@ngx-translate/core'; import { Weekday } from '../structure-list/enum/weekday.enum'; import { Day } from './day.model'; import { OpeningDay } from './openingDay.model'; @@ -33,7 +32,7 @@ export class Structure { public isOpen: boolean; public openedOn: OpeningDay; - constructor(obj?: any, private translateService: TranslateService) { + constructor(obj?: any) { Object.assign(this, obj, { hours: obj && obj.hours ? new Week(obj.hours) : null, }); diff --git a/src/app/structure-list/components/card/card.component.spec.ts b/src/app/structure-list/components/card/card.component.spec.ts index c0787da7b..cf8f87ef3 100644 --- a/src/app/structure-list/components/card/card.component.spec.ts +++ b/src/app/structure-list/components/card/card.component.spec.ts @@ -2,6 +2,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { CardComponent } from './card.component'; import { HttpClientModule } from '@angular/common/http'; +import { Structure } from '../../../models/structure.model'; +import { OpeningDay } from '../../../models/openingDay.model'; + describe('CardComponent', () => { let component: CardComponent; let fixture: ComponentFixture<CardComponent>; @@ -15,8 +18,152 @@ describe('CardComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(CardComponent); - component = fixture.componentInstance; - fixture.detectChanges(); + component = fixture.debugElement.componentInstance; + const structure = new Structure({ + id: 1, + numero: '26-63', + dateDeCreation: '2020-10-08T15:17:00.000Z', + derniereModification: '2020-10-08T15:17:00.000Z', + nomDeLusager: 'Erwan Le luron', + votreStructureEstElle: 'Un établissement principal (siège social)', + nomDeVotreStructure: 'Régie de Quartier Armstrong', + typeDeStructure: 'Tiers-lieu & coworking, FabLab', + description: "Association loi 1901 dont l'objet est l'insertion par l'économie social et solidaire", + n: 2, + voie: 21356, + telephone: '04 72 21 03 07', + courriel: 'sguillet@rqa.fr', + siteWeb: '', + facebook: '', + twitter: '@rqainfo69', + instagram: '', + civilite: 'Madame', + nom: 'GUILLET', + prenom: 'Séverine', + fonction: 'Autres', + accessibilitePersonnesAMobiliteReduitePmr: '', + choixMultiples: 'Tout public', + fermeturesExceptionnelles: '', + jaccompagneLesUsagersDansLeursDemarchesEnLigne: 'True', + accompagnementDesDemarches: 'Accompagnant CAF', + autresAccompagnements: '', + lesCompetencesDeBase: 260, + accesAuxDroits: 176, + insertionSocialeEtProfessionnelle: 254, + aideALaParentalite: '', + cultureEtSecuriteNumerique: 264, + wifiEnAccesLibre: 'True', + ordinateurs: '', + nombre: '', + tablettes: '', + bornesNumeriques: '', + imprimantes: '', + autresEspacesProposesParLaStructure: 'Espace libre service', + statutJuridique: '', + appartenezVousAUnReseauDeMediation: '', + precisezLequel: '', + idDeLitemStructureDansDirectus: 123, + statutDeLitemStructureDansDirectus: '', + idDeLitemOffreDansDirectus: '', + statut: 'Erreur lors du versement des données offre', + hours: { + monday: { + open: true, + time: [ + { + openning: 1330, + closing: 1630, + }, + { + openning: null, + closing: null, + }, + ], + }, + tuesday: { + open: true, + time: [ + { + openning: 830, + closing: 1130, + }, + { + openning: 1330, + closing: 1630, + }, + ], + }, + wednesday: { + open: true, + time: [ + { + openning: 1330, + closing: 1630, + }, + { + openning: null, + closing: null, + }, + ], + }, + thursday: { + open: true, + time: [ + { + openning: 830, + closing: 1130, + }, + { + openning: 1330, + closing: 1630, + }, + ], + }, + friday: { + open: true, + time: [ + { + openning: 830, + closing: 1130, + }, + { + openning: 1330, + closing: 1530, + }, + ], + }, + saturday: { + open: false, + time: [ + { + openning: null, + closing: null, + }, + { + openning: null, + closing: null, + }, + ], + }, + sunday: { + open: false, + time: [ + { + openning: null, + closing: null, + }, + { + openning: null, + closing: null, + }, + ], + }, + openedOn: new OpeningDay('monday', null), + }, + openedOn: new OpeningDay('monday', null), + }); + component.structure = structure; + fixture.detectChanges(); // calls NgOnit }); it('should create', () => { diff --git a/src/app/structure-list/structure-list.component.spec.ts b/src/app/structure-list/structure-list.component.spec.ts index bbd876b55..b00f05ee5 100644 --- a/src/app/structure-list/structure-list.component.spec.ts +++ b/src/app/structure-list/structure-list.component.spec.ts @@ -1,8 +1,11 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { StyleUtils } from '@angular/flex-layout'; +import { OpeningDay } from '../models/openingDay.model'; +import { Structure } from '../models/structure.model'; import { StructureListComponent } from './structure-list.component'; -describe('StructureComponent', () => { +describe('StructureListComponent', () => { let component: StructureListComponent; let fixture: ComponentFixture<StructureListComponent>; @@ -14,8 +17,155 @@ describe('StructureComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(StructureListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); + component = fixture.debugElement.componentInstance; + const structureList = new Array<Structure>( + new Structure({ + id: 1, + numero: '26-63', + dateDeCreation: '2020-10-08T15:17:00.000Z', + derniereModification: '2020-10-08T15:17:00.000Z', + nomDeLusager: 'Erwan Le luron', + votreStructureEstElle: 'Un établissement principal (siège social)', + nomDeVotreStructure: 'Régie de Quartier Armstrong', + typeDeStructure: 'Tiers-lieu & coworking, FabLab', + description: "Association loi 1901 dont l'objet est l'insertion par l'économie social et solidaire", + n: 2, + voie: 21356, + telephone: '04 72 21 03 07', + courriel: 'sguillet@rqa.fr', + siteWeb: '', + facebook: '', + twitter: '@rqainfo69', + instagram: '', + civilite: 'Madame', + nom: 'GUILLET', + prenom: 'Séverine', + fonction: 'Autres', + accessibilitePersonnesAMobiliteReduitePmr: '', + choixMultiples: 'Tout public', + fermeturesExceptionnelles: '', + jaccompagneLesUsagersDansLeursDemarchesEnLigne: 'True', + accompagnementDesDemarches: 'Accompagnant CAF', + autresAccompagnements: '', + lesCompetencesDeBase: 260, + accesAuxDroits: 176, + insertionSocialeEtProfessionnelle: 254, + aideALaParentalite: '', + cultureEtSecuriteNumerique: 264, + wifiEnAccesLibre: 'True', + ordinateurs: '', + nombre: '', + tablettes: '', + bornesNumeriques: '', + imprimantes: '', + autresEspacesProposesParLaStructure: 'Espace libre service', + statutJuridique: '', + appartenezVousAUnReseauDeMediation: '', + precisezLequel: '', + idDeLitemStructureDansDirectus: 123, + statutDeLitemStructureDansDirectus: '', + idDeLitemOffreDansDirectus: '', + statut: 'Erreur lors du versement des données offre', + hours: { + monday: { + open: true, + time: [ + { + openning: 1330, + closing: 1630, + }, + { + openning: null, + closing: null, + }, + ], + }, + tuesday: { + open: true, + time: [ + { + openning: 830, + closing: 1130, + }, + { + openning: 1330, + closing: 1630, + }, + ], + }, + wednesday: { + open: true, + time: [ + { + openning: 1330, + closing: 1630, + }, + { + openning: null, + closing: null, + }, + ], + }, + thursday: { + open: true, + time: [ + { + openning: 830, + closing: 1130, + }, + { + openning: 1330, + closing: 1630, + }, + ], + }, + friday: { + open: true, + time: [ + { + openning: 830, + closing: 1130, + }, + { + openning: 1330, + closing: 1530, + }, + ], + }, + saturday: { + open: false, + time: [ + { + openning: null, + closing: null, + }, + { + openning: null, + closing: null, + }, + ], + }, + sunday: { + open: false, + time: [ + { + openning: null, + closing: null, + }, + { + openning: null, + closing: null, + }, + ], + }, + }, + openedOn: new OpeningDay('monday', null), + }) + ); + structureList.length = 4; + console.log(structureList.length); + component.structureList = structureList; + fixture.detectChanges(); // calls NgOnit }); it('should create', () => { diff --git a/src/locale/messages.en.xlf b/src/locale/messages.en.xlf index 0a4b401a0..c5c8d8d50 100644 --- a/src/locale/messages.en.xlf +++ b/src/locale/messages.en.xlf @@ -58,6 +58,10 @@ <context context-type="linenumber">18</context> </context-group> </trans-unit> + <trans-unit id="monday" datatype="html"> + <source>monday</source> + <target>lundi</target> + </trans-unit> </body> </file> </xliff> -- GitLab From 47665178a6dc089131c593d5fbd25e4b7bdd9d91 Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Wed, 21 Oct 2020 12:42:29 +0200 Subject: [PATCH 07/10] fix: remove console log, better home css display --- src/app/home/home.component.html | 4 ++-- src/app/home/home.component.scss | 2 ++ src/app/map/services/geojson.service.spec.ts | 2 -- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html index 68c653d8b..6016ec21f 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -1,4 +1,4 @@ <div fxLayout="row"> - <app-structure-list [structureList]="structures" class="left-pane" fxFlex="30%"></app-structure-list> - <app-map fxFlex="70%" [structures]="structures"></app-map> + <app-structure-list [structureList]="structures" class="left-pane"></app-structure-list> + <app-map [structures]="structures" fxFlex="100"></app-map> </div> diff --git a/src/app/home/home.component.scss b/src/app/home/home.component.scss index 7d2eb86af..1a2d33f8e 100644 --- a/src/app/home/home.component.scss +++ b/src/app/home/home.component.scss @@ -1,3 +1,5 @@ .left-pane { padding: 0 25px; + width: 590px; + min-width: 590px; } diff --git a/src/app/map/services/geojson.service.spec.ts b/src/app/map/services/geojson.service.spec.ts index f25dadf4e..359674551 100644 --- a/src/app/map/services/geojson.service.spec.ts +++ b/src/app/map/services/geojson.service.spec.ts @@ -1,5 +1,4 @@ import { TestBed } from '@angular/core/testing'; -import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { Address } from '../models/address.model'; import { GeojsonService } from './geojson.service'; @@ -27,7 +26,6 @@ describe('GeojsonService', () => { await new Promise((resolve) => { service.getAddress(26061).subscribe( (val) => { - console.log(val); expect(val.zipcode).toEqual('69800'); expect(val.text).toEqual('13ème Rue Cité Berliet'); resolve(); -- GitLab From a457cbbaa2745a9de3b5ac32d9822eee7482ce77 Mon Sep 17 00:00:00 2001 From: Jeremie BRISON <ext.sopra.jbrison@grandlyon.com> Date: Wed, 21 Oct 2020 14:30:24 +0200 Subject: [PATCH 08/10] fix(map) : replace img with pure css --- src/app/map/services/map.service.ts | 15 ++++++++------- src/assets/scss/_icons.scss | 22 ++++++++++++++++++++++ src/styles.scss | 1 + 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts index eb5eb8d4f..f13895072 100644 --- a/src/app/map/services/map.service.ts +++ b/src/app/map/services/map.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { divIcon } from 'leaflet'; import { icon, Marker, Map } from 'leaflet'; @Injectable({ @@ -9,13 +10,13 @@ export class MapService { constructor() {} public createMarker(lat: number, lon: number, id: number, tooltip?: string): Marker { - const marker = new Marker([lat, lon]).setIcon( - icon({ - iconSize: [35, 41], - iconAnchor: [13, 41], - iconUrl: '../../../assets/img/ic_marker.png', - }) - ); + const icone = divIcon({ + className: null, + html: "<div class='ico-marker-pin'></div>", + iconSize: [35, 41], + iconAnchor: [13, 41], + }); + const marker = new Marker([lat, lon], { icon: icone }); if (tooltip) { marker.bindTooltip(tooltip); diff --git a/src/assets/scss/_icons.scss b/src/assets/scss/_icons.scss index de969d5b3..f907cb4d0 100644 --- a/src/assets/scss/_icons.scss +++ b/src/assets/scss/_icons.scss @@ -78,3 +78,25 @@ border-radius: 50%; display: inline-block; } + +.ico-marker-pin { + width: 30px; + height: 30px; + border-radius: 50% 50% 50% 0; + background: $purple; + position: absolute; + transform: rotate(-45deg); + left: 50%; + top: 50%; + margin: -15px 0 0 -15px; +} + +.ico-marker-pin::after { + content: ''; + width: 10px; + height: 10px; + margin: 10px 0 0 10px; + background: #fff; + position: absolute; + border-radius: 50%; +} diff --git a/src/styles.scss b/src/styles.scss index d62180f39..0a1dafb13 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -3,6 +3,7 @@ @import 'assets/scss/typography'; @import 'assets/scss/color'; @import 'assets/scss/breakpoint'; +@import 'assets/scss/icons'; @import '../node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css'; html, -- GitLab From d90c9ce885b97e31dc3d59dc95322639541385f6 Mon Sep 17 00:00:00 2001 From: Jeremie BRISON <ext.sopra.jbrison@grandlyon.com> Date: Wed, 21 Oct 2020 14:37:00 +0200 Subject: [PATCH 09/10] fix(map) : set maxZoom to prevent bug --- src/app/map/components/map.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts index e30ec0504..f63314cb9 100644 --- a/src/app/map/components/map.component.ts +++ b/src/app/map/components/map.component.ts @@ -121,6 +121,7 @@ export class MapComponent implements OnChanges { // Zoom is blocked on 11 to prevent people to zoom out from metropole this.mapOptions = { center: latLng(45.764043, 4.835659), + maxZoom: 19, zoom: 10, minZoom: 10, layers: [carteLayer, metroMaps], -- GitLab From 2f63c2c30ddfa02475bd9d5369f2aa4db4f260bf Mon Sep 17 00:00:00 2001 From: Jeremie BRISON <ext.sopra.jbrison@grandlyon.com> Date: Wed, 21 Oct 2020 14:41:46 +0200 Subject: [PATCH 10/10] fix(map) : Delete png icon --- src/app/map/services/map.service.spec.ts | 2 -- src/assets/img/ic_marker.png | Bin 1274 -> 0 bytes 2 files changed, 2 deletions(-) delete mode 100644 src/assets/img/ic_marker.png diff --git a/src/app/map/services/map.service.spec.ts b/src/app/map/services/map.service.spec.ts index 3470f88c5..de3b0e0fa 100644 --- a/src/app/map/services/map.service.spec.ts +++ b/src/app/map/services/map.service.spec.ts @@ -23,8 +23,6 @@ describe('MapService', () => { }); it('should add marker to map with icon ic_marker.png', () => { const marker = service.createMarker(45.764043, 4.835659, 1); - - expect(marker.getIcon().options.iconUrl).toEqual('../../../assets/img/ic_marker.png'); expect(marker.getIcon().options.iconSize).toEqual([35, 41]); expect(marker.getIcon().options.iconAnchor).toEqual([13, 41]); }); diff --git a/src/assets/img/ic_marker.png b/src/assets/img/ic_marker.png deleted file mode 100644 index f378d60ad21bd0bae4e7570e9b6cb9800fc8f0e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1274 zcmV<W1O@wvP)<h;3K|Lk000e1NJLTq001Wd001rs1^@s6tE>S100009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP<VFdsH1dmBXK~#7F&6z(; z6hRcm-x4dZxPsG?#SWtJj2f-vjExo=2sT)#L=vnxr9_Aj1uGFc3lq`C%1CUqF&tJJ zNq}IWk{e3?B+@{8zHfN58J0VCcDVz;<lW5P&h7qqGxO%n;86k<i^UWdt!!u6vTV5a zttLurj%^yH=Xr{%DTd0jO%;>r6I*MX_jxXj0L8^q+VPUs((fhu_2U<<6jo?`b)7cW zHiGu`C+aDEGEEJQ4RrDHMQS?TWIs-^wXrAXqTcI8K&1rg5w5qlw&}~~FWOLdRr*9) z1Ge93*LBet+Ym!;Qd~F&^SPK}^OHiAQhP_cHj!exT5ddgQDEz9>-4<uIiakS;JyBl ze&a<|4$#{V4CCtM@XG^xtCVW%YN@xcmzvKsmj(1fU>IYw2JBhiGpe@whx={7bM_dl z3AM%G*IfyZ9fn3nM$M4%<^6#I&q)mWgnF(kSJ5#RC5*in<1chq(@yv1QL#Pu3LhUo zd^}Vz2=7BA5Cz`TaN;%Hoq#(ESz#(GK|k<Z4j)Ou&>a^pU!az2EqZWUf!0|jmWs6Z zj!Edq;$mrGiQ)(l-H*Dd`E>K1d*8o(k3B>HcjML#{IT#}swM#A&=KcBST`|<1q{<a z&o&_?UAcBe-$y%F!Fy_1naftdWl)>>G2{FYcx+%~z|5{mwnm;|m}Q+Pan1G)_t7p+ zH_!YGI5L1kPDZMrTz{|EMgf~(n6~iZjY!XSAK+-$o$GdeG_5SJm}(2)eAG5pH=KTq zm!Zo<LlMn8@qtMqe@vvT)GHOhxsEsgly9o}sO(len%96OCQT_>9DWVORDHVMRF&gT zbU)P|ck`UB*l=6hTc(<E{E42fNmd=eDO6l%6k?%7@{GjDva(~SHPH7}!>J(jD8T8N z<~m>jW`&)%5zX~_jezW$6V}z$?Sh*}O>!zHS&`rD#(eueuJJurTjQ?R=P#W%)p@|> zLtjP;FB}~X@~|vhfnjC^6v=7<--p^c32U@y(v$4>FWlbK)f0PHg@A0uJuN(A`rEYj zSe)mf_mCO05X2jGvMF7V#lw<jCQWCW0x;}jlk7XN>5+K&nBm3@T$YQeB;Ko(;QfcW zho~x&&5n+9k{0JNV{dodro)yQ9-<+$^4LKb>)__~Ti5rDp=t|YW)I6?6XyE>PH6Q) zez)sxtUT<XVB!qLcGbSOYx%+;<YHWJc%SqpO1I+(y<~Og<8UIeXKm#MIJC)!jtnX; zcnduw!Z@1@w<)*qx3SGt3(%UG25hiYyZug?5S$VJGL<~cL05)6HdwB$%lVuJMC`-a z2@VUBDs=p{FIXg;1v$aRJ=9;1zt&kswZWX>1aOdKvm1Ar!}zjdXQv&@Dgu`T5FrU* zl4&4sY%_;66^9c*gc_Yhe*OHF-oJTI<-i7p2TW$G$nlW+KyU(>rJdul)Z)UTK4Y_! z1=nNMs!6h4B$-9^M-_V>^b|X8cIa|#b<O<mp%AstI21qtaj3DuW{(W46riP9iIGPy kfC$k41!g3GW0eH^2PkyRk|${KlmGw#07*qoM6N<$f^8vU!~g&Q -- GitLab