geojs 1.9.4 → 1.10.2
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 +34 -0
- package/geo.js +300 -35
- package/geo.lean.js +299 -34
- package/geo.lean.min.js +2 -2
- package/geo.min.js +3 -3
- package/package.json +3 -3
- package/src/action.js +2 -1
- package/src/annotation/annotation.js +65 -7
- package/src/annotation/polygonAnnotation.js +11 -0
- package/src/annotationLayer.js +45 -9
- package/src/canvas/quadFeature.js +9 -0
- package/src/canvas/tileLayer.js +1 -0
- package/src/event.js +28 -0
- package/src/main.styl +11 -0
- package/src/map.js +18 -7
- package/src/mapInteractor.js +3 -0
- package/src/pixelmapLayer.js +1 -0
- package/src/quadFeature.js +24 -0
- package/src/tileLayer.js +30 -0
- package/src/webgl/pixelmapFeature.js +3 -6
- package/src/webgl/quadFeature.js +13 -0
- package/src/webgl/tileLayer.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "geojs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.2",
|
|
4
4
|
"description": "JavaScript Geo Visualization and Analysis Library",
|
|
5
5
|
"homepage": "https://github.com/OpenGeoscience/geojs",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"optionalDependencies": {
|
|
29
29
|
"d3": "^3.5.17",
|
|
30
|
+
"glslang-validator-prebuilt-predownloaded": "^0.0.2",
|
|
30
31
|
"hammerjs": "^2.0.8",
|
|
31
32
|
"vtk.js": "*"
|
|
32
33
|
},
|
|
@@ -53,7 +54,6 @@
|
|
|
53
54
|
"express": "^4.17.2",
|
|
54
55
|
"fs-extra": "^10.0.0",
|
|
55
56
|
"glob": "^8.0.1",
|
|
56
|
-
"glslang-validator-prebuilt": "^0.0.7",
|
|
57
57
|
"imports-loader": "^4.0.0",
|
|
58
58
|
"jaguarjs-jsdoc": "^1.0.2",
|
|
59
59
|
"jasmine-core": "^4.0.0",
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
"build-website-tutorials": "node tutorials/build-website.js && webpack --config webpack-website-tutorials.config.js",
|
|
136
136
|
"lint": "eslint --cache . --max-warnings=0",
|
|
137
137
|
"puglint": "pug-lint src examples",
|
|
138
|
-
"glsllint": "find . \\( -name '*.frag' \\) -exec sh -c 'for n; do python scripts/preprocess_glsl.py \"$n\" | node_modules/glslang-validator-prebuilt/bin/glslangValidator --stdin -S frag || exit 1; done' sh {} \\+ && find . \\( -name '*.vert' \\) -exec sh -c 'for n; do python scripts/preprocess_glsl.py \"$n\" | node_modules/glslang-validator-prebuilt/bin/glslangValidator --stdin -S vert || exit 1; done' sh {} \\+",
|
|
138
|
+
"glsllint": "chmod +x node_modules/glslang-validator-prebuilt-predownloaded/bin/glslangValidator.linux; find . \\( -name '*.frag' \\) -exec sh -c 'for n; do python scripts/preprocess_glsl.py \"$n\" | node_modules/glslang-validator-prebuilt-predownloaded/bin/glslangValidator.linux --stdin -S frag || exit 1; done' sh {} \\+ && find . \\( -name '*.vert' \\) -exec sh -c 'for n; do python scripts/preprocess_glsl.py \"$n\" | node_modules/glslang-validator-prebuilt-predownloaded/bin/glslangValidator.linux --stdin -S vert || exit 1; done' sh {} \\+",
|
|
139
139
|
"test-headless": "GEOJS_TEST_CASE=tests/test-unit.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch,FirefoxHeadlessTouch",
|
|
140
140
|
"test-headless-all": "GEOJS_TEST_CASE=tests/test-unit.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch,FirefoxHeadlessTouch",
|
|
141
141
|
"test-headed": "GEOJS_TEST_CASE=tests/test-headed.js karma start karma-cov.conf.js --single-run --browsers ChromeFull",
|
package/src/action.js
CHANGED
|
@@ -17,7 +17,8 @@ var geo_action = {
|
|
|
17
17
|
zoomselect: 'geo_action_zoomselect',
|
|
18
18
|
|
|
19
19
|
// annotation actions -- some are also added by the registry
|
|
20
|
-
annotation_edit_handle: 'geo_annotation_edit_handle'
|
|
20
|
+
annotation_edit_handle: 'geo_annotation_edit_handle',
|
|
21
|
+
annotation_cursor: 'geo_annotation_cursor'
|
|
21
22
|
};
|
|
22
23
|
|
|
23
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';
|
|
@@ -153,10 +154,13 @@ var annotation = function (type, args) {
|
|
|
153
154
|
|
|
154
155
|
/**
|
|
155
156
|
* Assign a new id to this annotation.
|
|
157
|
+
*
|
|
158
|
+
* @returns {this}
|
|
156
159
|
*/
|
|
157
160
|
this.newId = function () {
|
|
158
161
|
annotationId += 1;
|
|
159
162
|
m_id = annotationId;
|
|
163
|
+
return m_this;
|
|
160
164
|
};
|
|
161
165
|
|
|
162
166
|
/**
|
|
@@ -308,6 +312,27 @@ var annotation = function (type, args) {
|
|
|
308
312
|
return m_this;
|
|
309
313
|
};
|
|
310
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
|
+
|
|
311
336
|
/**
|
|
312
337
|
* Get or set the state of this annotation.
|
|
313
338
|
*
|
|
@@ -328,6 +353,17 @@ var annotation = function (type, args) {
|
|
|
328
353
|
annotation: m_this
|
|
329
354
|
});
|
|
330
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
|
+
}
|
|
331
367
|
}
|
|
332
368
|
return m_this;
|
|
333
369
|
};
|
|
@@ -356,6 +392,18 @@ var annotation = function (type, args) {
|
|
|
356
392
|
owner: annotationActionOwner,
|
|
357
393
|
input: 'pan'
|
|
358
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
|
+
}];
|
|
359
407
|
default:
|
|
360
408
|
return [];
|
|
361
409
|
}
|
|
@@ -479,7 +527,7 @@ var annotation = function (type, args) {
|
|
|
479
527
|
/* For style objects, re-extend them without recursion. This allows
|
|
480
528
|
* setting colors without an opacity field, for instance. */
|
|
481
529
|
['style', 'createStyle', 'editStyle', 'editHandleStyle', 'labelStyle',
|
|
482
|
-
'highlightStyle'
|
|
530
|
+
'highlightStyle', 'cursorStyle'
|
|
483
531
|
].forEach(function (key) {
|
|
484
532
|
if (arg1[key] !== undefined) {
|
|
485
533
|
$.extend(m_options[key], arg1[key]);
|
|
@@ -528,8 +576,8 @@ var annotation = function (type, args) {
|
|
|
528
576
|
* current style with the values in the specified object.
|
|
529
577
|
* @param {*} [arg2] If `arg1` is a string, the new value for that style.
|
|
530
578
|
* @param {string} [styleType='style'] The name of the style type, such as
|
|
531
|
-
* `createStyle`, `editStyle`, `editHandleStyle`, `labelStyle`,
|
|
532
|
-
* `highlightStyle`.
|
|
579
|
+
* `createStyle`, `editStyle`, `editHandleStyle`, `labelStyle`,
|
|
580
|
+
* `highlightStyle`, or `cursorStyle`.
|
|
533
581
|
* @returns {object|this} Either the entire style object, the value of a
|
|
534
582
|
* specific style, or the current class instance.
|
|
535
583
|
*/
|
|
@@ -578,12 +626,18 @@ var annotation = function (type, args) {
|
|
|
578
626
|
* @instance
|
|
579
627
|
*/
|
|
580
628
|
/**
|
|
581
|
-
* Calls {@link geo.annotation#style} with `styleType='
|
|
582
|
-
* @function
|
|
629
|
+
* Calls {@link geo.annotation#style} with `styleType='highlightStyle'`.
|
|
630
|
+
* @function highlightStyle
|
|
583
631
|
* @memberof geo.annotation
|
|
584
632
|
* @instance
|
|
585
633
|
*/
|
|
586
|
-
|
|
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'
|
|
587
641
|
].forEach(function (styleType) {
|
|
588
642
|
m_this[styleType] = function (arg1, arg2) {
|
|
589
643
|
return m_this.style(arg1, arg2, styleType);
|
|
@@ -608,6 +662,10 @@ var annotation = function (type, args) {
|
|
|
608
662
|
return $.extend({}, m_options.style, m_options.editStyle,
|
|
609
663
|
m_options[state + 'Style']);
|
|
610
664
|
}
|
|
665
|
+
if (state === annotationState.cursor) {
|
|
666
|
+
return $.extend({}, m_options.style, m_options.editStyle,
|
|
667
|
+
m_options.createStyle, m_options[state + 'Style']);
|
|
668
|
+
}
|
|
611
669
|
return m_options[state + 'Style'] || m_options.style || {};
|
|
612
670
|
};
|
|
613
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;
|
|
@@ -591,7 +607,8 @@ var annotationLayer = function (arg) {
|
|
|
591
607
|
|
|
592
608
|
/* A list of special modes */
|
|
593
609
|
this.modes = {
|
|
594
|
-
edit: 'edit'
|
|
610
|
+
edit: 'edit',
|
|
611
|
+
cursor: 'cursor'
|
|
595
612
|
};
|
|
596
613
|
|
|
597
614
|
/* Keys are short-hand for preferred event modifiers. Values are classes to
|
|
@@ -608,11 +625,13 @@ var annotationLayer = function (arg) {
|
|
|
608
625
|
*
|
|
609
626
|
* @param {string|null} [arg] `undefined` to get the current mode, `null` to
|
|
610
627
|
* stop creating/editing, `this.modes.edit` (`'edit'`) plus an annotation
|
|
611
|
-
* to switch to edit mode,
|
|
612
|
-
*
|
|
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
|
|
613
631
|
* {@link geo.listAnnotations}.
|
|
614
|
-
* @param {geo.annotation} [editAnnotation] If `arg === this.modes.edit
|
|
615
|
-
* 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.
|
|
616
635
|
* @param {object} [options] Additional options to pass when creating an
|
|
617
636
|
* annotation.
|
|
618
637
|
* @returns {string|null|this} The current mode or the layer.
|
|
@@ -622,11 +641,14 @@ var annotationLayer = function (arg) {
|
|
|
622
641
|
if (arg === undefined) {
|
|
623
642
|
return m_mode;
|
|
624
643
|
}
|
|
625
|
-
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
|
+
) {
|
|
626
648
|
var createAnnotation, actions,
|
|
627
649
|
mapNode = m_this.map().node(), oldMode = m_mode;
|
|
628
650
|
m_mode = arg;
|
|
629
|
-
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));
|
|
630
652
|
if (!m_mode || m_mode === m_this.modes.edit) {
|
|
631
653
|
Object.values(m_this._booleanClasses).forEach((c) => mapNode.toggleClass(c, false));
|
|
632
654
|
m_this._currentBooleanClass = undefined;
|
|
@@ -649,6 +671,12 @@ var annotationLayer = function (arg) {
|
|
|
649
671
|
m_this.modified();
|
|
650
672
|
m_this.draw();
|
|
651
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;
|
|
652
680
|
}
|
|
653
681
|
m_this.currentAnnotation = null;
|
|
654
682
|
}
|
|
@@ -656,6 +684,12 @@ var annotationLayer = function (arg) {
|
|
|
656
684
|
m_this.currentAnnotation = editAnnotation;
|
|
657
685
|
m_this.currentAnnotation.state(geo_annotation.state.edit);
|
|
658
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);
|
|
659
693
|
} else if (registry.registries.annotations[m_mode]) {
|
|
660
694
|
createAnnotation = registry.registries.annotations[m_mode].func;
|
|
661
695
|
}
|
|
@@ -669,13 +703,15 @@ var annotationLayer = function (arg) {
|
|
|
669
703
|
m_this.currentAnnotation = createAnnotation(options);
|
|
670
704
|
m_this.addAnnotation(m_this.currentAnnotation, null);
|
|
671
705
|
actions = m_this.currentAnnotation.actions(geo_annotation.state.create);
|
|
706
|
+
}
|
|
707
|
+
if (actions) {
|
|
672
708
|
$.each(actions, function (idx, action) {
|
|
673
709
|
m_this.map().interactor().addAction(action);
|
|
674
710
|
});
|
|
675
711
|
}
|
|
676
712
|
m_this.geoTrigger(geo_event.annotation.mode, {
|
|
677
713
|
mode: m_mode, oldMode: oldMode});
|
|
678
|
-
if (oldMode === m_this.modes.edit) {
|
|
714
|
+
if (oldMode === m_this.modes.edit || oldMode === m_this.modes.cursor) {
|
|
679
715
|
m_this.modified();
|
|
680
716
|
}
|
|
681
717
|
}
|
|
@@ -138,6 +138,14 @@ var canvas_quadFeature = function (arg) {
|
|
|
138
138
|
|
|
139
139
|
var oldAlpha = context2d.globalAlpha;
|
|
140
140
|
var opacity = oldAlpha;
|
|
141
|
+
var nearestPixel = m_this.nearestPixel();
|
|
142
|
+
if (nearestPixel !== undefined) {
|
|
143
|
+
if (nearestPixel !== true && util.isNonNullFinite(nearestPixel)) {
|
|
144
|
+
const curZoom = m_this.layer().map().zoom();
|
|
145
|
+
nearestPixel = curZoom >= nearestPixel;
|
|
146
|
+
}
|
|
147
|
+
context2d.imageSmoothingEnabled = !nearestPixel;
|
|
148
|
+
}
|
|
141
149
|
$.each([m_quads.imgQuads, m_quads.vidQuads], function (listidx, quadlist) {
|
|
142
150
|
if (!quadlist) {
|
|
143
151
|
return;
|
|
@@ -193,6 +201,7 @@ var canvas_quadFeature = function (arg) {
|
|
|
193
201
|
context2d.globalAlpha = oldAlpha;
|
|
194
202
|
}
|
|
195
203
|
context2d.setTransform(1, 0, 0, 1, 0, 0);
|
|
204
|
+
context2d.imageSmoothingEnabled = true;
|
|
196
205
|
};
|
|
197
206
|
|
|
198
207
|
/**
|
package/src/canvas/tileLayer.js
CHANGED
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
|
|
|
@@ -1956,6 +1964,9 @@ var map = function (arg) {
|
|
|
1956
1964
|
return m_this;
|
|
1957
1965
|
};
|
|
1958
1966
|
|
|
1967
|
+
/* Report the current version on the map object. */
|
|
1968
|
+
this._version = require('./version');
|
|
1969
|
+
|
|
1959
1970
|
/**
|
|
1960
1971
|
* Draw a layer image to a canvas context. The layer's opacity and transform
|
|
1961
1972
|
* are applied. This is used as part of making a screenshot.
|
package/src/mapInteractor.js
CHANGED
|
@@ -134,6 +134,7 @@ var mapInteractor = function (args) {
|
|
|
134
134
|
m_boundKeys,
|
|
135
135
|
m_touchHandler,
|
|
136
136
|
m_state,
|
|
137
|
+
m_nextStateId = 0,
|
|
137
138
|
m_queue,
|
|
138
139
|
$node,
|
|
139
140
|
m_selectionLayer = null,
|
|
@@ -1117,6 +1118,7 @@ var mapInteractor = function (args) {
|
|
|
1117
1118
|
};
|
|
1118
1119
|
|
|
1119
1120
|
// store the state object
|
|
1121
|
+
m_nextStateId += 1;
|
|
1120
1122
|
m_state = {
|
|
1121
1123
|
action: action,
|
|
1122
1124
|
actionRecord: actionRecord,
|
|
@@ -1124,6 +1126,7 @@ var mapInteractor = function (args) {
|
|
|
1124
1126
|
initialZoom: map.zoom(),
|
|
1125
1127
|
initialRotation: map.rotation(),
|
|
1126
1128
|
initialEventRotation: evt.rotation,
|
|
1129
|
+
stateId: m_nextStateId,
|
|
1127
1130
|
delta: {x: 0, y: 0}
|
|
1128
1131
|
};
|
|
1129
1132
|
|
package/src/pixelmapLayer.js
CHANGED
package/src/quadFeature.js
CHANGED
|
@@ -47,6 +47,10 @@ var feature = require('./feature');
|
|
|
47
47
|
* call `cacheUpdate` on the data item or for all data.
|
|
48
48
|
* @property {geo.quadFeature.styleSpec} [style] Style object with default
|
|
49
49
|
* style options.
|
|
50
|
+
* @property {boolean|number} [nearestPixel] If true, image quads are
|
|
51
|
+
* rendered with near-neighbor sampling. If false, with interpolated
|
|
52
|
+
* sampling. If a number, interpolate at that zoom level or below and
|
|
53
|
+
* nearest neighbor at that zoom level or above.
|
|
50
54
|
*/
|
|
51
55
|
|
|
52
56
|
/**
|
|
@@ -106,6 +110,7 @@ var quadFeature = function (arg) {
|
|
|
106
110
|
var m_this = this,
|
|
107
111
|
s_init = this._init,
|
|
108
112
|
m_cacheQuads,
|
|
113
|
+
m_nearestPixel = arg.nearestPixel,
|
|
109
114
|
m_nextQuadId = 0,
|
|
110
115
|
m_images = [],
|
|
111
116
|
m_videos = [],
|
|
@@ -677,6 +682,25 @@ var quadFeature = function (arg) {
|
|
|
677
682
|
return null;
|
|
678
683
|
};
|
|
679
684
|
|
|
685
|
+
/**
|
|
686
|
+
* Get/Set nearestPixel value.
|
|
687
|
+
*
|
|
688
|
+
* @param {boolean|number} [val] If not specified, return the current value.
|
|
689
|
+
* If true, image quads are rendered with near-neighbor sampling. If
|
|
690
|
+
* false, with interpolated sampling. If a number, interpolate at that
|
|
691
|
+
* zoom level or below and nearest neighbor at that zoom level or above.
|
|
692
|
+
* @returns {boolean|number|this}
|
|
693
|
+
*/
|
|
694
|
+
this.nearestPixel = function (val) {
|
|
695
|
+
if (val === undefined) {
|
|
696
|
+
return m_nearestPixel;
|
|
697
|
+
} else {
|
|
698
|
+
m_nearestPixel = val;
|
|
699
|
+
m_this.modified();
|
|
700
|
+
}
|
|
701
|
+
return m_this;
|
|
702
|
+
};
|
|
703
|
+
|
|
680
704
|
/**
|
|
681
705
|
* Initialize.
|
|
682
706
|
*
|
package/src/tileLayer.js
CHANGED
|
@@ -81,6 +81,10 @@ var featureLayer = require('./featureLayer');
|
|
|
81
81
|
* any tile layers. If specified, this uses the quad defaults, so this is a
|
|
82
82
|
* ``geo.quadFeature.position`` object with, typically, an ``image`` property
|
|
83
83
|
* added to it. The quad positions are in the map gcs coordinates.
|
|
84
|
+
* @property {boolean|number} [nearestPixel] If true, image quads are
|
|
85
|
+
* rendered with near-neighbor sampling. If false, with interpolated
|
|
86
|
+
* sampling. If a number, interpolate at that zoom level or below and
|
|
87
|
+
* nearest neighbor at that zoom level or above.
|
|
84
88
|
*/
|
|
85
89
|
|
|
86
90
|
/**
|
|
@@ -228,6 +232,7 @@ var tileLayer = function (arg) {
|
|
|
228
232
|
m_reference,
|
|
229
233
|
m_exited,
|
|
230
234
|
m_lastBaseQuad,
|
|
235
|
+
m_nearestPixel = arg.nearestPixel,
|
|
231
236
|
m_this = this;
|
|
232
237
|
|
|
233
238
|
// copy the options into a private variable
|
|
@@ -1682,6 +1687,31 @@ var tileLayer = function (arg) {
|
|
|
1682
1687
|
return m_this;
|
|
1683
1688
|
};
|
|
1684
1689
|
|
|
1690
|
+
/**
|
|
1691
|
+
* Get/Set nearestPixel value.
|
|
1692
|
+
*
|
|
1693
|
+
* @param {boolean|number} [val] If not specified, return the current value.
|
|
1694
|
+
* If true, image quads are rendered with near-neighbor sampling. If
|
|
1695
|
+
* false, with interpolated sampling. If a number, interpolate at that
|
|
1696
|
+
* zoom level or below and nearest neighbor at that zoom level or above.
|
|
1697
|
+
* @param {boolean} [skipUpdate] If specifying val and this value is truthy,
|
|
1698
|
+
* don't update the layer or mark it as modified.
|
|
1699
|
+
* @returns {boolean|number|this}
|
|
1700
|
+
*/
|
|
1701
|
+
this.nearestPixel = function (val, skipUpdate) {
|
|
1702
|
+
if (val === undefined) {
|
|
1703
|
+
return m_nearestPixel;
|
|
1704
|
+
}
|
|
1705
|
+
if (m_nearestPixel !== val) {
|
|
1706
|
+
m_nearestPixel = val;
|
|
1707
|
+
if (!skipUpdate) {
|
|
1708
|
+
m_this.modified();
|
|
1709
|
+
m_this._update();
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
return m_this;
|
|
1713
|
+
};
|
|
1714
|
+
|
|
1685
1715
|
/**
|
|
1686
1716
|
* Get/set the baseQuad.
|
|
1687
1717
|
*
|
|
@@ -134,7 +134,8 @@ var webgl_pixelmapFeature = function (arg) {
|
|
|
134
134
|
m_quadFeature = m_this.layer().createFeature('quad', {
|
|
135
135
|
selectionAPI: false,
|
|
136
136
|
gcs: m_this.gcs(),
|
|
137
|
-
visible: m_this.visible(undefined, true)
|
|
137
|
+
visible: m_this.visible(undefined, true),
|
|
138
|
+
nearestPixel: true
|
|
138
139
|
});
|
|
139
140
|
m_quadFeatureInit = false;
|
|
140
141
|
}
|
|
@@ -153,11 +154,6 @@ var webgl_pixelmapFeature = function (arg) {
|
|
|
153
154
|
prog.addUniform(lutHeight);
|
|
154
155
|
};
|
|
155
156
|
m_quadFeature._hookRenderImageQuads = (renderState, quads) => {
|
|
156
|
-
quads.forEach((quad) => {
|
|
157
|
-
if (quad.image && quad.texture && !quad.texture.nearestPixel()) {
|
|
158
|
-
quad.texture.setNearestPixel(true);
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
157
|
m_lookupTable.bind(renderState, quads);
|
|
162
158
|
};
|
|
163
159
|
if (m_quadFeatureInit === false) {
|
|
@@ -188,6 +184,7 @@ var webgl_pixelmapFeature = function (arg) {
|
|
|
188
184
|
|
|
189
185
|
if (arg.quadFeature) {
|
|
190
186
|
m_quadFeature = arg.quadFeature;
|
|
187
|
+
m_quadFeature.nearestPixel(true);
|
|
191
188
|
}
|
|
192
189
|
this._init(arg);
|
|
193
190
|
return this;
|