【问题标题】:border around geo coordinates地理坐标的边界
【发布时间】:2014-03-24 07:55:04
【问题描述】:

我在 Google 地图上显示了一组地理坐标。如何确定最外面的点以构建包含所有点的多边形边界?

我已经知道如何创建多边形了。但我需要确定所有外点。

所有的地理坐标都在一个 mysql 数据库中。我想使用 PHP 来分隔创建多边形所需的坐标。

我不是在寻找如何做一个边界框。

【问题讨论】:

    标签: php google-maps google-maps-api-3 geocoding


    【解决方案1】:

    您可以使用 delaunay 三角剖分并连接凸包上的所有顶点,即找到不与邻居的顶点。你可以在@phpclasses.org 下载我的php 类凸包。您还可以查看我的网站 http://www.phpdevpad.de/geofence 作为 delaunay 三角剖分和基于 lat-lng 对的凹壳的示例。你可以用我的例子没有。 5 找到 lat-lng 对的凸包:

    require_once("convex-hull.php"); 
    //example5 
    $mapPadding  = 100; 
    $mapWidth    = 500; 
    $mapHeight   = 500; 
    $mapLonLeft  =1000; 
    $mapLatBottom=1000; 
    $mapLonRight =   0; 
    $mapLatTop   =   0; 
    $set=array(); 
    $geocoord = array ("8.6544487,50.1005233", 
                       "8.7839489,50.0907496", 
                       "8.1004734,50.2002273", 
                       "8.4117234,50.0951493", 
                       "8.3508367,49.4765982", 
                       "9.1828630,48.7827027", 
                       "9.1686483,48.7686426", 
                       "9.2118466,48.7829101", 
                       "8.9670738,48.9456327"); 
    
    foreach ($geocoord as $key => $arr) 
    { 
        list($lon,$lat) = explode(",",$arr); 
        $mapLonLeft = min($mapLonLeft,$lon); 
        $mapLonRight = max($mapLonRight,$lon); 
        $mapLatBottom = min($mapLatBottom,$lat); 
        $mapLatTop = max($mapLatTop,$lat); 
        $set[]=array($lon,$lat); 
    } 
    
    $mapLonDelta = $mapLonRight-$mapLonLeft; 
    $mapLatDelta = $mapLatTop-$mapLatBottom; 
    $mapLatTopY=$mapLatTop*(M_PI/180); 
    $worldMapWidth=(($mapWidth/$mapLonDelta)*360)/(2*M_PI); 
    $LatBottomSin=min(max(sin($mapLatBottom*(M_PI/180)),-0.9999),0.9999); 
    $mapOffsetY=$worldMapWidth/2 * log((1+$LatBottomSin)/(1-$LatBottomSin)); 
    $LatTopSin=min(max(sin($mapLatTop*(M_PI/180)),-0.9999),0.9999); 
    $mapOffsetTopY=$worldMapWidth/2 * log((1+$LatTopSin)/(1-$LatTopSin)); 
    $mapHeightD=$mapOffsetTopY-$mapOffsetY; 
    $mapRatioH=$mapHeight/$mapHeightD; 
    $newWidth=$mapWidth*($mapHeightD/$mapHeight); 
    $mapRatioW=$mapWidth/$newWidth; 
    
    foreach ($set as $key => $arr) 
    { 
        list($lon,$lat) = $arr; 
        $tx = ($lon - $mapLonLeft) * ($newWidth/$mapLonDelta)*$mapRatioW; 
        $f = sin($lat*M_PI/180); 
        $ty = ($mapHeightD-(($worldMapWidth/2 * log((1+$f)/(1-$f)))-$mapOffsetY)); 
    } 
    
    $chull=new convexhull(); 
    $chull->main($set,$mapWidth,$mapHeightD); 
    

    那么convex-hull在数组中,你需要从超三角形中移除顶点并检查顶点是否在lat-lng对中:

    foreach ($chull->convexhull as $key => $arr)
          {
         foreach ($arr as $ikey => $iarr)
         {
            list($x1,$y1,$x2,$y2) = $iarr;
            if (abs($x1) != SUPER_TRIANGLE && abs($y1) != SUPER_TRIANGLE && abs($x2) != SUPER_TRIANGLE && abs($y2) != SUPER_TRIANGLE)
            {
               $ok=0;
               foreach ($chull->pointset as $iikey => $iiarr)
               {
              if ($iiarr==array($x1,$y1))
              {
                 $ok=1;
              }
               }
               if ($ok)
               {
              solution[]=set[$iikey];  
               }
            }
         }
          }
    

    【讨论】:

    • 完美。正是我需要知道的。 5,000 或高达 20,000 点的性能如何?
    • 如果我的回答有帮助,请考虑接受。非常感谢!?
    • 是的,不确定接受它是否会关闭更多的 cmets。谢谢你的帮助。我必须测试性能。
    • 高达 2000-5000 点,这不是那么成问题。但是,您可以使用另一种算法并将点提升到抛物面。但也可以试试快速船体算法:westhoffswelt.de/blog/2009/10/21/….
    • Phpdna,快速外壳非常好用。不是不完美。谢谢你的建议。我想试试你的,但觉得有点困难。它只返回一个图像吗?您能否分享一个传入地理坐标数组并仅将边缘坐标作为数组返回的示例?谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 1970-01-01
    • 2019-05-27
    • 2015-08-08
    • 1970-01-01
    • 2014-05-15
    • 2015-11-26
    相关资源
    最近更新 更多