|
|
@ -0,0 +1,410 @@ |
|
|
|
/** |
|
|
|
* @module ol/control/MessureControl |
|
|
|
*/ |
|
|
|
import Control from 'ol/control/Control.js'; |
|
|
|
import {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_UNSUPPORTED} from 'ol/css.js'; |
|
|
|
import {replaceNode} from 'ol/dom.js'; |
|
|
|
import {listen} from 'ol/events.js'; |
|
|
|
import EventType from 'ol/events/EventType.js'; |
|
|
|
import {Vector as VectorSource} from 'ol/source'; |
|
|
|
import Overlay from 'ol/Overlay.js'; |
|
|
|
import {LineString, Polygon} from 'ol/geom.js'; |
|
|
|
import Draw from 'ol/interaction/Draw.js'; |
|
|
|
import {Circle as CircleStyle, Fill, Stroke, Style} from 'ol/style.js'; |
|
|
|
import {getArea, getLength} from 'ol/sphere.js'; |
|
|
|
import {unByKey} from 'ol/Observable.js'; |
|
|
|
|
|
|
|
/** |
|
|
|
* @typedef {Object} Options |
|
|
|
* @property {string} [className='ol-full-screen'] CSS class name. |
|
|
|
* @property {string|Text} [label='\u2922'] Text label to use for the button. |
|
|
|
* Instead of text, also an element (e.g. a `span` element) can be used. |
|
|
|
* @property {string|Text} [labelActive='\u00d7'] Text label to use for the |
|
|
|
* button when full-screen is active. |
|
|
|
* Instead of text, also an element (e.g. a `span` element) can be used. |
|
|
|
* @property {string} [tipLabel='Toggle full-screen'] Text label to use for the button tip. |
|
|
|
* @property {boolean} [keys=false] Full keyboard access. |
|
|
|
* @property {HTMLElement|string} [target] Specify a target if you want the |
|
|
|
* control to be rendered outside of the map's viewport. |
|
|
|
* @property {HTMLElement|string} [source] The element to be displayed |
|
|
|
* fullscreen. When not provided, the element containing the map viewport will |
|
|
|
* be displayed fullscreen. |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @classdesc |
|
|
|
* Provides a button that when clicked fills up the full screen with the map. |
|
|
|
* The full screen source element is by default the element containing the map viewport unless |
|
|
|
* overridden by providing the `source` option. In which case, the dom |
|
|
|
* element introduced using this parameter will be displayed in full screen. |
|
|
|
* |
|
|
|
* When in full screen mode, a close button is shown to exit full screen mode. |
|
|
|
* The [Fullscreen API](http://www.w3.org/TR/fullscreen/) is used to
|
|
|
|
* toggle the map in full screen mode. |
|
|
|
* |
|
|
|
* @api |
|
|
|
*/ |
|
|
|
var MessureControl = /*@__PURE__*/(function (Control) { |
|
|
|
function MessureControl(opt_options) { |
|
|
|
|
|
|
|
var self = this; |
|
|
|
var options = opt_options ? opt_options : {}; |
|
|
|
|
|
|
|
Control.call(this, { |
|
|
|
element: document.createElement('div'), |
|
|
|
target: options.target |
|
|
|
}); |
|
|
|
|
|
|
|
this.active_ = options.active ? options.active : false; |
|
|
|
|
|
|
|
/** |
|
|
|
* @private |
|
|
|
* @type {string} |
|
|
|
*/ |
|
|
|
this.cssClassName_ = options.className !== undefined ? options.className : |
|
|
|
'ol-messure'; |
|
|
|
|
|
|
|
var label = options.label !== undefined ? options.label : '\ud83d\udccf'; |
|
|
|
|
|
|
|
/** |
|
|
|
* @private |
|
|
|
* @type {Text} |
|
|
|
*/ |
|
|
|
this.labelNode_ = typeof label === 'string' ? |
|
|
|
document.createTextNode(label) : label; |
|
|
|
|
|
|
|
var labelActive = options.labelActive !== undefined ? options.labelActive : '\ud83d\udccf'; |
|
|
|
|
|
|
|
/** |
|
|
|
* @private |
|
|
|
* @type {Text} |
|
|
|
*/ |
|
|
|
this.labelActiveNode_ = typeof labelActive === 'string' ? |
|
|
|
document.createTextNode(labelActive) : labelActive; |
|
|
|
|
|
|
|
/** |
|
|
|
* @private |
|
|
|
* @type {HTMLElement} |
|
|
|
*/ |
|
|
|
this.button_ = document.createElement('button'); |
|
|
|
|
|
|
|
var tipLabel = options.tipLabel ? options.tipLabel : 'messure distance'; |
|
|
|
this.setClassName_(this.button_, this.active_); |
|
|
|
this.button_.setAttribute('type', 'button'); |
|
|
|
this.button_.title = tipLabel; |
|
|
|
this.button_.appendChild(this.labelNode_); |
|
|
|
|
|
|
|
listen(this.button_, EventType.CLICK, |
|
|
|
this.handleClick_, this); |
|
|
|
|
|
|
|
var cssClasses = this.cssClassName_ + ' ' + CLASS_UNSELECTABLE + |
|
|
|
' ' + CLASS_CONTROL; |
|
|
|
var element = this.element; |
|
|
|
element.className = cssClasses; |
|
|
|
element.appendChild(this.button_); |
|
|
|
|
|
|
|
/** |
|
|
|
* @private |
|
|
|
* @type {boolean} |
|
|
|
* / |
|
|
|
this.keys_ = options.keys !== undefined ? options.keys : false;*/ |
|
|
|
|
|
|
|
/** |
|
|
|
* @private |
|
|
|
* @type {HTMLElement|string|undefined} |
|
|
|
*/ |
|
|
|
this.source_ = options.source ? options.source : new VectorSource(); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Currently drawn feature. |
|
|
|
* @type {module:ol/Feature~Feature} |
|
|
|
*/ |
|
|
|
this.sketch; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* The help tooltip element. |
|
|
|
* @type {Element} |
|
|
|
*/ |
|
|
|
this.helpTooltipElement; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Overlay to show the help messages. |
|
|
|
* @type {module:ol/Overlay} |
|
|
|
*/ |
|
|
|
this.helpTooltip; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* The measure tooltip element. |
|
|
|
* @type {Element} |
|
|
|
*/ |
|
|
|
this.measureTooltipElement; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Overlay to show the measurement. |
|
|
|
* @type {module:ol/Overlay} |
|
|
|
*/ |
|
|
|
this.measureTooltip; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Message to show when the user is drawing a polygon. |
|
|
|
* @type {string} |
|
|
|
*/ |
|
|
|
this.continuePolygonMsg = 'Click to continue drawing the polygon'; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Message to show when the user is drawing a line. |
|
|
|
* @type {string} |
|
|
|
*/ |
|
|
|
this.continueLineMsg = 'Click to continue drawing the line'; |
|
|
|
|
|
|
|
var type = (false ? 'Polygon' : 'LineString'); |
|
|
|
this.draw_ = new Draw({ |
|
|
|
source: this.source_, |
|
|
|
type: type, |
|
|
|
style: new Style({ |
|
|
|
fill: new Fill({ |
|
|
|
color: 'rgba(255, 255, 255, 0.2)' |
|
|
|
}), |
|
|
|
stroke: new Stroke({ |
|
|
|
color: 'rgba(0, 0, 0, 0.5)', |
|
|
|
lineDash: [10, 10], |
|
|
|
width: 2 |
|
|
|
}), |
|
|
|
image: new CircleStyle({ |
|
|
|
radius: 5, |
|
|
|
stroke: new Stroke({ |
|
|
|
color: 'rgba(0, 0, 0, 0.7)' |
|
|
|
}), |
|
|
|
fill: new Fill({ |
|
|
|
color: 'rgba(255, 255, 255, 0.2)' |
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
}); |
|
|
|
|
|
|
|
var listener; |
|
|
|
this.draw_.on('drawstart', |
|
|
|
function(evt) { |
|
|
|
// set sketch
|
|
|
|
self.sketch = evt.feature; |
|
|
|
|
|
|
|
/** @type {module:ol/coordinate~Coordinate|undefined} */ |
|
|
|
var tooltipCoord = evt.coordinate; |
|
|
|
|
|
|
|
listener = self.sketch.getGeometry().on('change', function(evt) { |
|
|
|
var geom = evt.target; |
|
|
|
var output; |
|
|
|
if (geom instanceof Polygon) { |
|
|
|
output = formatArea(geom); |
|
|
|
tooltipCoord = geom.getInteriorPoint().getCoordinates(); |
|
|
|
} else if (geom instanceof LineString) { |
|
|
|
output = self.formatLength(geom); |
|
|
|
tooltipCoord = geom.getLastCoordinate(); |
|
|
|
} |
|
|
|
self.measureTooltipElement.innerHTML = output; |
|
|
|
self.measureTooltip.setPosition(tooltipCoord); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
this.draw_.on('drawend', |
|
|
|
function() { |
|
|
|
self.measureTooltipElement.className = 'tooltip tooltip-static'; |
|
|
|
self.measureTooltip.setOffset([0, -7]); |
|
|
|
// unset sketch
|
|
|
|
self.sketch = null; |
|
|
|
// unset tooltip so that a new one can be created
|
|
|
|
self.measureTooltipElement = null; |
|
|
|
self.createMeasureTooltip(); |
|
|
|
unByKey(listener); |
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if ( Control ) MessureControl.__proto__ = Control; |
|
|
|
MessureControl.prototype = Object.create( Control && Control.prototype ); |
|
|
|
MessureControl.prototype.constructor = MessureControl; |
|
|
|
|
|
|
|
/** |
|
|
|
* @param {MouseEvent} event The event to handle |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
MessureControl.prototype.handleClick_ = function handleClick_ (event) { |
|
|
|
event.preventDefault(); |
|
|
|
this.handleMessureControl_(); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
MessureControl.prototype.isActive = function isActive () { |
|
|
|
return this.active_; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
*/ |
|
|
|
MessureControl.prototype.activate = function activate () { |
|
|
|
if (this.isActive()) { |
|
|
|
return; |
|
|
|
} |
|
|
|
var map = this.getMap(); |
|
|
|
var self = this; |
|
|
|
this.pointerMoveHandler_ = (e) => self.pointerMoveHandler(e); |
|
|
|
map.on('pointermove', this.pointerMoveHandler_); |
|
|
|
map.addInteraction(this.draw_); |
|
|
|
|
|
|
|
this.active_ = true; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
*/ |
|
|
|
MessureControl.prototype.deactivate = function deactivate () { |
|
|
|
var map = this.getMap(); |
|
|
|
map.un('pointermove', this.pointerMoveHandler_); |
|
|
|
map.removeInteraction(this.draw_); |
|
|
|
this.helpTooltipElement.classList.add('hidden'); |
|
|
|
this.active_ = true; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Handle pointer move. |
|
|
|
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt The event. |
|
|
|
*/ |
|
|
|
MessureControl.prototype.pointerMoveHandler = function pointerMoveHandler (evt) { |
|
|
|
if (evt.dragging) { |
|
|
|
return; |
|
|
|
} |
|
|
|
/** @type {string} */ |
|
|
|
var helpMsg = 'Click to start drawing'; |
|
|
|
|
|
|
|
if (this.sketch) { |
|
|
|
var geom = (this.sketch.getGeometry()); |
|
|
|
if (geom instanceof Polygon) { |
|
|
|
helpMsg = this.continuePolygonMsg; |
|
|
|
} else if (geom instanceof LineString) { |
|
|
|
helpMsg = this.continueLineMsg; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
this.helpTooltipElement.innerHTML = helpMsg; |
|
|
|
this.helpTooltip.setPosition(evt.coordinate); |
|
|
|
|
|
|
|
this.helpTooltipElement.classList.remove('hidden'); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* @param {HTMLElement} element Target element |
|
|
|
* @param {boolean} fullscreen True if fullscreen class name should be active |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
MessureControl.prototype.setClassName_ = function setClassName_ (element, fullscreen) { |
|
|
|
var activeClassName = this.cssClassName_ + '-true'; |
|
|
|
var inactiveClassName = this.cssClassName_ + '-false'; |
|
|
|
var nextClassName = fullscreen ? activeClassName : inactiveClassName; |
|
|
|
element.classList.remove(activeClassName); |
|
|
|
element.classList.remove(inactiveClassName); |
|
|
|
element.classList.add(nextClassName); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* @inheritDoc |
|
|
|
* @api |
|
|
|
*/ |
|
|
|
MessureControl.prototype.setMap = function setMap (map) { |
|
|
|
Control.prototype.setMap.call(this, map); |
|
|
|
var self = this; |
|
|
|
|
|
|
|
if (map) { |
|
|
|
this.createHelpTooltip(); |
|
|
|
map.getViewport().addEventListener('mouseout', function() { |
|
|
|
self.helpTooltipElement.classList.add('hidden'); |
|
|
|
}); |
|
|
|
this.createMeasureTooltip(); |
|
|
|
this.createHelpTooltip(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Creates a new help tooltip |
|
|
|
*/ |
|
|
|
MessureControl.prototype.createHelpTooltip = function createHelpTooltip() { |
|
|
|
if (this.helpTooltipElement) { |
|
|
|
this.helpTooltipElement.parentNode.removeChild(this.helpTooltipElement); |
|
|
|
} |
|
|
|
this.helpTooltipElement = document.createElement('div'); |
|
|
|
this.helpTooltipElement.className = 'tooltip hidden'; |
|
|
|
this.helpTooltip = new Overlay({ |
|
|
|
element: this.helpTooltipElement, |
|
|
|
offset: [15, 0], |
|
|
|
positioning: 'center-left' |
|
|
|
}); |
|
|
|
this.getMap().addOverlay(this.helpTooltip); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
MessureControl.prototype.handleMessureControl_ = function handleMessureControl_ () { |
|
|
|
var map = this.getMap(); |
|
|
|
var self = this; |
|
|
|
if (!map) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if (this.isActive()) { |
|
|
|
//exitMessureControl();
|
|
|
|
this.deactivate(); |
|
|
|
} else { |
|
|
|
this.activate(); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Creates a new measure tooltip |
|
|
|
*/ |
|
|
|
MessureControl.prototype.createMeasureTooltip = function createMeasureTooltip() { |
|
|
|
var map = this.getMap(); |
|
|
|
if (this.measureTooltipElement) { |
|
|
|
measureTooltipElement.parentNode.removeChild(measureTooltipElement); |
|
|
|
} |
|
|
|
this.measureTooltipElement = document.createElement('div'); |
|
|
|
this.measureTooltipElement.className = 'tooltip tooltip-measure'; |
|
|
|
this.measureTooltip = new Overlay({ |
|
|
|
element: this.measureTooltipElement, |
|
|
|
offset: [0, -15], |
|
|
|
positioning: 'bottom-center' |
|
|
|
}); |
|
|
|
map.addOverlay(this.measureTooltip); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Format length output. |
|
|
|
* @param {module:ol/geom/LineString~LineString} line The line. |
|
|
|
* @return {string} The formatted length. |
|
|
|
*/ |
|
|
|
MessureControl.prototype.formatLength = function formatLength(line) { |
|
|
|
var length = getLength(line); |
|
|
|
var output; |
|
|
|
if (length > 100) { |
|
|
|
output = (Math.round(length / 1000 * 100) / 100) + |
|
|
|
' ' + 'km'; |
|
|
|
} else { |
|
|
|
output = (Math.round(length * 100) / 100) + |
|
|
|
' ' + 'm'; |
|
|
|
} |
|
|
|
return output; |
|
|
|
}; |
|
|
|
|
|
|
|
return MessureControl; |
|
|
|
}(Control)); |
|
|
|
|
|
|
|
export default MessureControl; |
|
|
|
|
|
|
|
//# sourceMappingURL=MessureControl.js.map
|