更新:
我已经发布了扩展库:https ://bitbucket.org/mutopia/earth
请参阅https://bitbucket.org/mutopia/earth/src/master/sample/index.html运行它。
请参阅示例代码类中的 drag() 方法,该方法调用setDragMode()
和addDragEvent()
以启用对KmlPolygon
.
我在earth-api-utility-library和三个事件中使用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
是一个添加和删除事件的布尔值。这三个事件控制拖动时发生的情况。addEvent
并且removeEvent
是我自己的包装函数:
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
(它只是我正在使用的一个变量)。它保存了原始的经纬度坐标。
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
回调更新到最新的经纬度坐标:
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
也是我自己的函数,它将经纬度值添加到多边形的现有坐标中 - 有效地将其移动到全球范围内。我使用每个坐标的内置函数setLatitude()
和函数来执行此操作。setLongitude()
您可以像这样获得坐标,其中多边形是一个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 地球 API 中实现拖动有所了解。而且我还计划在将来解决问题后发布我的库:)