From: Sarah Hoffmann Date: Fri, 6 Jul 2018 18:26:33 +0000 (+0200) Subject: Merge branch 'geojson-output' of https://github.com/mtmail/Nominatim into mtmail... X-Git-Tag: v3.2.0~54 X-Git-Url: https://git.openstreetmap.org./nominatim.git/commitdiff_plain/f50f46c1ce3fe44d8de55071d2fe1126ecb1d0ac?ds=inline;hp=-c Merge branch 'geojson-output' of https://github.com/mtmail/Nominatim into mtmail-geojson-output --- f50f46c1ce3fe44d8de55071d2fe1126ecb1d0ac diff --combined lib/PlaceLookup.php index cf744929,0bf8c2fe..57d6166e --- a/lib/PlaceLookup.php +++ b/lib/PlaceLookup.php @@@ -11,6 -11,7 +11,7 @@@ class PlaceLooku protected $aLangPrefOrderSql = "''"; protected $bAddressDetails = false; + protected $bAddressAdminLevels = false; protected $bExtraTags = false; protected $bNameDetails = false; @@@ -42,6 -43,16 +43,16 @@@ $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 +65,21 @@@ $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 +444,13 @@@ ); } + 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 +536,33 @@@ 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 @@@ -528,7 -577,7 +577,7 @@@ */ - public function getOutlines($iPlaceID, $fLon = null, $fLat = null, $fRadius = null) + public function getOutlines($iPlaceID, $fLon = null, $fLat = null, $fRadius = null, $fLonReverse = null, $fLatReverse = null) { $aOutlineResult = array(); @@@ -536,27 -585,15 +585,27 @@@ if (CONST_Search_AreaPolygons) { // Get the bounding box and outline polygon - $sSQL = 'select place_id,0 as numfeatures,st_area(geometry) as area,'; - $sSQL .= 'ST_Y(centroid) as centrelat,ST_X(centroid) as centrelon,'; - $sSQL .= 'ST_YMin(geometry) as minlat,ST_YMax(geometry) as maxlat,'; - $sSQL .= 'ST_XMin(geometry) as minlon,ST_XMax(geometry) as maxlon'; + $sSQL = 'select place_id,0 as numfeatures,st_area(geometry) as area,'; + if ($fLonReverse != null && $fLatReverse != null) { + $sSQL .= ' ST_Y(closest_point) as centrelat,'; + $sSQL .= ' ST_X(closest_point) as centrelon,'; + } else { + $sSQL .= ' ST_Y(centroid) as centrelat, ST_X(centroid) as centrelon,'; + } + $sSQL .= ' ST_YMin(geometry) as minlat,ST_YMax(geometry) as maxlat,'; + $sSQL .= ' ST_XMin(geometry) as minlon,ST_XMax(geometry) as maxlon'; if ($this->bIncludePolygonAsGeoJSON) $sSQL .= ',ST_AsGeoJSON(geometry) as asgeojson'; if ($this->bIncludePolygonAsKML) $sSQL .= ',ST_AsKML(geometry) as askml'; if ($this->bIncludePolygonAsSVG) $sSQL .= ',ST_AsSVG(geometry) as assvg'; if ($this->bIncludePolygonAsText || $this->bIncludePolygonAsPoints) $sSQL .= ',ST_AsText(geometry) as astext'; - $sFrom = ' from placex where place_id = '.$iPlaceID; + if ($fLonReverse != null && $fLatReverse != null) { + $sFrom = ' from (SELECT * , CASE WHEN (class = \'highway\') AND (ST_GeometryType(geometry) = \'ST_LineString\') THEN '; + $sFrom .=' ST_ClosestPoint(geometry, ST_SetSRID(ST_Point('.$fLatReverse.','.$fLonReverse.'),4326))'; + $sFrom .=' ELSE centroid END AS closest_point'; + $sFrom .= ' from placex where place_id = '.$iPlaceID.') as plx'; + } else { + $sFrom = ' from placex where place_id = '.$iPlaceID; + } if ($this->fPolygonSimplificationThreshold > 0) { $sSQL .= ' from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry,'.$this->fPolygonSimplificationThreshold.') as geometry'.$sFrom.') as plx'; } else { diff --combined test/bdd/api/reverse/simple.feature index ecaca483,3f307e0e..115b0fd3 --- a/test/bdd/api/reverse/simple.feature +++ b/test/bdd/api/reverse/simple.feature @@@ -11,6 -11,8 +11,8 @@@ Feature: Simple Reverse Test 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 +44,10 @@@ | 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,23 -66,25 +66,25 @@@ 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 | zoom | - | 4 | + | 8 | Then result has bounding box in 9,20,102,113 Examples: | format | | json | | jsonv2 | + | geojson | | xml | Scenario Outline: Reverse-geocoding with zoom @@@ -89,6 -97,7 +97,7 @@@ | format | | json | | jsonv2 | + | geojson | | html | | xml | diff --combined website/reverse.php index e131a844,3c3824eb..3d5a3ec7 --- a/website/reverse.php +++ b/website/reverse.php @@@ -12,7 -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 +23,10 @@@ $hLog = logStart($oDB, 'reverse', $_SER $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); @@@ -55,9 -59,7 +59,9 @@@ if (isset($aPlace)) $aPlace['place_id'], $aPlace['lon'], $aPlace['lat'], - $fRadius + $fRadius, + $fLat, + $fLon ); if ($aOutlineResult) { @@@ -77,7 -79,12 +81,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');