add messure, I <3 JS, not
parent
b6b4a309d8
commit
46ef181ec7
|
@ -2,6 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<title>CCCamp19 map of milliways</title>
|
||||
<link rel="stylesheet" href="./main.css" type="text/css">
|
||||
<style>
|
||||
|
|
|
@ -384,5 +384,45 @@ html, body {
|
|||
bottom: 0;
|
||||
width: 100%; }
|
||||
|
||||
.hidden {
|
||||
display: none; }
|
||||
|
||||
.ol-messure {
|
||||
right: .25em;
|
||||
top: 10em;
|
||||
font-size: 1.5em; }
|
||||
|
||||
.tooltip {
|
||||
position: relative;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
opacity: 0.7;
|
||||
white-space: nowrap; }
|
||||
|
||||
.tooltip-measure {
|
||||
opacity: 1;
|
||||
font-weight: bold; }
|
||||
|
||||
.tooltip-static {
|
||||
background-color: #ffcc33;
|
||||
color: black;
|
||||
border: 1px solid white; }
|
||||
|
||||
.tooltip-measure:before,
|
||||
.tooltip-static:before {
|
||||
border-top: 6px solid rgba(0, 0, 0, 0.5);
|
||||
border-right: 6px solid transparent;
|
||||
border-left: 6px solid transparent;
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: -6px;
|
||||
margin-left: -7px;
|
||||
left: 50%; }
|
||||
|
||||
.tooltip-static:before {
|
||||
border-top-color: #ffcc33; }
|
||||
|
||||
|
||||
/*# sourceMappingURL=main.css.map*/
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -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
|
30
src/app.js
30
src/app.js
|
@ -3,7 +3,8 @@ import Map from 'ol/Map.js';
|
|||
import WebGLMap from 'ol/WebGLMap.js';
|
||||
import {WEBGL} from 'ol/has.js'
|
||||
import View from 'ol/View.js';
|
||||
import {defaults as defaultControls, Attribution as AttributionControl} from 'ol/control.js';
|
||||
import {defaults as defaultControls, Attribution as AttributionControl, ScaleLine as ScaleLineControl} from 'ol/control.js';
|
||||
import MessureControl from './MessureControl.js';
|
||||
import LayerSwitcher from 'ol-layerswitcher';
|
||||
import {all as allStrategy} from 'ol/loadingstrategy';
|
||||
import {bbox as bboxStrategy} from 'ol/loadingstrategy.js';
|
||||
|
@ -134,6 +135,26 @@ var vectorSource = new VectorSource({
|
|||
attributions: '©<a href="https://git.milliways.info/Milliways/cccamp19-map">Milliways</a>',
|
||||
});
|
||||
|
||||
var messureSource = new VectorSource();
|
||||
var messureLayer = new VectorLayer({
|
||||
title: 'Messure',
|
||||
source: messureSource,
|
||||
style: new Style({
|
||||
fill: new Fill({
|
||||
color: 'rgba(255, 255, 255, 0.2)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#ffcc33',
|
||||
width: 2
|
||||
}),
|
||||
image: new CircleStyle({
|
||||
radius: 7,
|
||||
fill: new Fill({
|
||||
color: '#ffcc33'
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
var orthoLayer = new TileLayer({
|
||||
title: 'Ortho Imagery',
|
||||
type: 'base',
|
||||
|
@ -182,7 +203,9 @@ var osmLayer = new TileLayer({
|
|||
var map = new MapClass({
|
||||
target: 'map',
|
||||
controls: defaultControls().extend([
|
||||
new LayerSwitcher()
|
||||
new LayerSwitcher(),
|
||||
new ScaleLineControl(),
|
||||
new MessureControl({ source: messureSource}),
|
||||
]),
|
||||
numZoomLevels: 19,
|
||||
units: 'm',
|
||||
|
@ -197,7 +220,8 @@ var map = new MapClass({
|
|||
new LayerGroup({
|
||||
title: 'overlays',
|
||||
layers: [
|
||||
vectorLayer
|
||||
vectorLayer,
|
||||
messureLayer,
|
||||
]
|
||||
})
|
||||
],
|
||||
|
|
43
src/app.scss
43
src/app.scss
|
@ -12,3 +12,46 @@ html, body {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ol-messure {
|
||||
right: .25em;
|
||||
top: 10em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
position: relative;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
opacity: 0.7;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tooltip-measure {
|
||||
opacity: 1;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltip-static {
|
||||
background-color: #ffcc33;
|
||||
color: black;
|
||||
border: 1px solid white;
|
||||
}
|
||||
.tooltip-measure:before,
|
||||
.tooltip-static:before {
|
||||
border-top: 6px solid rgba(0, 0, 0, 0.5);
|
||||
border-right: 6px solid transparent;
|
||||
border-left: 6px solid transparent;
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: -6px;
|
||||
margin-left: -7px;
|
||||
left: 50%;
|
||||
}
|
||||
.tooltip-static:before {
|
||||
border-top-color: #ffcc33;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue