diff --git a/proxy.conf.json b/proxy.conf.json index 70c21305f4f69a5eddeb234cf6d4b134a539301d..f5d9180245f7dc46708cd6947716af80568f6e29 100644 --- a/proxy.conf.json +++ b/proxy.conf.json @@ -14,20 +14,20 @@ "changeOrigin": true, "logLevel": "info" }, - "/geocoding/photon/api": { + "/wfs/grandlyon": { "target": "https://download.data.grandlyon.com", "secure": false, "changeOrigin": true, "logLevel": "info" }, - "/wfs/grandlyon": { - "target": "https://download.data.grandlyon.com", + "/reverse": { + "target": "https://api-adresse.data.gouv.fr", "secure": false, "changeOrigin": true, "logLevel": "info" }, - "/reverse": { - "target": "https://api-adresse.data.gouv.fr", + "/geocoding/photon/api": { + "target": "https://download.data.grandlyon.com", "secure": false, "changeOrigin": true, "logLevel": "info" diff --git a/src/app/home/home.component.spec.ts b/src/app/home/home.component.spec.ts index d389cc50d4660f6f2a92755adc25ad9c3c7d0eab..4bc5950f6a1619d1bed7a4eb96a87c539b75e5c2 100644 --- a/src/app/home/home.component.spec.ts +++ b/src/app/home/home.component.spec.ts @@ -31,20 +31,6 @@ describe('HomeComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); - - it('getCoord(): should get coord', async () => { - await new Promise((resolve) => { - component.getCoord('Rue de la Mairie ', 'Feyzin').subscribe( - (val) => { - expect(val.geometry.getLat()).toEqual(4.8591584); - expect(val.geometry.getLon()).toEqual(45.6727968); - resolve(); - }, - (err) => { - resolve(); - } - ); - }); }); it('getAddress(): should getAddress', () => { diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index 521b21db97bb58fa6201381cf842107e31a2b38d..8ccaba5fc7a2c28232b0ff8513a15724420c6065 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; public isMapPhone = false; constructor(private structureService: StructureService, private geoJsonService: GeojsonService) {} @@ -34,87 +36,96 @@ export class HomeComponent implements OnInit { } public getStructures(filters: Filter[]): void { - this.structureService.getStructures(filters).subscribe((structures) => { - filters ? (structures = this.applyFilters(structures, filters)) : structures; - if (structures) { - Promise.all( - structures.map((structure) => { - return this.getStructurePosition(structure).then((val) => { - return this.structureService.updateOpeningStructure(val, 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; }); } /** - * Delete when we have back-end - * Fix a bug with Json-server request + * Retrive GeoJson for a given address + * @param address string */ - private applyFilters(structures, filters): Structure[] { - let structuresFiltered = []; - structures.forEach((s: Structure) => { - let count = 0; - filters.forEach((filter: Filter) => { - let properties: string[] = []; - properties = s[filter.name]; - if (properties && properties.includes(filter.value)) { - count++; - } + private getCoordByAddress(address: string): Promise<GeoJson> { + return new Promise((resolve) => { + this.geoJsonService.getCoord(address, '', '69000').subscribe((res) => { + resolve(res); }); - if (count === filters.length) { - structuresFiltered.push(s); - } }); - return structuresFiltered; } /** - * Get structures positions and add marker corresponding to those positons on the map + * Check with a regex that an address is request + * @param value string */ - private getStructurePosition(structure: Structure): Promise<Structure> { - return new Promise((resolve, reject) => { - this.getCoord(structure.n, structure.voie, structure.commune).subscribe((coord: GeoJson) => { - structure.address = structure.voie + ' - ' + coord.properties.postcode + ' ' + coord.properties.city; - // If location available, process structure distance - if (this.currentLocation) { - structure.distance = parseInt( - this.geoJsonService.getDistance( - coord.geometry.getLon(), - coord.geometry.getLat(), - this.currentLocation.geometry.getLon(), - this.currentLocation.geometry.getLat(), - 'M' - ), - 10 - ); - } - resolve(structure); - }); - }); + private isLocationRequest(value: string): boolean { + const regex = /^\d+\s[A-z]+\s[A-z]+/g; + if (value.match(regex)) { + return true; + } + return false; } /** - * Get coord with a street reference - * @param idVoie Street reference + * Get structures positions and add marker corresponding to those positons on the map + * @param structure Structure + * @param lon number + * @param lat number */ - public getCoord(numero: string, voie: string, zipcode: string): Observable<GeoJson> { - return this.geoJsonService.getCoord(numero, voie, zipcode); + private getStructurePosition(structure: Structure, lon: number, lat: number): Structure { + structure.distance = parseInt( + this.geoJsonService.getDistance(structure.getLat(), structure.getLon(), lat, lon, 'M'), + 10 + ); + return structure; } 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); }, (err) => { @@ -125,6 +136,11 @@ export class HomeComponent implements OnInit { ); } + /** + * 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 da2b10cac064afb593f51a3ec51a5654bda2822d..c2938329097567d9ca7640579eec19bb464bf9c4 100644 --- a/src/app/map/components/map.component.ts +++ b/src/app/map/components/map.component.ts @@ -110,22 +110,20 @@ export class MapComponent implements OnChanges { } private getStructuresPositions(structureListe: Structure[]): void { - structureListe.forEach((element: Structure) => { - this.getCoord(element.n, element.voie, element.commune).subscribe((coord: GeoJson) => { - this.mapService - .createMarker( - coord.geometry.getLon(), - coord.geometry.getLat(), - MarkerType.structure, - element.id, - this.buildToolTip(element) - ) - .addTo(this.map) - // store structure before user click on button - .on('popupopen', () => { - this.currentStructure = element; - }); - }); + structureListe.forEach((structure: Structure) => { + this.mapService + .createMarker( + structure.getLat(), + structure.getLon(), + MarkerType.structure, + structure.id, + this.buildToolTip(structure) + ) + .addTo(this.map) + // store structure before user click on button + .on('popupopen', () => { + this.currentStructure = structure; + }); }); } @@ -161,14 +159,6 @@ export class MapComponent implements OnChanges { return `<h1>${mdmProperties.nom}</h1><p>${mdmProperties.adresse}</p>`; } - /** - * Get coord with a street reference - * @param idVoie Street reference - */ - public getCoord(numero: string, voie: string, zipcode: string): Observable<GeoJson> { - return this.geoJsonService.getCoord(numero, voie, zipcode); - } - /** * Add marker when map is ready to be showned * @param map map diff --git a/src/app/map/models/addressGeometry.model.ts b/src/app/map/models/addressGeometry.model.ts index 71e1ce346c39c7c7c52861356026d8fc4bba74ed..b7612f2fc5fb6cd32127ca4e6779560bccd9f103 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 221dd15cf608b56b2ba6ce9fe1056d0a363a8671..597234630cd1e1fd8ca06e75b5c7eaa8a0af18d0 100644 --- a/src/app/models/structure.model.ts +++ b/src/app/models/structure.model.ts @@ -40,6 +40,7 @@ export class Structure { public accesAuxDroits: string[]; public distance?: number; public address?: string; + public coord?: number[]; constructor(obj?: any) { Object.assign(this, obj, { @@ -109,4 +110,12 @@ export class Structure { } } } + + public getLat(): number { + return this.coord[1]; + } + + public getLon(): number { + return this.coord[0]; + } } diff --git a/src/app/services/geojson.service.spec.ts b/src/app/services/geojson.service.spec.ts index a947152a8b9a78cd5c5eba10ef1d73f5bdfac840..71045a64d867491b1fe53f051ffd73cb0159749d 100644 --- a/src/app/services/geojson.service.spec.ts +++ b/src/app/services/geojson.service.spec.ts @@ -21,19 +21,4 @@ describe('GeojsonService', () => { it('should be created', () => { expect(service).toBeTruthy(); }); - - it('should get coord with query string Rue de la Mairie Feyzin ', async () => { - await new Promise((resolve) => { - service.getCoord('Rue de la Mairie', 'Feyzin').subscribe( - (val) => { - expect(val.geometry.getLat()).toEqual(4.8591584); - expect(val.geometry.getLon()).toEqual(45.6727968); - resolve(); - }, - (err) => { - resolve(); - } - ); - }); - }); }); diff --git a/src/app/services/structure-list.service.ts b/src/app/services/structure-list.service.ts index faf14254cda6410e18fcb0c340881d90ef2826d8..3224f378ae072c1eabb1c65a71dacb6336229379 100644 --- a/src/app/services/structure-list.service.ts +++ b/src/app/services/structure-list.service.ts @@ -3,6 +3,7 @@ import { Injectable } from '@angular/core'; import { WeekDay } from '@angular/common'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import * as _ from 'lodash'; import { Structure } from '../models/structure.model'; import { Day } from '../models/day.model'; @@ -18,7 +19,26 @@ export class StructureService { constructor(private http: HttpClient) {} public getStructures(filters: Filter[]): Observable<Structure[]> { - return this.http.get('/api/structures').pipe(map((data: any[]) => data.map((item) => new Structure(item)))); + if (filters && filters.length > 0) { + let requestUrl = '/api/structures/search'; + const queryString = _.find(filters, { name: 'query' }); + if (queryString) { + _.remove(filters, { name: 'query' }); + requestUrl += `?query=${queryString.value}`; + } + const formatedFilters = this.formatFilters(filters); + return this.http + .post(requestUrl, { filters: formatedFilters }) + .pipe(map((data: any[]) => data.map((item) => new Structure(item)))); + } else { + return this.http.get('/api/structures').pipe(map((data: any[]) => data.map((item) => new Structure(item)))); + } + } + + private formatFilters(filters: Filter[]): object { + return filters.map((filter) => { + return { [filter.name]: filter.value }; + }); } /** diff --git a/src/app/structure-list/components/search/search.component.spec.ts b/src/app/structure-list/components/search/search.component.spec.ts index 647c986a81195db21a32ba7708eb03e74c9d0296..be7013937a1b0b5882c840ca2ed33e1ad60e5dcf 100644 --- a/src/app/structure-list/components/search/search.component.spec.ts +++ b/src/app/structure-list/components/search/search.component.spec.ts @@ -33,7 +33,7 @@ describe('SearchComponent', () => { // applyFilter function it('should emit filters', () => { - const filter: Filter[] = [new Filter('nomDeVotreStructure', 'valInput')]; + const filter: Filter[] = [new Filter('query', 'valInput')]; spyOn(component.searchEvent, 'emit'); component.applyFilter('valInput'); expect(component.searchEvent.emit).toHaveBeenCalled(); diff --git a/src/app/structure-list/components/search/search.component.ts b/src/app/structure-list/components/search/search.component.ts index 39a0f9eaafc65cfa68f429eecf5a6c1f9b2bcc46..6149a0fd9b2e773401724832339072d36260b62e 100644 --- a/src/app/structure-list/components/search/search.component.ts +++ b/src/app/structure-list/components/search/search.component.ts @@ -64,7 +64,7 @@ export class SearchComponent implements OnInit { // Add search input filter const filters: Filter[] = []; if (term) { - filters.push(new Filter('nomDeVotreStructure', term)); + filters.push(new Filter('query', term)); } // Add checked box filter this.checkedModulesFilter.forEach((cm) => { diff --git a/src/app/structure-list/services/search.service.ts b/src/app/structure-list/services/search.service.ts index 3f57cd50fdf4e9273328c9758b63f0fe1bae20e4..2c2b58e37ad26ba60f432ac6a8728e1e9d23b254 100644 --- a/src/app/structure-list/services/search.service.ts +++ b/src/app/structure-list/services/search.service.ts @@ -14,17 +14,17 @@ export class SearchService { public getCategoriesTraining(): Observable<Category[]> { return this.http - .get('/api/CategoriesFormations') + .get('/api/categories/categoriesFormations') .pipe(map((data: any[]) => data.map((item) => new Category(item)))); } public getCategoriesAccompaniment(): Observable<Category[]> { return this.http - .get('/api/CategoriesAccompagnement') + .get('/api/categories/categoriesAccompagnement') .pipe(map((data: any[]) => data.map((item) => new Category(item)))); } public getCategoriesMoreFilters(): Observable<Category[]> { return this.http - .get('/api/CategoriesPlusDeFiltres') + .get('/api/categories/categoriesOthers') .pipe(map((data: any[]) => data.map((item) => new Category(item)))); }