From 3407dfc81528f22b9bf7efcefdf44e4e2e79f736 Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Fri, 27 Nov 2020 10:19:15 +0100 Subject: [PATCH] feat: add location search --- proxy.conf.json | 6 ++ src/app/home/home.component.ts | 102 +++++++++++++++----- src/app/map/components/map.component.ts | 2 +- src/app/map/models/addressGeometry.model.ts | 4 +- src/app/models/structure.model.ts | 4 +- src/app/services/geojson.service.ts | 10 ++ 6 files changed, 99 insertions(+), 29 deletions(-) diff --git a/proxy.conf.json b/proxy.conf.json index cc19a8115..f5d918024 100644 --- a/proxy.conf.json +++ b/proxy.conf.json @@ -25,5 +25,11 @@ "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/home/home.component.ts b/src/app/home/home.component.ts index 265131817..ce2ef32e6 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -22,6 +22,8 @@ export class HomeComponent implements OnInit { public geolocation = false; public currentLocation: GeoJson; public currentStructure: Structure; + public userLatitude: number; + public userLongitude: number; constructor(private structureService: StructureService, private geoJsonService: GeojsonService) {} ngOnInit(): void { @@ -33,37 +35,84 @@ export class HomeComponent implements OnInit { } public getStructures(filters: Filter[]): void { - this.structureService.getStructures(filters).subscribe((structures) => { - if (structures) { - Promise.all( - structures.map((structure) => { - if (this.geolocation) { - structure = this.getStructurePosition(structure); - } - return this.structureService.updateOpeningStructure(structure, DateTime.local()); - }) - ).then((structureList) => { - structureList = _.sortBy(structureList, ['distance']); - this.structures = structureList; + const queryString = _.find(filters, { name: 'query' }); + if (queryString) { + if (this.isLocationRequest(queryString.value)) { + this.getCoordByAddress(queryString.value).then((res) => { + this.currentLocation = res; + this.updateStructuresdistance( + this.structures, + this.currentLocation.geometry.getLon(), + this.currentLocation.geometry.getLat() + ); }); } else { - this.structures = null; + this.structureService.getStructures(filters).subscribe((structures) => { + if (structures) { + this.updateStructuresdistance(structures, this.userLongitude, this.userLatitude); + } else { + this.structures = null; + } + }); } + } else { + this.structureService.getStructures(filters).subscribe((structures) => { + if (structures) { + this.updateStructuresdistance(structures, this.userLongitude, this.userLatitude); + } else { + this.structures = null; + } + }); + } + } + + private updateStructuresdistance(structures: Structure[], lon: number, lat: number): void { + Promise.all( + structures.map((structure) => { + if (this.geolocation) { + structure = this.getStructurePosition(structure, lon, lat); + } + return this.structureService.updateOpeningStructure(structure, DateTime.local()); + }) + ).then((structureList) => { + structureList = _.sortBy(structureList, ['distance']); + this.structures = structureList; }); } + /** + * Retrive GeoJson for a given address + * @param address string + */ + private getCoordByAddress(address: string): Promise<GeoJson> { + return new Promise((resolve) => { + this.geoJsonService.getCoord(address, '', '69000').subscribe((res) => { + resolve(res); + }); + }); + } + + /** + * Check with a regex that an address is request + * @param value string + */ + private isLocationRequest(value: string): boolean { + const regex = /^\d+\s[A-z]+\s[A-z]+/g; + if (value.match(regex)) { + return true; + } + return false; + } + /** * Get structures positions and add marker corresponding to those positons on the map + * @param structure Structure + * @param lon number + * @param lat number */ - private getStructurePosition(structure: Structure): Structure { + private getStructurePosition(structure: Structure, lon: number, lat: number): Structure { structure.distance = parseInt( - this.geoJsonService.getDistance( - structure.getLon(), - structure.getLat(), - this.currentLocation.geometry.getLon(), - this.currentLocation.geometry.getLat(), - 'M' - ), + this.geoJsonService.getDistance(structure.getLat(), structure.getLon(), lat, lon, 'M'), 10 ); return structure; @@ -72,13 +121,18 @@ export class HomeComponent implements OnInit { public getLocation(): void { navigator.geolocation.getCurrentPosition((position) => { this.geolocation = true; - const longitude = position.coords.longitude; - const latitude = position.coords.latitude; - this.getAddress(longitude, latitude); + this.userLongitude = position.coords.longitude; + this.userLatitude = position.coords.latitude; + this.getAddress(position.coords.longitude, position.coords.latitude); this.getStructures(null); }); } + /** + * Get an address by coord + * @param longitude number + * @param latitude number + */ private getAddress(longitude: number, latitude: number): void { this.geoJsonService.getAddressByCoord(longitude, latitude).subscribe( (location) => { diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts index 6bccd2d44..875be42c0 100644 --- a/src/app/map/components/map.component.ts +++ b/src/app/map/components/map.component.ts @@ -111,8 +111,8 @@ export class MapComponent implements OnChanges { structureListe.forEach((structure: Structure) => { this.mapService .createMarker( - structure.getLon(), structure.getLat(), + structure.getLon(), MarkerType.structure, structure.id, this.buildToolTip(structure) diff --git a/src/app/map/models/addressGeometry.model.ts b/src/app/map/models/addressGeometry.model.ts index 71e1ce346..b7612f2fc 100644 --- a/src/app/map/models/addressGeometry.model.ts +++ b/src/app/map/models/addressGeometry.model.ts @@ -7,10 +7,10 @@ export class AddressGeometry { } public getLat(): number { - return this.coordinates[0]; + return this.coordinates[1]; } public getLon(): number { - return this.coordinates[1]; + return this.coordinates[0]; } } diff --git a/src/app/models/structure.model.ts b/src/app/models/structure.model.ts index bcc5b4a08..597234630 100644 --- a/src/app/models/structure.model.ts +++ b/src/app/models/structure.model.ts @@ -112,10 +112,10 @@ export class Structure { } public getLat(): number { - return this.coord[0]; + return this.coord[1]; } public getLon(): number { - return this.coord[1]; + return this.coord[0]; } } diff --git a/src/app/services/geojson.service.ts b/src/app/services/geojson.service.ts index befafee6c..5f15ae6d8 100644 --- a/src/app/services/geojson.service.ts +++ b/src/app/services/geojson.service.ts @@ -43,6 +43,16 @@ export class GeojsonService { .pipe(map((data: { features: any[] }) => _.map(data.features, this.parseToGeoJson))); } + /** + * Get GeoLocation with an address + * @param address Address + */ + public getCoord(numero: string, address: string, zipcode: string): Observable<GeoJson> { + return this.http + .get('/geocoding/photon/api' + '?q=' + numero + ' ' + address + ' ' + zipcode) + .pipe(map((data: { features: any[]; type: string }) => new GeoJson(data.features[0]))); + } + // ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: // ::: ::: // ::: This routine calculates the distance between two points (given the ::: -- GitLab