- new BoreholeTool: BoreholeControl.css, BoreholeControl.js, BaseEditor.js, MarkerLayer

- changes in: Picking.js, domUtil.js, Map.js, Layer.js (for popup), main.js, index.html (third data tab)
- npm updates
This commit is contained in:
Arno Kaimbacher 2021-03-23 12:26:43 +01:00
parent a09db46a03
commit 37d7973071
12 changed files with 830 additions and 150 deletions

View file

@ -17,6 +17,8 @@ export class Picking {
plane;
touchCapable = false;
isDraging = false;
enabled = true;
defaultMapCursor;
constructor(size, center, simulation) {
this.size = size;
@ -43,6 +45,7 @@ export class Picking {
simulation.scene.add(this.plane);
this.domElement = simulation.renderer.domElement;
this.defaultMapCursor = this.domElement.style.cursor;
domEvent.on(this.domElement, 'mousemove', this.mouseMove, this);
if (this.touchCapable == true) {
domEvent.on(this.domElement, 'touchstart', this.beginDrag, this);
@ -78,7 +81,7 @@ export class Picking {
}
mouseMove(event) {
if (this.isDraging == true || this.simulation.selection.visible == false) {
if (this.isDraging == true || this.simulation.selection.visible == false || this.enabled == false) {
return;
}
let point = this._getCanvasPoint(event);
@ -110,14 +113,14 @@ export class Picking {
// cursor is not selecting the box
this.intersected.guardian.rayOut();
this.intersected = null;
this.simulation.renderer.domElement.style.cursor = 'auto';
this.simulation.renderer.domElement.style.cursor = this.defaultMapCursor;
// this.simulation.throttledRender();
this.simulation.deferringThrottle();
}
}
beginDrag(event) {
if (this.simulation.selection.visible == false) {
if (this.simulation.selection.visible == false && this.enabled == false) {
return;
}
// exit drag method, if not left mouse button was clicked
@ -225,5 +228,25 @@ export class Picking {
}
}
disable () {
domEvent.off(this.domElement, 'mousemove', this.mouseMove, this);
if (this.touchCapable == true) {
domEvent.off(this.domElement, 'touchstart', this.beginDrag, this);
} else {
domEvent.off(this.domElement, 'mousedown', this.beginDrag, this);
}
this.enabled = false;
}
enable() {
domEvent.on(this.domElement, 'mousemove', this.mouseMove, this);
if (this.touchCapable == true) {
domEvent.on(this.domElement, 'touchstart', this.beginDrag, this);
} else {
domEvent.on(this.domElement, 'mousedown', this.beginDrag, this);
}
this.enabled = true;
}
}

View file

@ -0,0 +1,51 @@
.gba-maptool-control {
border-radius: 4px;
border: 1px solid #bbb;
box-shadow: none;
margin:0;
padding:0;
overflow:hidden;
}
.gba-maptool-control a {
background-position: 50% 50%;
margin: 0;
background-repeat: no-repeat;
display: block;
height: 30px;
width: 30px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAdCAAAAACYz4PQAAAAAnRSTlMA/1uRIrUAAAAJcEhZcwAAFxIAABcSAWef0lIAAACLSURBVCjPzZExGQUxCINjoB5qAge1UBvdKgIN3c8ELjqjAQu89W4g8+tG/4+QAPL9zMw+H3gXd5mtKLGfTK3x/XPsDLskyR3SyFr2wKi7cwCLiAPPqcUDhwbbmfxi2thaDjpxPoFZ4+gYSjCEOpdg2DVdmPPojcxWATlodrRNgz27np029RLx9PjWPwOEKTMp8DmSAAAAAElFTkSuQmCC') /*img/drill2.png*/;
float: left;
}
.measure-enabled .gba-maptool-control a{
background-color:skyblue;
}
#radio{
float: left;
}
.gba-maptool-toggle {
display: inline-block;
vertical-align: middle;
}
.gba-maptool-control input:checked + label:before {
content: '✓';
padding-left: -2em;
}
.gba-maptool-control input[type=radio] {
display: none;
}
.gba-maptool-control input[type=radio] + label {
display: none;
line-height: 30px;
height: 30px;
width: 30px;
margin: 0;
padding: 0;
font-size: 12px;
text-align: center;
vertical-align: middle;
cursor: pointer;
}
.measure-enabled .gba-maptool-control input[type=radio] + label {
display: inline-block;
}

View file

@ -0,0 +1,34 @@
import { Control } from "./Control";
import * as dom from '../core/domUtil';
import * as util from '../core/utilities';
import * as domEvent from '../core/domEvent';
import { BoreholeTool } from '../tools/BoreholeTool';
import './BoreholeControl.css';
export class BoreholeControl extends Control {
onAdd (map) {
this.map = map;
// var b = this._nls = util.mixin({}, N.widgets.boreholetool);
this._container = dom.createDom("div", { "class": 'gba-maptool-control gba-control' });
//new L.Measurable(map);
let mapTool = new BoreholeTool(this.map);
//var inputDiv = dom.createDom("div", { id: "radio" }, this._container);
//this.addUnit(inputDiv, 'km', 'km', 'kilometers', true);
//this.addUnit(inputDiv, 'mi', 'mi', 'miles');
////this.addUnit(inputDiv, 'nm', 'NM', 'nautical miles');
let toggle = dom.createDom('a', { "class": "gba-maptool-toggle", href: "#", title: "b.title" }, this._container);
domEvent.disableClickPropagation(this._container);
domEvent
// .on(toggle, 'click', domEvent.stop)
// .on(toggle, 'click', domEvent.preventDefault)
.on(toggle, 'click', mapTool.toggle, mapTool);
return this._container;
}
}

150
src/js/core/BaseEditor.js Normal file
View file

@ -0,0 +1,150 @@
import * as util from './utilities';
var Editable = {
makeCancellable: function (e) {
e.cancel = function () {
e._cancelled = true;
};
}
};
export class BaseEditor {
map;
marker;
mapTool;
constructor(map, featureLayer, options = {}) {
util.setOptions(this, options);
this.map = map;
this.marker = featureLayer;
this.marker.editor = this;
//this.editLayer = new LayerGroup();
this.mapTool = map.mapTool; //this.options.editTools || map.mapTool;
// this.marker.bindPopup(map._controls.boreholePopup);
}
enable() {
if (this._enabled) return this;
//if (this.isConnected() == true) {
// this.mapTool.editLayer.addLayer(this.editLayer);
//}
this.onEnable();
this._enabled = true;
this.marker.on('remove', this.disable.bind(this));
return this;
}
disable() {
this.marker.off('remove', this.disable.bind(this));
//this.editLayer.clearLayers();
//this.mapTool.editLayer.removeLayer(this.editLayer);
this.onDisable();
delete this._enabled;
if (this._drawing) this.cancelDrawing();
return this;
}
isConnected() {
return this.map.hasLayer(this.marker);
}
drawing() {
return !!this._drawing;
}
fireAndForward(type, e) {
e = e || {};
e.layer = this.marker;
this.marker.emit(type, e);
this.mapTool.fireAndForward(type, e);
}
onEnable() {
this.fireAndForward('editable:enable');
}
onDisable() {
this.fireAndForward('editable:disable');
}
onEditing() {
this.fireAndForward('editable:editing');
}
onDrawingMouseDown(e) {
this.fireAndForward('editable:drawing:mousedown', e);
}
startDrawing() {
if (!this._drawing) {
this._drawing = 1;// L.Editable.FORWARD;
}
this.mapTool.registerForDrawing(this);
this._onStartDrawing();
}
_onStartDrawing() {
this.fireAndForward('editable:drawing:start');
}
onDrawingClick(e) {
if (!this.drawing) return;
Editable.makeCancellable(e);
this.fireAndForward('editable:drawing:click', e);
if (e._cancelled) return;
//if (!this.isConnected()) {
// this.connect(e);
//}
var dxfIdentifyParams = {};
dxfIdentifyParams.clientX = e.clientX;
dxfIdentifyParams.clientY = e.clientY;
dxfIdentifyParams.width = this.map.container.clientWidth;
dxfIdentifyParams.height = this.map.container.clientHeight;
// var deferred = this.mapTool.drillTask.execute(dxfIdentifyParams);
// deferred.then(this.handleQueryResults3.bind(this));
this._processDrawingClick(e);
}
_processDrawingClick (e) {
this.fireAndForward('editable:drawing:clicked', e);
this._commitDrawing(e);
}
_commitDrawing (e) {
this._onCommitDrawing(e);
}
_onCommitDrawing(e) {
this.fireAndForward('editable:drawing:commit', e);
}
cancelDrawing() {
this._onCancelDrawing();
this._endDrawing();
}
_onCancelDrawing () {
this.fireAndForward('editable:drawing:cancel');
}
_endDrawing () {
this._drawing = false;
this.mapTool.unregisterForDrawing(this);
this._onEndDrawing();
}
_onEndDrawing() {
this.fireAndForward('editable:drawing:end');
}
}

View file

@ -2,6 +2,7 @@ import { OrbitControls } from '../lib/OrbitControls';
import * as dom from './domUtil';
import { HomeButton } from '../controls/HomeButton';
import { ZoomControl } from '../controls/ZoomControl';
import { BoreholeControl } from '../controls/BoreholeControl';
import * as util from './utilities';
import { TinLayer } from '../layer/TinLayer';
@ -125,6 +126,8 @@ class Map extends OrbitControls {
let zoomControl = this._controls.zoomControl = new ZoomControl();
zoomControl.addTo(this);
this._controls.maptoolControl = new BoreholeControl().addTo(this);
}
async addLayer(layer) {
@ -150,6 +153,10 @@ class Map extends OrbitControls {
return !!layer && (util.stamp(layer) in this._layers);
}
getCenter () { // (Boolean) -> LatLng
return this.target;
}
}
export { Map };

View file

@ -86,6 +86,17 @@ export function setProperties(element, properties) {
}
}
// @function hasClass(el: HTMLElement, name: String): Boolean
// Returns `true` if the element's class attribute contains `name`.
export function hasClass(el, name) {
if (el.classList !== undefined) {
return el.classList.contains(name);
}
var className = getClass(el);
return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className);
}
// @function addClass(el: HTMLElement, name: String)
// Adds `name` to the element's class attribute.
export function addClass(el, name) {

View file

@ -41,7 +41,58 @@ class Layer extends EventEmitter {
getScene() {
return this._map.scene;
}
// @method bindPopup(content: String|HTMLElement|Function|Popup, options?: Popup options): this
// Binds a popup to the layer with the passed `content` and sets up the
// neccessary event listeners. If a `Function` is passed it will receive
// the layer as the first argument and should return a `String` or `HTMLElement`.
bindPopup(content) {
if (content instanceof BoreholePopup) {
//util.setOptions(content, options);
this._popup = content;
content._source = this;
}
if (!this._popup) {
//this._popup = new L.Popup(options, this);
this._popup = new BoreholePopup({}, this);
this._popup.addTo(this._map);
this._popup.setChartContent(content);
}
if (!this._popupHandlersAdded) {
this.on("click", this.openPopup, this); //remove: this.closePopup //move: this._movePopup
this.on('remove', this.closePopup, this);
this._popupHandlersAdded = true;
}
//// save the originally passed offset
//this._originalPopupOffset = this._popup.options.offset;
return this;
}
setPopupChartData(content) {
this._popup.setChartContent(content);
}
openPopup() {
this._popup.show();
}
// @method closePopup(): this
// Closes the popup bound to this layer if it is open.
closePopup() {
if (this._popup) {
this._popup._close();
//this._popup.removeFrom(this._map);
}
return this;
}
}
export { Layer };

131
src/js/layer/MarkerLayer.js Normal file
View file

@ -0,0 +1,131 @@
import { Layer } from './Layer';
import * as util from '../core/utilities';
import { BaseEditor } from '../core/BaseEditor';
export class MarkerLayer extends Layer {
createEditor(map) {
map = map || this._map;
var Klass = this.options.editorClass || this.getEditorClass(map);
return new Klass(map, this, this.options.editOptions);
}
enableEdit(map) {
if (!this.editor) {
this.createEditor(map);
}
return this.editor.enable();
}
getEditorClass(map) {
return BaseEditor;
}
options = {
pane: 'markerPane',
nonBubblingEvents: ['click', 'dblclick', 'mouseover', 'mouseout', 'contextmenu'],
//icon: new L.Icon.Default(),
opacity: 1,
clickable: true,
};
constructor(latlng, options) {
super();
util.setOptions(this, options);
this._latlng = latlng;
}
onAdd(map) {
//this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation;
this._initIcon();
this.update();
this.emit('add');
}
onRemove() {
//if (this.dragging && this.dragging.enabled()) {
// this.options.draggable = true;
// this.dragging.removeHooks();
//}
this._removeIcon();
//this._removeShadow();
this.emit('remove');
this._map = null;
}
update() {
if (this._icon) {
var pos = this._latlng;
this._setPos(pos);
}
this._map.emit("change");
return this;
}
getElement() {
return this._icon;
}
_initIcon() {
//create default icon
var opt = { r: 0.25, c: 0xffff00, o: 0.8 };
var icon = new THREE.Mesh(new THREE.CylinderGeometry(0, 0.5, 2),
new THREE.MeshLambertMaterial({ color: 0x38eeff, opacity: opt.o, transparent: (opt.o < 1) }));
icon.rotation.x = THREE.Math.degToRad(-90);
icon.visible = true;
//app.scene.add(app.boreholeMarker);
var addIcon = false;
// if we're not reusing the icon, remove the old one and init new one
if (icon !== this._icon) {
if (this._icon) {
this._removeIcon();
}
addIcon = true;
//if (options.title) {
// icon.title = options.title;
//}
//if (options.alt) {
// icon.alt = options.alt;
//}
}
this._icon = icon;
//this._initInteraction();
if (addIcon === true) {
this.getPane().add(this._icon);
}
}
_removeIcon() {
//if (this.options.riseOnHover) {
// this.off({
// mouseover: this._bringToFront,
// mouseout: this._resetZIndex
// });
//}
//L.DomUtil.remove(this._icon);
this.getPane().remove(this._icon);
//this.removeInteractiveTarget(this._icon);
this._icon = null;
}
_setPos(pos) {
//L.DomUtil.setPosition(this._icon, pos);
this._icon.position.set(pos.x, pos.y, pos.z);
}
setLatLng(latlng) {
this._latlng = latlng;
this.update();
}
}

View file

@ -13,7 +13,6 @@ import { NorthArrow } from './controls/NorthArrow';
import { LayerControl } from './controls/LayerControl';
import { BasemapControl } from './controls/BasemapControl';
import { SliderControl } from './controls/SliderControl';
// import { SlicerControl } from './controls/SlicerControl';
import { Mesh } from 'three/src/objects/Mesh';
import { SphereGeometry } from 'three/src/geometries/SphereGeometry';
import { MeshLambertMaterial } from 'three/src/materials/MeshLambertMaterial';
@ -196,7 +195,7 @@ class Application {
);
this.map.addLayer(this.selection);
new Picking(size, center, this);
this.map.picking = new Picking(size, center, this);
// let boxLayer = new BoxLayer({

View file

@ -0,0 +1,185 @@
import { EventEmitter } from '../core/EventEmitter';
import { MeshLambertMaterial } from 'three/src/materials/MeshLambertMaterial';
import * as domEvent from '../core/domEvent';
import { MarkerLayer } from '../layer/MarkerLayer';
import * as dom from '../core/domUtil';
import * as util from '../core/utilities';
export class BoreholeTool extends EventEmitter {
options = {
zIndex: 1000,
markerClass: MarkerLayer,//THREE.CylinderGeometry,
drawingCSSClass: 'gba-editable-drawing',
drawingCursor: 'crosshair'
};
constructor(map, options = {}) {
super();
util.setOptions(this, options);
this._lastZIndex = this.options.zIndex;
this.map = map;
// this.featuresLayer = this._createFeaturesLayer();
//this.forwardLineGuide = this.createLineGuide();
//this.backwardLineGuide = this.createLineGuide();
this.map.mapTool = this;
//this.on('editable:drawing:end', function () {
// if (this.enabled()) this.startMarker();
//});
let highlightMaterial = new MeshLambertMaterial({ emissive: 0x999900, transparent: true, opacity: 0.5 });
this.defaultMapCursor = this.map.domElement.style.cursor;
}
// _createFeaturesLayer () {
// return new LayerGroup().addTo(this.map);
// }
enabled() {
return dom.hasClass(this.map.container, 'measure-enabled');
}
toggle() {
if (this.enabled()) {
this.disable();
}
else {
this.enable();
}
}
enable() {
//if (this.map.mapTool) this.map.mapTool.on('editable:drawing:start', this.disable.bind(this));
dom.addClass(this.map.container, 'measure-enabled');
//this.fireAndForward('showmeasure');
this._startMarker();
}
disable() {
//if (this.map.mapTool) this.map.mapTool.off('editable:drawing:start', this.disable.bind(this));
dom.removeClass(this.map.container, 'measure-enabled');
// this.featuresLayer.clearLayers();
//this.fireAndForward('hidemeasure');
if (this._drawingEditor) {
this._drawingEditor.cancelDrawing();
}
}
fireAndForward(type, e) {
e = e || {};
e.mapTool = this;
this.emit(type, e);
this.map.emit(type, e);
}
_startMarker(latlng, options) {
latlng = latlng || this.map.getCenter().clone();
let markerLayer = this._createMarker(latlng, options);//.addTo(this.map);
//this.map.addLayer(marker);
//marker.enableEdit(this.map).startDrawing(); //editor.startDrawing() -> registerForDrawing
let baseEditor = markerLayer.enableEdit(this.map);
baseEditor.startDrawing();
return markerLayer;
}
_createMarker(latlng, options) {
return this._createLayer(options && options.markerClass || this.options.markerClass, latlng, options);
}
_createLayer(klass, latlngs, options) {
options = util.extend({ editOptions: { mapTool: this } }, options);
let layer = new klass(latlngs, options);
//this.fireAndForward('editable:created', { layer: layer });
return layer;
}
registerForDrawing(editor) {
if (this._drawingEditor) {
this.unregisterForDrawing(this._drawingEditor);
}
//this.map.on('mousemove touchmove', editor.onDrawingMouseMove, editor);
this._blockEvents();
this._drawingEditor = editor;
this.map.on('mousedown', this._onMousedown);
this.map.on('clicked', this._onMouseup);
dom.addClass(this.map.domElement, this.options.drawingCSSClass);
// this.defaultMapCursor = this.map.domElement.style.cursor;
//this.map.domElement.style.cursor = this.options.drawingCursor;
// this.map.domElement.style.cursor = "crosshair";
this.map.domElement.style.cursor = "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAdCAMAAABRwYYcAAABPlBMVEUAAAC7u7vQ0NCTk5PU1NTr6+u6urpVVVXR0dEhISG8vLxISEjS0tL09PTo6OiEhISlpaX39/cAAABNTU2mpqZRUVH4+Phzc3NOTk75+fmBgYHu7u7CwsKdnZ1cXFzQ0NAvLy8FBQXb29v9/f0rKysJCQmFhYVlZWUyMjLa2tr///96enoMDAyJiYkXFxcZGRkLCwtZWVl/f38aGhqrq6vV1dXj4+N5eXnb29vd3d1FRUXR0dG5ubnQ0NCCgoKVlZWNjY1BQUHt7e0GBgYAAAC3t7ctLS2/v783NzcfHx/r6+uUlJSkpKQCAgKoqKh8fHyAgIAsLCynp6cHBwddXV0yMjIXFxfOzs4+Pj7g4OCioqITExOfn58BAQEbGxsxMTGTk5PPz8+QkJAICAi4uLjf39+zs7O+vr5LS0uLi4svZJaIAAAATHRSTlMA7uD+DN/YA9/Y/tjfye4Z9Mn+/vTuydj+yfTmFRULC+7+38nY/hUZ/uDJ2P7+C/7Y2BT+/tjJFeD8C+AL3/702O7f/gPu/hTY7uDuXbwlLQAAAKxJREFUeF6VzWVyAmEMBuCwuLu7lsW9uBWqK7i7tb3/BcjHDciPPJPJmwnUBb8KCQBQ/OXWtAOUTVLtSg9Qe8JNCdW5jiEACHDLYTSGDhZvSpyrHTZhRen1mCuoAcS7nwi5oxy9l38L+Zfj3zGvYk4GOeY8ZjacRb+nW2MbFc98bpJv/GleiXTrY24LAshG13wG993D3v+Jpr7YdPxxd2aSmPP2J8IiYIkqTux3Y8Yeb6YtyDkAAAAASUVORK5CYII=') 3 31, crosshair";
//background-image:url(/content/img/drill.png);
}
unregisterForDrawing(editor) {
this._unblockEvents();
dom.removeClass(this.map.domElement, this.options.drawingCSSClass);
this.map.domElement.style.cursor = this.defaultMapCursor;
editor = editor || this._drawingEditor;
if (!editor) return;
//this.map.off('mousemove touchmove', editor.onDrawingMouseMove, editor);
this.map.off('mousedown', this._onMousedown);
this.map.off('clicked', this._onMouseup);
if (editor !== this._drawingEditor) return;
delete this._drawingEditor;
//if (editor._drawing) {
// editor.cancelDrawing();
//}
}
_blockEvents() {
// Hack: force map not to listen to other layers events while drawing.
//if (!this._oldTargets) {
//this._oldTargets = this.map._events;
//this.map._events = {};
//}
if (!this._oldClickTargets) {
this._oldClickTargets = this.map._events.clicked;
this.map._events.clicked = [];
}
if (this.map.picking) {
this.map.picking.disable();
}
}
_unblockEvents() {
//if (this._oldTargets) {
// // Reset, but keep targets created while drawing.
// this.map._events = util.extend(this.map._events, this._oldTargets);
// delete this._oldTargets;
//}
if (this._oldClickTargets) {
// Reset, but keep targets created while drawing.
this.map._events.clicked = this.map._events.clicked.concat(this._oldClickTargets);
delete this._oldClickTargets;
}
if (this.map.picking) {
this.map.picking.enable();
}
}
_onMousedown(e) {
//var canvasOffset = $(this.domElement).offset();
//var xClickedOnCanvas = e.clientX - canvasOffset.left;
//var yClickedonCanvas = e.clientY - canvasOffset.top;
//var event = { x: xClickedOnCanvas, y: yClickedonCanvas };
this.mapTool._mouseDown = e;
this.mapTool._drawingEditor.onDrawingMouseDown(e);
}
_onMouseup(e) {
if (this.mapTool._mouseDown) {
//var originPoint = new Point(this.mapTool._mouseDown.clientX, this.mapTool._mouseDown.clientY);
//var endPoint = new Point(e.clientX, e.clientY);
//var distance = endPoint.distanceTo(originPoint);
//if (Math.abs(distance) < 9 * (window.devicePixelRatio || 1)) this.mapTool._drawingEditor.onDrawingClick(e);
//else this._drawingEditor.onDrawingMouseUp(e);
this.mapTool._drawingEditor.onDrawingClick(this.mapTool._mouseDown);
}
this.mapTool._mouseDown = null;
}
}