From 7a964efb3a104e304be7620dc18fa123559f05c8 Mon Sep 17 00:00:00 2001 From: Marc Tobias Metten Date: Sun, 18 Mar 2018 01:49:26 +0100 Subject: [PATCH] search/reverse/lookup with geojson,geocodejson output --- lib/Geocode.php | 5 ++ lib/PlaceLookup.php | 65 ++++++++++++++++++++--- lib/template/address-geocodejson.php | 77 ++++++++++++++++++++++++++++ lib/template/address-geojson.php | 67 ++++++++++++++++++++++++ lib/template/address-json.php | 2 +- lib/template/search-geocodejson.php | 69 +++++++++++++++++++++++++ lib/template/search-geojson.php | 71 +++++++++++++++++++++++++ lib/template/search-json.php | 3 +- test/bdd/api/lookup/simple.feature | 7 +-- test/bdd/api/reverse/params.feature | 16 ++++++ test/bdd/api/reverse/simple.feature | 17 ++++-- test/bdd/api/search/params.feature | 18 +++++++ test/bdd/api/search/simple.feature | 6 +++ test/bdd/steps/queries.py | 33 ++++++++++++ website/lookup.php | 5 +- website/reverse.php | 13 ++++- website/search.php | 4 +- 17 files changed, 455 insertions(+), 23 deletions(-) create mode 100644 lib/template/address-geocodejson.php create mode 100644 lib/template/address-geojson.php create mode 100644 lib/template/search-geocodejson.php create mode 100644 lib/template/search-geojson.php diff --git a/lib/Geocode.php b/lib/Geocode.php index 6cc2e4cb..948cc0a6 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -249,6 +249,11 @@ class Geocode $this->oPlaceLookup->loadParamArray($oParams, $sForceGeometryType); $this->oPlaceLookup->setIncludeAddressDetails(false); $this->oPlaceLookup->setIncludePolygonAsPoints($oParams->getBool('polygon')); + + if ($oParams->getString('format', '') == 'geocodejson') { + $this->oPlaceLookup->setAddressDetails(true); + $this->oPlaceLookup->setAddressAdminLevels(true); + } } public function setQueryFromParams($oParams) diff --git a/lib/PlaceLookup.php b/lib/PlaceLookup.php index 98af69f2..0bf8c2fe 100644 --- a/lib/PlaceLookup.php +++ b/lib/PlaceLookup.php @@ -11,6 +11,7 @@ class PlaceLookup protected $aLangPrefOrderSql = "''"; protected $bAddressDetails = false; + protected $bAddressAdminLevels = false; protected $bExtraTags = false; protected $bNameDetails = false; @@ -42,6 +43,16 @@ class PlaceLookup $this->bIncludePolygonAsPoints = $b; } + public function setAddressDetails($b = true) + { + $this->bAddressDetails = $b; + } + + public function setAddressAdminLevels($b = true) + { + $this->bAddressAdminLevels = $b; + } + public function loadParamArray($oParams, $sGeomType = null) { $aLangs = $oParams->getPreferredLanguages(); @@ -54,17 +65,21 @@ class PlaceLookup $this->bDeDupe = $oParams->getBool('dedupe', $this->bDeDupe); - if ($sGeomType === null || $sGeomType == 'text') { - $this->bIncludePolygonAsText = $oParams->getBool('polygon_text'); - } if ($sGeomType === null || $sGeomType == 'geojson') { $this->bIncludePolygonAsGeoJSON = $oParams->getBool('polygon_geojson'); + $this->bIncludePolygonAsPoints = false; } - if ($sGeomType === null || $sGeomType == 'kml') { - $this->bIncludePolygonAsKML = $oParams->getBool('polygon_kml'); - } - if ($sGeomType === null || $sGeomType == 'svg') { - $this->bIncludePolygonAsSVG = $oParams->getBool('polygon_svg'); + + if ($oParams->getString('format', '') !== 'geojson') { + if ($sGeomType === null || $sGeomType == 'text') { + $this->bIncludePolygonAsText = $oParams->getBool('polygon_text'); + } + if ($sGeomType === null || $sGeomType == 'kml') { + $this->bIncludePolygonAsKML = $oParams->getBool('polygon_kml'); + } + if ($sGeomType === null || $sGeomType == 'svg') { + $this->bIncludePolygonAsSVG = $oParams->getBool('polygon_svg'); + } } $this->fPolygonSimplificationThreshold = $oParams->getFloat('polygon_threshold', 0.0); @@ -429,6 +444,13 @@ class PlaceLookup ); } + if ($this->bAddressAdminLevels) { + $aPlace['aAddressAdminLevels'] = $this->getAddressAdminLevels( + $aPlace['place_id'], + $aPlace['housenumber'] + ); + } + if ($this->bExtraTags) { if ($aPlace['extra']) { $aPlace['sExtraTags'] = json_decode($aPlace['extra']); @@ -514,6 +536,33 @@ class PlaceLookup return $aAddress; } + /* "Downing Street, London" + * [ + * "level15" => "Covent Garden", + * "level8" => "Westminster", + * "level6" => "London", + * "level5" => "Greater London", + * "level4" => "England", + * "level2" => "United Kingdom" + * ] + */ + + public function getAddressAdminLevels($iPlaceID, $sHousenumber = null) + { + $aAddressLines = $this->getAddressDetails( + $iPlaceID, + false, + $sHousenumber === null ? -1 : $sHousenumber + ); + + $aAddress = array(); + foreach ($aAddressLines as $aLine) { + if (isset($aLine['admin_level'])) { + $aAddress['level'.$aLine['admin_level']] = $aLine['localname']; + } + } + return $aAddress; + } /* returns an array which will contain the keys diff --git a/lib/template/address-geocodejson.php b/lib/template/address-geocodejson.php new file mode 100644 index 00000000..92efc8fe --- /dev/null +++ b/lib/template/address-geocodejson.php @@ -0,0 +1,77 @@ + 'Feature', + 'properties' => array( + 'geocoding' => array() + ) + ); + + if (isset($aPlace['place_id'])) $aFilteredPlaces['properties']['geocoding']['place_id'] = $aPlace['place_id']; + $sOSMType = formatOSMType($aPlace['osm_type']); + if ($sOSMType) { + $aFilteredPlaces['properties']['geocoding']['osm_type'] = $sOSMType; + $aFilteredPlaces['properties']['geocoding']['osm_id'] = $aPlace['osm_id']; + } + + $aFilteredPlaces['properties']['geocoding']['type'] = $aPlace['type']; + + $aFilteredPlaces['properties']['geocoding']['accuracy'] = (int) $fDistance; + + $aFilteredPlaces['properties']['geocoding']['label'] = $aPlace['langaddress']; + + $aFilteredPlaces['properties']['geocoding']['name'] = $aPlace['placename']; + + $aFieldMappings = array( + 'house_number' => 'housenumber', + 'road' => 'street', + 'locality' => 'locality', + 'postcode' => 'postcode', + 'city' => 'city', + 'district' => 'district', + 'county' => 'county', + 'state' => 'state', + 'country' => 'country' + ); + + foreach ($aFieldMappings as $sFrom => $sTo) { + if (isset($aPlace['aAddress'][$sFrom])) { + $aFilteredPlaces['properties']['geocoding'][$sTo] = $aPlace['aAddress'][$sFrom]; + } + } + + $aFilteredPlaces['properties']['geocoding']['admin'] = $aPlace['aAddressAdminLevels']; + + if (isset($aPlace['asgeojson'])) { + $aFilteredPlaces['geometry'] = json_decode($aPlace['asgeojson']); + } else { + $aFilteredPlaces['geometry'] = array( + 'type' => 'Point', + 'coordinates' => array( + (float) $aPlace['lon'], + (float) $aPlace['lat'] + ) + ); + } + + javascript_renderData(array( + 'type' => 'FeatureCollection', + 'geocoding' => array( + 'version' => '0.1.0', + 'attribution' => 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright', + 'licence' => 'ODbL', + 'query' => $sQuery + ), + 'features' => $aFilteredPlaces + )); +} diff --git a/lib/template/address-geojson.php b/lib/template/address-geojson.php new file mode 100644 index 00000000..8ef5713b --- /dev/null +++ b/lib/template/address-geojson.php @@ -0,0 +1,67 @@ + 'Feature', + 'properties' => array() + ); + + if (isset($aPlace['place_id'])) $aFilteredPlaces['properties']['place_id'] = $aPlace['place_id']; + $sOSMType = formatOSMType($aPlace['osm_type']); + if ($sOSMType) { + $aFilteredPlaces['properties']['osm_type'] = $sOSMType; + $aFilteredPlaces['properties']['osm_id'] = $aPlace['osm_id']; + } + + $aFilteredPlaces['properties']['place_rank'] = $aPlace['rank_search']; + + $aFilteredPlaces['properties']['category'] = $aPlace['class']; + $aFilteredPlaces['properties']['type'] = $aPlace['type']; + + $aFilteredPlaces['properties']['importance'] = $aPlace['importance']; + + $aFilteredPlaces['properties']['addresstype'] = strtolower($aPlace['addresstype']); + + $aFilteredPlaces['properties']['name'] = $aPlace['placename']; + + $aFilteredPlaces['properties']['display_name'] = $aPlace['langaddress']; + + if (isset($aPlace['aAddress'])) $aFilteredPlaces['properties']['address'] = $aPlace['aAddress']; + if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['properties']['extratags'] = $aPlace['sExtraTags']; + if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['properties']['namedetails'] = $aPlace['sNameDetails']; + + if (isset($aPlace['aBoundingBox'])) { + $aFilteredPlaces['bbox'] = array( + (float) $aPlace['aBoundingBox'][2], // minlon + (float) $aPlace['aBoundingBox'][0], // minlat + (float) $aPlace['aBoundingBox'][3], // maxlon + (float) $aPlace['aBoundingBox'][1] // maxlat + ); + } + + if (isset($aPlace['asgeojson'])) { + $aFilteredPlaces['geometry'] = json_decode($aPlace['asgeojson']); + } else { + $aFilteredPlaces['geometry'] = array( + 'type' => 'Point', + 'coordinates' => array( + (float) $aPlace['lon'], + (float) $aPlace['lat'] + ) + ); + } + + + javascript_renderData(array( + 'type' => 'FeatureCollection', + 'licence' => 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright', + 'features' => array($aFilteredPlaces) + )); +} diff --git a/lib/template/address-json.php b/lib/template/address-json.php index 4f0d024f..b620c63e 100644 --- a/lib/template/address-json.php +++ b/lib/template/address-json.php @@ -17,7 +17,7 @@ if (empty($aPlace)) { if (isset($aPlace['lat'])) $aFilteredPlaces['lat'] = $aPlace['lat']; if (isset($aPlace['lon'])) $aFilteredPlaces['lon'] = $aPlace['lon']; - if ($sOutputFormat == 'jsonv2') { + if ($sOutputFormat == 'jsonv2' || $sOutputFormat == 'geojson') { $aFilteredPlaces['place_rank'] = $aPlace['rank_search']; $aFilteredPlaces['category'] = $aPlace['class']; diff --git a/lib/template/search-geocodejson.php b/lib/template/search-geocodejson.php new file mode 100644 index 00000000..25299716 --- /dev/null +++ b/lib/template/search-geocodejson.php @@ -0,0 +1,69 @@ + $aPointDetails) { + $aPlace = array( + 'type' => 'Feature', + 'properties' => array( + 'geocoding' => array() + ) + ); + + if (isset($aPlace['place_id'])) $aPlace['properties']['geocoding']['place_id'] = $aPointDetails['place_id']; + $sOSMType = formatOSMType($aPlace['osm_type']); + if ($sOSMType) { + $aPlace['properties']['geocoding']['osm_type'] = $sOSMType; + $aPlace['properties']['geocoding']['osm_id'] = $aPointDetails['osm_id']; + } + + $aPlace['properties']['geocoding']['type'] = $aPointDetails['type']; + + $aPlace['properties']['geocoding']['label'] = $aPointDetails['langaddress']; + + $aPlace['properties']['geocoding']['name'] = $aPointDetails['placename']; + + $aFieldMappings = array( + 'house_number' => 'housenumber', + 'road' => 'street', + 'locality' => 'locality', + 'postcode' => 'postcode', + 'city' => 'city', + 'district' => 'district', + 'county' => 'county', + 'state' => 'state', + 'country' => 'country' + ); + + foreach ($aFieldMappings as $sFrom => $sTo) { + if (isset($aPointDetails['aAddress'][$sFrom])) { + $aPlace['properties']['geocoding'][$sTo] = $aPointDetails['aAddress'][$sFrom]; + } + } + + $aPlace['properties']['geocoding']['admin'] = $aPointDetails['aAddressAdminLevels']; + + if (isset($aPointDetails['asgeojson'])) { + $aPlace['geometry'] = json_decode($aPointDetails['asgeojson']); + } else { + $aPlace['geometry'] = array( + 'type' => 'Point', + 'coordinates' => array( + (float) $aPointDetails['lon'], + (float) $aPointDetails['lat'] + ) + ); + } + $aFilteredPlaces[] = $aPlace; +} + + +javascript_renderData(array( + 'type' => 'FeatureCollection', + 'geocoding' => array( + 'version' => '0.1.0', + 'attribution' => 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright', + 'licence' => 'ODbL', + 'query' => $sQuery + ), + 'features' => $aFilteredPlaces + )); diff --git a/lib/template/search-geojson.php b/lib/template/search-geojson.php new file mode 100644 index 00000000..0d04ddc7 --- /dev/null +++ b/lib/template/search-geojson.php @@ -0,0 +1,71 @@ + $aPointDetails) { + $aPlace = array( + 'type' => 'Feature', + 'properties' => array( + 'place_id'=>$aPointDetails['place_id'], + ) + ); + + $sOSMType = formatOSMType($aPointDetails['osm_type']); + if ($sOSMType) { + $aPlace['properties']['osm_type'] = $sOSMType; + $aPlace['properties']['osm_id'] = $aPointDetails['osm_id']; + } + + if (isset($aPointDetails['aBoundingBox'])) { + $aPlace['bbox'] = array( + (float) $aPointDetails['aBoundingBox'][2], // minlon + (float) $aPointDetails['aBoundingBox'][0], // minlat + (float) $aPointDetails['aBoundingBox'][3], // maxlon + (float) $aPointDetails['aBoundingBox'][1] // maxlat + ); + } + + if (isset($aPointDetails['zoom'])) { + $aPlace['properties']['zoom'] = $aPointDetails['zoom']; + } + + $aPlace['properties']['display_name'] = $aPointDetails['name']; + + $aPlace['properties']['place_rank'] = $aPointDetails['rank_search']; + $aPlace['properties']['category'] = $aPointDetails['class']; + + $aPlace['properties']['type'] = $aPointDetails['type']; + + $aPlace['properties']['importance'] = $aPointDetails['importance']; + + if (isset($aPointDetails['icon']) && $aPointDetails['icon']) { + $aPlace['properties']['icon'] = $aPointDetails['icon']; + } + + if (isset($aPointDetails['address']) && !empty($aPointDetails['address'])) { + $aPlace['properties']['address'] = $aPointDetails['address']; + } + + if (isset($aPointDetails['asgeojson'])) { + $aPlace['geometry'] = json_decode($aPointDetails['asgeojson']); + } else { + $aPlace['geometry'] = array( + 'type' => 'Point', + 'coordinates' => array( + (float) $aPointDetails['lon'], + (float) $aPointDetails['lat'] + ) + ); + } + + + if (isset($aPointDetails['sExtraTags'])) $aPlace['properties']['extratags'] = $aPointDetails['sExtraTags']; + if (isset($aPointDetails['sNameDetails'])) $aPlace['properties']['namedetails'] = $aPointDetails['sNameDetails']; + + $aFilteredPlaces[] = $aPlace; +} + +javascript_renderData(array( + 'type' => 'FeatureCollection', + 'licence' => 'Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright', + 'features' => $aFilteredPlaces + )); diff --git a/lib/template/search-json.php b/lib/template/search-json.php index 7c87f636..30817c04 100644 --- a/lib/template/search-json.php +++ b/lib/template/search-json.php @@ -27,9 +27,10 @@ foreach ($aSearchResults as $iResNum => $aPointDetails) { $aPlace['lat'] = $aPointDetails['lat']; $aPlace['lon'] = $aPointDetails['lon']; + $aPlace['display_name'] = $aPointDetails['name']; - if ($sOutputFormat == 'jsonv2') { + if ($sOutputFormat == 'jsonv2' || $sOutputFormat == 'geojson') { $aPlace['place_rank'] = $aPointDetails['rank_search']; $aPlace['category'] = $aPointDetails['class']; } else { diff --git a/test/bdd/api/lookup/simple.feature b/test/bdd/api/lookup/simple.feature index 5ec185c5..e29812e0 100644 --- a/test/bdd/api/lookup/simple.feature +++ b/test/bdd/api/lookup/simple.feature @@ -8,9 +8,10 @@ Feature: Places by osm_type and osm_id Tests And exactly 3 results are returned Examples: - | format | - | xml | - | json | + | format | + | xml | + | json | + | geojson | Scenario: address lookup for non-existing or invalid node, way, relation When sending xml lookup query for X99,,N0,nN158845944,ABC,,W9 diff --git a/test/bdd/api/reverse/params.feature b/test/bdd/api/reverse/params.feature index 1de31c9d..f78c4c6a 100644 --- a/test/bdd/api/reverse/params.feature +++ b/test/bdd/api/reverse/params.feature @@ -13,6 +13,7 @@ Feature: Parameters for Reverse API | format | | json | | jsonv2 | + | geojson | | xml | Scenario Outline: Coordinates must be floating-point numbers @@ -35,6 +36,7 @@ Feature: Parameters for Reverse API | xml | | json | | jsonv2 | + | geojson | Scenario Outline: Reverse Geocoding with namedetails When sending reverse coordinates 10.776455623137625,106.70175343751907 @@ -47,6 +49,7 @@ Feature: Parameters for Reverse API | xml | | json | | jsonv2 | + | geojson | Scenario Outline: Reverse Geocoding contains TEXT geometry When sending reverse coordinates 47.165989816710066,9.515774846076965 @@ -107,5 +110,18 @@ Feature: Parameters for Reverse API | xml | geojson | | json | geojson | | jsonv2 | geojson | + | geojson | geojson | + Scenario Outline: Reverse Geocoding in geojson format contains no non-geojson geometry + When sending geojson reverse coordinates 47.165989816710066,9.515774846076965 + | polygon_text | polygon | polygon_svg | polygon_geokml | + | 1 | 1 | 1 | 1 | + Then result 0 has not attributes + + Examples: + | response_attribute | + | geotext | + | polygonpoints | + | svg | + | geokml | diff --git a/test/bdd/api/reverse/simple.feature b/test/bdd/api/reverse/simple.feature index 3f4bd6eb..3f307e0e 100644 --- a/test/bdd/api/reverse/simple.feature +++ b/test/bdd/api/reverse/simple.feature @@ -11,6 +11,8 @@ Feature: Simple Reverse Tests Then the result is valid json When sending jsonv2 reverse coordinates , Then the result is valid json + When sending geojson reverse coordinates , + Then the result is valid geojson When sending html reverse coordinates , Then the result is valid html @@ -42,6 +44,10 @@ Feature: Simple Reverse Tests | param | value | | | | Then the result is valid json + When sending geojson reverse coordinates 53.603,10.041 + | param | value | + | | | + Then the result is valid geojson Examples: | parameter | value | @@ -60,12 +66,13 @@ Feature: Simple Reverse Tests When sending reverse coordinates 67.3245,0.456 | json_callback | | foo | - Then the result is valid json + Then the result is valid Examples: - | format | - | json | - | jsonv2 | + | format | outformat | + | json | json | + | jsonv2 | json | + | geojson | geojson | Scenario Outline: Boundingbox is returned When sending reverse coordinates 14.62,108.1 @@ -77,6 +84,7 @@ Feature: Simple Reverse Tests | format | | json | | jsonv2 | + | geojson | | xml | Scenario Outline: Reverse-geocoding with zoom @@ -89,6 +97,7 @@ Feature: Simple Reverse Tests | format | | json | | jsonv2 | + | geojson | | html | | xml | diff --git a/test/bdd/api/search/params.feature b/test/bdd/api/search/params.feature index b184fd86..fcd2b603 100644 --- a/test/bdd/api/search/params.feature +++ b/test/bdd/api/search/params.feature @@ -276,6 +276,7 @@ Feature: Search queries | xml | | json | | jsonv2 | + | geojson | Scenario Outline: Search with namedetails When sending search query "Hauptstr" @@ -288,6 +289,7 @@ Feature: Search queries | xml | | json | | jsonv2 | + | geojson | Scenario Outline: Search result with contains TEXT geometry When sending search query "Highmore" @@ -348,6 +350,20 @@ Feature: Search queries | xml | geojson | | json | geojson | | jsonv2 | geojson | + | geojson | geojson | + + Scenario Outline: Search result in geojson format contains no non-geojson geometry + When sending geojson search query "Highmore" + | polygon_text | polygon | polygon_svg | polygon_geokml | + | 1 | 1 | 1 | 1 | + Then result 0 has not attributes + + Examples: + | response_attribute | + | geotext | + | polygonpoints | + | svg | + | geokml | Scenario: Search along a route When sending json search query "restaurant" with address @@ -356,3 +372,5 @@ Feature: Search queries Then result addresses contain | city | | Rapid City | + + diff --git a/test/bdd/api/search/simple.feature b/test/bdd/api/search/simple.feature index 25494952..06c24a2e 100644 --- a/test/bdd/api/search/simple.feature +++ b/test/bdd/api/search/simple.feature @@ -23,6 +23,10 @@ Feature: Simple Tests | param | value | | | | Then at least 1 result is returned + When sending geojson search query "Hamburg" + | param | value | + | | | + Then at least 1 result is returned Examples: | parameter | value | @@ -68,6 +72,8 @@ Feature: Simple Tests Then the result is valid json When sending jsonv2 search query "" Then the result is valid json + When sending geojson search query "" + Then the result is valid geojson Examples: | query | diff --git a/test/bdd/steps/queries.py b/test/bdd/steps/queries.py index caefb661..1584d1ed 100644 --- a/test/bdd/steps/queries.py +++ b/test/bdd/steps/queries.py @@ -110,6 +110,10 @@ class SearchResponse(GenericResponse): self.header['json_func'] = m.group(1) self.result = json.JSONDecoder(object_pairs_hook=OrderedDict).decode(code) + def parse_geojson(self): + self.parse_json() + self.result = geojson_results_to_json_results(self.result) + def parse_html(self): content, errors = tidy_document(self.page, options={'char-encoding' : 'utf8'}) @@ -185,6 +189,12 @@ class ReverseResponse(GenericResponse): self.header['json_func'] = m.group(1) self.result = [json.JSONDecoder(object_pairs_hook=OrderedDict).decode(code)] + def parse_geojson(self): + self.parse_json() + if 'error' in self.result: + return + self.result = geojson_results_to_json_results(self.result[0]) + def parse_xml(self): et = ET.fromstring(self.page) @@ -250,6 +260,27 @@ class StatusResponse(GenericResponse): self.result = [json.JSONDecoder(object_pairs_hook=OrderedDict).decode(self.page)] +def geojson_result_to_json_result(geojson_result): + result = geojson_result['properties'] + result['geojson'] = geojson_result['geometry'] + if 'bbox' in geojson_result: + # bbox is minlon, minlat, maxlon, maxlat + # boundingbox is minlat, maxlat, minlon, maxlon + result['boundingbox'] = [ + geojson_result['bbox'][1], + geojson_result['bbox'][3], + geojson_result['bbox'][0], + geojson_result['bbox'][2] + ] + return result + + +def geojson_results_to_json_results(geojson_results): + if 'error' in geojson_results: + return + return list(map(geojson_result_to_json_result, geojson_results['features'])) + + @when(u'searching for "(?P.*)"(?P with dups)?') def query_cmd(context, query, dups): """ Query directly via PHP script. @@ -414,6 +445,8 @@ def website_lookup_request(context, fmt, query): if fmt == 'json ': outfmt = 'json' + elif fmt == 'geojson ': + outfmt = 'geojson' else: outfmt = 'xml' diff --git a/website/lookup.php b/website/lookup.php index 71c93715..695a083a 100755 --- a/website/lookup.php +++ b/website/lookup.php @@ -11,7 +11,7 @@ ini_set('memory_limit', '200M'); $oParams = new Nominatim\ParameterParser(); // Format for output -$sOutputFormat = $oParams->getSet('format', array('xml', 'json'), 'xml'); +$sOutputFormat = $oParams->getSet('format', array('xml', 'json', 'geojson'), 'xml'); // Preferred language $aLangPrefOrder = $oParams->getPreferredLanguages(); @@ -66,4 +66,5 @@ $bShowPolygons = ''; $aExcludePlaceIDs = array(); $sMoreURL = ''; -include(CONST_BasePath.'/lib/template/search-'.$sOutputFormat.'.php'); +$sOutputTemplate = ($sOutputFormat == 'jsonv2') ? 'json' : $sOutputFormat; +include(CONST_BasePath.'/lib/template/search-'.$sOutputTemplate.'.php'); diff --git a/website/reverse.php b/website/reverse.php index 3bcac2ce..3c3824eb 100755 --- a/website/reverse.php +++ b/website/reverse.php @@ -12,7 +12,7 @@ ini_set('memory_limit', '200M'); $oParams = new Nominatim\ParameterParser(); // Format for output -$sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2'), 'xml'); +$sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2', 'geojson', 'geocodejson'), 'xml'); // Preferred language $aLangPrefOrder = $oParams->getPreferredLanguages(); @@ -23,6 +23,10 @@ $hLog = logStart($oDB, 'reverse', $_SERVER['QUERY_STRING'], $aLangPrefOrder); $oPlaceLookup = new Nominatim\PlaceLookup($oDB); $oPlaceLookup->loadParamArray($oParams); +if ($sOutputFormat == 'geocodejson') { + $oPlaceLookup->setAddressDetails(true); + $oPlaceLookup->setAddressAdminLevels(true); +} $sOsmType = $oParams->getSet('osm_type', array('N', 'W', 'R')); $iOsmId = $oParams->getInt('osm_id', -1); @@ -75,7 +79,12 @@ if ($sOutputFormat == 'html') { $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1")); $sTileURL = CONST_Map_Tile_URL; $sTileAttribution = CONST_Map_Tile_Attribution; +} elseif ($sOutputFormat == 'geocodejson') { + $sQuery = $fLat.','.$fLon; + if (isset($aPlace['place_id'])) { + $fDistance = chksql($oDB->getOne('SELECT ST_Distance(ST_SetSRID(ST_Point('.$fLon.','.$fLat.'),4326), centroid) FROM placex where place_id='.$aPlace['place_id'])); + } } -$sOutputTemplate = ($sOutputFormat=='jsonv2' ? 'json' : $sOutputFormat); +$sOutputTemplate = ($sOutputFormat == 'jsonv2') ? 'json' : $sOutputFormat; include(CONST_BasePath.'/lib/template/address-'.$sOutputTemplate.'.php'); diff --git a/website/search.php b/website/search.php index 6dc44335..0ebf1814 100755 --- a/website/search.php +++ b/website/search.php @@ -26,7 +26,7 @@ if (CONST_Search_ReversePlanForAll } // Format for output -$sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2'), 'html'); +$sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2', 'geojson', 'geocodejson'), 'html'); $sForcedGeometry = ($sOutputFormat == 'html') ? 'geojson' : null; $oGeocode->loadParamArray($oParams, $sForcedGeometry); @@ -81,5 +81,5 @@ $sMoreURL = CONST_Website_BaseURL.'search.php?'.http_build_query($aMoreParams); if (CONST_Debug) exit; -$sOutputTemplate = ($sOutputFormat=='jsonv2' ? 'json' : $sOutputFormat); +$sOutputTemplate = ($sOutputFormat == 'jsonv2') ? 'json' : $sOutputFormat; include(CONST_BasePath.'/lib/template/search-'.$sOutputTemplate.'.php'); -- 2.39.5