From d3233af6f32a5031dd9836ae8b2cf499a2e372e2 Mon Sep 17 00:00:00 2001
From: ncastejon <castejon.nicolas@gmail.com>
Date: Mon, 4 Jun 2018 15:33:28 +0200
Subject: [PATCH] Add model Data - Add map with disply of markers

---
 package-lock.json                             | 23 +++++++-
 webapp/.angular-cli.json                      |  3 +-
 webapp/package-lock.json                      | 18 ++++++
 webapp/package.json                           |  2 +
 .../dataset-map/dataset-map.component.html    |  6 +-
 .../dataset-map/dataset-map.component.scss    |  4 ++
 .../dataset-map/dataset-map.component.ts      | 55 ++++++++++++++++++-
 webapp/src/app/geosource/models/data.model.ts | 33 +++++++++++
 webapp/src/app/geosource/models/index.ts      |  1 +
 .../app/geosource/models/metadata.model.ts    |  2 +
 .../app/geosource/services/dataset.service.ts | 21 +++++--
 .../services/elasticsearch.service.ts         | 14 +++++
 webapp/src/environments/environment.ts        |  2 +-
 webapp/src/tsconfig.app.json                  |  4 +-
 14 files changed, 173 insertions(+), 15 deletions(-)
 create mode 100644 webapp/src/app/geosource/models/data.model.ts

diff --git a/package-lock.json b/package-lock.json
index 48e341a0..6c56f8e8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,3 +1,24 @@
 {
-  "lockfileVersion": 1
+  "requires": true,
+  "lockfileVersion": 1,
+  "dependencies": {
+    "@types/geojson": {
+      "version": "7946.0.3",
+      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.3.tgz",
+      "integrity": "sha512-BYHiG1vQJ7T93uswzuXZ0OBPWqj5tsAPtaMDQADV8sn2InllXarwg9llr6uaW22q1QCwBZ81gVajOpYWzjesug=="
+    },
+    "@types/leaflet": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.2.7.tgz",
+      "integrity": "sha512-y9KEOzVB1uIPVPOc8FBqQjBvFykb/WhNfHDN6eTL8FlUy6F7FaqGMWHj5OhDSBHMWoqc70eR3FGiXdzbg1rqtg==",
+      "requires": {
+        "@types/geojson": "7946.0.3"
+      }
+    },
+    "leaflet": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.3.1.tgz",
+      "integrity": "sha512-adQOIzh+bfdridLM1xIgJ9VnJbAUY3wqs/ueF+ITla+PLQ1z47USdBKUf+iD9FuUA8RtlT6j6hZBfZoA6mW+XQ=="
+    }
+  }
 }
diff --git a/webapp/.angular-cli.json b/webapp/.angular-cli.json
index 862071be..572b319d 100644
--- a/webapp/.angular-cli.json
+++ b/webapp/.angular-cli.json
@@ -19,7 +19,8 @@
       "testTsconfig": "tsconfig.spec.json",
       "prefix": "app",
       "styles": [
-        "styles.scss"
+        "styles.scss",
+        "../node_modules/leaflet/dist/leaflet.css"
       ],
       "scripts": [],
       "environmentSource": "environments/environment.ts",
diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index 676242a6..30c09f31 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -283,6 +283,11 @@
         "semver-intersect": "1.3.1"
       }
     },
+    "@types/geojson": {
+      "version": "7946.0.3",
+      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.3.tgz",
+      "integrity": "sha512-BYHiG1vQJ7T93uswzuXZ0OBPWqj5tsAPtaMDQADV8sn2InllXarwg9llr6uaW22q1QCwBZ81gVajOpYWzjesug=="
+    },
     "@types/jasmine": {
       "version": "2.8.6",
       "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.6.tgz",
@@ -298,6 +303,14 @@
         "@types/jasmine": "2.8.6"
       }
     },
