From ab477736045a1e68dc7545140a04cb58c8a4a06e Mon Sep 17 00:00:00 2001 From: Oleksandr Shulgin Date: Mon, 27 Apr 2015 15:16:38 +0200 Subject: [PATCH 1/2] Add polygon simplification New query string parameter polygon_threshold=<0.0..1> is introduced. The float value of this parameter (defaults to 0) is passed to ST_SimplifyPreserveTopology() on geometry we're about to output in one (or many) requested formats such as GeoJSON, KML, etc. This is useful when getting border polygons for whole countries, but rendering them at large scale, when most of the high resolution details cannot be seen anyway. For example, the unsimplified polygon data for Germany in GeoJSON format currently makes for about 3 MB response body. With use of this new parameter, the application can greatly reduce the amount of downloaded data and server response time while providing its users with the same picture. On a typical laptop screen resolution, zooming out to fit the whole country borders on screen, only 1/100 amount of details could be well enough. --- lib/Geocode.php | 8 +++++++- website/search.php | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/Geocode.php b/lib/Geocode.php index 7bd4f552..a5454867 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -12,6 +12,7 @@ protected $bIncludePolygonAsGeoJSON = false; protected $bIncludePolygonAsKML = false; protected $bIncludePolygonAsSVG = false; + protected $fPolygonSimplificationThreshold = 0.0; protected $aExcludePlaceIDs = array(); protected $bDeDupe = true; @@ -102,6 +103,11 @@ $this->bIncludePolygonAsSVG = $b; } + function setPolygonSimplificationThreshold($f) + { + $this->fPolygonSimplificationThreshold = $f; + } + function setDeDupe($bDeDupe = true) { $this->bDeDupe = (bool)$bDeDupe; @@ -1612,7 +1618,7 @@ 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"; - $sSQL .= " from placex where place_id = ".$aResult['place_id']; + $sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry,".$this->fPolygonSimplificationThreshold.") as geometry from placex where place_id = ".$aResult['place_id'].") as plx"; $aPointPolygon = $this->oDB->getRow($sSQL); if (PEAR::IsError($aPointPolygon)) { diff --git a/website/search.php b/website/search.php index a9e20d4e..ecf584ae 100755 --- a/website/search.php +++ b/website/search.php @@ -44,6 +44,8 @@ $bAsKML = (boolean)isset($_GET['polygon_kml']) && $_GET['polygon_kml']; $bAsSVG = (boolean)isset($_GET['polygon_svg']) && $_GET['polygon_svg']; $bAsText = (boolean)isset($_GET['polygon_text']) && $_GET['polygon_text']; + $fThreshold = 0.0; + if (isset($_GET['polygon_threshold'])) $fThreshold = (float)$_GET['polygon_threshold']; if ( ( ($bAsGeoJSON?1:0) + ($bAsKML?1:0) + ($bAsSVG?1:0) @@ -66,6 +68,7 @@ $oGeocode->setIncludePolygonAsGeoJSON($bAsGeoJSON); $oGeocode->setIncludePolygonAsKML($bAsKML); $oGeocode->setIncludePolygonAsSVG($bAsSVG); + $oGeocode->setPolygonSimplificationThreshold($fThreshold); } $oGeocode->loadParamArray($_GET); From 46e64bd93385d7c2e30154a07fa7cae79bf9ecee Mon Sep 17 00:00:00 2001 From: Oleksandr Shulgin Date: Wed, 29 Apr 2015 16:13:39 +0200 Subject: [PATCH 2/2] Check for positive polygon simplification threshold Don't run the simplification function if no threshold was given (or in case of a negative one). Also process the query string parameter in case of html out format. --- lib/Geocode.php | 11 ++++++++++- website/search.php | 8 +++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/Geocode.php b/lib/Geocode.php index a5454867..6781ceec 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -1618,7 +1618,16 @@ 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"; - $sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry,".$this->fPolygonSimplificationThreshold.") as geometry from placex where place_id = ".$aResult['place_id'].") as plx"; + $sFrom = " from placex where place_id = ".$aResult['place_id']; + if ($this->fPolygonSimplificationThreshold > 0) + { + $sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry,".$this->fPolygonSimplificationThreshold.") as geometry".$sFrom.") as plx"; + } + else + { + $sSQL .= $sFrom; + } + $aPointPolygon = $this->oDB->getRow($sSQL); if (PEAR::IsError($aPointPolygon)) { diff --git a/website/search.php b/website/search.php index ecf584ae..bf27ef9a 100755 --- a/website/search.php +++ b/website/search.php @@ -44,8 +44,6 @@ $bAsKML = (boolean)isset($_GET['polygon_kml']) && $_GET['polygon_kml']; $bAsSVG = (boolean)isset($_GET['polygon_svg']) && $_GET['polygon_svg']; $bAsText = (boolean)isset($_GET['polygon_text']) && $_GET['polygon_text']; - $fThreshold = 0.0; - if (isset($_GET['polygon_threshold'])) $fThreshold = (float)$_GET['polygon_threshold']; if ( ( ($bAsGeoJSON?1:0) + ($bAsKML?1:0) + ($bAsSVG?1:0) @@ -68,9 +66,13 @@ $oGeocode->setIncludePolygonAsGeoJSON($bAsGeoJSON); $oGeocode->setIncludePolygonAsKML($bAsKML); $oGeocode->setIncludePolygonAsSVG($bAsSVG); - $oGeocode->setPolygonSimplificationThreshold($fThreshold); } + // Polygon simplification threshold (optional) + $fThreshold = 0.0; + if (isset($_GET['polygon_threshold'])) $fThreshold = (float)$_GET['polygon_threshold']; + $oGeocode->setPolygonSimplificationThreshold($fThreshold); + $oGeocode->loadParamArray($_GET); if (CONST_Search_BatchMode && isset($_GET['batch']))