Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Geoapify Provider #361

Merged
merged 2 commits into from
Apr 18, 2023
Merged
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
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ GOOGLE_API_KEY=___YOUR_KEY___
LOCATIONIQ_API_KEY=___YOUR_KEY___
OPENCAGE_API_KEY=___YOUR_KEY___
HERE_API_KEY=___YOUR_KEY___
GEOAPIFY_API_KEY=___YOUR_KEY___
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Leaflet.GeoSearch

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

[![All Contributors](https://img.shields.io/badge/all_contributors-53-orange.svg?style=flat-square)](#contributors-)

<!-- ALL-CONTRIBUTORS-BADGE:END -->

**Demo and Docs: [smeijer.github.io/leaflet-geosearch](https://smeijer.github.io/leaflet-geosearch)**
Expand Down Expand Up @@ -58,6 +60,7 @@ The control comes with a number of default providers:
- [Pelias]
- [Mapbox](https://docs.mapbox.com/help/tutorials/local-search-geocoding-api/)
- [GeoApiFR](https://geo.api.gouv.fr/adresse)
- [Geoapify](https://apidocs.geoapify.com/docs/geocoding/forward-geocoding/#about)

Although this project is still named `leaflet-geosearch`, this library is also
usable without LeafletJS, and does not have any dependencies whatsoever.
Expand Down Expand Up @@ -424,10 +427,11 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center"><a href="https://paulschreiber.com/"><img src="https://avatars.githubusercontent.com/u/86784?v=4?s=100" width="100px;" alt="Paul Schreiber"/><br /><sub><b>Paul Schreiber</b></sub></a><br /><a href="https://github.com/smeijer/leaflet-geosearch/commits?author=paulschreiber" title="Code">💻</a></td>
<td align="center"><a href="https://nsilvestri.me/"><img src="https://avatars.githubusercontent.com/u/33607815?v=4?s=100" width="100px;" alt="Nick Silvestri"/><br /><sub><b>Nick Silvestri</b></sub></a><br /><a href="#ideas-nsilvestri" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/smeijer/leaflet-geosearch/commits?author=nsilvestri" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/teriblus"><img src="https://avatars.githubusercontent.com/u/17048774?v=4?s=100" width="100px;" alt="teriblus"/><br /><sub><b>teriblus</b></sub></a><br /><a href="https://github.com/smeijer/leaflet-geosearch/commits?author=teriblus" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/CarolineVantim"><img src="https://avatars.githubusercontent.com/u/82098788?s=400&u=b20b0acc98f9bdb694e20c56d6c157b3198b7c62&v=4" width="100px;" alt="Caroline Vantim"/><br /><sub><b>Caroline Vantim</b></sub></a><br /><a href="https://github.com/smeijer/leaflet-geosearch/commits?author=CarolineVantim" title="Code">💻</a></td>
</tr>
</tbody>
<tfoot>

</tfoot>
</table>

Expand Down
5 changes: 5 additions & 0 deletions docs/lib/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
OpenStreetMapProvider,
PeliasProvider,
GeoApiFrProvider,
GeoapifyProvider,
} from 'leaflet-geosearch';

export default {
Expand Down Expand Up @@ -44,6 +45,10 @@ export default {
params: { key: process.env.GATSBY_OPENCAGE_API_KEY },
}),

Geoapify: new GeoapifyProvider({
params: { apiKey: process.env.GATSBY_GEOAPIFY_API_KEY },
}),

OpenStreetMap: new OpenStreetMapProvider(),

Pelias: new PeliasProvider(),
Expand Down
40 changes: 40 additions & 0 deletions docs/providers/geoapify.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: Geoapify
menu: Providers
route: /providers/geoapify
---

import Playground from '../components/Playground';
import Map from '../components/Map';

# Geoapify Provider

**note**: Geoapify services require an API key. [Obtain geoapify][1].
For more options and configurations, see the [Geoapify developer docs][2].

<Playground>
<Map provider="Geoapify" />
</Playground>

```js
import { GeoapifyProvider } from 'leaflet-geosearch';

const provider = new GeoapifyProvider({
params: {
apiKey: '__YOUR_HERE_KEY__',
},
});

// add to leaflet
import { GeoSearchControl } from 'leaflet-geosearch';

map.addControl(
new GeoSearchControl({
provider,
style: 'bar',
}),
);
```

[1]: https://apidocs.geoapify.com/
[2]: https://apidocs.geoapify.com/docs/geocoding/forward-geocoding/#geocode-addresses
1 change: 1 addition & 0 deletions doczrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default {
'OpenStreetMap',
'Pelias',
'Custom Providers',
'Geoapify',
],
},
],
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export { default as OpenStreetMapProvider } from './providers/openStreetMapProvi
export { default as PeliasProvider } from './providers/peliasProvider';
export { default as MapBoxProvider } from './providers/mapBoxProvider';
export { default as GeoApiFrProvider } from './providers/geoApiFrProvider';
export { default as GeoapifyProvider } from './providers/geoapifyProvider';

export { default as JsonProvider } from './providers/provider';
39 changes: 39 additions & 0 deletions src/providers/__tests__/geoapifyProvider.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Provider from '../geoapifyProvider';
import fixtures from './geoapifyResponse.json';

describe('Geoapify', () => {
beforeAll(() => {
fetch.mockResponse(async () => ({ body: JSON.stringify(fixtures) }));
});

test('Can fetch results', async () => {
const provider = new Provider({
params: {
apiKey: process.env.GEOAPIFY_API_KEY,
},
});

const results = await provider.search({ query: 'Chicago' });
const result = results[0];

expect(result.label).toBeTruthy();
expect(result.x).toEqual(+fixtures.results[0].lon);
expect(result.y).toEqual(+fixtures.results[0].lat);
expect(result.bounds).toBeValidBounds();
});

test.skip('Can get localized results', async () => {
const provider = new Provider({
params: {
apiKey: process.env.GEOAPIFY_API_KEY,
'accept-language': 'nl',
},
});

const results = await provider.search({ query: 'Chicago' });
t.is(
results[0].label,
'1214-1224 West Van Buren Street, Chicago, IL 60607, United States of America',
);
});
});
65 changes: 65 additions & 0 deletions src/providers/__tests__/geoapifyResponse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"results": [
{
"datasource": {
"sourcename": "openstreetmap",
"attribution": "© OpenStreetMap contributors",
"license": "Open Database License",
"url": "https://www.openstreetmap.org/copyright"
},
"country": "United States",
"country_code": "us",
"state": "Illinois",
"county": "Cook County",
"city": "Chicago",
"postcode": "60607",
"suburb": "Near West Side",
"street": "West Van Buren Street",
"housenumber": "1214-1224",
"lon": -87.65816734222005,
"lat": 41.87695205,
"state_code": "IL",
"formatted": "1214-1224 West Van Buren Street, Chicago, IL 60607, United States of America",
"address_line1": "1214-1224 West Van Buren Street",
"address_line2": "Chicago, IL 60607, United States of America",
"category": "building",
"timezone": {
"name": "America/Chicago",
"offset_STD": "-06:00",
"offset_STD_seconds": -21600,
"offset_DST": "-05:00",
"offset_DST_seconds": -18000,
"abbreviation_STD": "CST",
"abbreviation_DST": "CDT"
},
"result_type": "building",
"rank": {
"importance": 0.60001,
"popularity": 6.686411370288237,
"confidence": 1,
"confidence_city_level": 1,
"confidence_street_level": 1,
"match_type": "full_match"
},
"place_id": "515888ea691fea55c0598074fbf63ff04440f00102f9013076880c00000000c00203",
"bbox": {
"lon1": -87.658723,
"lat1": 41.8765924,
"lon2": -87.6576007,
"lat2": 41.8770888
}
}
],
"query": {
"text": "1214-1224 West Van Buren Street, Chicago, IL 60607, United States of America",
"parsed": {
"housenumber": "1214-1224",
"street": "west van buren street",
"postcode": "60607",
"city": "chicago",
"state": "il",
"country": "united states of america",
"expected_type": "building"
}
}
}
95 changes: 95 additions & 0 deletions src/providers/geoapifyProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import AbstractProvider, {
EndpointArgument,
ParseArgument,
ProviderOptions,
RequestType,
SearchResult,
} from './provider';

export type RequestResult = {
results: RawResult[];
query: RawQuery[];
};

export interface RawResult {
country: string;
country_code: string;
state: string;
county: string;
city: string;
postcode: number;
suburb: string;
street: string;
lon: string;
lat: string;
state_code: string;
formatted: string;
bbox: BBox;
}

export interface RawQuery {
text: string;
parsed: RawQueryParsed;
}

export type RawQueryParsed = {
city: string;
expected_type: string;
};

export type BBox = {
lon1: string;
lat1: string;
lon2: string;
lat2: string;
};

export type GeoapifyProviderOptions = {
searchUrl?: string;
reverseUrl?: string;
} & ProviderOptions;

export default class GeoapifyProvider extends AbstractProvider<
RequestResult,
RawResult
> {
searchUrl: string;
reverseUrl: string;

constructor(options: GeoapifyProviderOptions = {}) {
super(options);

const host = 'https://api.geoapify.com/v1/geocode';
this.searchUrl = options.searchUrl || `${host}/search`;
this.reverseUrl = options.reverseUrl || `${host}/reverse`;
}

endpoint({ query, type }: EndpointArgument): string {
const params = typeof query === 'string' ? { text: query } : query;
params.format = 'json';

switch (type) {
case RequestType.REVERSE:
return this.getUrl(this.reverseUrl, params);

default:
return this.getUrl(this.searchUrl, params);
}
}

parse(response: ParseArgument<RequestResult>): SearchResult<RawResult>[] {
const records = Array.isArray(response.data.results)
? response.data.results
: [response.data.results];
return records.map((r) => ({
x: Number(r.lon),
y: Number(r.lat),
label: r.formatted,
bounds: [
[parseFloat(r.bbox.lat1), parseFloat(r.bbox.lon1)], // s, w
[parseFloat(r.bbox.lat2), parseFloat(r.bbox.lon2)], // n, e
],
raw: r,
}));
}
}
1 change: 1 addition & 0 deletions src/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ export { default as OpenStreetMapProvider } from './openStreetMapProvider';
export { default as PeliasProvider } from './peliasProvider';
export { default as MapBoxProvider } from './mapBoxProvider';
export { default as GeoApiFrProvider } from './geoApiFrProvider';
export { default as GeoapifyProvider } from './geoapifyProvider';

export { default as Provider } from './provider';