UNPKG

@osh-branches/osh-js

Version:
1,332 lines (1,102 loc) 78.4 kB
/** * 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