Skip to content

Commit

Permalink
feat: add subLocalityLevels for Nominatim (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
alanpoulain committed Dec 17, 2020
1 parent eeeca3d commit 1d303b1
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog

## 0.10.0

* [Nominatim] Add `subLocalityLevels`

## 0.9.0

* Introduce async / await (or Promise) syntax (providers return a promise if no callback is given)
Expand Down
2 changes: 1 addition & 1 deletion docs/provider_usage.md
Expand Up @@ -298,7 +298,7 @@ Here is a table listing the parameters according to the providers:
<td>geocoded</td>
<td>subLocalityLevels</td>
<td>Levels for the sublocality</td>
<td>Google Maps</td>
<td>Google Maps, Nominatim</td>
</tr>
<tr>
<td>geocoded</td>
Expand Down
2 changes: 1 addition & 1 deletion docs/provider_usage/googlemaps.md
Expand Up @@ -26,4 +26,4 @@
- `locationType`: a type representing the precision of the result
- `streetAddress`: the street number with the street name
- `intersection`, `political`, `colloquialArea`, `ward`, `neighborhood`, `premise`, `subpremise`, `naturalFeature`, `airport`, `park`, `pointOfInterest`, `establishment`, `postalCodeSuffix`: additional address components
- `subLocalityLevels`: levels for the sublocality
- `subLocalityLevels`: levels for the sublocality (greater level number means smaller area)
1 change: 1 addition & 0 deletions docs/provider_usage/nominatim.md
Expand Up @@ -22,3 +22,4 @@
- `osmId`, `osmType`: reference to the OpenStreetMap object
- `category`, `type`: key and value of the main OpenStreetMap tag
- `attribution`: OpenStreetMap licensing information
- `subLocalityLevels`: levels for the sublocality (greater level number means smaller area)
7 changes: 7 additions & 0 deletions spec/provider/NominatimProvider.spec.ts
Expand Up @@ -72,6 +72,10 @@ describe("OpenStreetMap / Nominatim Geocoder Provider", () => {
expect(geocoded.getStreetName()).toEqual("Pennsylvania Avenue");
expect(geocoded.getSubLocality()).toEqual(undefined);
expect(geocoded.getLocality()).toEqual("Washington");
expect(geocoded.getSubLocalityLevels()).toEqual([
AdminLevel.create({ level: 3, name: "Penn Quarter" }),
AdminLevel.create({ level: 5, name: "Pennsylvania Avenue" }),
]);
expect(geocoded.getPostalCode()).toEqual("20045");
expect(geocoded.getRegion()).toEqual("District of Columbia");
expect(geocoded.getAdminLevels()).toEqual([
Expand Down Expand Up @@ -125,6 +129,9 @@ describe("OpenStreetMap / Nominatim Geocoder Provider", () => {
expect(geocoded.getStreetName()).toEqual(undefined);
expect(geocoded.getSubLocality()).toEqual("Quartier du Père-Lachaise");
expect(geocoded.getLocality()).toEqual("Paris");
expect(geocoded.getSubLocalityLevels()).toEqual([
AdminLevel.create({ level: 1, name: "Quartier du Père-Lachaise" }),
]);
expect(geocoded.getPostalCode()).toEqual("75020");
expect(geocoded.getRegion()).toEqual("Île-de-France");
expect(geocoded.getAdminLevels()).toEqual([
Expand Down
15 changes: 15 additions & 0 deletions src/provider/nominatim/NominatimGeocoded.ts
@@ -1,4 +1,5 @@
import Geocoded, { GeocodedObject } from "Geocoded";
import AdminLevel from "AdminLevel";

export interface NominatimGeocodedObject extends GeocodedObject {
readonly displayName?: string;
Expand All @@ -7,6 +8,7 @@ export interface NominatimGeocodedObject extends GeocodedObject {
readonly category?: string;
readonly type?: string;
readonly attribution?: string;
readonly subLocalityLevels?: AdminLevel[];
}

export default class NominatimGeocoded extends Geocoded {
Expand All @@ -22,13 +24,16 @@ export default class NominatimGeocoded extends Geocoded {

private readonly attribution?: string;

private readonly subLocalityLevels: AdminLevel[];

protected constructor({
displayName,
osmId,
osmType,
category,
type,
attribution,
subLocalityLevels,
...geocodedObject
}: NominatimGeocodedObject) {
super(geocodedObject);
Expand All @@ -38,6 +43,7 @@ export default class NominatimGeocoded extends Geocoded {
this.category = category;
this.type = type;
this.attribution = attribution;
this.subLocalityLevels = subLocalityLevels || [];
}

public static create(object: NominatimGeocodedObject): NominatimGeocoded {
Expand All @@ -53,6 +59,7 @@ export default class NominatimGeocoded extends Geocoded {
category: this.category,
type: this.type,
attribution: this.attribution,
subLocalityLevels: this.subLocalityLevels,
};
}

Expand Down Expand Up @@ -121,4 +128,12 @@ export default class NominatimGeocoded extends Geocoded {
public getAttribution(): undefined | string {
return this.attribution;
}

public addSubLocalityLevel(subLocalityLevel: AdminLevel): void {
this.subLocalityLevels.push(subLocalityLevel);
}

public getSubLocalityLevels(): AdminLevel[] {
return this.subLocalityLevels;
}
}
79 changes: 77 additions & 2 deletions src/provider/nominatim/NominatimProvider.ts
Expand Up @@ -62,22 +62,47 @@ export interface NominatimResult {
icon: string;
address: {
attraction?: string;
pedestrian?: string;
// eslint-disable-next-line camelcase
house_name?: string;
// eslint-disable-next-line camelcase
house_number?: string;
road?: string;
pedestrian?: string;
retail?: string;
commercial?: string;
industrial?: string;
farmyard?: string;
farm?: string;
residental?: string;
// eslint-disable-next-line camelcase
city_block?: string;
quarter?: string;
allotments?: string;
neighbourhood?: string;
// eslint-disable-next-line camelcase
isolated_dwelling?: string;
croft?: string;
hamlet?: string;
// eslint-disable-next-line camelcase
city_district?: string;
district?: string;
borough?: string;
subdivision?: string;
suburb?: string;
municipality?: string;
city?: string;
town?: string;
village?: string;
hamlet?: string;
region?: string;
// eslint-disable-next-line camelcase
state_district?: string;
state?: string;
county?: string;
postcode?: string;
country?: string;
// eslint-disable-next-line camelcase
country_code?: string;
continent?: string;
};
}

Expand Down Expand Up @@ -385,6 +410,56 @@ export default class NominatimProvider
}
});

const subLocalityLevels: (
| "city_district"
| "district"
| "borough"
| "suburb"
| "subdivision"
| "hamlet"
| "croft"
| "isolated_dwelling"
| "neighbourhood"
| "allotments"
| "quarter"
| "city_block"
| "residental"
| "farm"
| "farmyard"
| "industrial"
| "commercial"
| "retail"
| "road"
| "house_name"
)[][] = [
["city_district", "district", "borough", "suburb", "subdivision"],
["hamlet", "croft", "isolated_dwelling"],
["neighbourhood", "allotments", "quarter"],
[
"city_block",
"residental",
"farm",
"farmyard",
"industrial",
"commercial",
"retail",
],
["road"],
["house_name"],
];
subLocalityLevels.forEach((subLocalities, level) => {
subLocalities.forEach((subLocalityLevel) => {
if (result.address[subLocalityLevel]) {
geocoded.addSubLocalityLevel(
AdminLevel.create({
level: level + 1,
name: result.address[subLocalityLevel] || "",
})
);
}
});
});

return geocoded;
}
}

0 comments on commit 1d303b1

Please sign in to comment.