]> git.openstreetmap.org Git - nominatim.git/commitdiff
simplify geometry handling in details page
authorSarah Hoffmann <lonvia@denofr.de>
Thu, 8 Nov 2012 21:21:20 +0000 (22:21 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Thu, 8 Nov 2012 21:21:20 +0000 (22:21 +0100)
Hand the WKT directly to OpenLayers and let the client do the parsing,
it will be able to handle multipolygons as well as line strings.
Simplify geometries if they have too many points.

Also limit the number of child objects listed to 500.

lib/template/details-html.php
website/details.php

index 3eaca8add06552d52b8be411472f6a924d41f036..a4619b55c6173adac947242e097fd0098374571a 100644 (file)
@@ -73,23 +73,27 @@ body {
                        };
                        var proj_EPSG4326 = new OpenLayers.Projection("EPSG:4326");
                        var proj_map = map.getProjectionObject();
-                       var latlon;
-<?php
-if (isset($aPolyPoints))
-{
-       foreach($aPolyPoints as $aPolyPoint)
-       {
-               echo "                        pointList.push(new OpenLayers.Geometry.Point(".$aPolyPoint[1].",".$aPolyPoint[2]."));\n";
-       }
-}
-?>
-                       var linearRing = new OpenLayers.Geometry.LinearRing(pointList).transform(proj_EPSG4326, proj_map);;
-                       var polygonFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon([linearRing]),null,style);
-                       vectorLayer.addFeatures([polygonFeature]);
 
-                       map.zoomToExtent(new OpenLayers.Bounds(<?php echo $aPointPolygon['minlon']?>, <?php echo $aPointPolygon['minlat']?>, <?php echo $aPointPolygon['maxlon']?>, <?php echo $aPointPolygon['maxlat']?>).transform(proj_EPSG4326, proj_map));
+                       freader = new OpenLayers.Format.WKT({
+                               'internalProjection': proj_map,
+                               'externalProjection': proj_EPSG4326
+                       });
+
+                       var feature = freader.read('<?php echo $aPointDetails['outlinestring'];?>');
+                       if (feature) {
+                               map.zoomToExtent(feature.geometry.getBounds());
+
+                               feature.style = {
+                                       strokeColor: "#75ADFF",
+                                       fillColor: "#F0F7FF",
+                                       strokeWidth: <?php echo ($aPointDetails['isarea']=='t'?'2':'5');?>,
+                                       strokeOpacity: 0.75,
+                                       fillOpacity: 0.75,
+                                       pointRadius: 100
+                               };
+                               vectorLayer.addFeatures([feature]);
+                       }
                }
-               
        </script>
   </head>
   <body onload="init();">
@@ -147,7 +151,7 @@ if (isset($aPolyPoints))
                echo '<span class="type"><span class="label">Type: </span>'.$aAddressLine['class'].':'.$aAddressLine['type'].'</span>';
                if ($sOSMType) echo ', <span class="osm"><span class="label"></span>'.$sOSMType.' <a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aAddressLine['osm_id'].'">'.$aAddressLine['osm_id'].'</a></span>';
                echo ', <span class="adminlevel">'.$aAddressLine['admin_level'].'</span>';
-               echo ', <span class="rankaddress">'.$aAddressLine['rank_search_label'].'</span>';
+               if (isset($aAddressLine['rank_search_label']) echo ', <span class="rankaddress">'.$aAddressLine['rank_search_label'].'</span>';
 //             echo ', <span class="area">'.($aAddressLine['fromarea']=='t'?'Polygon':'Point').'</span>';
                echo ', <span class="distance">'.$aAddressLine['distance'].'</span>';
                echo ' <a href="details.php?place_id='.$aAddressLine['place_id'].'">GOTO</a>';
@@ -231,6 +235,9 @@ if (isset($aPolyPoints))
                        echo '</div>';
                }
                }
+               if (sizeof($aParentOfLines) >= 500) {
+                       echo '<p>There are more child objects which are not shown.</p>';
+               }
                echo '</div>';
        }
 
index dcfe2090bf37ff4b06d72292048959dc2797c353..ad6da237356ae749fe0c3ede3268dd0c49c199d6 100755 (executable)
@@ -60,7 +60,8 @@
        // Get the details for this point
        $sSQL = "select place_id, osm_type, osm_id, class, type, name, admin_level, housenumber, street, isin, postcode, country_code, importance, wikipedia,";
        $sSQL .= " parent_place_id, rank_address, rank_search, get_searchrank_label(rank_search) as rank_search_label, get_name_by_language(name,$sLanguagePrefArraySQL) as localname, ";
