2

我正在构建 ac# 应用程序,该应用程序通过 Web 浏览器控件使用 Google Earth 插件。作为应用程序的一部分,我需要能够在地球上的某个区域周围创建一个多选框(想想类似于在文件浏览器中拖动选择多个文件)。

我现在设置它的方式是,c# 代码会跟踪我何时处于选择模式,如果是,第一次左键单击会从谷歌地球插件中拉出该点的经纬度。之后,鼠标移动得到对角的经纬度,然后c#代码调用以下2个javascript函数:

function clearHighlightBox(){
    var placemark = ge.getElementById('DARTselectBox');
    if(placemark)
    {
        ge.getFeatures().removeChild(placemark);
    }
}

function setHighlightBox(lat1, long1, lat2, long2){
    clearHighlightBox();
    var placemark = ge.createPlacemark('DARTselectBox');
    var lineString = ge.createLineString('');
    var coords = lineString.getCoordinates();
    coords.pushLatLngAlt(lat1, long1, 5000);
    coords.pushLatLngAlt(lat1, long2, 5000);
    coords.pushLatLngAlt(lat2, long2, 5000);
    coords.pushLatLngAlt(lat2, long1, 5000);
    coords.pushLatLngAlt(lat1, long1, 5000);
    placemark.setGeometry(lineString);
    ge.getFeatures().appendChild(placemark);
}

首先,以这种方式为地标创建 ID 似乎不起作用(ge.createPlacemark('DARTselectBox');)。如果我将其切换为清除所有内容并从 create Placemark 调用中删除 ID,则至少不会崩溃。但是,即使这样做,我也只能看到矩形的右垂直腿。

4

2 回答 2

1

如果我将其切换为清除所有内容并从 create Placemark 调用中删除 ID,这至少不会崩溃。

问题是您无法快速删除然后添加具有相同 ID 的对象。简单来说,是调用ge.createPlacemark('DARTselectBox')导致崩溃,因为 IDDARTselectBox仍在内部使用。您最终可以再次使用它,但时间取决于 WebBrowser 控件的垃圾回收。

为避免崩溃,您可以尝试在地标上调用 release,以便立即释放 ID。请参阅此注释,了解呼叫release的作用(我的重点

永久删除一个对象,允许其 ID 被重用。一旦对象被释放就试图访问它会导致错误。

如果失败,您可以简单地切换地标的可见状态,而不是每次都添加和删除它。

ID 重用的实际问题被列为错误,这里有更多关于该问题的信息

编辑:

看起来好像 release 方法可能存在错误。

如果您阅读我code.google.com/p/earth-api-samples/issues/detail?id=253在底部发布的一些评论的链接,似乎暗示了这一点。

无论如何,散列会起作用,增量计数器也会起作用。但我不明白您为什么不简单地将可见性设置为 false,或者创建一个完全没有 ID 的地标,并在操作过程中简单地保留对它的引用。

显示问题可能是由曲面细分和高度模式引起的。

尝试调用setTessellate(true)Placemarks 几何对象,并确保高度模式设置为clampToGround- 为此您调用setAltitudeMode(ge.ALTITUDE_CLAMP_TO_GROUND)- 再次在 Placemarks 几何对象上。

所以你有了

var lineString = ge.createLineString('');
lineString.getCoordinates().pushLatLngAlt( ... );
lineString.setTessellate(true);
lineString.setAltitudeMode(ge.ALTITUDE_CLAMP_TO_GROUND);

如果这不起作用,您可以尝试关闭地形图层并检查线条是否存在?

另外,我编写了一个免费的控制库,它使用 API 做很多事情——它是 GPL,所以你可以随心所欲地使用它。它确实涵盖了很多这样的事情。 http://code.google.com/p/winforms-geplugin-control-library/

于 2013-07-16T05:33:26.360 回答
-1

我有一个执行非常相似的应用程序。不幸的是,代码不是 GPL,所以我不能在这里发布它。一般来说,您的方法是正确的,但我相信您的问题是您用于构建盒子的结构。

您要么需要使用四个单独KmlLineString的对象(一个用于检测盒子的边缘),要么需要KmlLinearRing创建一个封闭的盒子。我不相信它的KmlLineString设计目的是创建一个封闭的多边形,这就是线性环的用途。

你计算你的盒子点的方式对我来说看起来不错(将它与我的工作解决方案进行比较),所以我在想如果你只是交换createLineStringcreateLinearRing会很好的方式。

Google 的示例位于下面的链接中。您会看到它们linearRing用于封闭的多边形。(大约在页面的一半)

https://developers.google.com/earth/documentation/geometries

于 2013-07-16T01:18:30.853 回答