Google Earth API移动多边形

时间:2010-06-04 15:38:57

标签: google-earth

我刚刚使用.Net的GEPlugin控件开始使用Google地球编码,但仍有很多需要学习的内容。

让我困惑的是当我尝试拖动多边形时。

只要mousemove事件触发,就会调用下面的方法,并且应该移动多边形的每个点,同时保留多边形的原始形状。每个点的纬度/经度都会改变,但多边形不会在地图上移动位置。

在多边形中移动一个点会导致它重绘,我是否需要调用一个方法强制重绘或者完全做其他事情?

谢谢!

private void DoMouseMove(IKmlMouseEvent mouseEvent)
    {
        if (isDragging)
        {
            mouseEvent.preventDefault();

            var placemark = mouseEvent.getTarget() as IKmlPlacemark;

            if (placemark == null)
            {
                return;
            }

            IKmlPolygon polygon = placemark.getGeometry() as IKmlPolygon;


            if (polygon != null)
            {
                float latOffset = startLatLong.Latitude - mouseEvent.getLatitude();
                float longOffset = startLatLong.Longitude - mouseEvent.getLongitude();

                KmlLinearRingCoClass outer = polygon.getOuterBoundary();
                KmlCoordArrayCoClass coordsArray = outer.getCoordinates();

                for(int i = 0; i < coordsArray.getLength(); i++)
                {
                    KmlCoordCoClass currentPoint = coordsArray.get(i);
                    currentPoint.setLatLngAlt(currentPoint.getLatitude() + latOffset, 
                        currentPoint.getLongitude() + longOffset, 0);
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

<强>更新

我发布了扩展程序库:https://bitbucket.org/mutopia/earth

请参阅https://bitbucket.org/mutopia/earth/src/master/sample/index.html以运行它。

请参阅调用setDragMode()addDragEvent()的{​​{3}}以启用KmlPolygon的拖动。


我使用drag() method in the sample code class中的takeOverCamera和三个事件

成功实现了此功能
setDragMode: function (mode) {
    // summary:
    //      Sets dragging mode on and off
    if (mode == this.dragMode) {
        Log.info('Drag mode is already', mode);
    } else {
        this.dragMode = mode;
        Log.info('Drag mode set', mode);
        if (mode) {
            this.addEvent(this.ge.getGlobe(), 'mousemove', this.dragMouseMoveCallback);
            this.addEvent(this.ge.getGlobe(), 'mouseup', this.dragMouseUpCallback);
            this.addEvent(this.ge.getView(), 'viewchange', this.dragViewChange, false);
        } else {
            this.removeEvent(this.ge.getGlobe(), 'mousemove', this.dragMouseMoveCallback);
            this.removeEvent(this.ge.getGlobe(), 'mouseup', this.dragMouseUpCallback);
            this.removeEvent(this.ge.getView(), 'viewchange', this.dragViewChange, false);
        }
    }
},

这是在一个更大的项目中的实用程序库中。 dragMode是一个布尔值,用于添加和删除事件。这三个事件控制着拖动时会发生什么。 addEventremoveEvent是我自己的包装函数:

addEvent: function (targetObject, eventID, listenerCallback, capture) {
    // summary:
    //      Convenience method for google.earth.addEventListener
    capture = setDefault(capture, true);
    google.earth.addEventListener(targetObject, eventID, listenerCallback, capture);
},

removeEvent: function (targetObject, eventID, listenerCallback, capture) {
    // summary:
    //      Convenience method for google.earth.removeEventListener
    capture = setDefault(capture, true);
    google.earth.removeEventListener(targetObject, eventID, listenerCallback, capture);
},

忽略次要细节,所有重要的东西都在这些事件的回调中。 mousedown事件锁定摄像机并将我拖动的多边形设置为dragObject(它只是我正在使用的变量)。它保存了原始的lat长坐标。

this.dragMouseDownCallback = lang.hitch(this, function (event) {
    var obj = event.getTarget();
    this.lockCamera(true);
    this.setSelected(obj);
    this.dragObject = obj;
    this.dragLatOrigin = this.dragLatLast = event.getLatitude();
    this.dragLngOrigin = this.dragLngLast = event.getLongitude();
}

mousemove回调更新到最新的lat长坐标:

this.dragMouseMoveCallback = lang.hitch(this, function (event) {
    if (this.dragObject) {
        var lat = event.getLatitude();
        var lng = event.getLongitude();
        var latDiff = lat - this.dragLatLast;
        var lngDiff = lng - this.dragLngLast;
        if (Math.abs(latDiff) > this.dragSensitivity || Math.abs(lngDiff > this.dragSensitivity)) {
            this.addPolyCoords(this.dragObject, [latDiff, lngDiff]);
            this.dragLatLast = lat;
            this.dragLngLast = lng;
        }
    }
});

这里我使用一些奇特的敏感度值来防止这种情况经常更新。最后,addPolyCoords也是我自己的函数,它将lat long值添加到多边形的现有坐标 - 有效地将它移动到全球范围内。我使用每个坐标的内置setLatitude()setLongitude()函数执行此操作。你可以像这样得到坐标,其中polygon是KmlPolyon对象:

polygon.getGeometry().getOuterBoundary().getCoordinates()

当然,mousedown回调会关闭拖动模式,因此移动鼠标不会继续拖动多边形:

this.dragMouseUpCallback = lang.hitch(this, function (event) {
    if (this.dragObject) {
        Log.info('Stop drag', this.dragObject.getType());
        setTimeout(lang.hitch(this, function () {
            this.lockCamera(false);
            this.setSelected(null);
        }), 100);
        this._dragEvent(event);
        this.dragObject = this.dragLatOrigin = this.dragLngOrigin = this.dragLatLast = this.dragLngLast = null;
    }
});

最后,调用_dragEvent以确保最终坐标是鼠标事件结束的实际坐标(而不是最新的mousemove调用):

_dragEvent: function (event) {
    // summary:
    //      Helper function for moving drag object
    var latDiff = event.getLatitude() - this.dragLatLast;
    var lngDiff = event.getLongitude() - this.dragLngLast;
    if (!(latDiff == 0 && lngDiff == 0)) {
        this.addPolyCoords(this.dragObject, [latDiff, lngDiff]);
        Log.info('Moved ' + latDiff + ', ' + lngDiff);
    }
},

mousemove回调并不太重要,实际上可以忽略 - 我使用它的唯一原因是当用户移动鼠标时显示多边形移动。移除它会导致物体在抬起鼠标时移动。

希望这个令人难以置信的长答案能够让您对如何在Google Earth API中实现拖动有所了解。我还计划在将来解决问题时释放我的图书馆:)