* `type` - value of the main tag of the object (e.g. residential, restaurant, ...)
* `label` - full comma-separated address
* `name` - localised name of the place
- * `housenumber`, `street`, `locality`, `postcode`, `city`,
- `district`, `county`, `state`, `country` -
+ * `housenumber`, `street`, `locality`, `district`, `postcode`, `city`,
+ `county`, `state`, `country` -
provided when it can be determined from the address
- (see [this issue](https://github.com/openstreetmap/Nominatim/issues/1080) for
- current limitations on the correctness of the address) and `addressdetails=1`
- was given
* `admin` - list of localised names of administrative boundaries (only with `addressdetails=1`)
Use `polygon_geojson` to output the full geometry of the object instead
return $aAddress;
}
+ /**
+ * Annotates the given json with geocodejson address information fields.
+ *
+ * @param array $aJson Json hash to add the fields to.
+ *
+ * Geocodejson has the following fields:
+ * street, locality, postcode, city, district,
+ * county, state, country
+ *
+ * Postcode and housenumber are added by type, district is not used.
+ * All other fields are set according to address rank.
+ */
+ public function addGeocodeJsonAddressParts(&$aJson)
+ {
+ foreach ($this->aAddressLines as $aLine) {
+ if (!$aLine['isaddress']) {
+ continue;
+ }
+
+ if (!isset($aLine['localname']) || $aLine['localname'] == '') {
+ continue;
+ }
+
+ $iRank = (int)$aLine['rank_address'];
+
+ if ($aLine['type'] == 'postcode' || $aLine['type'] == 'postal_code') {
+ $aJson['postcode'] = $aLine['localname'];
+ } else if ($aLine['type'] == 'house_number') {
+ $aJson['housenumber'] = $aLine['localname'];
+ } else if ($iRank > 25 && $iRank < 28) {
+ $aJson['street'] = $aLine['localname'];
+ } else if ($iRank >= 22 && $iRank <= 25) {
+ $aJson['locality'] = $aLine['localname'];
+ } else if ($iRank >= 17 && $iRank <= 21) {
+ $aJson['district'] = $aLine['localname'];
+ } else if ($iRank >= 13 && $iRank <= 16) {
+ $aJson['city'] = $aLine['localname'];
+ } else if ($iRank >= 10 && $iRank <= 12) {
+ $aJson['county'] = $aLine['localname'];
+ } else if ($iRank >= 5 && $iRank <= 9) {
+ $aJson['state'] = $aLine['localname'];
+ } else if ($iRank == 4) {
+ $aJson['country'] = $aLine['localname'];
+ }
+ }
+ }
+
public function getAdminLevels()
{
$aAddress = array();
$aFilteredPlaces['properties']['geocoding']['name'] = $aPlace['placename'];
if (isset($aPlace['address'])) {
- $aFieldMappings = array(
- 'house_number' => 'housenumber',
- 'road' => 'street',
- 'locality' => 'locality',
- 'postcode' => 'postcode',
- 'city' => 'city',
- 'district' => 'district',
- 'county' => 'county',
- 'state' => 'state',
- 'country' => 'country'
- );
-
- $aAddressNames = $aPlace['address']->getAddressNames();
- foreach ($aFieldMappings as $sFrom => $sTo) {
- if (isset($aAddressNames[$sFrom])) {
- $aFilteredPlaces['properties']['geocoding'][$sTo] = $aAddressNames[$sFrom];
- }
- }
+ $aPlace['address']->addGeocodeJsonAddressParts(
+ $aFilteredPlaces['properties']['geocoding']
+ );
$aFilteredPlaces['properties']['geocoding']['admin']
= $aPlace['address']->getAdminLevels();
$aPlace['properties']['geocoding']['name'] = $aPointDetails['placename'];
if (isset($aPointDetails['address'])) {
- $aFieldMappings = array(
- 'house_number' => 'housenumber',
- 'road' => 'street',
- 'locality' => 'locality',
- 'postcode' => 'postcode',
- 'city' => 'city',
- 'district' => 'district',
- 'county' => 'county',
- 'state' => 'state',
- 'country' => 'country'
- );
-
- $aAddrNames = $aPointDetails['address']->getAddressNames();
- foreach ($aFieldMappings as $sFrom => $sTo) {
- if (isset($aAddrNames[$sFrom])) {
- $aPlace['properties']['geocoding'][$sTo] = $aAddrNames[$sFrom];
- }
- }
+ $aPointDetails['address']->addGeocodeJsonAddressParts(
+ $aPlace['properties']['geocoding']
+ );
$aPlace['properties']['geocoding']['admin']
= $aPointDetails['address']->getAdminLevels();
--- /dev/null
+@APIDB
+Feature: Parameters for Reverse API
+ Testing correctness of geocodejson output.
+
+ Scenario: City housenumber-level address with street
+ When sending geocodejson reverse coordinates 53.556,9.9607
+ Then results contain
+ | housenumber | street | postcode | city | country |
+ | 10 | Brunnenhofstraße | 22767 | Hamburg | Deutschland |
+
+ Scenario: Town street-level address with street
+ When sending geocodejson reverse coordinates 47.066,9.504
+ Then results contain
+ | street | city | postcode | country |
+ | Gnetsch | Balzers | 9496 | Liechtenstein |
+
+ Scenario: Town street-level address with footway
+ When sending geocodejson reverse coordinates 47.0653,9.5007
+ Then results contain
+ | street | city | postcode | country |
+ | Burgweg | Balzers | 9496 | Liechtenstein |
+
+ Scenario: City address with suburb
+ When sending geocodejson reverse coordinates 53.5822,10.0805
+ Then results contain
+ | housenumber | street | district | city | postcode | country |
+ | 64 | Hinschenfelder Straße | Wandsbek | Hamburg | 22047 | Deutschland |
--- /dev/null
+@APIDB
+Feature: Parameters for Search API
+ Testing correctness of geocodejson output.
+
+ Scenario: City housenumber-level address with street
+ When sending geocodejson search query "Brunnenhofstr 10, Hamburg" with address
+ Then results contain
+ | housenumber | street | postcode | city | country |
+ | 10 | Brunnenhofstraße | 22767 | Hamburg | Deutschland |
+
+ Scenario: Town street-level address with street
+ When sending geocodejson search query "Gnetsch, Balzers" with address
+ Then results contain
+ | street | city | postcode | country |
+ | Gnetsch | Balzers | 9496 | Liechtenstein |
+
+ Scenario: Town street-level address with footway
+ When sending geocodejson search query "burg gutenberg 6000 jahre geschichte" with address
+ Then results contain
+ | street | city | postcode | country |
+ | Burgweg | Balzers | 9496 | Liechtenstein |
+
+ Scenario: City address with suburb
+ When sending geocodejson search query "hinschenfelder str 64, wandsbek" with address
+ Then results contain
+ | housenumber | street | district | city | postcode | country |
+ | 64 | Hinschenfelder Straße | Wandsbek | Hamburg | 22047 | Deutschland |
self.result = geojson_results_to_json_results(self.result)
def parse_geocodejson(self):
- return self.parse_geojson()
+ self.parse_geojson()
+ if self.result is not None:
+ self.result = [r['geocoding'] for r in self.result]
def parse_html(self):
content, errors = tidy_document(self.page,
self.result = geojson_results_to_json_results(self.result[0])
def parse_geocodejson(self):
- return self.parse_geojson()
+ self.parse_geojson()
+ if self.result is not None:
+ self.result = [r['geocoding'] for r in self.result]
def parse_xml(self):
et = ET.fromstring(self.page)