+    "@types/leaflet": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.2.7.tgz",
+      "integrity": "sha512-y9KEOzVB1uIPVPOc8FBqQjBvFykb/WhNfHDN6eTL8FlUy6F7FaqGMWHj5OhDSBHMWoqc70eR3FGiXdzbg1rqtg==",
+      "requires": {
+        "@types/geojson": "7946.0.3"
+      }
+    },
     "@types/node": {
       "version": "6.0.102",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.102.tgz",
@@ -6347,6 +6360,11 @@
         "invert-kv": "1.0.0"
       }
     },
+    "leaflet": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.3.1.tgz",
+      "integrity": "sha512-adQOIzh+bfdridLM1xIgJ9VnJbAUY3wqs/ueF+ITla+PLQ1z47USdBKUf+iD9FuUA8RtlT6j6hZBfZoA6mW+XQ=="
+    },
     "less": {
       "version": "2.7.3",
       "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz",
diff --git a/webapp/package.json b/webapp/package.json
index f0c41685..04895f12 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -30,9 +30,11 @@
     "@angular/platform-browser": "^5.2.0",
     "@angular/platform-browser-dynamic": "^5.2.0",
     "@angular/router": "^5.2.0",
+    "@types/leaflet": "^1.2.7",
     "bulma": "^0.7.1",
     "core-js": "^2.4.1",
     "font-awesome": "^4.7.0",
+    "leaflet": "^1.3.1",
     "rxjs": "^5.5.6",
     "zone.js": "^0.8.19"
   },
diff --git a/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.html b/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.html
index 2db5ee28..c0c8e3ce 100644
--- a/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.html
+++ b/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.html
@@ -1,3 +1,3 @@
-<p>
-  dataset-map works!
-</p>
+<div id="frugalmap">
+ 
+</div>
\ No newline at end of file
diff --git a/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.scss b/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.scss
index e69de29b..64d0b1d7 100644
--- a/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.scss
+++ b/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.scss
@@ -0,0 +1,4 @@
+#frugalmap {
+  height: 600px;
+  width: 80%
+}
diff --git a/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.ts b/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.ts
index d3947c74..e31e8fb6 100644
--- a/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.ts
+++ b/webapp/src/app/geosource/components/dataset-detail/dataset-map/dataset-map.component.ts
@@ -1,4 +1,8 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, Input } from '@angular/core';
+import * as L from 'leaflet';
+import { ActivatedRoute, ParamMap } from '@angular/router';
+import { DatasetService } from '../../../services';
+import { Metadata, Data } from '../../../models';
 
 @Component({
   selector: 'app-dataset-map',
@@ -6,10 +10,57 @@ import { Component, OnInit } from '@angular/core';
   styleUrls: ['./dataset-map.component.scss']
 })
 export class DatasetMapComponent implements OnInit {
+  metadata: Metadata;
 
-  constructor() { }
+  constructor(
+    private _route: ActivatedRoute,
+    private _datasetService: DatasetService,
+  ) { }
 
   ngOnInit() {
+    this._route.parent.paramMap
+      .switchMap((params: ParamMap) => this._datasetService.getMetadataById(params.get('id')))
+      .subscribe((metadata: Metadata) => {
+        this._datasetService.getDataByMetadataById(metadata.dataset_index).subscribe(results => {
+          this.constructMap(results);
+        });
+
+      });
   }
+  constructMap(results: Data[]) {
+    // Déclaration de la carte avec les coordonnées du centre et le niveau de zoom.
+    const dataGrandLyonMap = L.map('frugalmap', { minZoom: 9, maxZoom: 18 }).setView([45.75, 4.85], 12);
+
+    L.tileLayer('https://openstreetmap.data.grandlyon.com/3857/tms/1.0.0/osm_grandlyon@GoogleMapsCompatible/{z}/{x}/{-y}.png', {
+      attribution: 'Data Grand Lyon Map'
+    }).addTo(dataGrandLyonMap);
+
+    // Set icon marker
+    const myIcon = L.icon({
+      iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.2.0/images/marker-icon.png'
+    });
+
 
+    results.forEach(element => {
+      console.log(element);
+      switch (element.geometry.type) {
+        case 'Point':
+          L.marker([element.geometry.coordinates[1], element.geometry.coordinates[0]], { icon: myIcon })
+            .bindPopup(element.properties.nom).addTo(dataGrandLyonMap);
+          break;
+        case 'Polygon':
+          // create a red polygon from an array of LatLng points
+          element.geometry.coordinates.forEach(coordinates => {
+            coordinates.forEach(coord => {
+              coord.reverse();
+            });
+            L.polygon(coordinates, { color: 'red' }).addTo(dataGrandLyonMap);
+          });
+
+          break;
+      }
+    });
+
+    L.control.scale().addTo(dataGrandLyonMap);
+  }
 }
