Google 地图 Flash - 带孔的多边形,穿过子午线

发布于 2024-10-12 16:32:55 字数 3957 浏览 4 评论 0原文

我在使用包含以下内容的多边形创建覆盖层时遇到问题 多段折线。

我想创建一个为某些国家/地区切出孔的多边形(以显示 哪些区域是禁区)。我通过创建一个具有多个的多边形来做到这一点 折线。 创建第一条多段线以覆盖地图的整个可见区域。

我从这个开始:

只跨越一个区域 - 180/180

    var outer:Array = [ new LatLng(90, -180),
                        new LatLng(90, 180),
                        new LatLng(-90, 180),
                        new LatLng(-90, -180),
                        new LatLng(90, -180)]

    donut = new Polygon([],
                                        new PolygonOptions({
                                            strokeStyle: new StrokeStyle({
                                                thickness: 0}),
                                            fillStyle: new FillStyle({
                                                color: 0x000000,
                                                alpha: 0.5})
                                            }));

    donut.setPolyline(0, outer)
    map.addOverlay(donut);    

显然,这有一个问题,即只跨越一批纬度/经度。而当 缩小了,这不起作用。为了解决这个问题,我尝试了限制 地图的 toSpan() 和 getNorth()、getSouth() 等。这些没有返回 可见地图的真实跨度 - 最大为 180/360。

我的解决方案是使用 fromViewportToLatLng() 的像素点 地图,并将 opt_nowrap 设置为“true”

    var pnw:LatLng = map.fromViewportToLatLng(new Point(0, 0), true)
    var pse:LatLng = map.fromViewportToLatLng(new Point(map.width, map.height),
    true)

这产生了与此类似的结果

    Lat Lng North West (89.77386689378173, -614.3294000000001)
    LatLng South East  (-89.07253945829217, 370.0455999999999)

从这里我可以正确设置折线(在地图上移动和缩放 事件)以覆盖整个地图,无论经度有多少跨度 发生:

    outer = [
             new LatLng(pnw.lat(), pnw.lng(), true),
             new LatLng(pnw.lat(), pse.lng(), true),
             new LatLng(pse.lat(), pse.lng(), true),
             new LatLng(pse.lat(), pnw.lng(), true),    
             new LatLng(pnw.lat(), pnw.lng(), true)    
            ]
    donut.setPolyline(0, outer)

*到目前为止一切顺利。 * 现在,我想将甜甜圈孔添加到我的多边形中,再次将折线添加到 甜甜圈多边形。

    private var australia:Array    = [
                                      new LatLng(-9.7716, 143.0241),
                                      new LatLng(-23.4610, 158.1852),
                                      new LatLng(-45.1338, 147.1549),
                                      new LatLng(-35.2615, 111.5153),
                                      new LatLng(-20.6921, 113.0094),
                                      new LatLng(-10.0746, 130.3239),
                                      new LatLng(-9.7716, 143.0241)
                                     ]

    private var nz:Array    = [
                               new LatLng(-33.5951, 165.8254),
                               new LatLng(-33.5951, 179.7341),
                               new LatLng(-48.3845, 179.7341),
                               new LatLng(-48.3845, 165.8254),
                               new LatLng(-33.5951, 165.8254)
                              ]                

    private var hawaii:Array    = [            
                                   new LatLng(21.8000, -160.4347),
                                   new LatLng(22.5477, -159.7975),
                                   new LatLng(21.4067, -156.3533),
                                   new LatLng(19.5336, -154.4197),
                                   new LatLng(18.6511, -155.6392),
                                   new LatLng(20.6633, -157.8639),
                                   new LatLng(21.8000, -160.4347)    
                                   ]

    donut.setPolyline(1, hawaii)
    donut.setPolyline(2, nz)
    donut.setPolyline(3, australia)

问题在于子午线在地图视口中可见时。这 当放大时,问题更加明显,因为甜甜圈孔折线会跳跃
从可见视口到纬度长跨度的另一侧。

有时外部数组甚至无法正确渲染,导致甜甜圈 多边形本质上反转(国家上的多边形,而不是 剪纸)

我意识到这是一个很难想象的事情。我已附上 .as + .fla 文件以防有人想要测试它。

http://www.digital.leskiwis.com/maps/MapTest.zip

I have a problem with creating an overlay with a polygon that contains
multiple polylines.

I want to create a polygon with holes cut out for certain countries (to show
which areas are off limits). I do this by creating a polygone with multiple
polylines.
The first polyline was created to cover the entire visible area of the map.

i started off with this:

To get around only spanning one region-180/180

    var outer:Array = [ new LatLng(90, -180),
                        new LatLng(90, 180),
                        new LatLng(-90, 180),
                        new LatLng(-90, -180),
                        new LatLng(90, -180)]

    donut = new Polygon([],
                                        new PolygonOptions({
                                            strokeStyle: new StrokeStyle({
                                                thickness: 0}),
                                            fillStyle: new FillStyle({
                                                color: 0x000000,
                                                alpha: 0.5})
                                            }));

    donut.setPolyline(0, outer)
    map.addOverlay(donut);    

Obviously this has a problem with only spanning one lot of lat/lng. And when
zoomed out, this doesnt work. To get around this i tried getting the bounds
of the map, toSpan() and getNorth(),getSouth() and so on. These didnt return
a true span of the visible map - as it maxed out at 180/360.

My solution was to use fromViewportToLatLng() of the pixel points of the
map, and set the opt_nowrap to 'true'

    var pnw:LatLng = map.fromViewportToLatLng(new Point(0, 0), true)
    var pse:LatLng = map.fromViewportToLatLng(new Point(map.width, map.height),
    true)

