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