我正在构建一个通过Web浏览器控件使用Google Earth插件的c#应用程序。作为应用程序的一部分,我需要能够在地球上的某个区域周围创建一个多选框(想想类似于在文件浏览器中拖动选择多个文件)。
我现在设置它的方式,c#代码跟踪我处于选择模式的时间,如果是的话,第一个左键单击从谷歌地球插件中拉出该点的lat-long。之后,鼠标移动得到对角的lat-long,然后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');)。如果我将其切换为清除所有内容并从创建地标调用中删除ID,则至少不会崩溃。但是,即使我这样做,我也只能看到矩形的右侧垂直腿。
答案 0 :(得分:1)
如果我将其切换为清除所有内容并从中删除ID 创建地标调用,这至少不会崩溃。
问题是您无法删除然后快速添加具有相同ID的对象。简单来说,调用ge.createPlacemark('DARTselectBox')
会导致崩溃,因为内部仍在使用ID DARTselectBox
。您最终可以再次使用它,但时间取决于WebBrowser控件的垃圾收集。
为避免崩溃,您可以在地标上尝试calling release,以便立即释放ID。请参阅此说明,了解调用release
的内容(我的重点)
永久删除对象,允许重复使用其ID 。 一旦释放对象,尝试访问该对象将导致该对象 错误。
如果没有你可以简单地切换地标的可见状态,而不是每次都添加和删除它。
ID重用的实际问题列为错误,并且有一些more information on the problem here
修改强>
看起来好像发布方法可能存在错误。
如果您阅读了我发布的code.google.com/p/earth-api-samples/issues/detail?id=253
链接,那么底部的一些评论似乎暗示了这一点。
无论如何,散列会起作用,增量计数器也会起作用。但我不明白为什么你不简单地将可见性设置为false,或者根本不创建没有ID的地标,只是在操作期间保持对它的引用。
显示问题可能是由曲面细分和高度模式造成的。
尝试在地标几何对象上调用setTessellate(true)
并确保高度模式设置为clampToGround
- 为此,您可以在地标几何对象上再次调用setAltitudeMode(ge.ALTITUDE_CLAMP_TO_GROUND)
。< / p>
所以你有
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/
答案 1 :(得分:-1)
我有一个非常相似的应用程序。不幸的是,代码不是GPL,所以我不能在这里发布它。一般来说,您的方法是正确的,但我相信您的问题是您用于构建盒子的结构。
您需要使用四个单独的KmlLineString
个对象(一个用于框的边缘边缘)或一个KmlLinearRing
来创建一个封闭的框。我不相信KmlLineString
旨在创建一个封闭的多边形,这就是线性环的用途。
你计算盒子积分的方式对我来说很好(将它与我的工作解决方案进行比较),所以我想如果你只是createLineString
交换createLinearRing
你会很好方式。
Google的示例位于以下链接中。你会看到他们使用linearRing
作为封闭的多边形。 (大约一半的页面)
https://developers.google.com/earth/documentation/geometries