-       $sSQL .= " ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea,ST_GeometryType(geometry) as geotype, ST_Y(ST_Centroid(geometry)) as lat,ST_X(ST_Centroid(geometry)) as lon ";
+       $sSQL .= " ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, ";
+       $sSQL .= " ST_AsText(CASE WHEN ST_NPoints(geometry) > 5000 THEN ST_SimplifyPreserveTopology(geometry, 0.0001) ELSE geometry END) as outlinestring";
        $sSQL .= " from placex where place_id = $iPlaceID";
        $aPointDetails = $oDB->getRow($sSQL);
        if (PEAR::IsError($aPointDetails))
@@ -69,9 +70,6 @@
        }
 
         $aPointDetails['localname'] = $aPointDetails['localname']?$aPointDetails['localname']:$aPointDetails['housenumber'];
-       $fLon = $aPointDetails['lon'];
-       $fLat = $aPointDetails['lat'];
-       $iZoom = 14;
 
        $aClassType = getClassTypesWithImportance();
        $aPointDetails['icon'] = $aClassType[$aPointDetails['class'].':'.$aPointDetails['type']]['icon'];
        $sSQL = "select (each(extratags)).key,(each(extratags)).value from placex where place_id = $iPlaceID order by (each(extratags)).key";
        $aPointDetails['aExtraTags'] = $oDB->getAssoc($sSQL);
 
-       // Get the bounding box and outline polygon
-       $sSQL = "select ST_AsText(geometry) as outlinestring,";
-       $sSQL .= "ST_YMin(geometry) as minlat,ST_YMax(geometry) as maxlat,";
-       $sSQL .= "ST_XMin(geometry) as minlon,ST_XMax(geometry) as maxlon";
-       $sSQL .= " from placex where place_id = $iPlaceID";
-       $aPointPolygon = $oDB->getRow($sSQL);
-       IF (PEAR::IsError($aPointPolygon))
-       {
-               failInternalError("Could not get bounding box of place object.", $sSQL, $aPointPolygon);
-       }
-       if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#',$aPointPolygon['outlinestring'],$aMatch))
-       {
-               preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER);
-       }
-       elseif (preg_match('#MULTIPOLYGON\\(\\(\\(([- 0-9.,]+)#',$aPointPolygon['outlinestring'],$aMatch))
-       {
-               // TODO: this just takes the first ring
-               preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER);
-       }
-       elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#',$aPointPolygon['outlinestring'],$aMatch))
-       {
-               $fRadius = 0.01;
-               if ($aPointDetails['rank_search'] > 20) $fRadius = 0.0001;
-               $iSteps = min(max(($fRadius * 40000)^2,16),100);
-               $fStepSize = (2*pi())/$iSteps;
-               $aPolyPoints = array();
-               for($f = 0; $f < 2*pi(); $f += $fStepSize)
-               {
-
-                       $aPolyPoints[] = array('',$aMatch[1]+($fRadius*sin($f)),$aMatch[2]+($fRadius*cos($f)));
-               }
-               $aPointPolygon['minlat'] = $aPointPolygon['minlat'] - $fRadius;
-               $aPointPolygon['maxlat'] = $aPointPolygon['maxlat'] + $fRadius;
-               $aPointPolygon['minlon'] = $aPointPolygon['minlon'] - $fRadius;
-               $aPointPolygon['maxlon'] = $aPointPolygon['maxlon'] + $fRadius;
-       }
-
        // Address
        $aAddressLines = getAddressDetails($oDB, $sLanguagePrefArraySQL, $iPlaceID, $aPointDetails['country_code'], true);
 
        $aLinkedLines = $oDB->getAll($sSQL);
 
        // All places this is an imediate parent of
-       $sSQL = "select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, st_distance(geometry, placegeometry) as distance, ";
+       $sSQL = "select obj.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, st_distance(geometry, placegeometry) as distance, ";
        $sSQL .= " get_name_by_language(name,$sLanguagePrefArraySQL) as localname, length(name::text) as namelength ";
-       $sSQL .= " from placex, (select geometry as placegeometry from placex where place_id = $iPlaceID) as x";
-       $sSQL .= " where parent_place_id = $iPlaceID";
-       $sSQL .= " order by rank_address asc,rank_search asc,get_name_by_language(name,$sLanguagePrefArraySQL),housenumber";
+       $sSQL .= " from (select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, rank_search, geometry, name from placex ";
+       $sSQL .= " where parent_place_id = $iPlaceID order by rank_address asc,rank_search asc limit 500) as obj,";
+       $sSQL .= " (select geometry as placegeometry from placex where place_id = $iPlaceID) as x";
+       $sSQL .= " order by rank_address asc,rank_search asc,localname,housenumber";
        $aParentOfLines = $oDB->getAll($sSQL);
 
        $aPlaceSearchNameKeywords = false;