This produced results similar to this

    Lat Lng North West (89.77386689378173, -614.3294000000001)
    LatLng South East  (-89.07253945829217, 370.0455999999999)

From here i can then correctly set the polyline (on map move and zoom
events) to cover the entire map, no matter how many spans of longitude
occur:

    outer = [
             new LatLng(pnw.lat(), pnw.lng(), true),
             new LatLng(pnw.lat(), pse.lng(), true),
             new LatLng(pse.lat(), pse.lng(), true),
             new LatLng(pse.lat(), pnw.lng(), true),    
             new LatLng(pnw.lat(), pnw.lng(), true)    
            ]
    donut.setPolyline(0, outer)

*So far so good. *
Now, i want to add the donut holes to my polygon, again adding polylines to
the donut polygon.

    private var australia:Array    = [
                                      new LatLng(-9.7716, 143.0241),
                                      new LatLng(-23.4610, 158.1852),
                                      new LatLng(-45.1338, 147.1549),
                                      new LatLng(-35.2615, 111.5153),
                                      new LatLng(-20.6921, 113.0094),
                                      new LatLng(-10.0746, 130.3239),
                                      new LatLng(-9.7716, 143.0241)
                                     ]

    private var nz:Array    = [
                               new LatLng(-33.5951, 165.8254),
                               new LatLng(-33.5951, 179.7341),
                               new LatLng(-48.3845, 179.7341),
                               new LatLng(-48.3845, 165.8254),
                               new LatLng(-33.5951, 165.8254)
                              ]                

    private var hawaii:Array    = [            
                                   new LatLng(21.8000, -160.4347),
                                   new LatLng(22.5477, -159.7975),
                                   new LatLng(21.4067, -156.3533),
                                   new LatLng(19.5336, -154.4197),
                                   new LatLng(18.6511, -155.6392),
                                   new LatLng(20.6633, -157.8639),
                                   new LatLng(21.8000, -160.4347)    
                                   ]

    donut.setPolyline(1, hawaii)
    donut.setPolyline(2, nz)
    donut.setPolyline(3, australia)

The problem lies when the meridian line is visible in the map viewport. This
problem is more evident when zommed in, as the donut hole polylines jump
from the visible viewport to the other side of a lat long span.

Sometimes the outer array doesnt even correctly render, causing the donut
polygon to essentialy invert (polygons over the countries, rather than
cutouts)

I realise this is a tough one to visualise. I have attached the .as + .fla
file in case anyone wants to test it out.

http://www.digital.leskiwis.com/maps/MapTest.zip

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

债姬 2024-10-19 16:32:55

那么您正在尝试制作一个大多边形,其中为澳大利亚、新西兰、夏威夷...?您添加折线的代码对我来说似乎是错误的。我将从大正方形开始:

 var outer:Array = [ new LatLng(90, -180),
                        new LatLng(90, 180),
                        new LatLng(-90, 180),
                        new LatLng(-90, -180),
                        new LatLng(90, -180)]

    donut = new Polygon([outer],
    new PolygonOptions({
   strokeStyle: new StrokeStyle({
      thickness: 0}),
      fillStyle: new FillStyle({
      color: 0x000000,
      alpha: 0.5})
}));

然后添加孔

//define au, nz, hi
//...

//the 0th polyline is already the outer edge...
donut.setPolyline(1, hi);
donut.setPolyline(2, nz);
donut.setPolyline(3, au);

现在您的甜甜圈是一个有 3 个孔的大矩形。
然后将其添加到地图中:

map.addOverlay(donut);

我之前在 Google 地图中处理过许多跨越半球和子午线的多边形,您不必弄乱视口或缩放区域或类似的东西。只要您按照您认为的方式定义多边形,GM 就会在任何边界矩形中正确绘制它(即使您放大到看不到多边形的边缘)。

我看到的另一件事是,你制作的覆盖整个世界的巨型多边形有点模糊:例如 90、-180 和 90,180 是同一点(北极),连接这些坐标的线的长度为 0 。在墨卡托,在两极做事有点令人沮丧。有可能把它从北纬 89° 切掉吗?我认为这会让你的外多边形更快乐。

So you're trying to make a big polygon with holes cut out for Australia, nz, Hawaii,...? Your code for adding the polylines seems wrong to me. I'd start with the big square:

 var outer:Array = [ new LatLng(90, -180),
                        new LatLng(90, 180),
                        new LatLng(-90, 180),
                        new LatLng(-90, -180),
                        new LatLng(90, -180)]

    donut = new Polygon([outer],
    new PolygonOptions({
   strokeStyle: new StrokeStyle({
      thickness: 0}),
      fillStyle: new FillStyle({
      color: 0x000000,
      alpha: 0.5})
}));

Then add your holes

//define au, nz, hi
//...

//the 0th polyline is already the outer edge...
donut.setPolyline(1, hi);
donut.setPolyline(2, nz);
donut.setPolyline(3, au);

Now you dounut is a big rectangle with 3 holes.
Then add it to the map:

map.addOverlay(donut);

I've worked with lots of polygons that crossed hemispheres and meridians in Google Maps before, you don't have to mess with the viewport or zoom region or anything like that. As long as you're defining the polygon the way you think you are, GM will draw it correctly in any bounding rect (even if you are zoomed in so far that no edge of the polygon is visible).

The other thing I see is that the giant polygon you're making to cover the whole world is a little ambiguous: For example 90,-180 and 90,180 are the same point (the north pole) a line connecting those coordinates would have 0 length. Doing stuff at the poles is kinda effed in Mercator. Any possibility of cutting it off a 89° N? I think that would make your outer polygon more happy.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文