1- import { Component , Input } from '@angular/core' ;
2- import { LocationCoordinates } from '../../core/services/location.service' ;
1+ import { Component , Input , OnInit } from '@angular/core' ;
2+ import {
3+ LocationCoordinates ,
4+ LocationErrorCodes ,
5+ LocationPlace ,
6+ LocationService
7+ } from '../../core/services/location.service' ;
8+ import { filter , map } from 'rxjs/operators' ;
9+ import { BehaviorSubject , Observable } from 'rxjs' ;
10+ import { TranslateService } from '@ngx-translate/core' ;
11+ import { isNotEmpty } from '../empty.util' ;
312
413export interface OpenStreetMapPointer {
514 coordinates : LocationCoordinates ,
@@ -11,7 +20,7 @@ export interface OpenStreetMapPointer {
1120 templateUrl : './open-street-map.component.html' ,
1221 styleUrls : [ './open-street-map.component.scss' ] ,
1322} )
14- export class OpenStreetMapComponent {
23+ export class OpenStreetMapComponent implements OnInit {
1524
1625 // Spacial reference identifier
1726 SRID = 'EPSG:4326' ; // World Geodetic System 1984
@@ -31,12 +40,7 @@ export class OpenStreetMapComponent {
3140 /**
3241 * The map coordinates
3342 */
34- @Input ( ) coordinates : LocationCoordinates ;
35-
36- /**
37- * The pointers to be shown on the map
38- */
39- @Input ( ) pointers : OpenStreetMapPointer [ ] ;
43+ @Input ( ) coordinates : string ;
4044
4145 /**
4246 * The name of the location
@@ -53,6 +57,118 @@ export class OpenStreetMapComponent {
5357 */
5458 @Input ( ) showControlsZoom = true ;
5559
60+ /**
61+ * The name of the location
62+ */
63+ @Input ( ) showDisplayName = false ;
64+
65+ /**
66+ * The coordinates of the place once retrieved by the location service
67+ */
68+ coordinates$ : Observable < LocationCoordinates > ;
69+
70+ /**
71+ * The name of the address to display
72+ */
73+ displayName$ : Observable < string > ;
74+
75+ /**
76+ * Contains error codes from the location service
77+ */
78+ invalidLocationErrorCode : BehaviorSubject < string > = new BehaviorSubject ( undefined ) ;
79+
80+ /**
81+ * The place to be shown in the map
82+ */
83+ place = new BehaviorSubject < LocationPlace > ( undefined ) ;
84+
85+ /**
86+ * The pointers to be shown on the map
87+ */
88+ pointers$ : Observable < OpenStreetMapPointer [ ] > ;
89+
90+ constructor (
91+ protected translateService : TranslateService ,
92+ private locationService : LocationService ) {
93+ }
94+
95+ ngOnInit ( ) : void {
96+
97+ this . coordinates$ = this . place . asObservable ( ) . pipe (
98+ filter ( ( place ) => isNotEmpty ( place ) ) ,
99+ map ( ( place ) => place . coordinates ) ,
100+ ) ;
101+
102+ this . pointers$ = this . place . asObservable ( ) . pipe (
103+ filter ( ( place ) => isNotEmpty ( place ) ) ,
104+ map ( ( place ) => {
105+ const pointer : OpenStreetMapPointer = {
106+ coordinates : place . coordinates ,
107+ color : 'green' ,
108+ } ;
109+ return [ pointer ] ;
110+ } ) ,
111+ ) ;
112+
113+ this . displayName$ = this . place . asObservable ( ) . pipe (
114+ filter ( ( place ) => isNotEmpty ( place ) ) ,
115+ map ( ( place ) => place . displayName ) ,
116+ ) ;
117+
118+ if ( this . locationService . isCoordinateString ( this . coordinates ) ) {
119+
120+ // Validate the coordinates, then retrieve the location name
121+
122+ if ( this . locationService . isValidCoordinateString ( this . coordinates ) ) {
123+ const coordinates = this . locationService . parseCoordinates ( this . coordinates ) ;
124+ this . locationService . searchCoordinates ( coordinates ) . subscribe ( {
125+ next : ( displayName ) => {
126+ const place : LocationPlace = {
127+ coordinates : coordinates ,
128+ displayName : displayName , // Show the name retrieved from Nominatim
129+ } ;
130+ this . place . next ( place ) ;
131+ } ,
132+ error : ( err ) => {
133+ // show the map centered on provided coordinates despite the possibility to retrieve a description for the place
134+ const place : LocationPlace = {
135+ coordinates : coordinates ,
136+ } ;
137+ this . place . next ( place ) ;
138+ if ( err . message === LocationErrorCodes . API_ERROR ) {
139+ console . error ( err . message ) ;
140+ } else {
141+ console . warn ( err . message ) ;
142+ }
143+ } ,
144+ } ) ;
145+ } else {
146+ console . error ( `Invalid coordinates: "${ this . coordinates } "` ) ;
147+ this . invalidLocationErrorCode . next ( LocationErrorCodes . INVALID_COORDINATES ) ;
148+ }
149+
150+ } else {
151+
152+ // Retrieve the coordinates for the provided POI or address
153+
154+ this . locationService . searchPlace ( this . coordinates ) . subscribe ( {
155+ next : ( place ) => {
156+ place . displayName = this . coordinates ; // Show the name stored in metadata (comment out to show name retrieved from Nominatim)
157+ this . place . next ( place ) ;
158+ } ,
159+ error : ( err ) => {
160+ this . invalidLocationErrorCode . next ( err . message ) ; // either LOCATION_NOT_FOUND or API_ERROR
161+ if ( err . message === LocationErrorCodes . API_ERROR ) {
162+ console . error ( err . message ) ;
163+ } else {
164+ console . warn ( err . message ) ;
165+ }
166+ } ,
167+ } ) ;
168+ }
169+
170+ }
171+
56172 increaseZoom ( ) {
57173 this . zoom ++ ;
58174 }
0 commit comments