diff --git a/webapp/src/app/geosource/models/data.model.ts b/webapp/src/app/geosource/models/data.model.ts
new file mode 100644
index 00000000..50824a19
--- /dev/null
+++ b/webapp/src/app/geosource/models/data.model.ts
@@ -0,0 +1,33 @@
+export interface IData {
+  geometry: IDataGeometry;
+  href: string;
+  properties: IDataProperties;
+}
+
+interface IDataGeometry {
+  coordinates: any[];
+  type: string;
+}
+
+interface IDataProperties {
+  capacite: string;
+  gid: string;
+  horaires: string;
+  id: string;
+  last_update: string;
+  last_update_fme: string;
+  nom: string;
+  p_surv: string;
+  place_handi: string;
+}
+
+export class Data implements IData {
+  geometry: IDataGeometry;
+  href: string;
+  properties: IDataProperties;
+  constructor(data: IData) {
+    Object.assign(this, data);
+  }
+}
+
+
diff --git a/webapp/src/app/geosource/models/index.ts b/webapp/src/app/geosource/models/index.ts
index aae31257..dc676943 100644
--- a/webapp/src/app/geosource/models/index.ts
+++ b/webapp/src/app/geosource/models/index.ts
@@ -8,3 +8,4 @@ export { IFilter } from './filter.model';
 export { IHighlights, Highlights } from './highlights.model';
 export { SearchCompletion } from './search-completion.model';
 export { SearchSuggestion } from './suggestion.model';
