【问题标题】:Tools or libraries for getting cross-section of 2D polygons into 1D geometry?用于将 2D 多边形的横截面转换为 1D 几何图形的工具或库?
【发布时间】:2013-12-17 09:54:45
【问题描述】:

我是一名业余飞行员,从事一些空域建模实验。我想要实现的是一种轻松创建空域横截面的工具,即 3D 空域到 2D。所以最后我想创建一个类似的图像:airspace example。准确性并不重要,因为这些横截面不会用于导航目的,而仅用于培训/可视化。因此坐标几何就足够了,不需要测地线计算。

目前,我将 GeoJSON 2D 几何图形(所有多边形)存储在我的数据库中,其中包含包含每个空域元素的上下高度限制的附加元数据。因此,我实际上只在我的 OpenLayers 和 Leaflet.js 地图上显示 2D 数据。

我希望用户能够在地图上绘制线串(请参见下图中的绿色线串,出于演示目的,笔划宽度显着增加)。我可以用 OpenLayers 或 Leaflet 来做到这一点。结果应该是与用户绘制的线相交的 2D 元素的 1 维横截面,就像我在这个非常艺术的插图中一样:

澄清:如果输出的一维横截面的长度例如为1L,那么示例中横截面的内容应该是一组以下几何图形:1)0.1L和0.1L之间的黑线0.5L 和 2) 0.7L 和 0.825L 之间的红线。

用户界面部分是可行的,它将运行在 OpenLayers 或 Leaflet 之上。我还发现了几种不同语言的算法,用于确定两条线是否相交,甚至找出相交点。然后我可以使用 Raphael.js 来绘制横截面。

我应该能够在一两天内完成所有这些...但我想知道 是否有更简单的方法可以采取?例如,有没有人知道一个软件库可以计算我想要实现的横截面?哦,请不要提及那些 10,000 美元的 GIS 包:-)。

由于这将是一个 Web 应用程序,我主要研究 Javascript、Perl 或 PHP 解决方案。 GeoJSON Utilities for JavaScript 看起来很适合计算交点,不知道还有没有其他的?

【问题讨论】:

    标签: javascript mapping openlayers intersection geojson


    【解决方案1】:

    发布我自己问题的答案以供将来参考。我能够想出一个创建空域横截面的解决方案。它基于坐标几何。

    1) 输入数据是横截面的起点和终点坐标。

    2) 遍历所有区域并检查开始和/或结束坐标是否落在任何空域区域(多边形)内。 PHP 代码从另一个 SO 答案略微修改,以检查点是否在多边形内:

    // Point class, storage of lat/long-pairs
    class Point {
      var $lat;
      var $long;
      function Point($lat, $long) {
        $this->lat = $lat;
        $this->long = $long;
      }
    }
    
    function pointInPolygon($p, $polygon) {
      $c = 0;
      $p1 = $polygon[0];
      $n = count($polygon);
    
      for ($i=1; $i<=$n; $i++) {
        $p2 = $polygon[$i % $n];
        if ($p->long > min($p1->long, $p2->long)
            && $p->long <= max($p1->long, $p2->long)
            && $p->lat <= max($p1->lat, $p2->lat)
            && $p1->long != $p2->long) {
                $xinters = ($p->long - $p1->long) * ($p2->lat - $p1->lat) / ($p2->long - $p1->long)
           if ($p1->lat == $p2->lat || $p->lat <= $xinters) {
             $c++;
           }
        }
        $p1 = $p2;
      }
      // if the number of edges we passed through is even, then it's not in the poly.
      return $c%2!=0;
    }
    

    3) 循环遍历包含空域数据的每个区域(多边形)的所有线段。 PHP 代码从另一个 SO 答案稍作修改以返回两条线段的交点:

    function Det2($x1, $x2, $y1, $y2) {
      return ($x1 * $y2 - $y1 * $x2);
    }
    
    function lineIntersection ($v1Y, $v1X, $v2Y, $v2X, $v3Y, $v3X, $v4Y, $v4X) {
      $tolerance = 0.000001;
    
      $a = Det2($v1X - $v2X, $v1Y - $v2Y, $v3X - $v4X, $v3Y - $v4Y);
      if (abs($a) < $tolerance) return null; // Lines are parallel
    
      $d1 = Det2($v1X, $v1Y, $v2X, $v2Y);
      $d2 = Det2($v3X, $v3Y, $v4X, $v4Y);
      $x = Det2($d1, $v1X - $v2X, $d2, $v3X - $v4X) / $a;
      $y = Det2($d1, $v1Y - $v2Y, $d2, $v3Y - $v4Y) / $a;
    
      if ($x < min($v1X, $v2X) - $tolerance || $x > max($v1X, $v2X) + $tolerance) return null;
      if ($y < min($v1Y, $v2Y) - $tolerance || $y > max($v1Y, $v2Y) + $tolerance) return null;
      if ($x < min($v3X, $v4X) - $tolerance || $x > max($v3X, $v4X) + $tolerance) return null;
      if ($y < min($v3Y, $v4Y) - $tolerance || $y > max($v3Y, $v4Y) + $tolerance) return null;
    
      return array($x, $y);
    }
    

    4) 如果有相交的线段,计算出相交的距离(作为上一步的结果)到横截面的起始坐标。将其除以横截面的总长度,得到空域区域边界在横截面上的相对位置。

    5) 根据第 2 点和第 4 点的结果,绘制 SVG 多边形。相对交点位置被转换为多边形的 X 坐标,高度数据(下限和上限)成为多边形的 Y 坐标。

    【讨论】:

      猜你喜欢
      • 2012-09-27
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 2013-09-18
      • 2021-05-17
      • 2016-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多