@geosdi/ngx-geocoding 1.1.4 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"geosdi-ngx-geocoding.mjs","sources":["../tmp-esm2022/lib/ngx-geocoding.module.js","../tmp-esm2022/lib/ngx-geocoding.service.js","../tmp-esm2022/index.js","../tmp-esm2022/geosdi-ngx-geocoding.js"],"sourcesContent":["import { NgModule } from \"@angular/core\";\nimport * as i0 from \"@angular/core\";\n/**\n * @author Vito Salvia - CNR IMAA geoSDI Group\n * @email vito.salvia@gmail.com\n */\nexport class NgxGeocodingModule {\n /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"20.3.6\", ngImport: i0, type: NgxGeocodingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }\n /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: \"14.0.0\", version: \"20.3.6\", ngImport: i0, type: NgxGeocodingModule }); }\n /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: \"12.0.0\", version: \"20.3.6\", ngImport: i0, type: NgxGeocodingModule }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"20.3.6\", ngImport: i0, type: NgxGeocodingModule, decorators: [{\n type: NgModule,\n args: [{\n declarations: [],\n imports: [],\n exports: [],\n }]\n }] });\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWdlb2NvZGluZy5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9nZW9zZGkvc3VwcG9ydC9uZ3gtZ2VvY29kaW5nL3NyYy9saWIvbmd4LWdlb2NvZGluZy5tb2R1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFFekM7OztHQUdHO0FBTUgsTUFBTSxPQUFPLGtCQUFrQjtpSUFBbEIsa0JBQWtCO2tJQUFsQixrQkFBa0I7a0lBQWxCLGtCQUFrQjs7MkZBQWxCLGtCQUFrQjtrQkFMOUIsUUFBUTttQkFBQztvQkFDTixZQUFZLEVBQUUsRUFBRTtvQkFDaEIsT0FBTyxFQUFFLEVBQUU7b0JBQ1gsT0FBTyxFQUFFLEVBQUU7aUJBQ2QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5cbi8qKlxuICogQGF1dGhvciBWaXRvIFNhbHZpYSAtIENOUiBJTUFBIGdlb1NESSBHcm91cFxuICogQGVtYWlsIHZpdG8uc2FsdmlhQGdtYWlsLmNvbVxuICovXG5ATmdNb2R1bGUoe1xuICAgIGRlY2xhcmF0aW9uczogW10sXG4gICAgaW1wb3J0czogW10sXG4gICAgZXhwb3J0czogW10sXG59KVxuZXhwb3J0IGNsYXNzIE5neEdlb2NvZGluZ01vZHVsZSB7fVxuIl19","import { Injectable, inject } from \"@angular/core\";\nimport { HttpClient } from \"@angular/common/http\";\nimport { Subject } from \"rxjs\";\nimport { map, tap } from \"rxjs/operators\";\nimport * as i0 from \"@angular/core\";\n/**\n * @author Vito Salvia - CNR IMAA geoSDI Group\n * @email vito.salvia@gmail.com\n */\nexport class NgxGeocodingService {\n constructor() {\n this.subjectLocation = new Subject();\n this.subjectNoResults = new Subject();\n this.subjectRemove = new Subject();\n this.http = inject(HttpClient);\n }\n /**\n *\n * @param address\n */\n geocode(address) {\n const encoded = encodeURIComponent(address);\n return this.http\n .get(`https://nominatim.openstreetmap.org/search.php?q=${encoded}&format=jsonv2`)\n .pipe(tap((res) => {\n if (res.length <= 0) {\n this.subjectNoResults.next(null);\n }\n // return res;\n }))\n .pipe(map((res) => res.map((item) => ({\n display_name: item.display_name,\n lat: item.lat,\n lon: item.lon,\n place_id: item.place_id,\n }))));\n }\n /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: \"12.0.0\", version: \"20.3.6\", ngImport: i0, type: NgxGeocodingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }\n /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: \"12.0.0\", version: \"20.3.6\", ngImport: i0, type: NgxGeocodingService, providedIn: \"root\" }); }\n}\ni0.ɵɵngDeclareClassMetadata({ minVersion: \"12.0.0\", version: \"20.3.6\", ngImport: i0, type: NgxGeocodingService, decorators: [{\n type: Injectable,\n args: [{\n providedIn: \"root\",\n }]\n }] });\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWdlb2NvZGluZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZ2Vvc2RpL3N1cHBvcnQvbmd4LWdlb2NvZGluZy9zcmMvbGliL25neC1nZW9jb2Rpbmcuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFbEQsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQUUxQzs7O0dBR0c7QUFJSCxNQUFNLE9BQU8sbUJBQW1CO0lBSGhDO1FBSUksb0JBQWUsR0FBRyxJQUFJLE9BQU8sRUFBcUIsQ0FBQztRQUNuRCxxQkFBZ0IsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQ2pDLGtCQUFhLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUN0QixTQUFJLEdBQWUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0tBK0JqRDtJQTdCRzs7O09BR0c7SUFDSCxPQUFPLENBQUMsT0FBZTtRQUNuQixNQUFNLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QyxPQUFPLElBQUksQ0FBQyxJQUFJO2FBQ1gsR0FBRyxDQUNBLG9EQUFvRCxPQUFPLGdCQUFnQixDQUM5RTthQUNBLElBQUksQ0FDRCxHQUFHLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtZQUNiLElBQUksR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDbEIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNyQyxDQUFDO1lBQ0QsY0FBYztRQUNsQixDQUFDLENBQUMsQ0FDTDthQUNBLElBQUksQ0FDRCxHQUFHLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRSxDQUNiLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDcEIsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO1lBQy9CLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRztZQUNiLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRztZQUNiLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtTQUMxQixDQUFDLENBQUMsQ0FDTixDQUNKLENBQUM7SUFDVixDQUFDO2lJQWxDUSxtQkFBbUI7cUlBQW5CLG1CQUFtQixjQUZoQixNQUFNOzsyRkFFVCxtQkFBbUI7a0JBSC9CLFVBQVU7bUJBQUM7b0JBQ1IsVUFBVSxFQUFFLE1BQU07aUJBQ3JCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uL2h0dHBcIjtcbmltcG9ydCB7IEdlb2NvZGluZ0xvY2F0aW9uIH0gZnJvbSBcIi4vbW9kZWwvZ2VvY29kaW5nLWxvY2F0aW9uLm1vZGVsXCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IG1hcCwgdGFwIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5cbi8qKlxuICogQGF1dGhvciBWaXRvIFNhbHZpYSAtIENOUiBJTUFBIGdlb1NESSBHcm91cFxuICogQGVtYWlsIHZpdG8uc2FsdmlhQGdtYWlsLmNvbVxuICovXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogXCJyb290XCIsXG59KVxuZXhwb3J0IGNsYXNzIE5neEdlb2NvZGluZ1NlcnZpY2Uge1xuICAgIHN1YmplY3RMb2NhdGlvbiA9IG5ldyBTdWJqZWN0PEdlb2NvZGluZ0xvY2F0aW9uPigpO1xuICAgIHN1YmplY3ROb1Jlc3VsdHMgPSBuZXcgU3ViamVjdCgpO1xuICAgIHN1YmplY3RSZW1vdmUgPSBuZXcgU3ViamVjdCgpO1xuICAgIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCA9IGluamVjdChIdHRwQ2xpZW50KTtcblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIGFkZHJlc3NcbiAgICAgKi9cbiAgICBnZW9jb2RlKGFkZHJlc3M6IHN0cmluZyk6IE9ic2VydmFibGU8R2VvY29kaW5nTG9jYXRpb25bXT4ge1xuICAgICAgICBjb25zdCBlbmNvZGVkID0gZW5jb2RlVVJJQ29tcG9uZW50KGFkZHJlc3MpO1xuICAgICAgICByZXR1cm4gdGhpcy5odHRwXG4gICAgICAgICAgICAuZ2V0PExvY2F0aW9uPihcbiAgICAgICAgICAgICAgICBgaHR0cHM6Ly9ub21pbmF0aW0ub3BlbnN0cmVldG1hcC5vcmcvc2VhcmNoLnBocD9xPSR7ZW5jb2RlZH0mZm9ybWF0PWpzb252MmAsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICB0YXAoKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXMubGVuZ3RoIDw9IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3ViamVjdE5vUmVzdWx0cy5uZXh0KG51bGwpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIHJldHVybiByZXM7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBtYXAoKHJlczogYW55KSA9PlxuICAgICAgICAgICAgICAgICAgICByZXMubWFwKChpdGVtOiBhbnkpID0+ICh7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5X25hbWU6IGl0ZW0uZGlzcGxheV9uYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGF0OiBpdGVtLmxhdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvbjogaXRlbS5sb24sXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGFjZV9pZDogaXRlbS5wbGFjZV9pZCxcbiAgICAgICAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICApO1xuICAgIH1cbn1cbiJdfQ==","/*\n * Public API Surface of ngx-geocoding\n */\nexport * from \"./lib/ngx-geocoding.module\";\nexport * from \"./lib/ngx-geocoding.service\";\nexport * from \"./lib/model/geocoding-location.model\";\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nZW9zZGkvc3VwcG9ydC9uZ3gtZ2VvY29kaW5nL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYyw2QkFBNkIsQ0FBQztBQUM1QyxjQUFjLHNDQUFzQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIFB1YmxpYyBBUEkgU3VyZmFjZSBvZiBuZ3gtZ2VvY29kaW5nXG4gKi9cblxuZXhwb3J0ICogZnJvbSBcIi4vbGliL25neC1nZW9jb2RpbmcubW9kdWxlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9saWIvbmd4LWdlb2NvZGluZy5zZXJ2aWNlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9saWIvbW9kZWwvZ2VvY29kaW5nLWxvY2F0aW9uLm1vZGVsXCI7XG4iXX0=","/**\n * Generated bundle index. Do not edit.\n */\nexport * from './index';\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2Vvc2RpLW5neC1nZW9jb2RpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nZW9zZGkvc3VwcG9ydC9uZ3gtZ2VvY29kaW5nL3NyYy9nZW9zZGktbmd4LWdlb2NvZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsU0FBUyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHZW5lcmF0ZWQgYnVuZGxlIGluZGV4LiBEbyBub3QgZWRpdC5cbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2luZGV4JztcbiJdfQ=="],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"geosdi-ngx-geocoding.mjs","sources":["../../../../projects/geosdi/support/ngx-geocoding/src/lib/ngx-geocoding.module.ts","../../../../projects/geosdi/support/ngx-geocoding/src/lib/ngx-geocoding.config.ts","../../../../projects/geosdi/support/ngx-geocoding/src/lib/google-maps-sdk.ts","../../../../projects/geosdi/support/ngx-geocoding/src/lib/ngx-geocoding.service.ts","../../../../projects/geosdi/support/ngx-geocoding/src/lib/model/ngx-geocoding-config.model.ts","../../../../projects/geosdi/support/ngx-geocoding/src/index.ts","../../../../projects/geosdi/support/ngx-geocoding/src/geosdi-ngx-geocoding.ts"],"sourcesContent":["import { NgModule } from \"@angular/core\";\n\n/**\n * @author Vito Salvia - CNR IMAA geoSDI Group\n * @email vito.salvia@gmail.com\n */\n@NgModule({\n declarations: [],\n imports: [],\n exports: [],\n})\nexport class NgxGeocodingModule {}\n","import { InjectionToken, Provider } from \"@angular/core\";\nimport { NgxGeocodingConfig } from \"./model/ngx-geocoding-config.model\";\n\n/**\n * @author Vito Salvia - CNR IMAA geoSDI Group\n * @email vito.salvia@gmail.com\n */\n\n/**\n * La configurazione della ricerca, che **può non esserci** : in quel caso vale\n * il comportamento storico, cioè Nominatim e basta.\n */\nexport const NGX_GEOCODING_CONFIG: InjectionToken<NgxGeocodingConfig> =\n new InjectionToken<NgxGeocodingConfig>(\"NGX_GEOCODING_CONFIG\");\n\n/**\n * Dichiara da dove arrivano gli indirizzi, nei `providers` dell'applicazione :\n *\n * ```ts\n * provideNgxGeocoding({\n * sources: [\"google\", \"nominatim\"],\n * country: \"it\",\n * bias: { lat: 40.83, lon: 14.11, radiusM: 25_000 },\n * })\n * ```\n *\n * L'ordine è quello in cui le sorgenti si provano, e una che non è utilizzabile\n * si salta : la stessa riga vale quindi per il deploy che ha la chiave Google e\n * per quello che non ce l'ha.\n *\n * Chi non la chiama non cambia niente.\n */\nexport function provideNgxGeocoding(config: NgxGeocodingConfig): Provider {\n return { provide: NGX_GEOCODING_CONFIG, useValue: config };\n}","/**\n * L'SDK Maps JS dell'applicazione ospite, e l'attesa perché sia pronto.\n *\n * **Questa libreria non lo carica** : il tag lo mette in pagina chi la usa, con\n * la propria chiave —\n *\n * ```html\n * <script defer src=\"https://maps.googleapis.com/maps/api/js?key=…&libraries=places&language=it\"></script>\n * ```\n *\n * — e le ragioni perché resti così sono due : la chiave è dell'applicazione e\n * non deve passare di qui, e caricarlo una seconda volta vorrebbe dire due\n * copie dell'SDK nella stessa pagina.\n *\n * Serve però **aspettarlo** : quel tag è di norma `defer`, quindi chi cerca un\n * indirizzo subito dopo l'avvio può arrivare prima di lui.\n *\n * Della query contano due parametri : `libraries=places`, senza cui non c'è\n * niente da aspettare, e `language`, che decide la lingua delle proposte —\n * `getPlacePredictions` non ha un parametro per chiederla.\n *\n * @author Vito Salvia - CNR IMAA geoSDI Group\n * @email vito.salvia@gmail.com\n */\n\n/** Quanto si aspetta l'SDK prima di rinunciare, e ogni quanto lo si guarda. */\nconst ATTESA: { tetto_ms: number; passo_ms: number } = {\n tetto_ms: 10_000,\n passo_ms: 100,\n};\n\n/**\n * La libreria `places` dell'SDK, quel poco che se ne usa.\n *\n * Tipi **nostri** e non `@types/google.maps` : quel pacchetto diventerebbe una\n * dipendenza di chiunque usi la libreria, per due classi e una manciata di\n * campi.\n */\nexport interface LibreriaPlaces {\n /**\n * Places **(New)**, la strada che Google raccomanda dal 1° marzo 2025 —\n * `AutocompleteService` «non è disponibile per i nuovi clienti».\n *\n * **Opzionale**, e per due ragioni diverse : su un SDK più vecchio la\n * classe non c'è, e dove c'è può comunque rispondere `403` perché sotto sta\n * il prodotto **Places API (New)**, che sul progetto Cloud va abilitato a\n * parte. In tutti e due i casi si scende di un gradino.\n */\n AutocompleteSuggestion?: {\n fetchAutocompleteSuggestions(richiesta: {\n input: string;\n includedRegionCodes?: string[];\n locationBias?: CerchioSdk;\n language?: string;\n region?: string;\n }): Promise<{ suggestions?: SuggerimentoSdk[] }>;\n };\n /** Il luogo di Places (New), da cui si prendono le coordinate. */\n Place?: new (opzioni: { id: string }) => LuogoNuovoSdk;\n AutocompleteService: new () => {\n getPlacePredictions(\n richiesta: {\n input: string;\n componentRestrictions?: { country: string | string[] };\n locationBias?: CerchioSdk;\n },\n risposta: (proposte: PropostaSdk[] | null, stato: string) => void,\n ): void;\n };\n PlacesService: new (contenitore: HTMLElement) => {\n getDetails(\n richiesta: { placeId: string; fields: string[] },\n risposta: (luogo: LuogoSdk | null, stato: string) => void,\n ): void;\n };\n}\n\n/**\n * Il punto e il raggio su cui polarizzare le proposte, nella forma che l'SDK\n * accetta come `locationBias` : un oggetto, non una `Circle` da costruire, così\n * questi tipi restano dichiarazioni e non richiedono l'SDK a chi compila.\n */\nexport interface CerchioSdk {\n center: { lat: number; lng: number };\n radius: number;\n}\n\n/** Il riquadro che il `Geocoder` accetta come `bounds`. */\nexport interface RiquadroSdk {\n north: number;\n south: number;\n east: number;\n west: number;\n}\n\n/**\n * Il **Geocoder** dell'SDK, che è l'equivalente nel browser della terza strada\n * di Google : nessuna proposta incrementale, di norma un risultato solo, ma\n * **porta già le coordinate** e risponde dove Places è negata.\n */\nexport interface Geocoder {\n geocode(\n richiesta: {\n address: string;\n componentRestrictions?: { country: string | string[] };\n bounds?: RiquadroSdk;\n region?: string;\n },\n risposta: (\n risultati: RisultatoGeocoder[] | null,\n stato: string,\n ) => void,\n ): void;\n}\n\n/** Un risultato del `Geocoder`, con le coordinate dentro. */\nexport interface RisultatoGeocoder {\n place_id?: string;\n formatted_address?: string;\n geometry?: { location?: { lat(): number; lng(): number } };\n}\n\n/**\n * Una proposta di `AutocompleteSuggestion`.\n *\n * `text` non è una stringa ma un oggetto formattabile : va letto con\n * `toString()`, e scritto in un template verrebbe fuori `[object Object]`.\n */\nexport interface SuggerimentoSdk {\n placePrediction?: {\n placeId?: string;\n text?: { toString(): string };\n };\n}\n\n/**\n * Il luogo di Places (New) : nasce con l'id e si riempie con `fetchFields`,\n * che **muta l'oggetto** invece di restituire i campi — dopo l'attesa si\n * leggono da lui.\n */\nexport interface LuogoNuovoSdk {\n formattedAddress?: string | null;\n location?: { lat(): number; lng(): number } | null;\n fetchFields(richiesta: { fields: string[] }): Promise<unknown>;\n}\n\n/** Una proposta di `AutocompleteService`, che le coordinate non le porta. */\nexport interface PropostaSdk {\n place_id?: string;\n description?: string;\n}\n\n/** Il dettaglio di `PlacesService`, che invece le porta. */\nexport interface LuogoSdk {\n formatted_address?: string;\n geometry?: { location?: { lat(): number; lng(): number } };\n}\n\n/** Gli stati dell'SDK su cui si decide qualcosa. */\nexport const STATO_PLACES: {\n ok: string;\n nessuno: string;\n negato: string;\n quota: string;\n} = {\n ok: \"OK\",\n nessuno: \"ZERO_RESULTS\",\n negato: \"REQUEST_DENIED\",\n quota: \"OVER_QUERY_LIMIT\",\n};\n\ninterface FinestraConMaps extends Window {\n google?: {\n maps?: {\n places?: LibreriaPlaces;\n Geocoder?: new () => Geocoder;\n };\n };\n}\n\n/** La libreria `places` se è già in pagina, `undefined` altrimenti. */\nfunction places(): LibreriaPlaces | undefined {\n return (window as FinestraConMaps).google?.maps?.places;\n}\n\n/** Il costruttore del `Geocoder`, che sta nell'SDK di base. */\nfunction geocoder(): (new () => Geocoder) | undefined {\n return (window as FinestraConMaps).google?.maps?.Geocoder;\n}\n\n/**\n * La libreria `places`, aspettando che l'SDK finisca di caricarsi.\n *\n * Rifiuta dopo {@link ATTESA} : il chiamante ripiega sulla strada successiva,\n * perché una ricerca che non risponde mai è peggio di una che risponde meno\n * bene. Il motivo tipico di un'attesa che scade è che al tag dello script manchi\n * `libraries=places` — l'SDK c'è, ma quella libreria no.\n */\nexport function attendiPlaces(): Promise<LibreriaPlaces> {\n return attendi(places, \"la libreria 'places' (manca `libraries=places` ?)\");\n}\n\n/**\n * Il `Geocoder`, aspettando l'SDK.\n *\n * **Non vuole `libraries=places`** : sta nell'SDK di base, ed è la ragione per\n * cui regge da ultima spiaggia anche dove Places non è disponibile.\n */\nexport function attendiGeocoder(): Promise<Geocoder> {\n return attendi(geocoder, \"il Geocoder\").then(\n (costruttore: new () => Geocoder) => new costruttore(),\n );\n}\n\n/** L'attesa vera, uguale per le due parti dell'SDK. */\nfunction attendi<T>(cerca: () => T | undefined, cosa: string): Promise<T> {\n const gia: T | undefined = cerca();\n if (gia) return Promise.resolve(gia);\n\n return new Promise<T>((risolvi: (trovato: T) => void, rifiuta) => {\n const scadenza: number = Date.now() + ATTESA.tetto_ms;\n const attesa: ReturnType<typeof setInterval> = setInterval(() => {\n const pronto: T | undefined = cerca();\n if (pronto) {\n clearInterval(attesa);\n risolvi(pronto);\n return;\n }\n if (Date.now() > scadenza) {\n clearInterval(attesa);\n rifiuta(new Error(`SDK Maps senza ${cosa}`));\n }\n }, ATTESA.passo_ms);\n });\n}\n","import { Injectable, inject } from \"@angular/core\";\nimport { HttpClient } from \"@angular/common/http\";\nimport { GeocodingLocation } from \"./model/geocoding-location.model\";\nimport { Observable, Subject, from, of, throwError } from \"rxjs\";\nimport { catchError, map, switchMap, tap } from \"rxjs/operators\";\nimport {\n NgxGeocodingBias,\n NgxGeocodingConfig,\n NgxGeocodingSource,\n} from \"./model/ngx-geocoding-config.model\";\nimport { NGX_GEOCODING_CONFIG } from \"./ngx-geocoding.config\";\nimport {\n CerchioSdk,\n Geocoder,\n LibreriaPlaces,\n LuogoNuovoSdk,\n LuogoSdk,\n PropostaSdk,\n RiquadroSdk,\n RisultatoGeocoder,\n STATO_PLACES,\n SuggerimentoSdk,\n attendiGeocoder,\n attendiPlaces,\n} from \"./google-maps-sdk\";\n\n/**\n * @author Vito Salvia - CNR IMAA geoSDI Group\n * @email vito.salvia@gmail.com\n */\n\n/** Il servizio pubblico di OpenStreetMap, quando non se ne dichiara un altro. */\nconst NOMINATIM: string = \"https://nominatim.openstreetmap.org/search.php\";\n\n/** Le sorgenti da provare quando l'applicazione non dice niente. */\nconst SOLO_NOMINATIM: NgxGeocodingSource[] = [\"nominatim\"];\n\n/** Quanti metri fa un grado di latitudine, per il riquadro del Geocoder. */\nconst METRI_PER_GRADO: number = 111_320;\n\n/**\n * La ricerca di indirizzi, da una o più sorgenti.\n *\n * **Senza configurazione fa quello che ha sempre fatto** : interroga Nominatim,\n * che non vuole nessuna chiave. Google si accende con\n * `provideNgxGeocoding({ sources: [\"google\", \"nominatim\"] })`, e vuole che\n * l'applicazione abbia in pagina l'**SDK Maps** con `libraries=places`.\n *\n * **Perché l'SDK e non una chiamata a Google**, che è la cosa da sapere prima\n * di «semplificare» questo codice : delle API di Google dal browser si può\n * chiamare la sola **Places (New)**, l'unica che esponga CORS, e quel prodotto\n * va abilitato a parte sul progetto Cloud — dove non lo è, una `fetch` prende\n * `403 SERVICE_DISABLED`. **Places legacy** e **Geocoding** CORS non ce l'hanno\n * affatto, ma l'SDK le raggiunge da sé : passando da lui la ricerca funziona\n * con le abilitazioni che il progetto ha già.\n *\n * Dentro `google` c'è quindi una **cascata**, ed è la stessa che si scriverebbe\n * lato server :\n *\n * 1. **`AutocompleteSuggestion`** (Places **New**), che è la strada\n * raccomandata da Google dal 1° marzo 2025 e l'unica offerta ai progetti\n * nuovi. Sotto sta un prodotto che va **abilitato a parte** sulla console\n * Cloud : dove non lo è risponde `403`, e si scende;\n * 2. **`AutocompleteService`** (Places legacy), che dà le stesse proposte\n * incrementali. Google la dà per deprecata — «non disponibile per i nuovi\n * clienti», con dodici mesi di preavviso prima di spegnerla — ma è quella\n * che risponde sui progetti dove la New non è stata abilitata;\n * 3. **`Geocoder`**, quando nemmeno Places risponde : nessuna proposta\n * incrementale, di norma un risultato solo, ma **porta già le coordinate** e\n * sta nell'SDK di base, quindi non dipende da `libraries=places`.\n *\n * I gradini si scendono da sé e non si risalgono nella stessa sessione. Il\n * primo è in cima **anche se oggi, su un progetto senza la New, fallisce\n * sempre** : costa una richiesta negata per sessione, e il giorno in cui quel\n * prodotto viene abilitato la ricerca si sposta sulla strada giusta senza che\n * nessuno tocchi il codice.\n *\n * **Le proposte di Places non portano le coordinate**, che si chiedono per il\n * solo luogo scelto : vedi {@link resolve}, ed è il motivo per cui esiste.\n */\n@Injectable({\n providedIn: \"root\",\n})\nexport class NgxGeocodingService {\n subjectLocation = new Subject<GeocodingLocation>();\n subjectNoResults = new Subject();\n subjectRemove = new Subject();\n private http: HttpClient = inject(HttpClient);\n private config: NgxGeocodingConfig | null = inject(NGX_GEOCODING_CONFIG, {\n optional: true,\n });\n\n /**\n * Una sorgente che ha detto di no non si richiama per il resto della\n * sessione : chiave senza il prodotto abilitato, referrer fuori dalle\n * restrizioni, quota. Senza questo sarebbe una richiesta negata a ogni\n * tasto premuto.\n */\n private spente: Set<NgxGeocodingSource> = new Set<NgxGeocodingSource>();\n\n /**\n * Dentro `google`, i gradini già scesi : `AutocompleteSuggestion` (Places\n * New) e `AutocompleteService` (Places legacy). Da lì in poi si parte\n * direttamente da dove si era arrivati.\n */\n private suggestionSpenta: boolean = false;\n private placesSpenta: boolean = false;\n\n /**\n * Le proposte per quello che si sta digitando, dalla prima sorgente che\n * risponde.\n *\n * @param address il testo digitato\n */\n geocode(address: string): Observable<GeocodingLocation[]> {\n return this.daSorgenti(address, this.sorgenti());\n }\n\n /**\n * Le coordinate del luogo **scelto**, chieste solo adesso.\n *\n * Le proposte di Places arrivano senza, e risolverle tutte a ogni tasto\n * premuto vorrebbe dire una richiesta di dettaglio per proposta. Chi le ha\n * già — Nominatim le manda sempre, e il `Geocoder` pure — non paga niente e\n * si riprende il luogo così com'è, quindi **chiamarla è sempre corretto** :\n * è la riga da mettere dove si sceglie una proposta, prima di usarne `lat`\n * e `lon`.\n *\n * Fallendo restituisce il luogo com'è, senza coordinate : chi ha chiamato\n * lo sa già gestire, ed è meglio che muovere una mappa a caso.\n *\n * @param place la proposta scelta fra quelle di {@link geocode}\n */\n resolve(place: GeocodingLocation): Observable<GeocodingLocation> {\n if (!place?.place_id || (place.lat && place.lon)) return of(place);\n if (this.spente.has(\"google\")) return of(place);\n if (!this.sorgenti().includes(\"google\")) return of(place);\n\n // Lo stesso ordine delle proposte : chi le ha date sa dare anche il\n // dettaglio, e chiedere il dettaglio a Places (New) quando le proposte\n // sono arrivate dalla legacy sarebbe una richiesta negata in più.\n if (!this.suggestionSpenta) {\n return this.luogoDaSuggestion(place).pipe(\n catchError((err: unknown) => {\n this.suggestionSpenta = true;\n console.warn(\n \"[ngx-geocoding] dettaglio da Places (New) non \" +\n `riuscito, si prova la legacy — ${this.perche(err)}`,\n );\n return this.luogoDaLegacy(place);\n }),\n );\n }\n if (this.placesSpenta) return of(place);\n return this.luogoDaLegacy(place);\n }\n\n /**\n * Le coordinate con **Places (New)** : `Place` nasce con l'id e\n * `fetchFields` lo **riempie**, quindi i campi si leggono dall'oggetto\n * dopo l'attesa e non dal valore restituito.\n */\n private luogoDaSuggestion(\n place: GeocodingLocation,\n ): Observable<GeocodingLocation> {\n return from(attendiPlaces()).pipe(\n switchMap((places: LibreriaPlaces) => {\n const Luogo = places.Place;\n if (!Luogo) {\n return throwError(\n () => new Error(\"Place non c'è in questo SDK\"),\n );\n }\n\n const luogo: LuogoNuovoSdk = new Luogo({\n id: place.place_id as string,\n });\n return from(\n luogo.fetchFields({\n fields: [\"location\", \"formattedAddress\"],\n }),\n ).pipe(\n map(() => ({\n ...place,\n display_name:\n place.display_name ?? luogo.formattedAddress ?? \"\",\n lat: this.testo(luogo.location?.lat()),\n lon: this.testo(luogo.location?.lng()),\n })),\n );\n }),\n );\n }\n\n /** Le coordinate con **Places legacy**, cioè `PlacesService.getDetails`. */\n private luogoDaLegacy(\n place: GeocodingLocation,\n ): Observable<GeocodingLocation> {\n return from(attendiPlaces()).pipe(\n switchMap(\n (places: LibreriaPlaces) =>\n new Observable<GeocodingLocation>((chi) => {\n new places.PlacesService(\n document.createElement(\"div\"),\n ).getDetails(\n {\n placeId: place.place_id as string,\n fields: [\"geometry\", \"formatted_address\"],\n },\n (luogo: LuogoSdk | null, stato: string) => {\n if (stato !== STATO_PLACES.ok || !luogo) {\n chi.error(new Error(stato));\n return;\n }\n const punto = luogo.geometry?.location;\n chi.next({\n ...place,\n display_name:\n place.display_name ??\n luogo.formatted_address ??\n \"\",\n lat: this.testo(punto?.lat()),\n lon: this.testo(punto?.lng()),\n });\n chi.complete();\n },\n );\n }),\n ),\n catchError((err: unknown) => {\n console.warn(\n \"[ngx-geocoding] coordinate del luogo non risolte — \" +\n this.perche(err),\n );\n return of(place);\n }),\n );\n }\n\n /**\n * Prova le sorgenti in ordine, passando alla successiva quando una rifiuta.\n *\n * Finite le sorgenti si rilancia un errore invece di restituire un elenco\n * vuoto : «non ho trovato niente» e «non ho potuto cercare» sono due cose\n * diverse, e chi mostra la barra deve poterle distinguere.\n */\n private daSorgenti(\n address: string,\n restanti: NgxGeocodingSource[],\n ): Observable<GeocodingLocation[]> {\n const sorgente: NgxGeocodingSource | undefined = restanti[0];\n if (!sorgente) {\n return throwError(\n () => new Error(\"Nessuna sorgente di geocoding disponibile\"),\n );\n }\n\n const dopo: NgxGeocodingSource[] = restanti.slice(1);\n if (this.spente.has(sorgente)) return this.daSorgenti(address, dopo);\n\n const richiesta: Observable<GeocodingLocation[]> =\n sorgente === \"google\"\n ? this.daGoogle(address)\n : this.daNominatim(address);\n\n return richiesta.pipe(\n tap((luoghi: GeocodingLocation[]) => {\n if (luoghi.length <= 0) {\n this.subjectNoResults.next(null);\n }\n }),\n catchError((err: unknown) => {\n this.spente.add(sorgente);\n console.warn(\n `[ngx-geocoding] sorgente \"${sorgente}\" non utilizzabile, ` +\n `non la si richiede più — ${this.perche(err)}`,\n );\n return this.daSorgenti(address, dopo);\n }),\n );\n }\n\n /**\n * Nominatim, **identico a come questa libreria l'ha sempre chiamato** : è\n * il comportamento su cui contano le applicazioni che la usavano prima che\n * Google esistesse qui dentro.\n */\n private daNominatim(address: string): Observable<GeocodingLocation[]> {\n const encoded = encodeURIComponent(address);\n const base: string = this.config?.nominatimUrl ?? NOMINATIM;\n return this.http\n .get<Location>(`${base}?q=${encoded}&format=jsonv2`)\n .pipe(\n map((res: any) =>\n res.map((item: any) => ({\n display_name: item.display_name,\n lat: item.lat,\n lon: item.lon,\n place_id: item.place_id,\n })),\n ),\n );\n }\n\n /**\n * Google : le proposte di Places, e il `Geocoder` quando Places dice di no.\n *\n * `ZERO_RESULTS` **non** è un rifiuto : è una ricerca senza esiti, e\n * confonderlo con un errore farebbe scivolare al `Geocoder` — e poi fuori\n * da Google — alla prima ricerca sfortunata.\n */\n private daGoogle(address: string): Observable<GeocodingLocation[]> {\n if (this.suggestionSpenta) return this.dallaLegacy(address);\n\n return this.daSuggestion(address).pipe(\n catchError((err: unknown) => {\n this.suggestionSpenta = true;\n console.warn(\n \"[ngx-geocoding] Places (New) non utilizzabile, si prova \" +\n `quella legacy — ${this.perche(err)}`,\n );\n return this.dallaLegacy(address);\n }),\n );\n }\n\n /** Il secondo e il terzo gradino : Places legacy, poi il `Geocoder`. */\n private dallaLegacy(address: string): Observable<GeocodingLocation[]> {\n if (this.placesSpenta) return this.daGeocoder(address);\n\n return this.daPlaces(address).pipe(\n catchError((err: unknown) => {\n this.placesSpenta = true;\n console.warn(\n \"[ngx-geocoding] Places legacy non utilizzabile, si prova \" +\n `il Geocoder — ${this.perche(err)}`,\n );\n return this.daGeocoder(address);\n }),\n );\n }\n\n /**\n * Le proposte di **Places (New)**, con `AutocompleteSuggestion`.\n *\n * Due cose che non si vedono dalla firma : `text` di una proposta non è una\n * stringa ma un oggetto formattabile, e va letto con `toString()` — messo\n * in un template darebbe `[object Object]` ; e un elenco **vuoto non è un\n * errore**, è una ricerca senza esiti, quindi non fa scendere di gradino.\n *\n * Se la classe non c'è nell'SDK — versione più vecchia — si solleva subito,\n * che è il modo di scendere senza aspettare una risposta che non arriverà.\n */\n private daSuggestion(address: string): Observable<GeocodingLocation[]> {\n const paese: string | undefined = this.config?.country;\n const cerchio: CerchioSdk | undefined = this.cerchio();\n\n return from(attendiPlaces()).pipe(\n switchMap((places: LibreriaPlaces) => {\n const nuova = places.AutocompleteSuggestion;\n if (!nuova) {\n return throwError(\n () =>\n new Error(\n \"AutocompleteSuggestion non c'è in questo SDK\",\n ),\n );\n }\n\n return from(\n nuova.fetchAutocompleteSuggestions({\n input: address,\n ...(paese\n ? { includedRegionCodes: [paese], region: paese }\n : {}),\n ...(cerchio ? { locationBias: cerchio } : {}),\n }),\n ).pipe(\n map((risposta: { suggestions?: SuggerimentoSdk[] }) =>\n (risposta?.suggestions ?? [])\n .map((s: SuggerimentoSdk) => s.placePrediction)\n .filter(\n (p): p is NonNullable<typeof p> => !!p?.placeId,\n )\n .map((p) => ({\n place_id: p.placeId,\n display_name: p.text?.toString() ?? \"\",\n })),\n ),\n );\n }),\n );\n }\n\n /** Le proposte incrementali di `AutocompleteService`. */\n private daPlaces(address: string): Observable<GeocodingLocation[]> {\n const paese: string | undefined = this.config?.country;\n const cerchio: CerchioSdk | undefined = this.cerchio();\n\n return from(attendiPlaces()).pipe(\n switchMap(\n (places: LibreriaPlaces) =>\n new Observable<GeocodingLocation[]>((chi) => {\n new places.AutocompleteService().getPlacePredictions(\n {\n input: address,\n ...(paese\n ? {\n componentRestrictions: {\n country: paese,\n },\n }\n : {}),\n ...(cerchio ? { locationBias: cerchio } : {}),\n },\n (proposte: PropostaSdk[] | null, stato: string) => {\n if (stato === STATO_PLACES.nessuno) {\n chi.next([]);\n chi.complete();\n return;\n }\n if (stato !== STATO_PLACES.ok) {\n chi.error(new Error(stato));\n return;\n }\n chi.next(\n (proposte ?? [])\n .filter(\n (p: PropostaSdk) => !!p.place_id,\n )\n .map((p: PropostaSdk) => ({\n place_id: p.place_id,\n display_name: p.description ?? \"\",\n })),\n );\n chi.complete();\n },\n );\n }),\n ),\n );\n }\n\n /**\n * Il `Geocoder`, l'ultima strada di Google.\n *\n * I suoi risultati **portano già le coordinate**, quindi su questi\n * {@link resolve} non fa nessuna richiesta in più.\n */\n private daGeocoder(address: string): Observable<GeocodingLocation[]> {\n const paese: string | undefined = this.config?.country;\n const riquadro: RiquadroSdk | undefined = this.riquadro();\n\n return from(attendiGeocoder()).pipe(\n switchMap(\n (geocoder: Geocoder) =>\n new Observable<GeocodingLocation[]>((chi) => {\n geocoder.geocode(\n {\n address,\n ...(paese\n ? {\n componentRestrictions: {\n country: paese,\n },\n region: paese,\n }\n : {}),\n ...(riquadro ? { bounds: riquadro } : {}),\n },\n (\n risultati: RisultatoGeocoder[] | null,\n stato: string,\n ) => {\n if (stato === STATO_PLACES.nessuno) {\n chi.next([]);\n chi.complete();\n return;\n }\n if (stato !== STATO_PLACES.ok) {\n chi.error(new Error(stato));\n return;\n }\n chi.next(\n (risultati ?? []).map(\n (r: RisultatoGeocoder) => ({\n place_id: r.place_id,\n display_name:\n r.formatted_address ?? \"\",\n lat: this.testo(\n r.geometry?.location?.lat(),\n ),\n lon: this.testo(\n r.geometry?.location?.lng(),\n ),\n }),\n ),\n );\n chi.complete();\n },\n );\n }),\n ),\n );\n }\n\n /** Il bias come lo vuole `AutocompleteService`. */\n private cerchio(): CerchioSdk | undefined {\n const bias: NgxGeocodingBias | undefined = this.config?.bias;\n return bias\n ? {\n center: { lat: bias.lat, lng: bias.lon },\n radius: bias.radiusM,\n }\n : undefined;\n }\n\n /**\n * Il bias come lo vuole il `Geocoder`, che prende un **riquadro** e non un\n * cerchio : lo si iscrive attorno al punto. La longitudine si stringe con\n * la latitudine (`cos`), o alle nostre latitudini il riquadro verrebbe\n * largo un terzo in più del voluto.\n */\n private riquadro(): RiquadroSdk | undefined {\n const bias: NgxGeocodingBias | undefined = this.config?.bias;\n if (!bias) return undefined;\n\n const dLat: number = bias.radiusM / METRI_PER_GRADO;\n const dLon: number =\n dLat / Math.max(Math.cos((bias.lat * Math.PI) / 180), 0.01);\n return {\n north: bias.lat + dLat,\n south: bias.lat - dLat,\n east: bias.lon + dLon,\n west: bias.lon - dLon,\n };\n }\n\n /** Le sorgenti dichiarate, o quella storica. */\n private sorgenti(): NgxGeocodingSource[] {\n const dichiarate: NgxGeocodingSource[] = this.config?.sources ?? [];\n return dichiarate.length ? dichiarate : SOLO_NOMINATIM;\n }\n\n /**\n * Perché una strada ha detto di no, in una riga : dall'SDK arriva uno stato\n * (`REQUEST_DENIED` per la chiave senza il prodotto abilitato o per il\n * referrer, `OVER_QUERY_LIMIT` per la quota), da una http il corpo\n * d'errore. Senza questo il motivo resta dentro un oggetto che in console\n * va aperto, e si legge solo «si ripiega».\n */\n private perche(err: unknown): string {\n if (err instanceof Error && err.message) return err.message;\n\n const dettaglio: { status?: string; message?: string } | undefined = (\n (err as { error?: unknown })?.error as {\n error?: { status?: string; message?: string };\n }\n )?.error;\n if (!dettaglio) return \"motivo non dichiarato\";\n\n return [dettaglio.status, dettaglio.message]\n .filter((pezzo: string | undefined) => !!pezzo)\n .join(\" : \");\n }\n\n /**\n * Una coordinata come stringa, o `undefined` se non c'è.\n *\n * `String(undefined)` darebbe `\"undefined\"`, che passerebbe indenne per\n * ogni controllo di presenza e morirebbe in `Number()` — cioè una mappa\n * portata su `NaN, NaN` senza che niente lo dica.\n */\n private testo(valore: number | null | undefined): string | undefined {\n return valore === null || valore === undefined\n ? undefined\n : String(valore);\n }\n}","/**\n * @author Vito Salvia - CNR IMAA geoSDI Group\n * @email vito.salvia@gmail.com\n */\n\n/**\n * Da dove arrivano le proposte di indirizzo.\n *\n * - `google` : l'**SDK Maps JS**, che l'applicazione deve caricare con\n * `libraries=places`. Non vuole nessuna chiave qui : ce l'ha il tag dello\n * script. Dentro è **una cascata** — le proposte di Places e, quando Places\n * è negata, il `Geocoder` — perché è quello che il browser può raggiungere;\n * - `nominatim` : il servizio pubblico di OpenStreetMap, che non vuole nessuna\n * chiave. È il comportamento storico di questa libreria.\n */\nexport type NgxGeocodingSource = \"google\" | \"nominatim\";\n\n/**\n * Il punto su cui polarizzare le proposte, e con che raggio.\n *\n * È un **bias, non un filtro** : un indirizzo fuori area resta raggiungibile,\n * ma «via Roma» propone prima quella vicina. Senza, Google ordina come crede,\n * e su un nome di via comune la prima proposta è quasi sempre altrove.\n */\nexport interface NgxGeocodingBias {\n lat: number;\n lon: number;\n /** Raggio in metri. */\n radiusM: number;\n}\n\n/**\n * Come questa libreria cerca gli indirizzi.\n *\n * **Non fornirla lascia tutto com'era** : una sola sorgente, Nominatim, che è\n * quello che la libreria ha sempre fatto. Google si accende dichiarandolo in\n * {@link sources}.\n */\nexport interface NgxGeocodingConfig {\n /**\n * Le sorgenti da provare, **in ordine**. La prima che risponde vince, e\n * quella che rifiuta passa la mano alla successiva.\n *\n * Una sorgente che non è utilizzabile viene **saltata**, e non è un errore :\n * `google` senza l'SDK in pagina. È il modo in cui la stessa configurazione\n * vale per il deploy che ha la chiave e per quello che non ce l'ha.\n *\n * Default : `[\"nominatim\"]`.\n */\n sources?: NgxGeocodingSource[];\n\n /**\n * Paese a cui limitare le proposte, in due lettere (`\"it\"`). Vale per\n * `google` — Nominatim qui non è filtrato, per non cambiare quello che la\n * libreria ha sempre restituito.\n */\n country?: string;\n\n /** Dove polarizzare le proposte di `google`. Vedi {@link NgxGeocodingBias}. */\n bias?: NgxGeocodingBias;\n\n /** Il servizio Nominatim, se non quello pubblico di OpenStreetMap. */\n nominatimUrl?: string;\n}","/*\n * Public API Surface of ngx-geocoding\n */\n\nexport * from \"./lib/ngx-geocoding.module\";\nexport * from \"./lib/ngx-geocoding.service\";\nexport * from \"./lib/ngx-geocoding.config\";\nexport * from \"./lib/model/geocoding-location.model\";\nexport * from \"./lib/model/ngx-geocoding-config.model\";\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geosdi/ngx-geocoding",
3
- "version": "1.1.4",
3
+ "version": "1.2.1",
4
4
  "description": "Component to get a list of place with a geocoding service",
5
5
  "author": "Salvia Vito (vito.salvia@gmail.com)",
6
6
  "keywords": [
@@ -19,16 +19,17 @@
19
19
  },
20
20
  "sideEffects": false,
21
21
  "module": "fesm2022/geosdi-ngx-geocoding.mjs",
22
- "typings": "index.d.ts",
22
+ "typings": "types/geosdi-ngx-geocoding.d.ts",
23
23
  "exports": {
24
24
  "./package.json": {
25
25
  "default": "./package.json"
26
26
  },
27
27
  ".": {
28
- "types": "./index.d.ts",
28
+ "types": "./types/geosdi-ngx-geocoding.d.ts",
29
29
  "default": "./fesm2022/geosdi-ngx-geocoding.mjs"
30
30
  }
31
31
  },
32
+ "type": "module",
32
33
  "dependencies": {
33
34
  "tslib": "^2.3.0"
34
35
  }
@@ -0,0 +1,281 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, Provider } from '@angular/core';
3
+ import { Subject, Observable } from 'rxjs';
4
+
5
+ /**
6
+ * @author Vito Salvia - CNR IMAA geoSDI Group
7
+ * @email vito.salvia@gmail.com
8
+ */
9
+ declare class NgxGeocodingModule {
10
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxGeocodingModule, never>;
11
+ static ɵmod: i0.ɵɵNgModuleDeclaration<NgxGeocodingModule, never, never, never>;
12
+ static ɵinj: i0.ɵɵInjectorDeclaration<NgxGeocodingModule>;
13
+ }
14
+
15
+ /**
16
+ * @author Vito Salvia - CNR IMAA geoSDI Group
17
+ * @email vito.salvia@gmail.com
18
+ */
19
+ interface GeocodingLocation {
20
+ display_name?: string;
21
+ lat?: string;
22
+ lon?: string;
23
+ place_id?: string;
24
+ }
25
+
26
+ /**
27
+ * La ricerca di indirizzi, da una o più sorgenti.
28
+ *
29
+ * **Senza configurazione fa quello che ha sempre fatto** : interroga Nominatim,
30
+ * che non vuole nessuna chiave. Google si accende con
31
+ * `provideNgxGeocoding({ sources: ["google", "nominatim"] })`, e vuole che
32
+ * l'applicazione abbia in pagina l'**SDK Maps** con `libraries=places`.
33
+ *
34
+ * **Perché l'SDK e non una chiamata a Google**, che è la cosa da sapere prima
35
+ * di «semplificare» questo codice : delle API di Google dal browser si può
36
+ * chiamare la sola **Places (New)**, l'unica che esponga CORS, e quel prodotto
37
+ * va abilitato a parte sul progetto Cloud — dove non lo è, una `fetch` prende
38
+ * `403 SERVICE_DISABLED`. **Places legacy** e **Geocoding** CORS non ce l'hanno
39
+ * affatto, ma l'SDK le raggiunge da sé : passando da lui la ricerca funziona
40
+ * con le abilitazioni che il progetto ha già.
41
+ *
42
+ * Dentro `google` c'è quindi una **cascata**, ed è la stessa che si scriverebbe
43
+ * lato server :
44
+ *
45
+ * 1. **`AutocompleteSuggestion`** (Places **New**), che è la strada
46
+ * raccomandata da Google dal 1° marzo 2025 e l'unica offerta ai progetti
47
+ * nuovi. Sotto sta un prodotto che va **abilitato a parte** sulla console
48
+ * Cloud : dove non lo è risponde `403`, e si scende;
49
+ * 2. **`AutocompleteService`** (Places legacy), che dà le stesse proposte
50
+ * incrementali. Google la dà per deprecata — «non disponibile per i nuovi
51
+ * clienti», con dodici mesi di preavviso prima di spegnerla — ma è quella
52
+ * che risponde sui progetti dove la New non è stata abilitata;
53
+ * 3. **`Geocoder`**, quando nemmeno Places risponde : nessuna proposta
54
+ * incrementale, di norma un risultato solo, ma **porta già le coordinate** e
55
+ * sta nell'SDK di base, quindi non dipende da `libraries=places`.
56
+ *
57
+ * I gradini si scendono da sé e non si risalgono nella stessa sessione. Il
58
+ * primo è in cima **anche se oggi, su un progetto senza la New, fallisce
59
+ * sempre** : costa una richiesta negata per sessione, e il giorno in cui quel
60
+ * prodotto viene abilitato la ricerca si sposta sulla strada giusta senza che
61
+ * nessuno tocchi il codice.
62
+ *
63
+ * **Le proposte di Places non portano le coordinate**, che si chiedono per il
64
+ * solo luogo scelto : vedi {@link resolve}, ed è il motivo per cui esiste.
65
+ */
66
+ declare class NgxGeocodingService {
67
+ subjectLocation: Subject<GeocodingLocation>;
68
+ subjectNoResults: Subject<unknown>;
69
+ subjectRemove: Subject<unknown>;
70
+ private http;
71
+ private config;
72
+ /**
73
+ * Una sorgente che ha detto di no non si richiama per il resto della
74
+ * sessione : chiave senza il prodotto abilitato, referrer fuori dalle
75
+ * restrizioni, quota. Senza questo sarebbe una richiesta negata a ogni
76
+ * tasto premuto.
77
+ */
78
+ private spente;
79
+ /**
80
+ * Dentro `google`, i gradini già scesi : `AutocompleteSuggestion` (Places
81
+ * New) e `AutocompleteService` (Places legacy). Da lì in poi si parte
82
+ * direttamente da dove si era arrivati.
83
+ */
84
+ private suggestionSpenta;
85
+ private placesSpenta;
86
+ /**
87
+ * Le proposte per quello che si sta digitando, dalla prima sorgente che
88
+ * risponde.
89
+ *
90
+ * @param address il testo digitato
91
+ */
92
+ geocode(address: string): Observable<GeocodingLocation[]>;
93
+ /**
94
+ * Le coordinate del luogo **scelto**, chieste solo adesso.
95
+ *
96
+ * Le proposte di Places arrivano senza, e risolverle tutte a ogni tasto
97
+ * premuto vorrebbe dire una richiesta di dettaglio per proposta. Chi le ha
98
+ * già — Nominatim le manda sempre, e il `Geocoder` pure — non paga niente e
99
+ * si riprende il luogo così com'è, quindi **chiamarla è sempre corretto** :
100
+ * è la riga da mettere dove si sceglie una proposta, prima di usarne `lat`
101
+ * e `lon`.
102
+ *
103
+ * Fallendo restituisce il luogo com'è, senza coordinate : chi ha chiamato
104
+ * lo sa già gestire, ed è meglio che muovere una mappa a caso.
105
+ *
106
+ * @param place la proposta scelta fra quelle di {@link geocode}
107
+ */
108
+ resolve(place: GeocodingLocation): Observable<GeocodingLocation>;
109
+ /**
110
+ * Le coordinate con **Places (New)** : `Place` nasce con l'id e
111
+ * `fetchFields` lo **riempie**, quindi i campi si leggono dall'oggetto
112
+ * dopo l'attesa e non dal valore restituito.
113
+ */
114
+ private luogoDaSuggestion;
115
+ /** Le coordinate con **Places legacy**, cioè `PlacesService.getDetails`. */
116
+ private luogoDaLegacy;
117
+ /**
118
+ * Prova le sorgenti in ordine, passando alla successiva quando una rifiuta.
119
+ *
120
+ * Finite le sorgenti si rilancia un errore invece di restituire un elenco
121
+ * vuoto : «non ho trovato niente» e «non ho potuto cercare» sono due cose
122
+ * diverse, e chi mostra la barra deve poterle distinguere.
123
+ */
124
+ private daSorgenti;
125
+ /**
126
+ * Nominatim, **identico a come questa libreria l'ha sempre chiamato** : è
127
+ * il comportamento su cui contano le applicazioni che la usavano prima che
128
+ * Google esistesse qui dentro.
129
+ */
130
+ private daNominatim;
131
+ /**
132
+ * Google : le proposte di Places, e il `Geocoder` quando Places dice di no.
133
+ *
134
+ * `ZERO_RESULTS` **non** è un rifiuto : è una ricerca senza esiti, e
135
+ * confonderlo con un errore farebbe scivolare al `Geocoder` — e poi fuori
136
+ * da Google — alla prima ricerca sfortunata.
137
+ */
138
+ private daGoogle;
139
+ /** Il secondo e il terzo gradino : Places legacy, poi il `Geocoder`. */
140
+ private dallaLegacy;
141
+ /**
142
+ * Le proposte di **Places (New)**, con `AutocompleteSuggestion`.
143
+ *
144
+ * Due cose che non si vedono dalla firma : `text` di una proposta non è una
145
+ * stringa ma un oggetto formattabile, e va letto con `toString()` — messo
146
+ * in un template darebbe `[object Object]` ; e un elenco **vuoto non è un
147
+ * errore**, è una ricerca senza esiti, quindi non fa scendere di gradino.
148
+ *
149
+ * Se la classe non c'è nell'SDK — versione più vecchia — si solleva subito,
150
+ * che è il modo di scendere senza aspettare una risposta che non arriverà.
151
+ */
152
+ private daSuggestion;
153
+ /** Le proposte incrementali di `AutocompleteService`. */
154
+ private daPlaces;
155
+ /**
156
+ * Il `Geocoder`, l'ultima strada di Google.
157
+ *
158
+ * I suoi risultati **portano già le coordinate**, quindi su questi
159
+ * {@link resolve} non fa nessuna richiesta in più.
160
+ */
161
+ private daGeocoder;
162
+ /** Il bias come lo vuole `AutocompleteService`. */
163
+ private cerchio;
164
+ /**
165
+ * Il bias come lo vuole il `Geocoder`, che prende un **riquadro** e non un
166
+ * cerchio : lo si iscrive attorno al punto. La longitudine si stringe con
167
+ * la latitudine (`cos`), o alle nostre latitudini il riquadro verrebbe
168
+ * largo un terzo in più del voluto.
169
+ */
170
+ private riquadro;
171
+ /** Le sorgenti dichiarate, o quella storica. */
172
+ private sorgenti;
173
+ /**
174
+ * Perché una strada ha detto di no, in una riga : dall'SDK arriva uno stato
175
+ * (`REQUEST_DENIED` per la chiave senza il prodotto abilitato o per il
176
+ * referrer, `OVER_QUERY_LIMIT` per la quota), da una http il corpo
177
+ * d'errore. Senza questo il motivo resta dentro un oggetto che in console
178
+ * va aperto, e si legge solo «si ripiega».
179
+ */
180
+ private perche;
181
+ /**
182
+ * Una coordinata come stringa, o `undefined` se non c'è.
183
+ *
184
+ * `String(undefined)` darebbe `"undefined"`, che passerebbe indenne per
185
+ * ogni controllo di presenza e morirebbe in `Number()` — cioè una mappa
186
+ * portata su `NaN, NaN` senza che niente lo dica.
187
+ */
188
+ private testo;
189
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxGeocodingService, never>;
190
+ static ɵprov: i0.ɵɵInjectableDeclaration<NgxGeocodingService>;
191
+ }
192
+
193
+ /**
194
+ * @author Vito Salvia - CNR IMAA geoSDI Group
195
+ * @email vito.salvia@gmail.com
196
+ */
197
+ /**
198
+ * Da dove arrivano le proposte di indirizzo.
199
+ *
200
+ * - `google` : l'**SDK Maps JS**, che l'applicazione deve caricare con
201
+ * `libraries=places`. Non vuole nessuna chiave qui : ce l'ha il tag dello
202
+ * script. Dentro è **una cascata** — le proposte di Places e, quando Places
203
+ * è negata, il `Geocoder` — perché è quello che il browser può raggiungere;
204
+ * - `nominatim` : il servizio pubblico di OpenStreetMap, che non vuole nessuna
205
+ * chiave. È il comportamento storico di questa libreria.
206
+ */
207
+ type NgxGeocodingSource = "google" | "nominatim";
208
+ /**
209
+ * Il punto su cui polarizzare le proposte, e con che raggio.
210
+ *
211
+ * È un **bias, non un filtro** : un indirizzo fuori area resta raggiungibile,
212
+ * ma «via Roma» propone prima quella vicina. Senza, Google ordina come crede,
213
+ * e su un nome di via comune la prima proposta è quasi sempre altrove.
214
+ */
215
+ interface NgxGeocodingBias {
216
+ lat: number;
217
+ lon: number;
218
+ /** Raggio in metri. */
219
+ radiusM: number;
220
+ }
221
+ /**
222
+ * Come questa libreria cerca gli indirizzi.
223
+ *
224
+ * **Non fornirla lascia tutto com'era** : una sola sorgente, Nominatim, che è
225
+ * quello che la libreria ha sempre fatto. Google si accende dichiarandolo in
226
+ * {@link sources}.
227
+ */
228
+ interface NgxGeocodingConfig {
229
+ /**
230
+ * Le sorgenti da provare, **in ordine**. La prima che risponde vince, e
231
+ * quella che rifiuta passa la mano alla successiva.
232
+ *
233
+ * Una sorgente che non è utilizzabile viene **saltata**, e non è un errore :
234
+ * `google` senza l'SDK in pagina. È il modo in cui la stessa configurazione
235
+ * vale per il deploy che ha la chiave e per quello che non ce l'ha.
236
+ *
237
+ * Default : `["nominatim"]`.
238
+ */
239
+ sources?: NgxGeocodingSource[];
240
+ /**
241
+ * Paese a cui limitare le proposte, in due lettere (`"it"`). Vale per
242
+ * `google` — Nominatim qui non è filtrato, per non cambiare quello che la
243
+ * libreria ha sempre restituito.
244
+ */
245
+ country?: string;
246
+ /** Dove polarizzare le proposte di `google`. Vedi {@link NgxGeocodingBias}. */
247
+ bias?: NgxGeocodingBias;
248
+ /** Il servizio Nominatim, se non quello pubblico di OpenStreetMap. */
249
+ nominatimUrl?: string;
250
+ }
251
+
252
+ /**
253
+ * @author Vito Salvia - CNR IMAA geoSDI Group
254
+ * @email vito.salvia@gmail.com
255
+ */
256
+ /**
257
+ * La configurazione della ricerca, che **può non esserci** : in quel caso vale
258
+ * il comportamento storico, cioè Nominatim e basta.
259
+ */
260
+ declare const NGX_GEOCODING_CONFIG: InjectionToken<NgxGeocodingConfig>;
261
+ /**
262
+ * Dichiara da dove arrivano gli indirizzi, nei `providers` dell'applicazione :
263
+ *
264
+ * ```ts
265
+ * provideNgxGeocoding({
266
+ * sources: ["google", "nominatim"],
267
+ * country: "it",
268
+ * bias: { lat: 40.83, lon: 14.11, radiusM: 25_000 },
269
+ * })
270
+ * ```
271
+ *
272
+ * L'ordine è quello in cui le sorgenti si provano, e una che non è utilizzabile
273
+ * si salta : la stessa riga vale quindi per il deploy che ha la chiave Google e
274
+ * per quello che non ce l'ha.
275
+ *
276
+ * Chi non la chiama non cambia niente.
277
+ */
278
+ declare function provideNgxGeocoding(config: NgxGeocodingConfig): Provider;
279
+
280
+ export { NGX_GEOCODING_CONFIG, NgxGeocodingModule, NgxGeocodingService, provideNgxGeocoding };
281
+ export type { GeocodingLocation, NgxGeocodingBias, NgxGeocodingConfig, NgxGeocodingSource };
package/index.d.ts DELETED
@@ -1,44 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { Subject, Observable } from 'rxjs';
3
-
4
- /**
5
- * @author Vito Salvia - CNR IMAA geoSDI Group
6
- * @email vito.salvia@gmail.com
7
- */
8
- declare class NgxGeocodingModule {
9
- static ɵfac: i0.ɵɵFactoryDeclaration<NgxGeocodingModule, never>;
10
- static ɵmod: i0.ɵɵNgModuleDeclaration<NgxGeocodingModule, never, never, never>;
11
- static ɵinj: i0.ɵɵInjectorDeclaration<NgxGeocodingModule>;
12
- }
13
-
14
- /**
15
- * @author Vito Salvia - CNR IMAA geoSDI Group
16
- * @email vito.salvia@gmail.com
17
- */
18
- interface GeocodingLocation {
19
- display_name?: string;
20
- lat?: string;
21
- lon?: string;
22
- place_id?: string;
23
- }
24
-
25
- /**
26
- * @author Vito Salvia - CNR IMAA geoSDI Group
27
- * @email vito.salvia@gmail.com
28
- */
29
- declare class NgxGeocodingService {
30
- subjectLocation: Subject<GeocodingLocation>;
31
- subjectNoResults: Subject<unknown>;
32
- subjectRemove: Subject<unknown>;
33
- private http;
34
- /**
35
- *
36
- * @param address
37
- */
38
- geocode(address: string): Observable<GeocodingLocation[]>;
39
- static ɵfac: i0.ɵɵFactoryDeclaration<NgxGeocodingService, never>;
40
- static ɵprov: i0.ɵɵInjectableDeclaration<NgxGeocodingService>;
41
- }
42
-
43
- export { NgxGeocodingModule, NgxGeocodingService };
44
- export type { GeocodingLocation };