Merge branch 'geojson-output' of https://github.com/mtmail/Nominatim into mtmail-geojson-output

This commit is contained in:
Sarah Hoffmann
2018-07-06 20:26:33 +02:00
17 changed files with 455 additions and 23 deletions

View File

@@ -249,6 +249,11 @@ class Geocode
$this->oPlaceLookup->loadParamArray($oParams, $sForceGeometryType); $this->oPlaceLookup->loadParamArray($oParams, $sForceGeometryType);
$this->oPlaceLookup->setIncludeAddressDetails(false); $this->oPlaceLookup->setIncludeAddressDetails(false);
$this->oPlaceLookup->setIncludePolygonAsPoints($oParams->getBool('polygon')); $this->oPlaceLookup->setIncludePolygonAsPoints($oParams->getBool('polygon'));
if ($oParams->getString('format', '') == 'geocodejson') {
$this->oPlaceLookup->setAddressDetails(true);
$this->oPlaceLookup->setAddressAdminLevels(true);
}
} }
public function setQueryFromParams($oParams) public function setQueryFromParams($oParams)

View File

@@ -11,6 +11,7 @@ class PlaceLookup
protected $aLangPrefOrderSql = "''"; protected $aLangPrefOrderSql = "''";
protected $bAddressDetails = false; protected $bAddressDetails = false;
protected $bAddressAdminLevels = false;
protected $bExtraTags = false; protected $bExtraTags = false;
protected $bNameDetails = false; protected $bNameDetails = false;
@@ -42,6 +43,16 @@ class PlaceLookup
$this->bIncludePolygonAsPoints = $b; $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) public function loadParamArray($oParams, $sGeomType = null)
{ {
$aLangs = $oParams->getPreferredLanguages(); $aLangs = $oParams->getPreferredLanguages();
@@ -54,17 +65,21 @@ class PlaceLookup
$this->bDeDupe = $oParams->getBool('dedupe', $this->bDeDupe); $this->bDeDupe = $oParams->getBool('dedupe', $this->bDeDupe);
if ($sGeomType === null || $sGeomType == 'text') {
$this->bIncludePolygonAsText = $oParams->getBool('polygon_text');
}
if ($sGeomType === null || $sGeomType == 'geojson') { if ($sGeomType === null || $sGeomType == 'geojson') {
$this->bIncludePolygonAsGeoJSON = $oParams->getBool('polygon_geojson'); $this->bIncludePolygonAsGeoJSON = $oParams->getBool('polygon_geojson');
$this->bIncludePolygonAsPoints = false;
} }
if ($sGeomType === null || $sGeomType == 'kml') {
$this->bIncludePolygonAsKML = $oParams->getBool('polygon_kml'); if ($oParams->getString('format', '') !== 'geojson') {
} if ($sGeomType === null || $sGeomType == 'text') {
if ($sGeomType === null || $sGeomType == 'svg') { $this->bIncludePolygonAsText = $oParams->getBool('polygon_text');
$this->bIncludePolygonAsSVG = $oParams->getBool('polygon_svg'); }
if ($sGeomType === null || $sGeomType == 'kml') {
$this->bIncludePolygonAsKML = $oParams->getBool('polygon_kml');
}
if ($sGeomType === null || $sGeomType == 'svg') {
$this->bIncludePolygonAsSVG = $oParams->getBool('polygon_svg');
}
} }
$this->fPolygonSimplificationThreshold $this->fPolygonSimplificationThreshold
= $oParams->getFloat('polygon_threshold', 0.0); = $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 ($this->bExtraTags) {
if ($aPlace['extra']) { if ($aPlace['extra']) {
$aPlace['sExtraTags'] = json_decode($aPlace['extra']); $aPlace['sExtraTags'] = json_decode($aPlace['extra']);
@@ -514,6 +536,33 @@ class PlaceLookup
return $aAddress; 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 /* returns an array which will contain the keys

View File

@@ -0,0 +1,77 @@
<?php
// https://github.com/geocoders/geocodejson-spec/
$aFilteredPlaces = array();
if (empty($aPlace)) {
if (isset($sError))
$aFilteredPlaces['error'] = $sError;
else $aFilteredPlaces['error'] = 'Unable to geocode';
javascript_renderData($aFilteredPlaces);
} else {
$aFilteredPlaces = array(
'type' => '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
));
}

View File

@@ -0,0 +1,67 @@
<?php
$aFilteredPlaces = array();
if (empty($aPlace)) {
if (isset($sError))
$aFilteredPlaces['error'] = $sError;
else $aFilteredPlaces['error'] = 'Unable to geocode';
javascript_renderData($aFilteredPlaces);
} else {
$aFilteredPlaces = array(
'type' => '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)
));
}

View File

@@ -17,7 +17,7 @@ if (empty($aPlace)) {
if (isset($aPlace['lat'])) $aFilteredPlaces['lat'] = $aPlace['lat']; if (isset($aPlace['lat'])) $aFilteredPlaces['lat'] = $aPlace['lat'];
if (isset($aPlace['lon'])) $aFilteredPlaces['lon'] = $aPlace['lon']; if (isset($aPlace['lon'])) $aFilteredPlaces['lon'] = $aPlace['lon'];
if ($sOutputFormat == 'jsonv2') { if ($sOutputFormat == 'jsonv2' || $sOutputFormat == 'geojson') {
$aFilteredPlaces['place_rank'] = $aPlace['rank_search']; $aFilteredPlaces['place_rank'] = $aPlace['rank_search'];
$aFilteredPlaces['category'] = $aPlace['class']; $aFilteredPlaces['category'] = $aPlace['class'];

View File

@@ -0,0 +1,69 @@
<?php
$aFilteredPlaces = array();
foreach ($aSearchResults as $iResNum => $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
));

View File

@@ -0,0 +1,71 @@
<?php
$aFilteredPlaces = array();
foreach ($aSearchResults as $iResNum => $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
));

View File

@@ -27,9 +27,10 @@ foreach ($aSearchResults as $iResNum => $aPointDetails) {
$aPlace['lat'] = $aPointDetails['lat']; $aPlace['lat'] = $aPointDetails['lat'];
$aPlace['lon'] = $aPointDetails['lon']; $aPlace['lon'] = $aPointDetails['lon'];
$aPlace['display_name'] = $aPointDetails['name']; $aPlace['display_name'] = $aPointDetails['name'];
if ($sOutputFormat == 'jsonv2') { if ($sOutputFormat == 'jsonv2' || $sOutputFormat == 'geojson') {
$aPlace['place_rank'] = $aPointDetails['rank_search']; $aPlace['place_rank'] = $aPointDetails['rank_search'];
$aPlace['category'] = $aPointDetails['class']; $aPlace['category'] = $aPointDetails['class'];
} else { } else {

View File

@@ -8,9 +8,10 @@ Feature: Places by osm_type and osm_id Tests
And exactly 3 results are returned And exactly 3 results are returned
Examples: Examples:
| format | | format |
| xml | | xml |
| json | | json |
| geojson |
Scenario: address lookup for non-existing or invalid node, way, relation Scenario: address lookup for non-existing or invalid node, way, relation
When sending xml lookup query for X99,,N0,nN158845944,ABC,,W9 When sending xml lookup query for X99,,N0,nN158845944,ABC,,W9

View File

@@ -13,6 +13,7 @@ Feature: Parameters for Reverse API
| format | | format |
| json | | json |
| jsonv2 | | jsonv2 |
| geojson |
| xml | | xml |
Scenario Outline: Coordinates must be floating-point numbers Scenario Outline: Coordinates must be floating-point numbers
@@ -35,6 +36,7 @@ Feature: Parameters for Reverse API
| xml | | xml |
| json | | json |
| jsonv2 | | jsonv2 |
| geojson |
Scenario Outline: Reverse Geocoding with namedetails Scenario Outline: Reverse Geocoding with namedetails
When sending <format> reverse coordinates 10.776455623137625,106.70175343751907 When sending <format> reverse coordinates 10.776455623137625,106.70175343751907
@@ -47,6 +49,7 @@ Feature: Parameters for Reverse API
| xml | | xml |
| json | | json |
| jsonv2 | | jsonv2 |
| geojson |
Scenario Outline: Reverse Geocoding contains TEXT geometry Scenario Outline: Reverse Geocoding contains TEXT geometry
When sending <format> reverse coordinates 47.165989816710066,9.515774846076965 When sending <format> reverse coordinates 47.165989816710066,9.515774846076965
@@ -107,5 +110,18 @@ Feature: Parameters for Reverse API
| xml | geojson | | xml | geojson |
| json | geojson | | json | geojson |
| jsonv2 | 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 <response_attribute>
Examples:
| response_attribute |
| geotext |
| polygonpoints |
| svg |
| geokml |

View File

@@ -11,6 +11,8 @@ Feature: Simple Reverse Tests
Then the result is valid json Then the result is valid json
When sending jsonv2 reverse coordinates <lat>,<lon> When sending jsonv2 reverse coordinates <lat>,<lon>
Then the result is valid json Then the result is valid json
When sending geojson reverse coordinates <lat>,<lon>
Then the result is valid geojson
When sending html reverse coordinates <lat>,<lon> When sending html reverse coordinates <lat>,<lon>
Then the result is valid html Then the result is valid html
@@ -42,6 +44,10 @@ Feature: Simple Reverse Tests
| param | value | | param | value |
| <parameter> | <value> | | <parameter> | <value> |
Then the result is valid json Then the result is valid json
When sending geojson reverse coordinates 53.603,10.041
| param | value |
| <parameter> | <value> |
Then the result is valid geojson
Examples: Examples:
| parameter | value | | parameter | value |
@@ -60,12 +66,13 @@ Feature: Simple Reverse Tests
When sending <format> reverse coordinates 67.3245,0.456 When sending <format> reverse coordinates 67.3245,0.456
| json_callback | | json_callback |
| foo | | foo |
Then the result is valid json Then the result is valid <outformat>
Examples: Examples:
| format | | format | outformat |
| json | | json | json |
| jsonv2 | | jsonv2 | json |
| geojson | geojson |
Scenario Outline: Boundingbox is returned Scenario Outline: Boundingbox is returned
When sending <format> reverse coordinates 14.62,108.1 When sending <format> reverse coordinates 14.62,108.1
@@ -77,6 +84,7 @@ Feature: Simple Reverse Tests
| format | | format |
| json | | json |
| jsonv2 | | jsonv2 |
| geojson |
| xml | | xml |
Scenario Outline: Reverse-geocoding with zoom Scenario Outline: Reverse-geocoding with zoom
@@ -89,6 +97,7 @@ Feature: Simple Reverse Tests
| format | | format |
| json | | json |
| jsonv2 | | jsonv2 |
| geojson |
| html | | html |
| xml | | xml |

View File

@@ -276,6 +276,7 @@ Feature: Search queries
| xml | | xml |
| json | | json |
| jsonv2 | | jsonv2 |
| geojson |
Scenario Outline: Search with namedetails Scenario Outline: Search with namedetails
When sending <format> search query "Hauptstr" When sending <format> search query "Hauptstr"
@@ -288,6 +289,7 @@ Feature: Search queries
| xml | | xml |
| json | | json |
| jsonv2 | | jsonv2 |
| geojson |
Scenario Outline: Search result with contains TEXT geometry Scenario Outline: Search result with contains TEXT geometry
When sending <format> search query "Highmore" When sending <format> search query "Highmore"
@@ -348,6 +350,20 @@ Feature: Search queries
| xml | geojson | | xml | geojson |
| json | geojson | | json | geojson |
| jsonv2 | 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 <response_attribute>
Examples:
| response_attribute |
| geotext |
| polygonpoints |
| svg |
| geokml |
Scenario: Search along a route Scenario: Search along a route
When sending json search query "restaurant" with address When sending json search query "restaurant" with address
@@ -356,3 +372,5 @@ Feature: Search queries
Then result addresses contain Then result addresses contain
| city | | city |
| Rapid City | | Rapid City |

View File

@@ -23,6 +23,10 @@ Feature: Simple Tests
| param | value | | param | value |
| <parameter> | <value> | | <parameter> | <value> |
Then at least 1 result is returned Then at least 1 result is returned
When sending geojson search query "Hamburg"
| param | value |
| <parameter> | <value> |
Then at least 1 result is returned
Examples: Examples:
| parameter | value | | parameter | value |
@@ -68,6 +72,8 @@ Feature: Simple Tests
Then the result is valid json Then the result is valid json
When sending jsonv2 search query "<query>" When sending jsonv2 search query "<query>"
Then the result is valid json Then the result is valid json
When sending geojson search query "<query>"
Then the result is valid geojson
Examples: Examples:
| query | | query |

View File

@@ -110,6 +110,10 @@ class SearchResponse(GenericResponse):
self.header['json_func'] = m.group(1) self.header['json_func'] = m.group(1)
self.result = json.JSONDecoder(object_pairs_hook=OrderedDict).decode(code) 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): def parse_html(self):
content, errors = tidy_document(self.page, content, errors = tidy_document(self.page,
options={'char-encoding' : 'utf8'}) options={'char-encoding' : 'utf8'})
@@ -185,6 +189,12 @@ class ReverseResponse(GenericResponse):
self.header['json_func'] = m.group(1) self.header['json_func'] = m.group(1)
self.result = [json.JSONDecoder(object_pairs_hook=OrderedDict).decode(code)] 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): def parse_xml(self):
et = ET.fromstring(self.page) et = ET.fromstring(self.page)
@@ -250,6 +260,27 @@ class StatusResponse(GenericResponse):
self.result = [json.JSONDecoder(object_pairs_hook=OrderedDict).decode(self.page)] 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<query>.*)"(?P<dups> with dups)?') @when(u'searching for "(?P<query>.*)"(?P<dups> with dups)?')
def query_cmd(context, query, dups): def query_cmd(context, query, dups):
""" Query directly via PHP script. """ Query directly via PHP script.
@@ -414,6 +445,8 @@ def website_lookup_request(context, fmt, query):
if fmt == 'json ': if fmt == 'json ':
outfmt = 'json' outfmt = 'json'
elif fmt == 'geojson ':
outfmt = 'geojson'
else: else:
outfmt = 'xml' outfmt = 'xml'

View File

@@ -11,7 +11,7 @@ ini_set('memory_limit', '200M');
$oParams = new Nominatim\ParameterParser(); $oParams = new Nominatim\ParameterParser();
// Format for output // Format for output
$sOutputFormat = $oParams->getSet('format', array('xml', 'json'), 'xml'); $sOutputFormat = $oParams->getSet('format', array('xml', 'json', 'geojson'), 'xml');
// Preferred language // Preferred language
$aLangPrefOrder = $oParams->getPreferredLanguages(); $aLangPrefOrder = $oParams->getPreferredLanguages();
@@ -66,4 +66,5 @@ $bShowPolygons = '';
$aExcludePlaceIDs = array(); $aExcludePlaceIDs = array();
$sMoreURL = ''; $sMoreURL = '';
include(CONST_BasePath.'/lib/template/search-'.$sOutputFormat.'.php'); $sOutputTemplate = ($sOutputFormat == 'jsonv2') ? 'json' : $sOutputFormat;
include(CONST_BasePath.'/lib/template/search-'.$sOutputTemplate.'.php');

View File

@@ -12,7 +12,7 @@ ini_set('memory_limit', '200M');
$oParams = new Nominatim\ParameterParser(); $oParams = new Nominatim\ParameterParser();
// Format for output // 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 // Preferred language
$aLangPrefOrder = $oParams->getPreferredLanguages(); $aLangPrefOrder = $oParams->getPreferredLanguages();
@@ -23,6 +23,10 @@ $hLog = logStart($oDB, 'reverse', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
$oPlaceLookup = new Nominatim\PlaceLookup($oDB); $oPlaceLookup = new Nominatim\PlaceLookup($oDB);
$oPlaceLookup->loadParamArray($oParams); $oPlaceLookup->loadParamArray($oParams);
if ($sOutputFormat == 'geocodejson') {
$oPlaceLookup->setAddressDetails(true);
$oPlaceLookup->setAddressAdminLevels(true);
}
$sOsmType = $oParams->getSet('osm_type', array('N', 'W', 'R')); $sOsmType = $oParams->getSet('osm_type', array('N', 'W', 'R'));
$iOsmId = $oParams->getInt('osm_id', -1); $iOsmId = $oParams->getInt('osm_id', -1);
@@ -77,7 +81,12 @@ if ($sOutputFormat == 'html') {
$sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1")); $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
$sTileURL = CONST_Map_Tile_URL; $sTileURL = CONST_Map_Tile_URL;
$sTileAttribution = CONST_Map_Tile_Attribution; $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'); include(CONST_BasePath.'/lib/template/address-'.$sOutputTemplate.'.php');

View File

@@ -26,7 +26,7 @@ if (CONST_Search_ReversePlanForAll
} }
// Format for output // 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; $sForcedGeometry = ($sOutputFormat == 'html') ? 'geojson' : null;
$oGeocode->loadParamArray($oParams, $sForcedGeometry); $oGeocode->loadParamArray($oParams, $sForcedGeometry);
@@ -81,5 +81,5 @@ $sMoreURL = CONST_Website_BaseURL.'search.php?'.http_build_query($aMoreParams);
if (CONST_Debug) exit; if (CONST_Debug) exit;
$sOutputTemplate = ($sOutputFormat=='jsonv2' ? 'json' : $sOutputFormat); $sOutputTemplate = ($sOutputFormat == 'jsonv2') ? 'json' : $sOutputFormat;
include(CONST_BasePath.'/lib/template/search-'.$sOutputTemplate.'.php'); include(CONST_BasePath.'/lib/template/search-'.$sOutputTemplate.'.php');