Skip to content

Commit

Permalink
feat: add AMap(Gaode) provider (#409)
Browse files Browse the repository at this point in the history
Co-authored-by: Stephan Meijer <stephan.meijer@gmail.com>
  • Loading branch information
frees0l0 and smeijer authored Jan 21, 2025
1 parent 13f34aa commit 0ed69c3
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ GOOGLE_API_KEY=___YOUR_KEY___
LOCATIONIQ_API_KEY=___YOUR_KEY___
OPENCAGE_API_KEY=___YOUR_KEY___
HERE_API_KEY=___YOUR_KEY___
AMAP_API_KEY=___YOUR_KEY___
GEOAPIFY_API_KEY=___YOUR_KEY___
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ jobs:
GATSBY_LOCATIONIQ_API_KEY: ${{ secrets.LOCATIONIQ_API_KEY }}
GATSBY_OPENCAGE_API_KEY: ${{ secrets.OPENCAGE_API_KEY }}
GATSBY_HERE_API_KEY: ${{ secrets.HERE_API_KEY }}
GATSBY_AMAP_API_KEY: ${{ secrets.AMAP_API_KEY }}

update-docs:
name: Update docs
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 {
PeliasProvider,
GeoApiFrProvider,
GeoapifyProvider,
AMapProvider,
} from 'leaflet-geosearch';

export default {
Expand Down Expand Up @@ -51,4 +52,8 @@ export default {
Pelias: new PeliasProvider(),

GeoApiFr: new GeoApiFrProvider(),

AMap: new AMapProvider({
params: { key: process.env.GATSBY_AMAP_API_KEY },
}),
};
40 changes: 40 additions & 0 deletions docs/providers/amap.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: AMap
menu: Providers
route: /providers/amap
---

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

# AMap Provider

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

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

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

const provider = new AMapProvider({
params: {
key: '__YOUR_AMAP_KEY__',
},
});

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

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

[1]: https://console.amap.com/dev/key/app
[2]: https://lbs.amap.com/api/webservice/guide/api/georegeo
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ 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 AMapProvider } from './providers/amapProvider';

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

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

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

const results = await provider.search({ query: '上海市浦东新区外滩' });
const result = results[0];

expect(result.label).toBeTruthy();
expect(`${result.x},${result.y}`).toEqual(fixtures.geocodes[0].location);
// amap provider doesn't return bounds :(
expect(result.bounds).toBeNull();
});
});
30 changes: 30 additions & 0 deletions src/providers/__tests__/amapResponse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"status": "1",
"info": "OK",
"infocode": "10000",
"count": "1",
"geocodes": [
{
"formatted_address": "上海市浦东新区外滩",
"country": "中国",
"province": "上海市",
"citycode": "021",
"city": "上海市",
"district": "浦东新区",
"township": [],
"neighborhood": {
"name": [],
"type": []
},
"building": {
"name": [],
"type": []
},
"adcode": "310115",
"street": [],
"number": [],
"location": "121.497253,31.238235",
"level": "住宅区"
}
]
}
51 changes: 51 additions & 0 deletions src/providers/amapProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import AbstractProvider, {
EndpointArgument,
ParseArgument,
SearchResult,
} from './provider';

export type RequestResult = {
status: number;
count: number;
info: string;
geocodes: RawResult[];
};

export interface RawResult {
formatted_address: string;
country: string;
province: string;
city: string;
citycode: string;
district: string;
number: string;
adcode: string;
location: string;
level: string;
}

export default class AMapProvider extends AbstractProvider<
RequestResult,
RawResult
> {
searchUrl = 'https://restapi.amap.com/v3/geocode/geo';

endpoint({ query }: EndpointArgument): string {
const params = typeof query === 'string' ? { address: query } : query;
params.output = 'JSON';

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

parse(response: ParseArgument<RequestResult>): SearchResult<RawResult>[] {
const records = response.data.geocodes ?? [];

return records.map((r) => ({
x: Number(r.location.substring(0, r.location.indexOf(','))),
y: Number(r.location.substring(r.location.indexOf(',') + 1)),
label: r.formatted_address,
bounds: null,
raw: r,
}));
}
}

0 comments on commit 0ed69c3

Please # to comment.