+export { Data } from './data.model';
diff --git a/webapp/src/app/geosource/models/metadata.model.ts b/webapp/src/app/geosource/models/metadata.model.ts
index ce575790..836459bd 100644
--- a/webapp/src/app/geosource/models/metadata.model.ts
+++ b/webapp/src/app/geosource/models/metadata.model.ts
@@ -1,5 +1,6 @@
 export interface IMetadata {
   'dataset_id'?: string;
+  'dataset_index'?: string;
   'title': string;
   'abstract': string;
   'keyword': string[];
@@ -42,6 +43,7 @@ export interface IMetadataResolution {
 
 export class Metadata implements IMetadata {
   'dataset_id'?: string;
+  'dataset_index'?: string;
   'title': string;
   'abstract': string;
   'keyword': string[];
diff --git a/webapp/src/app/geosource/services/dataset.service.ts b/webapp/src/app/geosource/services/dataset.service.ts
index e62e4dba..507e751a 100644
--- a/webapp/src/app/geosource/services/dataset.service.ts
+++ b/webapp/src/app/geosource/services/dataset.service.ts
@@ -9,7 +9,8 @@ import { Subject } from 'rxjs/Subject';
 
 import {
   IElasticsearchOptions, IElasticsearchResponse, IMetadata,
-  Metadata, IDataset, ISortOption, IFilter, ElasticsearchOptions, IElasticsearchHit, Dataset, Highlights
+  Metadata, IDataset, ISortOption, IFilter, ElasticsearchOptions, IElasticsearchHit, Dataset, Highlights,
+  Data
 } from '../models';
 import { ElasticsearchService } from './elasticsearch.service';
 
@@ -48,7 +49,7 @@ export class DatasetService {
             aggregations[filter.field].buckets.forEach(element => {
               element.count_per_metadata = element.count_per_metadata.value;
             });
-            filter.aggregations =  aggregations[filter.field].buckets;
+            filter.aggregations = aggregations[filter.field].buckets;
           }
         });
         // NOtify that data have been reloaded
@@ -125,9 +126,7 @@ export class DatasetService {
       if (e.hits.hits.length > 0) {
         const metadata = new Metadata(e.hits.hits[0]._source['metadata-fr']);
         const coordinates = e.hits.hits[0]._source['metadata-fr']['bbox']['coordinates'][0];
-        const test = coordinates.map(point => {
-          return point[0];
-        });
+        metadata.dataset_index = e.hits.hits[0]._index;
         metadata.max_west = Math.max.apply(Math, coordinates.map(point => {
           return point[0];
         }));
@@ -148,6 +147,16 @@ export class DatasetService {
     });
   }
 
+  getDataByMetadataById(id: number | string): Observable<Data[]> {
+    return this._elasticsearchService.getAllDataByMetadataId(id).map(e => {
+      const dataList = [];
+      e.hits.hits.forEach(element => {
+        dataList.push(new Data(element._source['data-fr']));
+      });
+      return dataList;
+    });
+  }
+
   /* SEARCH */
   addFilter(field, value): any {
     this._elasticsearchOptions.filters.forEach((element) => {
@@ -209,7 +218,7 @@ export class DatasetService {
   sortChanged(value: string) {
     this._elasticsearchOptions.sortOptions.value = value;
     // If sorting by date the order by default is from the most recent to the oldest (desc)
-    if ( value === 'date') {
+    if (value === 'date') {
       this._elasticsearchOptions.sortOptions.order = 'desc';
     }
     this._searchChangeSubject.next();
diff --git a/webapp/src/app/geosource/services/elasticsearch.service.ts b/webapp/src/app/geosource/services/elasticsearch.service.ts
index 862804d3..36acfbc5 100644
--- a/webapp/src/app/geosource/services/elasticsearch.service.ts
+++ b/webapp/src/app/geosource/services/elasticsearch.service.ts
@@ -7,6 +7,7 @@ import { Observable } from 'rxjs/Observable';
 
 @Injectable()
 export class ElasticsearchService {
+
   private url: string;
 
   constructor(
@@ -34,6 +35,19 @@ export class ElasticsearchService {
     });
   }
 
+
+  getAllDataByMetadataId(index: number | string) {
+    return this._http.request<IElasticsearchResponse>('POST', this.url, {
+      body: {
+        'query': {
+          'term': {
+            '_index': index
+          }
+        }
+      }
+    });
+  }
+
   /*
   * This request will get the completion suggests of elasticsearch from one query text
   * We limit the size of options to 3.
diff --git a/webapp/src/environments/environment.ts b/webapp/src/environments/environment.ts
index 5fdd0d5e..45d82e10 100644
--- a/webapp/src/environments/environment.ts
+++ b/webapp/src/environments/environment.ts
@@ -7,7 +7,7 @@ export const environment = {
   production: false,
 
   elasticsearchUrl: {
-    full: 'http://localhost:8081/elasticsearch/*.full.v3',
+    full: 'http://localhost:8081/elasticsearch/*.full',
     meta: 'http://localhost:8081/elasticsearch/*.meta'
   },
 
diff --git a/webapp/src/tsconfig.app.json b/webapp/src/tsconfig.app.json
index 39ba8dba..1ca08cd0 100644
--- a/webapp/src/tsconfig.app.json
+++ b/webapp/src/tsconfig.app.json
@@ -4,7 +4,9 @@
     "outDir": "../out-tsc/app",
     "baseUrl": "./",
     "module": "es2015",
-    "types": []
+    "types": [
+      "leaflet"
+    ]
   },
   "exclude": [
     "test.ts",
-- 
GitLab