【问题标题】:Prevent Overlap of Polygon onto itself [closed]防止多边形自身重叠[关闭]
【发布时间】:2011-11-14 14:58:36
【问题描述】:

我正在使用 Google Maps V3 API 创建一个多边形。它从一个正方形的 4 边多边形开始。

问题:现在,当向多边形添加一个新点时,多边形可能会以奇怪的形状重叠自身,而不是形成五边形。这是因为多边形是按照点添加到数组的顺序绘制的。是否可以重新排列多边形点以使 2 条线不重叠?

【问题讨论】:

  • 图像映射也有同样的问题。在几何上,您要做的是遍历点列表,并确保多边形的两条不连续的边不相交。在代数上,您需要首先查看两条边是否平行,如果不平行,请查看穿过它们的(无限)线是否在边内相交。真正的问题是,当您向多边形添加更多点时,必须测试的边对的数量会急剧增加。
  • 另一种方法,对我来说似乎更简单:如果新点 (a) 不在现有多边形的内部并且 (b) 创建的内角大于 180 度,那么它必须是无效的。有许多现有的算法可以测试一个点是否在多边形的内部 (stackoverflow.com/q/471962/901048),而测量内角就是找出每个斜率的反正切之间的差异 (en.wikipedia.org/wiki/Analytic_geometry#Distance_and_angle)。

标签: javascript jquery google-maps google-maps-api-3 gis


【解决方案1】:

我已经成功实施了 Blazemonger 的上述建议,它对我有用。

这是他的新颖建议:

另一种方法,对我来说似乎更简单:如果新点是 (a) 不在现有多边形的内部,并且 (b) 创建一个 内角大于 180 度,则必须无效。 有许多现有的算法来测试一个点是否在 多边形的内部(stackoverflow.com/q/471962/901048)和 测量内角是找出差异的问题 每个斜率的反正切之间

为了确定该点是否在多边形中,我使用了 Mike Williams 更新的 epoly.js 中的 polygon.Contains 函数,可在此处找到:http://www.geocodezip.com/scripts/v3_epoly.js

如果点不在多边形中(见上文),我们: 1.) 确定最后两个向量的内角是否大于 180 度。为此,我们需要实现以下等式来找到多边形最后两个向量的角度:

angleRadians = Math.acos((vx1 * vx2 + vy1 * vy2) / ( Math.sqrt( vx1*vx1 + vy1*vy1 ) * Math.sqrt( vx2*vx2 + vy2*vy2 ) ));

这是使用向量的点积。

但这并没有考虑到“绕线方向”,首先你必须得到叉积,如果叉积为正,则左转,如果为负,则右转。

我在这里包含了我的 JS 代码,作为要点:https://gist.github.com/3741816

顺便说一句,我是 StackOverflow 的新手——感谢所有做出贡献的人,这对我来说是一个很好的资源!

【讨论】:

    【解决方案2】:

    我们可以检测两个多边形的重叠。但是我只是在 js 中编码,然后我们可以通过警告错误来防止多边形重叠。

    1. 包括库的 cdns。
    2. 现有的多边形是 js 变量或 js 数组中的多边形形状。(即)
    3. 制作新的多边形。
    4. 从第二个多边形搜索到第一个多边形。 两个多边形相同,因此您可以更改它们。 这些 CDN 库您必须使用它们。

    https://maps.googleapis.com/maps/api/js?v=3 https://code.jquery.com/jquery-1.11.1.min.js https://bl.ocks.org/christophermanning/raw/4450188/javascript.util.min.js https://bl.ocks.org/christophermanning/raw/4450188/jsts.min.js https://cdnjs.cloudflare.com/ajax/libs/wicket/1.1.0/wicket.js https://cdnjs.cloudflare.com/ajax/libs/wicket/1.1.0/wicket-gmap3.js

              var values=[ new google.maps.LatLng(59.73858,10.24296), new 
               google.maps.LatLng(59.74879,10.26459), new 
               google.maps.LatLng(59.73858,10.28965), new 
               google.maps.LatLng(59.7192,10.28965), new 
               google.maps.LatLng(59.7192,10.24296), new 
               google.maps.LatLng(59.73858,10.24296)];
              var new_shape=[ new google.maps.LatLng(59.73858,10.24296), new 
               google.maps.LatLng(59.74879,10.26459), new 
               google.maps.LatLng(59.73858,10.28965), new 
                google.maps.LatLng(59.7192,10.28965), new 
                google.maps.LatLng(59.7192,10.24296), new 
                google.maps.LatLng(59.73858,10.24296)];
    
    
               var existing_polygon = new google.maps.Polygon({
                             paths: values,
                             strokeColor: #000000,
                             strokeOpacity: 0.8,
                             strokeWeight: 1.5,
                             fillColor: #ff0000,
                             fillOpacity: 0.35,
                               });
    
                  var polygone_new_shape= new google.maps.Polygon({
                         paths: [new_shape],
                         strokeColor: '#000000',
                         strokeOpacity: 0.8,
                         strokeWeight: 1,
                         fillColor: '#00FF00',
                         fillOpacity: 0.35
                         });
    
    
             var wkt = UseWicketToGoFromGooglePolysToWKT(existing_polygon, polygone_new_shape);
             var result= UseJstsToTestForIntersection(wkt,wkt);
                    if(result==true){
                       alert("Polygon are overlapping existing polygon");
                       }
    
           function UseWicketToGoFromGooglePolysToWKT(poly1, poly2) {
    
                     var wicket = new Wkt.Wkt();
                      wicket.fromObject(poly1);
                      var wkt1 = wicket.write();
                      wicket.fromObject(poly2);
                      var wkt2 = wicket.write();
                        return [wkt1, wkt2];
                      }
             function UseJstsToTestForIntersection(wkt1, wkt2) {
    
                      var wktReader = new jsts.io.WKTReader();
                      var geom1 = wktReader.read(wkt1);
                      var geom2 = wktReader.read(wkt2);
                      var result;
                     if (geom2.intersects(geom1)) {
                       result=true;
                      }else{
                      result=false;
                      }
                     return result;
                    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-18
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      相关资源
      最近更新 更多