geojs 1.9.3 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/main.yml +1 -1
- package/CHANGELOG.md +22 -0
- package/geo.js +292 -43
- package/geo.lean.js +291 -42
- package/geo.lean.min.js +2 -2
- package/geo.min.js +3 -3
- package/package.json +1 -1
- package/src/action.js +3 -5
- package/src/annotation/annotation.js +73 -7
- package/src/annotation/polygonAnnotation.js +11 -0
- package/src/annotationLayer.js +60 -16
- package/src/event.js +28 -0
- package/src/main.styl +11 -0
- package/src/map.js +15 -7
- package/src/mapInteractor.js +49 -3
- package/src/registry.js +3 -0
- package/src/util/polyops.js +4 -1
package/package.json
CHANGED
package/src/action.js
CHANGED
|
@@ -16,11 +16,9 @@ var geo_action = {
|
|
|
16
16
|
zoomrotate: 'geo_action_zoom_rotate',
|
|
17
17
|
zoomselect: 'geo_action_zoomselect',
|
|
18
18
|
|
|
19
|
-
// annotation actions
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
annotation_rectangle: 'geo_annotation_rectangle',
|
|
23
|
-
annotation_edit_handle: 'geo_annotation_edit_handle'
|
|
19
|
+
// annotation actions -- some are also added by the registry
|
|
20
|
+
annotation_edit_handle: 'geo_annotation_edit_handle',
|
|
21
|
+
annotation_cursor: 'geo_annotation_cursor'
|
|
24
22
|
};
|
|
25
23
|
|
|
26
24
|
module.exports = geo_action;
|
|
@@ -15,7 +15,8 @@ var annotationState = {
|
|
|
15
15
|
create: 'create',
|
|
16
16
|
done: 'done',
|
|
17
17
|
highlight: 'highlight',
|
|
18
|
-
edit: 'edit'
|
|
18
|
+
edit: 'edit',
|
|
19
|
+
cursor: 'cursor'
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
var annotationActionOwner = 'annotationAction';
|
|
@@ -151,6 +152,17 @@ var annotation = function (type, args) {
|
|
|
151
152
|
return m_id;
|
|
152
153
|
};
|
|
153
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Assign a new id to this annotation.
|
|
157
|
+
*
|
|
158
|
+
* @returns {this}
|
|
159
|
+
*/
|
|
160
|
+
this.newId = function () {
|
|
161
|
+
annotationId += 1;
|
|
162
|
+
m_id = annotationId;
|
|
163
|
+
return m_this;
|
|
164
|
+
};
|
|
165
|
+
|
|
154
166
|
/**
|
|
155
167
|
* Get or set the name of this annotation.
|
|
156
168
|
*
|
|
@@ -300,6 +312,27 @@ var annotation = function (type, args) {
|
|
|
300
312
|
return m_this;
|
|
301
313
|
};
|
|
302
314
|
|
|
315
|
+
this._cursorHandleMousemove = function (evt) {
|
|
316
|
+
m_this.layer()._handleMouseMoveModifiers(evt);
|
|
317
|
+
const center = m_this._cursorCenter;
|
|
318
|
+
const delta = {
|
|
319
|
+
x: evt.mapgcs.x - center.x,
|
|
320
|
+
y: evt.mapgcs.y - center.y
|
|
321
|
+
};
|
|
322
|
+
if (delta.x || delta.y) {
|
|
323
|
+
const curPts = m_this._coordinates();
|
|
324
|
+
var pts = m_this._coordinatesMapFunc(curPts, function (elem) {
|
|
325
|
+
return {x: elem.x + delta.x, y: elem.y + delta.y};
|
|
326
|
+
});
|
|
327
|
+
m_this._coordinates(pts);
|
|
328
|
+
m_this._cursorCenter = evt.mapgcs;
|
|
329
|
+
m_this.modified();
|
|
330
|
+
m_this.draw();
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
return false;
|
|
334
|
+
};
|
|
335
|
+
|
|
303
336
|
/**
|
|
304
337
|
* Get or set the state of this annotation.
|
|
305
338
|
*
|
|
@@ -320,6 +353,17 @@ var annotation = function (type, args) {
|
|
|
320
353
|
annotation: m_this
|
|
321
354
|
});
|
|
322
355
|
}
|
|
356
|
+
if (m_this.layer()) {
|
|
357
|
+
m_this.layer().geoOff(geo_event.mousemove, m_this._cursorHandleMousemove);
|
|
358
|
+
}
|
|
359
|
+
switch (m_state) {
|
|
360
|
+
case annotationState.cursor:
|
|
361
|
+
m_this._cursorCenter = util.centerFromPerimeter(m_this._coordinates());
|
|
362
|
+
if (m_this.layer()) {
|
|
363
|
+
m_this.layer().geoOn(geo_event.mousemove, m_this._cursorHandleMousemove);
|
|
364
|
+
}
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
323
367
|
}
|
|
324
368
|
return m_this;
|
|
325
369
|
};
|
|
@@ -348,6 +392,18 @@ var annotation = function (type, args) {
|
|
|
348
392
|
owner: annotationActionOwner,
|
|
349
393
|
input: 'pan'
|
|
350
394
|
}];
|
|
395
|
+
case annotationState.cursor:
|
|
396
|
+
return [{
|
|
397
|
+
action: geo_action.annotation_cursor,
|
|
398
|
+
name: 'annotation cursor',
|
|
399
|
+
owner: annotationActionOwner,
|
|
400
|
+
input: 'pan'
|
|
401
|
+
}, {
|
|
402
|
+
action: geo_action.annotation_cursor,
|
|
403
|
+
name: 'annotation cursor',
|
|
404
|
+
owner: annotationActionOwner,
|
|
405
|
+
input: 'left'
|
|
406
|
+
}];
|
|
351
407
|
default:
|
|
352
408
|
return [];
|
|
353
409
|
}
|
|
@@ -471,7 +527,7 @@ var annotation = function (type, args) {
|
|
|
471
527
|
/* For style objects, re-extend them without recursion. This allows
|
|
472
528
|
* setting colors without an opacity field, for instance. */
|
|
473
529
|
['style', 'createStyle', 'editStyle', 'editHandleStyle', 'labelStyle',
|
|
474
|
-
'highlightStyle'
|
|
530
|
+
'highlightStyle', 'cursorStyle'
|
|
475
531
|
].forEach(function (key) {
|
|
476
532
|
if (arg1[key] !== undefined) {
|
|
477
533
|
$.extend(m_options[key], arg1[key]);
|
|
@@ -520,8 +576,8 @@ var annotation = function (type, args) {
|
|
|
520
576
|
* current style with the values in the specified object.
|
|
521
577
|
* @param {*} [arg2] If `arg1` is a string, the new value for that style.
|
|
522
578
|
* @param {string} [styleType='style'] The name of the style type, such as
|
|
523
|
-
* `createStyle`, `editStyle`, `editHandleStyle`, `labelStyle`,
|
|
524
|
-
* `highlightStyle`.
|
|
579
|
+
* `createStyle`, `editStyle`, `editHandleStyle`, `labelStyle`,
|
|
580
|
+
* `highlightStyle`, or `cursorStyle`.
|
|
525
581
|
* @returns {object|this} Either the entire style object, the value of a
|
|
526
582
|
* specific style, or the current class instance.
|
|
527
583
|
*/
|
|
@@ -570,12 +626,18 @@ var annotation = function (type, args) {
|
|
|
570
626
|
* @instance
|
|
571
627
|
*/
|
|
572
628
|
/**
|
|
573
|
-
* Calls {@link geo.annotation#style} with `styleType='
|
|
574
|
-
* @function
|
|
629
|
+
* Calls {@link geo.annotation#style} with `styleType='highlightStyle'`.
|
|
630
|
+
* @function highlightStyle
|
|
575
631
|
* @memberof geo.annotation
|
|
576
632
|
* @instance
|
|
577
633
|
*/
|
|
578
|
-
|
|
634
|
+
/**
|
|
635
|
+
* Calls {@link geo.annotation#style} with `styleType='cursorStyle'`.
|
|
636
|
+
* @function cursorStyle
|
|
637
|
+
* @memberof geo.annotation
|
|
638
|
+
* @instance
|
|
639
|
+
*/
|
|
640
|
+
['createStyle', 'editStyle', 'editHandleStyle', 'labelStyle', 'highlightStyle', 'cursorStyle'
|
|
579
641
|
].forEach(function (styleType) {
|
|
580
642
|
m_this[styleType] = function (arg1, arg2) {
|
|
581
643
|
return m_this.style(arg1, arg2, styleType);
|
|
@@ -600,6 +662,10 @@ var annotation = function (type, args) {
|
|
|
600
662
|
return $.extend({}, m_options.style, m_options.editStyle,
|
|
601
663
|
m_options[state + 'Style']);
|
|
602
664
|
}
|
|
665
|
+
if (state === annotationState.cursor) {
|
|
666
|
+
return $.extend({}, m_options.style, m_options.editStyle,
|
|
667
|
+
m_options.createStyle, m_options[state + 'Style']);
|
|
668
|
+
}
|
|
603
669
|
return m_options[state + 'Style'] || m_options.style || {};
|
|
604
670
|
};
|
|
605
671
|
|
|
@@ -3,6 +3,7 @@ const inherit = require('../inherit');
|
|
|
3
3
|
const registerAnnotation = require('../registry').registerAnnotation;
|
|
4
4
|
const lineFeature = require('../lineFeature');
|
|
5
5
|
const polygonFeature = require('../polygonFeature');
|
|
6
|
+
const util = require('../util');
|
|
6
7
|
|
|
7
8
|
const annotation = require('./annotation').annotation;
|
|
8
9
|
const annotationState = require('./annotation').state;
|
|
@@ -61,6 +62,9 @@ var polygonAnnotation = function (args) {
|
|
|
61
62
|
}
|
|
62
63
|
return m_this.options('vertices')[i];
|
|
63
64
|
}
|
|
65
|
+
},
|
|
66
|
+
cursorStyle: {
|
|
67
|
+
position: util.identityFunction
|
|
64
68
|
}
|
|
65
69
|
}, args);
|
|
66
70
|
args.vertices = args.vertices || args.coordinates || [];
|
|
@@ -332,6 +336,13 @@ polygonAnnotation.defaults = $.extend({}, annotation.defaults, {
|
|
|
332
336
|
stroke: false,
|
|
333
337
|
strokeColor: {r: 0, g: 0, b: 1}
|
|
334
338
|
},
|
|
339
|
+
cursorStyle: {
|
|
340
|
+
closed: true,
|
|
341
|
+
fillColor: {r: 0.3, g: 0.3, b: 0.3},
|
|
342
|
+
fillOpacity: 0.25,
|
|
343
|
+
stroke: true,
|
|
344
|
+
strokeColor: {r: 0, g: 0, b: 1}
|
|
345
|
+
},
|
|
335
346
|
allowBooleanOperations: true
|
|
336
347
|
});
|
|
337
348
|
|
package/src/annotationLayer.js
CHANGED
|
@@ -184,6 +184,15 @@ var annotationLayer = function (arg) {
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
break;
|
|
187
|
+
case m_this.modes.cursor:
|
|
188
|
+
m_this.currentAnnotation._cursorHandleMousemove(evt.mouse);
|
|
189
|
+
update = m_this.currentAnnotation.processAction(evt);
|
|
190
|
+
m_this.geoTrigger(geo_event.annotation.cursor_action, {
|
|
191
|
+
annotation: m_this.currentAnnotation,
|
|
192
|
+
operation: m_this.currentBooleanOperation(),
|
|
193
|
+
evt: evt
|
|
194
|
+
});
|
|
195
|
+
break;
|
|
187
196
|
default:
|
|
188
197
|
update = m_this.currentAnnotation.processAction(evt);
|
|
189
198
|
break;
|
|
@@ -261,7 +270,7 @@ var annotationLayer = function (arg) {
|
|
|
261
270
|
* @param {geo.event} evt The mouse move or click event.
|
|
262
271
|
*/
|
|
263
272
|
this._handleMouseMoveModifiers = function (evt) {
|
|
264
|
-
if (m_this.mode() !== m_this.modes.edit && m_this.currentAnnotation.options('allowBooleanOperations') && m_this.currentAnnotation._coordinates().length < 2) {
|
|
273
|
+
if (m_this.mode() !== m_this.modes.edit && m_this.currentAnnotation.options('allowBooleanOperations') && (m_this.currentAnnotation._coordinates().length < 2 || m_this.mode() === m_this.modes.cursor)) {
|
|
265
274
|
if (evt.modifiers) {
|
|
266
275
|
const mod = (evt.modifiers.shift ? 's' : '') + (evt.modifiers.ctrl ? 'c' : '') + (evt.modifiers.meta || evt.modifiers.alt ? 'a' : '');
|
|
267
276
|
if (m_this._currentBooleanClass === m_this._booleanClasses[mod]) {
|
|
@@ -392,6 +401,13 @@ var annotationLayer = function (arg) {
|
|
|
392
401
|
update = m_this.currentAnnotation.mouseClick(evt);
|
|
393
402
|
m_this._updateFromEvent(update);
|
|
394
403
|
retrigger = !m_this.mode();
|
|
404
|
+
if (m_this.mode() === m_this.modes.cursor) {
|
|
405
|
+
m_this.geoTrigger(geo_event.annotation.cursor_click, {
|
|
406
|
+
annotation: m_this.currentAnnotation,
|
|
407
|
+
operation: m_this.currentBooleanOperation(),
|
|
408
|
+
evt: evt
|
|
409
|
+
});
|
|
410
|
+
}
|
|
395
411
|
} else if (!m_this.mode() && !m_this.currentAnnotation && m_this.options('clickToEdit')) {
|
|
396
412
|
var highlighted = m_this.annotations().filter(function (ann) {
|
|
397
413
|
return ann.state() === geo_annotation.state.highlight;
|
|
@@ -481,6 +497,9 @@ var annotationLayer = function (arg) {
|
|
|
481
497
|
this.addAnnotation = function (annotation, gcs, update) {
|
|
482
498
|
var pos = $.inArray(annotation, m_annotations);
|
|
483
499
|
if (pos < 0) {
|
|
500
|
+
while (m_this.annotationById(annotation.id())) {
|
|
501
|
+
annotation.newId();
|
|
502
|
+
}
|
|
484
503
|
m_this.geoTrigger(geo_event.annotation.add_before, {
|
|
485
504
|
annotation: annotation
|
|
486
505
|
});
|
|
@@ -588,7 +607,8 @@ var annotationLayer = function (arg) {
|
|
|
588
607
|
|
|
589
608
|
/* A list of special modes */
|
|
590
609
|
this.modes = {
|
|
591
|
-
edit: 'edit'
|
|
610
|
+
edit: 'edit',
|
|
611
|
+
cursor: 'cursor'
|
|
592
612
|
};
|
|
593
613
|
|
|
594
614
|
/* Keys are short-hand for preferred event modifiers. Values are classes to
|
|
@@ -605,11 +625,13 @@ var annotationLayer = function (arg) {
|
|
|
605
625
|
*
|
|
606
626
|
* @param {string|null} [arg] `undefined` to get the current mode, `null` to
|
|
607
627
|
* stop creating/editing, `this.modes.edit` (`'edit'`) plus an annotation
|
|
608
|
-
* to switch to edit mode,
|
|
609
|
-
*
|
|
628
|
+
* to switch to edit mode, `this.modes.cursor` plus an annotation to
|
|
629
|
+
* switch to using the annotation as a cursor, or the name of the type of
|
|
630
|
+
* annotation to create. Available annotations can listed via
|
|
610
631
|
* {@link geo.listAnnotations}.
|
|
611
|
-
* @param {geo.annotation} [editAnnotation] If `arg === this.modes.edit
|
|
612
|
-
* this is the annotation that should be
|
|
632
|
+
* @param {geo.annotation} [editAnnotation] If `arg === this.modes.edit` or
|
|
633
|
+
* `arg === this.modes.cursor`, this is the annotation that should be
|
|
634
|
+
* edited or used.
|
|
613
635
|
* @param {object} [options] Additional options to pass when creating an
|
|
614
636
|
* annotation.
|
|
615
637
|
* @returns {string|null|this} The current mode or the layer.
|
|
@@ -619,11 +641,14 @@ var annotationLayer = function (arg) {
|
|
|
619
641
|
if (arg === undefined) {
|
|
620
642
|
return m_mode;
|
|
621
643
|
}
|
|
622
|
-
if (arg !== m_mode ||
|
|
644
|
+
if (arg !== m_mode ||
|
|
645
|
+
((arg === m_this.modes.edit || arg === m_this.modes.cursor) && editAnnotation !== m_this.editAnnotation) ||
|
|
646
|
+
(arg !== m_this.modes.edit && arg !== m_this.modes.cursor && arg && !m_this.currentAnnotation)
|
|
647
|
+
) {
|
|
623
648
|
var createAnnotation, actions,
|
|
624
649
|
mapNode = m_this.map().node(), oldMode = m_mode;
|
|
625
650
|
m_mode = arg;
|
|
626
|
-
mapNode.toggleClass('annotation-input', !!(m_mode && m_mode !== m_this.modes.edit));
|
|
651
|
+
mapNode.toggleClass('annotation-input', !!(m_mode && m_mode !== m_this.modes.edit && m_mode !== m_this.modes.cursor));
|
|
627
652
|
if (!m_mode || m_mode === m_this.modes.edit) {
|
|
628
653
|
Object.values(m_this._booleanClasses).forEach((c) => mapNode.toggleClass(c, false));
|
|
629
654
|
m_this._currentBooleanClass = undefined;
|
|
@@ -646,6 +671,12 @@ var annotationLayer = function (arg) {
|
|
|
646
671
|
m_this.modified();
|
|
647
672
|
m_this.draw();
|
|
648
673
|
break;
|
|
674
|
+
case geo_annotation.state.cursor:
|
|
675
|
+
m_this.currentAnnotation.state(geo_annotation.state.done);
|
|
676
|
+
m_this.modified();
|
|
677
|
+
m_this.draw();
|
|
678
|
+
m_this.map().node().toggleClass('annotation-cursor', false);
|
|
679
|
+
break;
|
|
649
680
|
}
|
|
650
681
|
m_this.currentAnnotation = null;
|
|
651
682
|
}
|
|
@@ -653,6 +684,12 @@ var annotationLayer = function (arg) {
|
|
|
653
684
|
m_this.currentAnnotation = editAnnotation;
|
|
654
685
|
m_this.currentAnnotation.state(geo_annotation.state.edit);
|
|
655
686
|
m_this.modified();
|
|
687
|
+
} else if (m_mode === m_this.modes.cursor) {
|
|
688
|
+
m_this.currentAnnotation = editAnnotation;
|
|
689
|
+
m_this.currentAnnotation.state(geo_annotation.state.cursor);
|
|
690
|
+
m_this.modified();
|
|
691
|
+
m_this.map().node().toggleClass('annotation-cursor', true);
|
|
692
|
+
actions = m_this.currentAnnotation.actions(geo_annotation.state.cursor);
|
|
656
693
|
} else if (registry.registries.annotations[m_mode]) {
|
|
657
694
|
createAnnotation = registry.registries.annotations[m_mode].func;
|
|
658
695
|
}
|
|
@@ -666,13 +703,15 @@ var annotationLayer = function (arg) {
|
|
|
666
703
|
m_this.currentAnnotation = createAnnotation(options);
|
|
667
704
|
m_this.addAnnotation(m_this.currentAnnotation, null);
|
|
668
705
|
actions = m_this.currentAnnotation.actions(geo_annotation.state.create);
|
|
706
|
+
}
|
|
707
|
+
if (actions) {
|
|
669
708
|
$.each(actions, function (idx, action) {
|
|
670
709
|
m_this.map().interactor().addAction(action);
|
|
671
710
|
});
|
|
672
711
|
}
|
|
673
712
|
m_this.geoTrigger(geo_event.annotation.mode, {
|
|
674
713
|
mode: m_mode, oldMode: oldMode});
|
|
675
|
-
if (oldMode === m_this.modes.edit) {
|
|
714
|
+
if (oldMode === m_this.modes.edit || oldMode === m_this.modes.cursor) {
|
|
676
715
|
m_this.modified();
|
|
677
716
|
}
|
|
678
717
|
}
|
|
@@ -1258,11 +1297,15 @@ var annotationLayer = function (arg) {
|
|
|
1258
1297
|
this.toPolygonList = function (opts) {
|
|
1259
1298
|
const poly = [];
|
|
1260
1299
|
opts = opts || {};
|
|
1261
|
-
|
|
1300
|
+
const indices = [];
|
|
1301
|
+
if (!opts.annotationIndices) {
|
|
1302
|
+
opts.annotationIndices = {};
|
|
1303
|
+
}
|
|
1304
|
+
opts.annotationIndices[m_this.id()] = indices;
|
|
1262
1305
|
m_annotations.forEach((annotation, idx) => {
|
|
1263
1306
|
if (annotation.toPolygonList) {
|
|
1264
1307
|
annotation.toPolygonList(opts).forEach((p) => poly.push(p));
|
|
1265
|
-
|
|
1308
|
+
indices.push(idx);
|
|
1266
1309
|
}
|
|
1267
1310
|
});
|
|
1268
1311
|
return poly;
|
|
@@ -1285,14 +1328,15 @@ var annotationLayer = function (arg) {
|
|
|
1285
1328
|
const keepIds = {};
|
|
1286
1329
|
const reusedIds = {};
|
|
1287
1330
|
let correspond, exact, annot;
|
|
1288
|
-
|
|
1331
|
+
const indices = (opts.annotationIndices || {})[m_this.id()];
|
|
1332
|
+
if (indices && opts.correspond && opts.correspond.poly1 && indices.length === opts.correspond.poly1.length) {
|
|
1289
1333
|
correspond = opts.correspond.poly1;
|
|
1290
1334
|
exact = opts.correspond.exact1;
|
|
1291
1335
|
annot = m_this.annotations();
|
|
1292
1336
|
}
|
|
1293
|
-
if (keep !== 'all' && keep !== 'none') {
|
|
1337
|
+
if (keep !== 'all' && keep !== 'none' && annot) {
|
|
1294
1338
|
annot.forEach((oldAnnot, idx) => {
|
|
1295
|
-
if (
|
|
1339
|
+
if (indices.indexOf(idx) < 0) {
|
|
1296
1340
|
keepIds[oldAnnot.id()] = true;
|
|
1297
1341
|
}
|
|
1298
1342
|
});
|
|
@@ -1306,7 +1350,7 @@ var annotationLayer = function (arg) {
|
|
|
1306
1350
|
if (correspond) {
|
|
1307
1351
|
for (let i = 0; i < correspond.length; i += 1) {
|
|
1308
1352
|
if (correspond[i] && correspond[i].indexOf(idx) >= 0) {
|
|
1309
|
-
const orig = annot[
|
|
1353
|
+
const orig = annot[indices[i]];
|
|
1310
1354
|
if (keep !== 'all' && keep !== 'none' && exact && exact[i] && exact[i].indexOf(idx) >= 0) {
|
|
1311
1355
|
keepIds[orig.id()] = true;
|
|
1312
1356
|
return;
|
|
@@ -1343,7 +1387,7 @@ var annotationLayer = function (arg) {
|
|
|
1343
1387
|
}
|
|
1344
1388
|
// add new annotations
|
|
1345
1389
|
polyAnnot.forEach((p) => {
|
|
1346
|
-
m_this.addAnnotation(registry.createAnnotation('polygon', p), m_this.gcs(), false);
|
|
1390
|
+
m_this.addAnnotation(registry.createAnnotation('polygon', p), m_this.map().gcs(), false);
|
|
1347
1391
|
update = true;
|
|
1348
1392
|
});
|
|
1349
1393
|
if (update) {
|
package/src/event.js
CHANGED
|
@@ -706,4 +706,32 @@ geo_event.annotation.mode = 'geo_annotation_mode';
|
|
|
706
706
|
*/
|
|
707
707
|
geo_event.annotation.boolean = 'geo_annotation_boolean';
|
|
708
708
|
|
|
709
|
+
/**
|
|
710
|
+
* Triggered when an annotation is in cursor mode and the mouse is clicked.
|
|
711
|
+
*
|
|
712
|
+
* @event geo.event.annotation.cursor_click
|
|
713
|
+
* @type {geo.event.base}
|
|
714
|
+
* @property {geo.annotation} annotation The annotation that is being operated
|
|
715
|
+
* on.
|
|
716
|
+
* @property {string} operation The operation being performed.
|
|
717
|
+
* @property {boolean} [cancel] If the handle sets this to false, don't apply
|
|
718
|
+
* the operation to the annotation layer.
|
|
719
|
+
* @property {object} event The triggering event.
|
|
720
|
+
*/
|
|
721
|
+
geo_event.annotation.cursor_click = 'geo_annotation_cursor_click';
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Triggered when an annotation is in cursor mode and an action occurs.
|
|
725
|
+
*
|
|
726
|
+
* @event geo.event.annotation.cursor_action
|
|
727
|
+
* @type {geo.event.base}
|
|
728
|
+
* @property {geo.annotation} annotation The annotation that is being operated
|
|
729
|
+
* on.
|
|
730
|
+
* @property {string} operation The operation being performed.
|
|
731
|
+
* @property {boolean} [cancel] If the handle sets this to false, don't apply
|
|
732
|
+
* the operation to the annotation layer.
|
|
733
|
+
* @property {object} event The triggering event.
|
|
734
|
+
*/
|
|
735
|
+
geo_event.annotation.cursor_action = 'geo_annotation_cursor_action';
|
|
736
|
+
|
|
709
737
|
module.exports = geo_event;
|
package/src/main.styl
CHANGED
|
@@ -58,6 +58,17 @@
|
|
|
58
58
|
&.annotation-xor
|
|
59
59
|
cursor embedurl("./css/cursor-crosshair-xor.svg") 12 12,crosshair
|
|
60
60
|
|
|
61
|
+
&.annotation-cursor
|
|
62
|
+
cursor crosshair
|
|
63
|
+
&.annotation-intersect
|
|
64
|
+
cursor embedurl("./css/cursor-crosshair-intersect.svg") 12 12,crosshair
|
|
65
|
+
&.annotation-difference
|
|
66
|
+
cursor embedurl("./css/cursor-crosshair-difference.svg") 12 12,crosshair
|
|
67
|
+
&.annotation-union
|
|
68
|
+
cursor embedurl("./css/cursor-crosshair-union.svg") 12 12,crosshair
|
|
69
|
+
&.annotation-xor
|
|
70
|
+
cursor embedurl("./css/cursor-crosshair-xor.svg") 12 12,crosshair
|
|
71
|
+
|
|
61
72
|
&.highlight-focus
|
|
62
73
|
&:after
|
|
63
74
|
content ""
|
package/src/map.js
CHANGED
|
@@ -407,18 +407,22 @@ var map = function (arg) {
|
|
|
407
407
|
* center.
|
|
408
408
|
* @param {boolean} [ignoreDiscreteZoom] If `true`, ignore the discreteZoom
|
|
409
409
|
* option when determining the new view.
|
|
410
|
+
* @param {boolean} [ignoreClampBounds] If `true`, ignore the clampBounds
|
|
411
|
+
* option when determining the new view.
|
|
410
412
|
* @returns {number|this}
|
|
411
413
|
* @fires geo.event.zoom
|
|
412
414
|
* @fires geo.event.pan
|
|
413
415
|
*/
|
|
414
|
-
this.zoom = function (val, origin, ignoreDiscreteZoom) {
|
|
416
|
+
this.zoom = function (val, origin, ignoreDiscreteZoom, ignoreClampBounds) {
|
|
415
417
|
if (val === undefined) {
|
|
416
418
|
return m_zoom;
|
|
417
419
|
}
|
|
418
420
|
var evt, bounds;
|
|
419
421
|
/* If we are zooming around a point, ignore the clamp bounds */
|
|
420
422
|
var aroundPoint = (origin && (origin.mapgcs || origin.geo) && origin.map);
|
|
421
|
-
|
|
423
|
+
if (aroundPoint) {
|
|
424
|
+
ignoreClampBounds = true;
|
|
425
|
+
}
|
|
422
426
|
|
|
423
427
|
/* The ignoreDiscreteZoom flag is intended to allow non-integer zoom values
|
|
424
428
|
* during animation. */
|
|
@@ -446,7 +450,7 @@ var map = function (arg) {
|
|
|
446
450
|
m_this.pan({x: origin.map.x - shifted.x, y: origin.map.y - shifted.y},
|
|
447
451
|
ignoreDiscreteZoom, true);
|
|
448
452
|
} else {
|
|
449
|
-
m_this.pan({x: 0, y: 0}, ignoreDiscreteZoom);
|
|
453
|
+
m_this.pan({x: 0, y: 0}, ignoreDiscreteZoom, ignoreClampBounds);
|
|
450
454
|
}
|
|
451
455
|
return m_this;
|
|
452
456
|
};
|
|
@@ -1101,6 +1105,8 @@ var map = function (arg) {
|
|
|
1101
1105
|
* a value based on what canceled a transition, `transition`: the current
|
|
1102
1106
|
* transition that just completed, `next`: a boolean if another transition
|
|
1103
1107
|
* follows immediately.
|
|
1108
|
+
* @param {boolean} [opts.endClamp=true] If `false`, the last center change
|
|
1109
|
+
* will not clamp to the bounds and zoom values.
|
|
1104
1110
|
* @param {string|geo.transform|null} [gcs] Input gcs. `undefined` to use
|
|
1105
1111
|
* the interface gcs, `null` to use the map gcs, or any other transform.
|
|
1106
1112
|
* Applies only to `opts.center` and to converting zoom values to height,
|
|
@@ -1205,7 +1211,8 @@ var map = function (arg) {
|
|
|
1205
1211
|
zCoord: opts.zCoord,
|
|
1206
1212
|
done: opts.done,
|
|
1207
1213
|
duration: opts.duration,
|
|
1208
|
-
zoomOrigin: opts.zoomOrigin
|
|
1214
|
+
zoomOrigin: opts.zoomOrigin,
|
|
1215
|
+
endClamp: opts.endClamp
|
|
1209
1216
|
};
|
|
1210
1217
|
|
|
1211
1218
|
m_transition.interp = opts.interp([
|
|
@@ -1260,9 +1267,10 @@ var map = function (arg) {
|
|
|
1260
1267
|
if (!next) {
|
|
1261
1268
|
if (m_transition.end.center) {
|
|
1262
1269
|
var needZoom = m_zoom !== m_this._fix_zoom(m_transition.end.zoom);
|
|
1263
|
-
|
|
1270
|
+
var noEndClamp = needZoom || opts.endClamp === false;
|
|
1271
|
+
m_this.center(m_transition.end.center, null, noEndClamp, noEndClamp);
|
|
1264
1272
|
}
|
|
1265
|
-
m_this.zoom(m_transition.end.zoom, m_transition.zoomOrigin);
|
|
1273
|
+
m_this.zoom(m_transition.end.zoom, m_transition.zoomOrigin, opts.endClamp === false, opts.endClamp === false);
|
|
1266
1274
|
m_this.rotation(fix_rotation(m_transition.end.rotation));
|
|
1267
1275
|
}
|
|
1268
1276
|
|
|
@@ -1297,7 +1305,7 @@ var map = function (arg) {
|
|
|
1297
1305
|
}, null, true, true);
|
|
1298
1306
|
} else {
|
|
1299
1307
|
m_center = m_this.gcsToWorld({x: p[0], y: p[1]}, null);
|
|
1300
|
-
m_this.zoom(p[2], m_transition.zoomOrigin, true);
|
|
1308
|
+
m_this.zoom(p[2], m_transition.zoomOrigin, true, true);
|
|
1301
1309
|
}
|
|
1302
1310
|
m_this.rotation(p[3], undefined, true);
|
|
1303
1311
|
|
package/src/mapInteractor.js
CHANGED
|
@@ -25,8 +25,8 @@ var Mousetrap = require('mousetrap');
|
|
|
25
25
|
* event must occur within this time in milliseconds of the mouse down
|
|
26
26
|
* event for it to be considered a click.
|
|
27
27
|
* @property {boolean|number} [click.cancelOnMove=true] If true, don't generate
|
|
28
|
-
* click events if the mouse moved at all. If a positive number, the
|
|
29
|
-
* at which to cancel click events when the mouse moves.
|
|
28
|
+
* click events if the mouse moved at all. If a positive number, the
|
|
29
|
+
* distance at which to cancel click events when the mouse moves.
|
|
30
30
|
* @property {object} [keyboard] An object describing which keyboard events are
|
|
31
31
|
* handled.
|
|
32
32
|
* @property {object} [keyboard.actions] An object with different actions that
|
|
@@ -39,6 +39,9 @@ var Mousetrap = require('mousetrap');
|
|
|
39
39
|
* an object with keys of the meta keys that are required to be down or
|
|
40
40
|
* up for that scale action to trigger. If the value of the meta key is
|
|
41
41
|
* truthy, it must be down. If `false`, it must be up.
|
|
42
|
+
* @property {string[]} [keyboard.metakeyMouseEvents] A list of meta keys
|
|
43
|
+
* * that, when typed singly, trigger a repeat of the last mousemove or
|
|
44
|
+
* actionmove event so that listeners can update metakey information.
|
|
42
45
|
* @property {boolean} [keyboard.focusHighlight=true] If truthy, when the map
|
|
43
46
|
* gains focus, a highlight style is shown around it. This gives an
|
|
44
47
|
* indicator that keyboard events will affect the map, but may not be
|
|
@@ -131,6 +134,7 @@ var mapInteractor = function (args) {
|
|
|
131
134
|
m_boundKeys,
|
|
132
135
|
m_touchHandler,
|
|
133
136
|
m_state,
|
|
137
|
+
m_nextStateId = 0,
|
|
134
138
|
m_queue,
|
|
135
139
|
$node,
|
|
136
140
|
m_selectionLayer = null,
|
|
@@ -294,6 +298,10 @@ var mapInteractor = function (args) {
|
|
|
294
298
|
1: {shift: true, ctrl: true},
|
|
295
299
|
2: {shift: true, ctrl: false}
|
|
296
300
|
},
|
|
301
|
+
/* This is a list of meta keys that when typed singly trigger a repeat
|
|
302
|
+
* of the last mousemove or actionmove event so that listeners can
|
|
303
|
+
* update metakey information. */
|
|
304
|
+
metakeyMouseEvents: ['shift', 'ctrl', 'shift+ctrl', 'shift+alt', 'shift+meta'],
|
|
297
305
|
/* if focusHighlight is truthy, then a class is added to the map such
|
|
298
306
|
* that when the map gets focus, it is indicated inside the border of
|
|
299
307
|
* the map -- browsers usually show focus on the outside, which isn't
|
|
@@ -648,6 +656,35 @@ var mapInteractor = function (args) {
|
|
|
648
656
|
}
|
|
649
657
|
};
|
|
650
658
|
|
|
659
|
+
/**
|
|
660
|
+
* Repeat a mousemove or actionmove event with new metakey information.
|
|
661
|
+
*
|
|
662
|
+
* @param {event} [evt] A Mousetrap event with the key change.
|
|
663
|
+
* @fires geo.event.mousemove
|
|
664
|
+
* @fires geo.event.actionmove
|
|
665
|
+
*/
|
|
666
|
+
this._repeatMouseMoveEvent = function (evt) {
|
|
667
|
+
if (!m_mouse || !m_mouse.modifiers) {
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
const old = {
|
|
671
|
+
alt: m_mouse.modifiers.alt,
|
|
672
|
+
ctrl: m_mouse.modifiers.ctrl,
|
|
673
|
+
meta: m_mouse.modifiers.meta,
|
|
674
|
+
shift: m_mouse.modifiers.shift
|
|
675
|
+
};
|
|
676
|
+
m_this._getMouseModifiers(evt);
|
|
677
|
+
if (m_mouse.modifiers.alt === old.alt && m_mouse.modifiers.ctrl === old.ctrl && m_mouse.modifiers.meta === old.meta && m_mouse.modifiers.shift === old.shift) {
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
if (m_state.boundDocumentHandlers) {
|
|
681
|
+
m_this.map().geoTrigger(geo_event.actionmove, {
|
|
682
|
+
state: m_this.state(), mouse: m_this.mouse(), event: evt});
|
|
683
|
+
} else {
|
|
684
|
+
m_this.map().geoTrigger(geo_event.mousemove, m_this.mouse());
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
|
|
651
688
|
/**
|
|
652
689
|
* Retrigger a mouse movement with the current mouse state.
|
|
653
690
|
* @fires geo.event.mousemove
|
|
@@ -711,6 +748,13 @@ var mapInteractor = function (args) {
|
|
|
711
748
|
bound = bound.concat(m_options.keyboard.actions[keyAction]);
|
|
712
749
|
}
|
|
713
750
|
}
|
|
751
|
+
if (m_options.keyboard.metakeyMouseEvents) {
|
|
752
|
+
m_options.keyboard.metakeyMouseEvents.forEach((meta) => {
|
|
753
|
+
m_keyHandler.bind(meta, m_this._repeatMouseMoveEvent, 'keydown');
|
|
754
|
+
m_keyHandler.bind(meta, m_this._repeatMouseMoveEvent, 'keyup');
|
|
755
|
+
bound.push(meta);
|
|
756
|
+
});
|
|
757
|
+
}
|
|
714
758
|
m_boundKeys = bound;
|
|
715
759
|
}
|
|
716
760
|
$node.toggleClass(
|
|
@@ -1074,6 +1118,7 @@ var mapInteractor = function (args) {
|
|
|
1074
1118
|
};
|
|
1075
1119
|
|
|
1076
1120
|
// store the state object
|
|
1121
|
+
m_nextStateId += 1;
|
|
1077
1122
|
m_state = {
|
|
1078
1123
|
action: action,
|
|
1079
1124
|
actionRecord: actionRecord,
|
|
@@ -1081,6 +1126,7 @@ var mapInteractor = function (args) {
|
|
|
1081
1126
|
initialZoom: map.zoom(),
|
|
1082
1127
|
initialRotation: map.rotation(),
|
|
1083
1128
|
initialEventRotation: evt.rotation,
|
|
1129
|
+
stateId: m_nextStateId,
|
|
1084
1130
|
delta: {x: 0, y: 0}
|
|
1085
1131
|
};
|
|
1086
1132
|
|
|
@@ -2095,7 +2141,7 @@ var mapInteractor = function (args) {
|
|
|
2095
2141
|
preventDefault: function () {},
|
|
2096
2142
|
simulated: true
|
|
2097
2143
|
};
|
|
2098
|
-
m_keyHandler.trigger(keys);
|
|
2144
|
+
m_keyHandler.trigger(keys, options.event);
|
|
2099
2145
|
return;
|
|
2100
2146
|
}
|
|
2101
2147
|
|
package/src/registry.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
var $ = require('jquery');
|
|
2
|
+
var geo_action = require('./action');
|
|
3
|
+
|
|
2
4
|
var widgets = {
|
|
3
5
|
dom: {}
|
|
4
6
|
};
|
|
@@ -398,6 +400,7 @@ util.registerAnnotation = function (name, func, features) {
|
|
|
398
400
|
console.warn('The ' + name + ' annotation is already registered');
|
|
399
401
|
}
|
|
400
402
|
annotations[name] = {func: func, features: features || {}};
|
|
403
|
+
geo_action['annotation_' + name] = 'geo_annotation_' + name;
|
|
401
404
|
return old;
|
|
402
405
|
};
|
|
403
406
|
|
package/src/util/polyops.js
CHANGED
|
@@ -327,16 +327,19 @@ function generateCorrespondence(poly1, poly2, newpoly, results) {
|
|
|
327
327
|
results[ekey] = Array(poly.length);
|
|
328
328
|
poly.forEach((p, idx) => {
|
|
329
329
|
const found = {};
|
|
330
|
+
let missed = 0;
|
|
330
331
|
p.forEach((h) => h.forEach((pt) => {
|
|
331
332
|
const key = '_' + pt[0] + '_' + pt[1];
|
|
332
333
|
if (pts[key]) {
|
|
333
334
|
pts[key].forEach((val) => {
|
|
334
335
|
found[val] = (found[val] || 0) + 1;
|
|
335
336
|
});
|
|
337
|
+
} else {
|
|
338
|
+
missed += 1;
|
|
336
339
|
}
|
|
337
340
|
}));
|
|
338
341
|
Object.keys(found).forEach((nidx) => {
|
|
339
|
-
if (found[nidx] === counts[+nidx]) {
|
|
342
|
+
if (found[nidx] === counts[+nidx] && !missed && p.length === newpoly[+nidx].length) {
|
|
340
343
|
if (!results[ekey][idx]) {
|
|
341
344
|
results[ekey][idx] = [];
|
|
342
345
|
}
|