Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ The plugin supports many different data providers:
- [ArcGIS](https://developers.arcgis.com/features/geocoding/)
- [Azure Maps Geocoding](https://www.microsoft.com/en-us/maps/azure/location-services/geocoding)

Multiple data providers can be combined by using the AggregatingGeocoder.

Comment on lines +30 to +31
The plugin can easily be extended to support other providers. Current extensions:

- [DAWA Geocoder](https://github.com/kjoller/leaflet-control-geocoder-dawa/tree/new) - support for Danish Address Web API by [Niels Kjøller Hansen](https://github.com/kjoller)
Expand Down
39 changes: 39 additions & 0 deletions spec/aggregating-geocoder.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { describe, expect, it, vi } from 'vitest';
import { AggregatingGeocoder, AgregatorOptions } from '../src/geocoders/aggregating-geocoder';
import { LatLngLiteral } from 'leaflet';

describe('L.Control.Geocoder.AggregatingGeocoder', () => {
it('geocde returns empty when no geocoders', async () => {
const options: AgregatorOptions = {
geocoders: []
}
const geocoder = new AggregatingGeocoder(options);

const results = await geocoder.geocode('foo');
expect(results).toEqual([]);
});

it('suggest returns empty when no geocoders', async () => {
const options: AgregatorOptions = {
geocoders: []
}
const geocoder = new AggregatingGeocoder(options);

const results = await geocoder.suggest('foo');
expect(results).toEqual([]);
});

it('reverse returns emtpy when no geocoders', async () => {
const options: AgregatorOptions = {
geocoders: []
}
const geocoder = new AggregatingGeocoder(options);

const loc: LatLngLiteral = {
lat: 0,
lng: 0
};
const results = await geocoder.reverse(loc, 1);
expect(results).toEqual([]);
});
});
Comment on lines +16 to +39
65 changes: 65 additions & 0 deletions src/geocoders/aggregating-geocoder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import * as L from 'leaflet';
import { LatLngLiteral } from 'leaflet';
import { IGeocoder, GeocodingContext, GeocodingResult } from './api';

export interface AgregatorOptions {
geocoders: IGeocoder[];
}
Comment on lines +5 to +7

/**
* Implementation of a geocoder that takes other geocoders and aggregates their results together.
**/
export class AggregatingGeocoder implements IGeocoder {
options: AgregatorOptions = {
geocoders: []
}

constructor(options?: Partial<AgregatorOptions>) {
L.Util.setOptions(this, options)
}
Comment on lines +13 to +19

private async combineResults(queries: Array<Promise<GeocodingResult[]>>): Promise<GeocodingResult[]> {
const queryResults: Array<GeocodingResult[]> = await Promise.all(queries);
const results: Array<GeocodingResult> = [];
for(const r of queryResults) {
results.push(...r);
}
return results;
}
Comment on lines +21 to +28

geocode(query: string, context?: GeocodingContext): Promise<GeocodingResult[]> {
const queries: Promise<GeocodingResult[]>[] = [];
for(const geocoder of this.options.geocoders) {
queries.push(geocoder.geocode(query, context));
}
return this.combineResults(queries);
}

suggest?(query: string, context?: GeocodingContext): Promise<GeocodingResult[]> {
const queries: Promise<GeocodingResult[]>[] = [];
for(const geocoder of this.options.geocoders) {
if (geocoder.suggest) {
queries.push(geocoder.suggest(query, context));
}
}
return this.combineResults(queries);
}

reverse?(location: LatLngLiteral, scale: number): Promise<GeocodingResult[]> {
const queries: Promise<GeocodingResult[]>[] = [];
for(const geocoder of this.options.geocoders) {
if (geocoder.reverse) {
queries.push(geocoder.reverse(location, scale));
}
}
return this.combineResults(queries);
}
Comment on lines +38 to +56
}

/**
* [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link AggregatingGeocoder}
* @param options the services to aggregate together.
*/
export function aggregatingGeocoder(options: Partial<AgregatorOptions>) {
return new AggregatingGeocoder(options);
}
Comment on lines +63 to +65
1 change: 1 addition & 0 deletions src/geocoders/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from './opencage';
export * from './pelias';
export * from './photon';
export * from './what3words';
export * from './aggregating-geocoder';