@osh-branches/osh-js
Version:
OSH javascript Toolkit
1,332 lines (1,102 loc) • 78.4 kB
JavaScript
/**
* Created by thomas on 9/01/14.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* (c) www.geocento.com
* www.metaaps.com
*
*/
var DrawHelper = (function() {
// static variables
var ellipsoid = Cesium.Ellipsoid.WGS84;
// constructor
function _(cesiumWidget) {
this._scene = cesiumWidget.scene;
this._tooltip = createTooltip(cesiumWidget.container);
this._surfaces = [];
this.initialiseHandlers();
this.enhancePrimitives();
}
_.prototype.initialiseHandlers = function() {
var scene = this._scene;
var _self = this;
// scene events
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
function callPrimitiveCallback(name, position) {
if(_self._handlersMuted == true) return;
var pickedObject = scene.pick(position);
if(pickedObject && pickedObject.primitive && pickedObject.primitive[name]) {
pickedObject.primitive[name](position);
}
}
handler.setInputAction(
function (movement) {
callPrimitiveCallback('leftClick', movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.setInputAction(
function (movement) {
callPrimitiveCallback('leftDoubleClick', movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
var mouseOutObject;
handler.setInputAction(
function (movement) {
if(_self._handlersMuted == true) return;
var pickedObject = scene.pick(movement.endPosition);
if(mouseOutObject && (!pickedObject || mouseOutObject != pickedObject.primitive)) {
!(mouseOutObject.isDestroyed && mouseOutObject.isDestroyed()) && mouseOutObject.mouseOut(movement.endPosition);
mouseOutObject = null;
}
if(pickedObject && pickedObject.primitive) {
pickedObject = pickedObject.primitive;
if(pickedObject.mouseOut) {
mouseOutObject = pickedObject;
}
if(pickedObject.mouseMove) {
pickedObject.mouseMove(movement.endPosition);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(
function (movement) {
callPrimitiveCallback('leftUp', movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_UP);
handler.setInputAction(
function (movement) {
callPrimitiveCallback('leftDown', movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
}
_.prototype.setListener = function(primitive, type, callback) {
primitive[type] = callback;
}
_.prototype.muteHandlers = function(muted) {
this._handlersMuted = muted;
}
// register event handling for an editable shape
// shape should implement setEditMode and setHighlighted
_.prototype.registerEditableShape = function(surface) {
var _self = this;
// handlers for interactions
// highlight polygon when mouse is entering
setListener(surface, 'mouseMove', function(position) {
surface.setHighlighted(true);
if(!surface._editMode) {
_self._tooltip.showAt(position, "Click to edit this shape");
}
});
// hide the highlighting when mouse is leaving the polygon
setListener(surface, 'mouseOut', function(position) {
surface.setHighlighted(false);
_self._tooltip.setVisible(false);
});
setListener(surface, 'leftClick', function(position) {
surface.setEditMode(true);
});
}
// register event handling to show name
// shape should implement setHighlighted
_.prototype.registerShowNameShape = function(surface) {
var _self = this;
// handlers for interactions
// highlight polygon when mouse is entering
setListener(surface, 'mouseMove', function(position) {
surface.setHighlighted(true);
if(!surface._editMode) {
_self._tooltip.showAt(position, surface.name+"");
}
});
// hide the highlighting when mouse is leaving the polygon
setListener(surface, 'mouseOut', function(position) {
surface.setHighlighted(false);
_self._tooltip.setVisible(false);
});
}
_.prototype.startDrawing = function(cleanUp) {
// undo any current edit of shapes
this.disableAllEditMode();
// check for cleanUp first
if(this.editCleanUp) {
this.editCleanUp();
}
this.editCleanUp = cleanUp;
this.muteHandlers(true);
}
_.prototype.stopDrawing = function() {
// check for cleanUp first
if(this.editCleanUp) {
this.editCleanUp();
this.editCleanUp = null;
}
this.muteHandlers(false);
}
// make sure only one shape is highlighted at a time
_.prototype.disableAllHighlights = function() {
this.setHighlighted(undefined);
}
_.prototype.setHighlighted = function(surface) {
if(this._highlightedSurface && !this._highlightedSurface.isDestroyed() && this._highlightedSurface != surface) {
this._highlightedSurface.setHighlighted(false);
}
this._highlightedSurface = surface;
}
_.prototype.disableAllEditMode = function() {
this.setEdited(undefined);
}
_.prototype.setEdited = function(surface) {
if(this._editedSurface && !this._editedSurface.isDestroyed()) {
this._editedSurface.setEditMode(false);
}
this._editedSurface = surface;
}
var material = Cesium.Material.fromType(Cesium.Material.ColorType);
material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.5);
var defaultShapeOptions = {
ellipsoid: Cesium.Ellipsoid.WGS84,
textureRotationAngle: 0.0,
height: 0.0,
asynchronous: true,
show: true,
debugShowBoundingVolume: false
}
var defaultSurfaceOptions = copyOptions(defaultShapeOptions, {
appearance: new Cesium.EllipsoidSurfaceAppearance({
aboveGround : false
}),
material : material,
granularity: Math.PI / 180.0
});
var defaultPolygonOptions = copyOptions(defaultShapeOptions, {});
var defaultExtentOptions = copyOptions(defaultShapeOptions, {});
var defaultCircleOptions = copyOptions(defaultShapeOptions, {});
var defaultEllipseOptions = copyOptions(defaultSurfaceOptions, {rotation: 0});
var defaultPolylineOptions = copyOptions(defaultShapeOptions, {
width: 5,
geodesic: true,
granularity: 10000,
appearance: new Cesium.PolylineMaterialAppearance({
aboveGround : false
}),
material : material
});
// Cesium.Polygon.prototype.setStrokeStyle = setStrokeStyle;
//
// Cesium.Polygon.prototype.drawOutline = drawOutline;
//
var ChangeablePrimitive = (function() {
function _() {
}
_.prototype.initialiseOptions = function(options) {
fillOptions(this, options);
this._ellipsoid = undefined;
this._granularity = undefined;
this._height = undefined;
this._textureRotationAngle = undefined;
this._id = undefined;
// set the flags to initiate a first drawing
this._createPrimitive = true;
this._primitive = undefined;
this._outlinePolygon = undefined;
}
_.prototype.setAttribute = function(name, value) {
this[name] = value;
this._createPrimitive = true;
};
_.prototype.getAttribute = function(name) {
return this[name];
};
/**
* @private
*/
_.prototype.update = function(context, frameState, commandList) {
if (!Cesium.defined(this.ellipsoid)) {
throw new Cesium.DeveloperError('this.ellipsoid must be defined.');
}
if (!Cesium.defined(this.appearance)) {
throw new Cesium.DeveloperError('this.material must be defined.');
}
if (this.granularity < 0.0) {
throw new Cesium.DeveloperError('this.granularity and scene2D/scene3D overrides must be greater than zero.');
}
if (!this.show) {
return;
}
if (!this._createPrimitive && (!Cesium.defined(this._primitive))) {
// No positions/hierarchy to draw
return;
}
if (this._createPrimitive ||
(this._ellipsoid !== this.ellipsoid) ||
(this._granularity !== this.granularity) ||
(this._height !== this.height) ||
(this._textureRotationAngle !== this.textureRotationAngle) ||
(this._id !== this.id)) {
var geometry = this.getGeometry();
if(!geometry) {
return;
}
this._createPrimitive = false;
this._ellipsoid = this.ellipsoid;
this._granularity = this.granularity;
this._height = this.height;
this._textureRotationAngle = this.textureRotationAngle;
this._id = this.id;
this._primitive = this._primitive && this._primitive.destroy();
this._primitive = new Cesium.Primitive({
geometryInstances : new Cesium.GeometryInstance({
geometry : geometry,
id : this.id,
pickPrimitive : this
}),
appearance : this.appearance,
asynchronous : this.asynchronous
});
this._outlinePolygon = this._outlinePolygon && this._outlinePolygon.destroy();
if(this.strokeColor && this.getOutlineGeometry) {
// create the highlighting frame
this._outlinePolygon = new Cesium.Primitive({
geometryInstances : new Cesium.GeometryInstance({
geometry : this.getOutlineGeometry(),
attributes : {
color : Cesium.ColorGeometryInstanceAttribute.fromColor(this.strokeColor)
}
}),
appearance : new Cesium.PerInstanceColorAppearance({
flat : true,
renderState : {
depthTest : {
enabled : true
},
lineWidth : this.strokeWidth || 4.0
}
})
});
}
}
var primitive = this._primitive;
primitive.appearance.material = this.material;
primitive.debugShowBoundingVolume = this.debugShowBoundingVolume;
primitive.update(context, frameState, commandList);
this._outlinePolygon && this._outlinePolygon.update(context, frameState, commandList);
};
_.prototype.isDestroyed = function() {
return false;
};
_.prototype.destroy = function() {
this._primitive = this._primitive && this._primitive.destroy();
return Cesium.destroyObject(this);
};
_.prototype.setStrokeStyle = function(strokeColor, strokeWidth) {
if(!this.strokeColor || !this.strokeColor.equals(strokeColor) || this.strokeWidth != strokeWidth) {
this._createPrimitive = true;
this.strokeColor = strokeColor;
this.strokeWidth = strokeWidth;
}
}
return _;
})();
_.ExtentPrimitive = (function() {
function _(options) {
if(!Cesium.defined(options.extent)) {
throw new Cesium.DeveloperError('Extent is required');
}
options = copyOptions(options, defaultSurfaceOptions);
this.initialiseOptions(options);
this.setExtent(options.extent);
}
_.prototype = new ChangeablePrimitive();
_.prototype.setExtent = function(extent) {
this.setAttribute('extent', extent);
};
_.prototype.getExtent = function() {
return this.getAttribute('extent');
};
_.prototype.getGeometry = function() {
if (!Cesium.defined(this.extent)) {
return;
}
return new Cesium.RectangleGeometry({
rectangle : this.extent,
height : this.height,
vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
stRotation : this.textureRotationAngle,
ellipsoid : this.ellipsoid,
granularity : this.granularity
});
};
_.prototype.getOutlineGeometry = function() {
return new Cesium.RectangleOutlineGeometry({
rectangle: this.extent
});
}
return _;
})();
_.PolygonPrimitive = (function() {
function _(options) {
options = copyOptions(options, defaultSurfaceOptions);
this.initialiseOptions(options);
this.isPolygon = true;
}
_.prototype = new ChangeablePrimitive();
_.prototype.setPositions = function(positions) {
this.setAttribute('positions', positions);
};
_.prototype.getPositions = function() {
return this.getAttribute('positions');
};
_.prototype.getGeometry = function() {
if (!Cesium.defined(this.positions) || this.positions.length < 3) {
return;
}
return Cesium.PolygonGeometry.fromPositions({
positions : this.positions,
height : this.height,
vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
stRotation : this.textureRotationAngle,
ellipsoid : this.ellipsoid,
granularity : this.granularity
});
};
_.prototype.getOutlineGeometry = function() {
return Cesium.PolygonOutlineGeometry.fromPositions({
positions : this.getPositions()
});
}
return _;
})();
_.CirclePrimitive = (function() {
function _(options) {
if(!(Cesium.defined(options.center) && Cesium.defined(options.radius))) {
throw new Cesium.DeveloperError('Center and radius are required');
}
options = copyOptions(options, defaultSurfaceOptions);
this.initialiseOptions(options);
this.setRadius(options.radius);
}
_.prototype = new ChangeablePrimitive();
_.prototype.setCenter = function(center) {
this.setAttribute('center', center);
};
_.prototype.setRadius = function(radius) {
this.setAttribute('radius', Math.max(0.1, radius));
};
_.prototype.getCenter = function() {
return this.getAttribute('center');
};
_.prototype.getRadius = function() {
return this.getAttribute('radius');
};
_.prototype.getGeometry = function() {
if (!(Cesium.defined(this.center) && Cesium.defined(this.radius))) {
return;
}
return new Cesium.CircleGeometry({
center : this.center,
radius : this.radius,
height : this.height,
vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
stRotation : this.textureRotationAngle,
ellipsoid : this.ellipsoid,
granularity : this.granularity
});
};
_.prototype.getOutlineGeometry = function() {
return new Cesium.CircleOutlineGeometry({
center: this.getCenter(),
radius: this.getRadius()
});
}
return _;
})();
_.EllipsePrimitive = (function() {
function _(options) {
if(!(Cesium.defined(options.center) && Cesium.defined(options.semiMajorAxis) && Cesium.defined(options.semiMinorAxis))) {
throw new Cesium.DeveloperError('Center and semi major and semi minor axis are required');
}
options = copyOptions(options, defaultEllipseOptions);
this.initialiseOptions(options);
}
_.prototype = new ChangeablePrimitive();
_.prototype.setCenter = function(center) {
this.setAttribute('center', center);
};
_.prototype.setSemiMajorAxis = function(semiMajorAxis) {
if(semiMajorAxis < this.getSemiMinorAxis()) return;
this.setAttribute('semiMajorAxis', semiMajorAxis);
};
_.prototype.setSemiMinorAxis = function(semiMinorAxis) {
if(semiMinorAxis > this.getSemiMajorAxis()) return;
this.setAttribute('semiMinorAxis', semiMinorAxis);
};
_.prototype.setRotation = function(rotation) {
return this.setAttribute('rotation', rotation);
};
_.prototype.getCenter = function() {
return this.getAttribute('center');
};
_.prototype.getSemiMajorAxis = function() {
return this.getAttribute('semiMajorAxis');
};
_.prototype.getSemiMinorAxis = function() {
return this.getAttribute('semiMinorAxis');
};
_.prototype.getRotation = function() {
return this.getAttribute('rotation');
};
_.prototype.getGeometry = function() {
if(!(Cesium.defined(this.center) && Cesium.defined(this.semiMajorAxis) && Cesium.defined(this.semiMinorAxis))) {
return;
}
return new Cesium.EllipseGeometry({
ellipsoid : this.ellipsoid,
center : this.center,
semiMajorAxis : this.semiMajorAxis,
semiMinorAxis : this.semiMinorAxis,
rotation : this.rotation,
height : this.height,
vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
stRotation : this.textureRotationAngle,
ellipsoid : this.ellipsoid,
granularity : this.granularity
});
};
_.prototype.getOutlineGeometry = function() {
return new Cesium.EllipseOutlineGeometry({
center: this.getCenter(),
semiMajorAxis: this.getSemiMajorAxis(),
semiMinorAxis: this.getSemiMinorAxis(),
rotation: this.getRotation()
});
}
return _;
})();
_.PolylinePrimitive = (function() {
function _(options) {
options = copyOptions(options, defaultPolylineOptions);
this.initialiseOptions(options);
}
_.prototype = new ChangeablePrimitive();
_.prototype.setPositions = function(positions) {
this.setAttribute('positions', positions);
};
_.prototype.setWidth = function(width) {
this.setAttribute('width', width);
};
_.prototype.setGeodesic = function(geodesic) {
this.setAttribute('geodesic', geodesic);
};
_.prototype.getPositions = function() {
return this.getAttribute('positions');
};
_.prototype.getWidth = function() {
return this.getAttribute('width');
};
_.prototype.getGeodesic = function(geodesic) {
return this.getAttribute('geodesic');
};
_.prototype.getGeometry = function() {
if (!Cesium.defined(this.positions) || this.positions.length < 2) {
return;
}
return new Cesium.PolylineGeometry({
positions: this.positions,
height : this.height,
width: this.width < 1 ? 1 : this.width,
vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
ellipsoid : this.ellipsoid
});
}
return _;
})();
var defaultBillboard = {
iconUrl: "./images/drawhelper/dragIcon.png",
shiftX: 0,
shiftY: 0
}
var dragBillboard = {
iconUrl: "./images/drawhelper/dragIcon.png",
shiftX: 0,
shiftY: 0
}
var dragHalfBillboard = {
iconUrl: "./images/drawhelper/dragIconLight.png",
shiftX: 0,
shiftY: 0
}
_.prototype.createBillboardGroup = function(points, options, callbacks) {
var markers = new _.BillboardGroup(this, options);
markers.addBillboards(points, callbacks);
return markers;
}
_.BillboardGroup = function(drawHelper, options) {
this._drawHelper = drawHelper;
this._scene = drawHelper._scene;
this._options = copyOptions(options, defaultBillboard);
// create one common billboard collection for all billboards
var b = new Cesium.BillboardCollection();
this._scene.primitives.add(b);
this._billboards = b;
// keep an ordered list of billboards
this._orderedBillboards = [];
}
_.BillboardGroup.prototype.createBillboard = function(position, callbacks) {
var billboard = this._billboards.add({
show : true,
position : position,
pixelOffset : new Cesium.Cartesian2(this._options.shiftX, this._options.shiftY),
eyeOffset : new Cesium.Cartesian3(0.0, 0.0, 0.0),
horizontalOrigin : Cesium.HorizontalOrigin.CENTER,
verticalOrigin : Cesium.VerticalOrigin.CENTER,
scale : 1.0,
image: this._options.iconUrl,
color : new Cesium.Color(1.0, 1.0, 1.0, 1.0)
});
// if editable
if(callbacks) {
var _self = this;
var screenSpaceCameraController = this._scene.screenSpaceCameraController;
function enableRotation(enable) {
screenSpaceCameraController.enableRotate = enable;
}
function getIndex() {
// find index
for (var i = 0, I = _self._orderedBillboards.length; i < I && _self._orderedBillboards[i] != billboard; ++i);
return i;
}
if(callbacks.dragHandlers) {
var _self = this;
setListener(billboard, 'leftDown', function(position) {
// TODO - start the drag handlers here
// create handlers for mouseOut and leftUp for the billboard and a mouseMove
function onDrag(position) {
billboard.position = position;
// find index
for (var i = 0, I = _self._orderedBillboards.length; i < I && _self._orderedBillboards[i] != billboard; ++i);
callbacks.dragHandlers.onDrag && callbacks.dragHandlers.onDrag(getIndex(), position);
}
function onDragEnd(position) {
handler.destroy();
enableRotation(true);
callbacks.dragHandlers.onDragEnd && callbacks.dragHandlers.onDragEnd(getIndex(), position);
}
var handler = new Cesium.ScreenSpaceEventHandler(_self._scene.canvas);
handler.setInputAction(function(movement) {
var cartesian = _self._scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);
if (cartesian) {
onDrag(cartesian);
} else {
onDragEnd(cartesian);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(function(movement) {
onDragEnd(_self._scene.camera.pickEllipsoid(movement.position, ellipsoid));
}, Cesium.ScreenSpaceEventType.LEFT_UP);
enableRotation(false);
callbacks.dragHandlers.onDragStart && callbacks.dragHandlers.onDragStart(getIndex(), _self._scene.camera.pickEllipsoid(position, ellipsoid));
});
}
if(callbacks.onDoubleClick) {
setListener(billboard, 'leftDoubleClick', function(position) {
callbacks.onDoubleClick(getIndex());
});
}
if(callbacks.onLeftClick) {
setListener(billboard, 'leftClick', function(position) {
callbacks.onClick(getIndex());
});
}
if(callbacks.tooltip) {
setListener(billboard, 'mouseMove', function(position) {
_self._drawHelper._tooltip.showAt(position, callbacks.tooltip());
});
setListener(billboard, 'mouseOut', function(position) {
_self._drawHelper._tooltip.setVisible(false);
});
}
}
return billboard;
}
_.BillboardGroup.prototype.insertBillboard = function(index, position, callbacks) {
this._orderedBillboards.splice(index, 0, this.createBillboard(position, callbacks));
}
_.BillboardGroup.prototype.addBillboard = function(position, callbacks) {
this._orderedBillboards.push(this.createBillboard(position, callbacks));
}
_.BillboardGroup.prototype.addBillboards = function(positions, callbacks) {
var index = 0;
for(; index < positions.length; index++) {
this.addBillboard(positions[index], callbacks);
}
}
_.BillboardGroup.prototype.updateBillboardsPositions = function(positions) {
var index = 0;
for(; index < positions.length; index++) {
this.getBillboard(index).position = positions[index];
}
}
_.BillboardGroup.prototype.countBillboards = function() {
return this._orderedBillboards.length;
}
_.BillboardGroup.prototype.getBillboard = function(index) {
return this._orderedBillboards[index];
}
_.BillboardGroup.prototype.removeBillboard = function(index) {
this._billboards.remove(this.getBillboard(index));
this._orderedBillboards.splice(index, 1);
}
_.BillboardGroup.prototype.remove = function() {
this._billboards = this._billboards && this._billboards.removeAll() && this._billboards.destroy();
}
_.BillboardGroup.prototype.setOnTop = function() {
this._scene.primitives.raiseToTop(this._billboards);
}
_.prototype.startDrawingMarker = function(options) {
var options = copyOptions(options, defaultBillboard);
this.startDrawing(
function() {
markers.remove();
mouseHandler.destroy();
tooltip.setVisible(false);
}
);
var _self = this;
var scene = this._scene;
var primitives = scene.primitives;
var tooltip = this._tooltip;
var markers = new _.BillboardGroup(this, options);
var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
// Now wait for start
mouseHandler.setInputAction(function(movement) {
if(movement.position != null) {
var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
if (cartesian) {
markers.addBillboard(cartesian);
_self.stopDrawing();
options.callback(cartesian);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
mouseHandler.setInputAction(function(movement) {
var position = movement.endPosition;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
_.prototype.startDrawingPolygon = function(options) {
var options = copyOptions(options, defaultSurfaceOptions);
this.startDrawingPolyshape(true, options);
}
_.prototype.startDrawingPolyline = function(options) {
var options = copyOptions(options, defaultPolylineOptions);
this.startDrawingPolyshape(false, options);
}
_.prototype.startDrawingPolyshape = function(isPolygon, options) {
this.startDrawing(
function() {
primitives.remove(poly);
markers.remove();
mouseHandler.destroy();
tooltip.setVisible(false);
}
);
var _self = this;
var scene = this._scene;
var primitives = scene.primitives;
var tooltip = this._tooltip;
var minPoints = isPolygon ? 3 : 2;
var poly;
if(isPolygon) {
poly = new DrawHelper.PolygonPrimitive(options);
} else {
poly = new DrawHelper.PolylinePrimitive(options);
}
poly.asynchronous = false;
primitives.add(poly);
var positions = [];
var markers = new _.BillboardGroup(this, defaultBillboard);
var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
// Now wait for start
mouseHandler.setInputAction(function(movement) {
if(movement.position != null) {
var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
if (cartesian) {
// first click
if(positions.length == 0) {
positions.push(cartesian.clone());
markers.addBillboard(positions[0]);
}
if(positions.length >= minPoints) {
poly.positions = positions;
poly._createPrimitive = true;
}
// add new point to polygon
// this one will move with the mouse
positions.push(cartesian);
// add marker at the new position
markers.addBillboard(cartesian);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
mouseHandler.setInputAction(function(movement) {
var position = movement.endPosition;
if(position != null) {
if(positions.length > 0) {
var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
if (cartesian) {
positions.pop();
// make sure it is slightly different
cartesian.y += (1 + Math.random());
positions.push(cartesian);
if(positions.length >= minPoints) {
poly.positions = positions;
poly._createPrimitive = true;
}
// update marker
markers.getBillboard(positions.length - 1).position = cartesian;
}
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
mouseHandler.setInputAction(function(movement) {
var position = movement.position;
if(position != null) {
if(positions.length < minPoints + 2) {
return;
} else {
var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
if (cartesian) {
_self.stopDrawing();
if(typeof options.callback == 'function') {
// remove overlapping ones
var index = positions.length - 1;
options.callback(positions);
}
}
}
}
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
}
function getExtentCorners(value) {
return ellipsoid.cartographicArrayToCartesianArray([Cesium.Rectangle.northwest(value), Cesium.Rectangle.northeast(value), Cesium.Rectangle.southeast(value), Cesium.Rectangle.southwest(value)]);
}
_.prototype.startDrawingExtent = function(options) {
var options = copyOptions(options, defaultSurfaceOptions);
this.startDrawing(
function() {
if(extent != null) {
primitives.remove(extent);
}
markers.remove();
mouseHandler.destroy();
tooltip.setVisible(false);
}
);
var _self = this;
var scene = this._scene;
var primitives = this._scene.primitives;
var tooltip = this._tooltip;
var firstPoint = null;
var extent = null;
var markers = null;
var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
function updateExtent(value) {
if(extent == null) {
extent = new Cesium.RectanglePrimitive();
extent.asynchronous = false;
primitives.add(extent);
}
extent.rectangle = value;
// update the markers
var corners = getExtentCorners(value);
// create if they do not yet exist
if(markers == null) {
markers = new _.BillboardGroup(_self, defaultBillboard);
markers.addBillboards(corners);
} else {
markers.updateBillboardsPositions(corners);
}
}
// Now wait for start
mouseHandler.setInputAction(function(movement) {
if(movement.position != null) {
var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
if (cartesian) {
if(extent == null) {
// create the rectangle
firstPoint = ellipsoid.cartesianToCartographic(cartesian);
var value = getExtent(firstPoint, firstPoint);
updateExtent(value);
} else {
_self.stopDrawing();
if(typeof options.callback == 'function') {
options.callback(getExtent(firstPoint, ellipsoid.cartesianToCartographic(cartesian)));
}
}
}
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
mouseHandler.setInputAction(function(movement) {
var position = movement.endPosition;
if(position != null) {
if(extent != null) {
var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
if (cartesian) {
var value = getExtent(firstPoint, ellipsoid.cartesianToCartographic(cartesian));
updateExtent(value);
tooltip.showAt(position, "<p>Drag to change rectangle extent</p><p>Click again to finish drawing</p>");
}
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
_.prototype.startDrawingCircle = function(options) {
var options = copyOptions(options, defaultSurfaceOptions);
this.startDrawing(
function cleanUp() {
if(circle != null) {
primitives.remove(circle);
}
markers.remove();
mouseHandler.destroy();
tooltip.setVisible(false);
}
);
var _self = this;
var scene = this._scene;
var primitives = this._scene.primitives;
var tooltip = this._tooltip;
var circle = null;
var markers = null;
var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
// Now wait for start
mouseHandler.setInputAction(function(movement) {
if(movement.position != null) {
var cartesian = scene.camera.pickEllipsoid(movement.position, ellipsoid);
if (cartesian) {
if(circle == null) {
// create the circle
circle = new _.CirclePrimitive({
center: cartesian,
radius: 0,
asynchronous: false,
material : options.material
});
primitives.add(circle);
markers = new _.BillboardGroup(_self, defaultBillboard);
markers.addBillboards([cartesian]);
} else {
if(typeof options.callback == 'function') {
options.callback(circle.getCenter(), circle.getRadius());
}
_self.stopDrawing();
}
}
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
mouseHandler.setInputAction(function(movement) {
var position = movement.endPosition;
if(position != null) {
if(circle == null) {
tooltip.showAt(position, "<p>Click to start drawing the circle</p>");
} else {
var cartesian = scene.camera.pickEllipsoid(position, ellipsoid);
if (cartesian) {
circle.setRadius(Cesium.Cartesian3.distance(circle.getCenter(), cartesian));
markers.updateBillboardsPositions(cartesian);
tooltip.showAt(position, "<p>Move mouse to change circle radius</p><p>Click again to finish drawing</p>");
}
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
_.prototype.startRemovePrimitive = function(options) {
var _self = this;
var scene = this._scene;
var primitives = this._scene.primitives;
var mouseHandler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
// Now wait for start
mouseHandler.setInputAction(function(click) {
var pickedObject = scene.pick(click.position);
if (Cesium.defined(pickedObject)) {
if(typeof pickedObject.collection !== "undefined") {
scene.primitives.remove(pickedObject.collection);
pickedObject.primitive.isPoint = true;
} else {
scene.primitives.remove(pickedObject.primitive);
}
options.callback(pickedObject.primitive);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
/*mouseHandler.setInputAction(function(click) {
for(var i=click.startPosition.x;i < click.endPosition.x;i++) {
for(var j=click.startPosition.y;j < click.endPosition.y;j++) {
var pickedObject = scene.pick(new Cesium.Cartesian2(i,j));
console.log("pick:"+pickedObject);
if (Cesium.defined(pickedObject)) {
if(typeof pickedObject.collection !== "undefined") {
scene.primitives.remove(pickedObject.collection);
} else {
scene.primitives.remove(pickedObject.primitive);
}
options.callback(pickedObject.primitive);
}
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
scene.screenSpaceCameraController.enableRotate = false;
scene.screenSpaceCameraController.enableTranslate = false;
scene.screenSpaceCameraController.enableZoom = false;
scene.screenSpaceCameraController.enableTilt = false;
scene.screenSpaceCameraController.enableLook = false;*/
}
_.prototype.enhancePrimitives = function() {
var drawHelper = this;
Cesium.Billboard.prototype.setShowName = function() {
var billboard = this;
var _self = this;
drawHelper.registerShowNameShape(billboard);
billboard.setHighlighted = function(highlighted) {
// disable if already in edit mode
if(this._editMode === true) {
return;
}
if(highlighted) {
billboard.image = "./images/drawhelper/glyphicons_242_google_maps_green.png";
} else {
billboard.image = "./images/drawhelper/glyphicons_242_google_maps.png";
}
}
billboard.getExtent = function() {
return Cesium.Extent.fromCartographicArray(ellipsoid.cartesianArrayToCartographicArray(this.positions));
}
enhanceWithListeners(billboard);
}
Cesium.Billboard.prototype.setEditable = function() {
if(this._editable) {
return;
}
this._editable = true;
var billboard = this;
var _self = this;
function enableRotation(enable) {
drawHelper._scene.screenSpaceCameraController.enableRotate = enable;
}
setListener(billboard, 'leftDown', function(position) {
// TODO - start the drag handlers here
// create handlers for mouseOut and leftUp for the billboard and a mouseMove
function onDrag(position) {
billboard.position = position;
_self.executeListeners({name: 'drag', positions: position});
}
function onDragEnd(position) {
handler.destroy();
enableRotation(true);
_self.executeListeners({name: 'dragEnd', positions: position});
}
var handler = new Cesium.ScreenSpaceEventHandler(drawHelper._scene.canvas);
handler.setInputAction(function(movement) {
var cartesian = drawHelper._scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);
if (cartesian) {
onDrag(cartesian);
} else {
onDragEnd(cartesian);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(function(movement) {
onDragEnd(drawHelper._scene.camera.pickEllipsoid(movement.position, ellipsoid));
}, Cesium.ScreenSpaceEventType.LEFT_UP);
enableRotation(false);
});
enhanceWithListeners(billboard);
}
function setHighlighted(highlighted) {
var scene = drawHelper._scene;
// if no change
// if already highlighted, the outline polygon will be available
if(this._highlighted && this._highlighted == highlighted) {
return;
}
// disable if already in edit mode
if(this._editMode === true) {
return;
}
this._highlighted = highlighted;
// highlight by creating an outline polygon matching the polygon points
if(highlighted) {
// make sure all other shapes are not highlighted
drawHelper.setHighlighted(this);
this._strokeColor = this.strokeColor;
this.setStrokeStyle(Cesium.Color.fromCssColorString('white'), this.strokeWidth);
} else {
if(this._strokeColor) {
this.setStrokeStyle(this._strokeColor, this.strokeWidth);
} else {
this.setStrokeStyle(undefined, undefined);
}
}
}
function setEditMode(editMode) {
// if no change
if(this._editMode == editMode) {
return;
}
// make sure all other shapes are not in edit mode before starting the editing of this shape
drawHelper.disableAllHighlights();
// display markers
if(editMode) {
drawHelper.setEdited(this);
var scene = drawHelper._scene;
var _self = this;
// create the markers and handlers for the editing
if(this._markers == null) {
var markers = new _.BillboardGroup(drawHelper, dragBillboard);
var editMarkers = new _.BillboardGroup(drawHelper, dragHalfBillboard);
// function for updating the edit markers around a certain point
function updateHalfMarkers(index, positions) {
// update the half markers before and after the index
var editIndex = index - 1 < 0 ? positions.length - 1 : index - 1;
if(editIndex < editMarkers.countBillboards()) {
editMarkers.getBillboard(editIndex).position = calculateHalfMarkerPosition(editIndex);
}
editIndex = index;
if(editIndex < editMarkers.countBillboards()) {
editMarkers.getBillboard(editIndex).position = calculateHalfMarkerPosition(editIndex);
}
}
function onEdited() {
_self.executeListeners({name: 'onEdited', positions: _self.positions});
}
var handleMarkerChanges = {
dragHandlers: {
onDrag: function(index, position) {
_self.positions[index] = position;
updateHalfMarkers(index, _self.positions);
_self._createPrimitive = true;
},
onDragEnd: function(index, position) {
_self._createPrimitive = true;
onEdited();
}
},
onDoubleClick: function(index) {
if(_self.positions.length < 4) {
return;
}
// remove the point and the corresponding markers
_self.positions.splice(index, 1);
_self._createPrimitive = true;
markers.removeBillboard(index);
editMarkers.removeBillboard(index);
updateHalfMarkers(index, _self.positions);
onEdited();
},
tooltip: function() {
if(_self.positions.length > 3) {
return "Double click to remove this point";
}
}
};
// add billboards and keep an ordered list of them for the polygon edges
markers.addBillboards(_self.positions, handleMarkerChanges);
this._markers = markers;
function calculateHalfMarkerPosition(index) {
var positions = _self.positions;
return ellipsoid.cartographicToCartesian(
new Cesium.Ellipsoid