geojs 1.4.2 → 1.6.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.
Files changed (47) hide show
  1. package/.github/workflows/main.yml +1 -1
  2. package/CHANGELOG.md +271 -245
  3. package/geo.js +80454 -84177
  4. package/geo.lean.js +69911 -64212
  5. package/geo.lean.min.js +28 -41
  6. package/geo.min.js +30 -47
  7. package/package.json +60 -81
  8. package/src/annotation.js +2 -2
  9. package/src/annotationLayer.js +13 -13
  10. package/src/canvas/heatmapFeature.js +39 -16
  11. package/src/choroplethFeature.js +3 -3
  12. package/src/feature.js +4 -4
  13. package/src/geojsonReader.js +5 -4
  14. package/src/heatmapFeature.js +16 -5
  15. package/src/index.js +1 -1
  16. package/src/isolineFeature.js +4 -4
  17. package/src/lineFeature.js +4 -4
  18. package/src/map.js +2 -2
  19. package/src/mapInteractor.js +3 -0
  20. package/src/markerFeature.js +8 -8
  21. package/src/object.js +1 -3
  22. package/src/osmLayer.js +3 -10
  23. package/src/pixelmapFeature.js +1 -1
  24. package/src/pointFeature.js +1 -1
  25. package/src/polygonFeature.js +4 -4
  26. package/src/registry.js +1 -1
  27. package/src/svg/svgRenderer.js +3 -0
  28. package/src/svg/vectorFeature.js +1 -1
  29. package/src/tileLayer.js +4 -4
  30. package/src/trackFeature.js +12 -12
  31. package/src/transform.js +11 -10
  32. package/src/ui/colorLegendWidget.js +6 -6
  33. package/src/ui/legendWidget.js +3 -3
  34. package/src/ui/sliderWidget.js +4 -4
  35. package/src/util/common.js +9 -8
  36. package/src/util/mockVGL.js +3 -2
  37. package/src/util/throttle.js +3 -3
  38. package/src/vendor.js +0 -2
  39. package/src/vtkjs/vtkjsRenderer.js +3 -0
  40. package/src/webgl/layer.js +1 -1
  41. package/src/webgl/markerFeature.js +4 -4
  42. package/src/webgl/meshColored.js +3 -3
  43. package/src/webgl/pointFeature.js +11 -11
  44. package/src/webgl/polygonFeature.js +3 -3
  45. package/src/webgl/quadFeature.js +3 -1
  46. package/src/webgl/webglRenderer.js +1 -2
  47. package/src/polyfills.js +0 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geojs",
3
- "version": "1.4.2",
3
+ "version": "1.6.1",
4
4
  "description": "JavaScript Geo Visualization and Analysis Library",
5
5
  "homepage": "https://github.com/OpenGeoscience/geojs",
6
6
  "license": "Apache-2.0",
@@ -13,15 +13,15 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "color-name": "^1.1.4",
16
- "earcut": "^2.2.2",
16
+ "earcut": "^2.2.3",
17
17
  "gl-mat3": "^2.0.0",
18
18
  "gl-mat4": "^1.2.0",
19
19
  "gl-vec3": "^1.1.3",
20
20
  "gl-vec4": "^1.0.1",
21
- "jquery": "^3.5.1",
21
+ "jquery": "^3.6.0",
22
22
  "kdbush": "^3.0.0",
23
23
  "mousetrap": "^1.6.5",
24
- "proj4": "2.6.0",
24
+ "proj4": "^2.7.5",
25
25
  "vgl": "0.3.11"
26
26
  },
27
27
  "optionalDependencies": {
@@ -30,94 +30,75 @@
30
30
  "vtk.js": "^14.3.2"
31
31
  },
32
32
  "devDependencies": {
33
- "@semantic-release/changelog": "^5.0.1",
34
- "babel-core": "^6.26.3",
35
- "babel-loader": "^7.1.5",
36
- "babel-plugin-istanbul": "^4.1.6",
37
- "babel-plugin-transform-object-rest-spread": "^6.26.0",
38
- "babel-polyfill": "^6.26.0",
39
- "babel-preset-env": "^1.7.0",
40
- "body-parser": "^1.19.0",
33
+ "@babel/core": "^7.16.5",
34
+ "@babel/plugin-proposal-class-properties": "^7.16.5",
35
+ "@babel/preset-env": "^7.16.5",
36
+ "babel-loader": "^8.2.3",
37
+ "babel-plugin-istanbul": "^6.1.1",
41
38
  "bootstrap": "^3.4.1",
42
39
  "bootswatch": "^3.4.1",
43
- "codemirror": "^5.54.0",
44
- "colorbrewer": "1.3.0",
45
- "css-loader": "^0.28.11",
46
- "docco": "^0.7.0",
47
- "eslint": "^5.16.0",
48
- "eslint-config-semistandard": "^13.0.0",
49
- "eslint-config-standard": "^12.0.0",
50
- "eslint-plugin-import": "^2.20.2",
51
- "eslint-plugin-node": "^7.0.1",
52
- "eslint-plugin-promise": "^4.2.1",
53
- "eslint-plugin-standard": "^4.0.1",
54
- "exports-loader": "^0.7.0",
55
- "expose-loader": "^0.7.5",
56
- "express": "^4.17.1",
57
- "file-loader": "^2.0.0",
58
- "forever": "^0.15.2",
59
- "fs-extra": "^7.0.0",
60
- "glob": "^7.1.6",
40
+ "codemirror": "^5.65.0",
41
+ "colorbrewer": "^1.5.1",
42
+ "css-loader": "^6.5.1",
43
+ "docco": "^0.9.1",
44
+ "eslint": "^8.5.0",
45
+ "eslint-config-semistandard": "^16.0.0",
46
+ "eslint-config-standard": "^16.0.3",
47
+ "eslint-plugin-import": "^2.25.3",
48
+ "eslint-plugin-node": "^11.1.0",
49
+ "eslint-plugin-promise": "^6.0.0",
50
+ "expose-loader": "^3.1.0",
51
+ "express": "^4.17.2",
52
+ "fs-extra": "^10.0.0",
53
+ "glob": "^7.2.0",
61
54
  "glslang-validator-prebuilt": "0.0.6",
62
- "imports-loader": "^0.8.0",
55
+ "imports-loader": "^3.1.1",
63
56
  "istanbul-combine": "^0.3.0",
64
57
  "istanbul-instrumenter-loader": "^3.0.1",
65
58
  "jaguarjs-jsdoc": "^1.0.2",
66
- "jasmine-core": "^3.5.0",
67
- "js-yaml": "^3.14.0",
68
- "jsdoc": "^3.6.4",
59
+ "jasmine-core": "^4.0.0",
60
+ "js-yaml": "^4.1.0",
61
+ "jsdoc": "^3.6.7",
69
62
  "jsdoc-autoprivate": "0.0.1",
70
- "jsonlint-mod": "^1.7.5",
63
+ "jsonlint-mod": "^1.7.6",
71
64
  "jstransformer-markdown-it": "^2.0.0",
72
- "karma": "^3.1.1",
73
- "karma-chrome-launcher": "^2.2.0",
74
- "karma-coverage": "^1.1.2",
75
- "karma-firefox-launcher": "^1.3.0",
76
- "karma-jasmine": "^2.0.0",
77
- "karma-jasmine-html-reporter": "^1.5.4",
78
- "karma-phantomjs-launcher": "^1.0.0",
79
- "karma-phantomjs-shim": "^1.5.0",
80
- "karma-sinon": "^1.0.4",
81
- "karma-sourcemap-loader": "^0.3.7",
65
+ "karma": "^6.3.9",
66
+ "karma-chrome-launcher": "^3.1.0",
67
+ "karma-coverage": "^2.1.0",
68
+ "karma-firefox-launcher": "^2.1.2",
69
+ "karma-jasmine": "^4.0.1",
70
+ "karma-jasmine-html-reporter": "^1.7.0",
71
+ "karma-sinon": "^1.0.5",
72
+ "karma-sourcemap-loader": "^0.3.8",
82
73
  "karma-spec-reporter": "^0.0.32",
83
- "karma-webpack": "^3.0.5",
74
+ "karma-webpack": "^5.0.0",
84
75
  "nib": "^1.1.2",
85
- "pako": "^1.0.11",
86
- "phantomjs-prebuilt": "^2.1.5",
87
- "pug": "^3.0.1",
88
- "pug-lint": "^2.4.0",
89
- "pug-loader": "^2.4.0",
90
- "raw-body": "^2.1.6",
91
- "resemblejs": "^3.2.4",
92
- "semantic-release": "^17.4.3",
76
+ "pako": "^2.0.4",
77
+ "pug": "^3.0.2",
78
+ "pug-lint": "^2.6.0",
79
+ "pug-load": "^3.0.0",
80
+ "raw-body": "^2.4.2",
81
+ "resemblejs": "^4.0.0",
82
+ "semantic-release": "^18.0.0",
93
83
  "serve-index": "^1.9.1",
94
84
  "shader-loader": "^1.3.1",
95
- "sinon": "^1.17.7",
85
+ "sinon": "^12.0.1",
96
86
  "string-replace-webpack-plugin": "^0.1.3",
97
- "style-loader": "^0.23.1",
98
- "stylus": "^0.54.7",
99
- "stylus-loader": "^3.0.2",
87
+ "style-loader": "^3.3.1",
88
+ "stylus": "^0.56.0",
89
+ "stylus-loader": "^6.2.0",
90
+ "terser-webpack-plugin": "^5.3.0",
100
91
  "touch-emulator": "^1.0.0",
101
- "typeface-lato": "^0.0.75",
102
- "uglifyjs-webpack-plugin": "^1.2.5",
103
- "url-loader": "^1.1.2",
104
- "webpack": "^3.12.0",
105
- "webpack-cli": "^2.1.3",
106
- "webpack-merge": "^4.2.2",
107
- "webpack-serve": "^1.0.2"
92
+ "typeface-lato": "^1.1.13",
93
+ "webpack": "^5.65.0",
94
+ "webpack-cli": "^4.9.1",
95
+ "webpack-merge": "^5.8.0"
108
96
  },
109
97
  "release": {
110
98
  "plugins": [
111
99
  "@semantic-release/commit-analyzer",
112
100
  "@semantic-release/release-notes-generator",
113
101
  "@semantic-release/npm",
114
- [
115
- "@semantic-release/changelog",
116
- {
117
- "changelogFile": "CHANGELOG.md",
118
- "changelogTitle": "# GeoJS Change Log"
119
- }
120
- ],
121
102
  [
122
103
  "@semantic-release/github",
123
104
  {
@@ -152,31 +133,29 @@
152
133
  "lint": "eslint --cache . --max-warnings=0",
153
134
  "puglint": "pug-lint src examples",
154
135
  "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 {} \\+",
155
- "test-headless": "GEOJS_TEST_CASE=tests/test-unit.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch,FirefoxHeadlessTouch,PhantomJS",
156
- "test-headless-all": "GEOJS_TEST_CASE=tests/test-unit.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch,FirefoxHeadlessTouch,PhantomJS",
136
+ "test-headless": "GEOJS_TEST_CASE=tests/test-unit.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch,FirefoxHeadlessTouch",
137
+ "test-headless-all": "GEOJS_TEST_CASE=tests/test-unit.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch,FirefoxHeadlessTouch",
157
138
  "test-headed": "GEOJS_TEST_CASE=tests/test-headed.js karma start karma-cov.conf.js --single-run --browsers ChromeFull",
158
139
  "tets-headed-all": "GEOJS_TEST_CASE=tests/test-headed.js karma start karma-cov.conf.js --single-run --browsers ChromeFull,FirefoxWithProxy",
159
140
  "test-headed-xvfb": "GEOJS_TEST_CASE=tests/test-headed.js xvfb-run -s '-ac -screen 0 1280x1024x24' karma start karma-cov.conf.js --single-run --browsers ChromeFull",
160
141
  "test-webglheadless": "GEOJS_TEST_CASE=tests/test-gl.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch",
161
142
  "test-webglheadless-all": "GEOJS_TEST_CASE=tests/test-gl.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch,FirefoxHeadlessTouch",
162
- "test-tutorials": "GEOJS_TEST_CASE=tests/tutorials.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch,PhantomJS",
163
- "test-tutorialsci-all": "GEOJS_TEST_CASE=tests/tutorials.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch,FirefoxHeadlessTouch,PhantomJS",
143
+ "test-tutorials": "GEOJS_TEST_CASE=tests/tutorials.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch",
144
+ "test-tutorialsci-all": "GEOJS_TEST_CASE=tests/tutorials.js karma start karma-cov.conf.js --single-run --browsers ChromeHeadlessTouch,FirefoxHeadlessTouch",
164
145
  "get-data-files": "node scripts/datastore.js dist/data",
165
146
  "ci-clean": "git clean -fxd dist -e dist/data jsdoc/tmpl jsdoc/static images lcov",
166
147
  "ci": "npm run ci-build && npm run ci-test",
167
- "ci-build": "(webpack --config webpack.config.js & webpack --config webpack-lean.config.js & npm run docs & npm run get-data-files & npm run lint & npm run puglint & npm run glsllint & npm run build-examples & npm run build-tutorials & wait)",
168
- "ci-test": "npm run test-headless && npm run test-headed && npm run test-webglheadless && npm run test-tutorials && npm run combine-coverage",
148
+ "ci-build": "bash -c '(webpack --config webpack.config.js & webpack --config webpack-lean.config.js & npm run docs & npm run get-data-files & npm run lint & npm run puglint & npm run glsllint & npm run build-examples & npm run build-tutorials & wait -n && wait -n && wait -n && wait -n && wait -n && wait -n && wait -n && wait -n && wait -n)'",
149
+ "ci-test": "npm run test-headless && npm run test-webglheadless && npm run test-headed && npm run test-tutorials && npm run combine-coverage",
169
150
  "ci-xvfb": "npm run ci-clean && npm run ci-build && TEST_SAVE_IMAGE='all' xvfb-run -s '-ac -screen 0 1280x1024x24' npm run ci-test",
170
151
  "start": "karma start karma.conf.js",
171
152
  "combine-coverage": "istanbul-combine -d dist/cobertura -r cobertura 'dist/coverage/json/**/coverage-final.json'",
172
153
  "examples": "node examples/build.js && webpack --config webpack-examples.config.js && node tutorials/build.js && webpack --config webpack-tutorials.config.js && node ./tests/runners/server.js --host \"${HOST-}\" --port ${PORT-8082} --dist",
173
- "start-test": "node examples/build.js; forever start ./tests/runners/server.js",
174
- "stop-test": "forever stop ./tests/runners/server.js",
175
154
  "docs": "jsdoc --pedantic -d dist/apidocs -r src package.json -c jsdoc.conf.json",
176
155
  "website": "cd website && npx hexo server",
177
156
  "setup-website": "cd website && npm install",
178
157
  "build-website": "npm run ci-build && npm run ci-build-website",
179
- "ci-build-website": "cp -a dist/built/. website/source/built && (npm run build-website-examples & npm run build-website-tutorials & wait) && cd dist && find data \\( -name tiles -o -name base-images -o -name '*-hash-stamp' -o -name '*.tgz' \\) -prune -o \\( -print0 \\) | cpio -pmdL0 ../website/source && cp -ar apidocs/. ../website/source/apidocs && cd ../website && npm install && rm -f db.json && npx hexo generate",
158
+ "ci-build-website": "cp -a dist/built/. website/source/built && bash -c '(npm run build-website-examples & npm run build-website-tutorials & wait -n && wait -n)' && cd dist && find data \\( -name tiles -o -name base-images -o -name '*-hash-stamp' -o -name '*.tgz' \\) -prune -o \\( -print0 \\) | cpio -pmdL0 ../website/source && cp -ar apidocs/. ../website/source/apidocs && cd ../website && npm install && rm -f db.json && npx hexo generate",
180
159
  "prepublishOnly": "webpack --config webpack.config.js && webpack --config webpack-lean.config.js && cp dist/built/*.js .",
181
160
  "semantic-release": "semantic-release"
182
161
  },
package/src/annotation.js CHANGED
@@ -1743,8 +1743,8 @@ var polygonAnnotation = function (args) {
1743
1743
  end = true;
1744
1744
  }
1745
1745
  } else if (vertices.length >= 2 && layer.displayDistance(
1746
- vertices[0], null, evt.map, 'display') <=
1747
- layer.options('finalPointProximity')) {
1746
+ vertices[0], null, evt.map, 'display') <=
1747
+ layer.options('finalPointProximity')) {
1748
1748
  end = true;
1749
1749
  } else {
1750
1750
  vertices[vertices.length - 1] = evt.mapgcs;
@@ -91,19 +91,19 @@ var annotationLayer = function (arg) {
91
91
  m_keyHandler;
92
92
 
93
93
  var geojsonStyleProperties = {
94
- 'closed': {dataType: 'boolean', keys: ['closed', 'close']},
95
- 'fill': {dataType: 'boolean', keys: ['fill']},
96
- 'fillColor': {dataType: 'color', keys: ['fillColor', 'fill-color', 'marker-color', 'fill']},
97
- 'fillOpacity': {dataType: 'opacity', keys: ['fillOpacity', 'fill-opacity']},
98
- 'lineCap': {dataType: 'text', keys: ['lineCap', 'line-cap']},
99
- 'lineJoin': {dataType: 'text', keys: ['lineJoin', 'line-join']},
100
- 'radius': {dataType: 'positive', keys: ['radius']},
101
- 'scaled': {dataType: 'booleanOrNumber', keys: ['scaled']},
102
- 'stroke': {dataType: 'boolean', keys: ['stroke']},
103
- 'strokeColor': {dataType: 'color', keys: ['strokeColor', 'stroke-color', 'stroke']},
104
- 'strokeOffset': {dataType: 'number', keys: ['strokeOffset', 'stroke-offset']},
105
- 'strokeOpacity': {dataType: 'opacity', keys: ['strokeOpacity', 'stroke-opacity']},
106
- 'strokeWidth': {dataType: 'positive', keys: ['strokeWidth', 'stroke-width']}
94
+ closed: {dataType: 'boolean', keys: ['closed', 'close']},
95
+ fill: {dataType: 'boolean', keys: ['fill']},
96
+ fillColor: {dataType: 'color', keys: ['fillColor', 'fill-color', 'marker-color', 'fill']},
97
+ fillOpacity: {dataType: 'opacity', keys: ['fillOpacity', 'fill-opacity']},
98
+ lineCap: {dataType: 'text', keys: ['lineCap', 'line-cap']},
99
+ lineJoin: {dataType: 'text', keys: ['lineJoin', 'line-join']},
100
+ radius: {dataType: 'positive', keys: ['radius']},
101
+ scaled: {dataType: 'booleanOrNumber', keys: ['scaled']},
102
+ stroke: {dataType: 'boolean', keys: ['stroke']},
103
+ strokeColor: {dataType: 'color', keys: ['strokeColor', 'stroke-color', 'stroke']},
104
+ strokeOffset: {dataType: 'number', keys: ['strokeOffset', 'stroke-offset']},
105
+ strokeOpacity: {dataType: 'opacity', keys: ['strokeOpacity', 'stroke-opacity']},
106
+ strokeWidth: {dataType: 'positive', keys: ['strokeWidth', 'stroke-width']}
107
107
  };
108
108
  var textFeatureDataTypes = {
109
109
  offset: 'coordinate2',
@@ -39,6 +39,7 @@ var canvas_heatmapFeature = function (arg) {
39
39
  m_heatMapTransform,
40
40
  s_init = this._init,
41
41
  s_update = this._update,
42
+ m_lastRenderDuration,
42
43
  m_renderTime = timestamp();
43
44
 
44
45
  /**
@@ -72,15 +73,22 @@ var canvas_heatmapFeature = function (arg) {
72
73
  };
73
74
 
74
75
  /**
75
- * Create circle for each data point.
76
+ * Create a circle to render at each data point.
76
77
  *
77
78
  * @returns {this}
78
79
  */
79
80
  this._createCircle = function () {
80
- var circle, ctx, r, r2, blur, gaussian;
81
+ var circle, ctx, r, r2, blur, gaussian, scale;
81
82
  r = m_this.style('radius');
82
83
  blur = m_this.style('blurRadius');
83
84
  gaussian = m_this.style('gaussian');
85
+ scale = m_this.style('scaleWithZoom');
86
+ if (scale) {
87
+ const zoom = this.layer().map().zoom();
88
+ scale = Math.pow(2, zoom);
89
+ r *= scale;
90
+ blur *= scale;
91
+ }
84
92
  if (!m_this._circle || m_this._circle.gaussian !== gaussian ||
85
93
  m_this._circle.radius !== r || m_this._circle.blurRadius !== blur) {
86
94
  circle = m_this._circle = document.createElement('canvas');
@@ -298,6 +306,7 @@ var canvas_heatmapFeature = function (arg) {
298
306
  this._renderOnCanvas = function (context2d, map) {
299
307
 
300
308
  if (m_renderTime.timestamp() < m_this.buildTime().timestamp()) {
309
+ const starttime = Date.now();
301
310
  var data = m_this.data() || [],
302
311
  radius = m_this.style('radius') + m_this.style('blurRadius'),
303
312
  binned = m_this.binned(),
@@ -305,9 +314,12 @@ var canvas_heatmapFeature = function (arg) {
305
314
  layer = m_this.layer(),
306
315
  mapSize = map.size();
307
316
 
317
+ if (m_this.style('scaleWithZoom')) {
318
+ radius *= Math.pow(2, map.zoom());
319
+ }
308
320
  /* Determine if we should bin the data */
309
321
  if (binned === true || binned === 'auto') {
310
- binned = Math.max(Math.floor(radius / 8), 3);
322
+ binned = Math.max(Math.floor(radius / 8), Math.max(1.5, Math.min(3, radius / 2.5)));
311
323
  if (m_this.binned() === 'auto') {
312
324
  var numbins = (Math.ceil((mapSize.width + radius * 2) / binned) *
313
325
  Math.ceil((mapSize.height + radius * 2) / binned));
@@ -325,20 +337,22 @@ var canvas_heatmapFeature = function (arg) {
325
337
  context2d.setTransform(1, 0, 0, 1, 0, 0);
326
338
  context2d.clearRect(0, 0, mapSize.width, mapSize.height);
327
339
  m_heatMapTransform = '';
328
- map.scheduleAnimationFrame(m_this._setTransform, false);
329
- layer.canvas().css({transform: ''});
330
-
331
- m_this._createCircle();
332
- m_this._computeGradient();
333
- if (!binned) {
334
- m_this._renderPoints(context2d, map, data, radius);
335
- } else {
336
- m_this._renderBinnedData(context2d, map, data, radius, binned);
340
+ if (radius > 0.5 && radius < 8192) {
341
+ map.scheduleAnimationFrame(m_this._setTransform, false);
342
+ layer.canvas().css({transform: ''});
343
+
344
+ m_this._createCircle();
345
+ m_this._computeGradient();
346
+ if (!binned) {
347
+ m_this._renderPoints(context2d, map, data, radius);
348
+ } else {
349
+ m_this._renderBinnedData(context2d, map, data, radius, binned);
350
+ }
351
+ canvas = layer.canvas()[0];
352
+ pixelArray = context2d.getImageData(0, 0, canvas.width, canvas.height);
353
+ m_this._colorize(pixelArray.data, m_this._grad);
354
+ context2d.putImageData(pixelArray, 0, 0);
337
355
  }
338
- canvas = layer.canvas()[0];
339
- pixelArray = context2d.getImageData(0, 0, canvas.width, canvas.height);
340
- m_this._colorize(pixelArray.data, m_this._grad);
341
- context2d.putImageData(pixelArray, 0, 0);
342
356
 
343
357
  m_heatMapPosition = {
344
358
  zoom: map.zoom(),
@@ -350,6 +364,7 @@ var canvas_heatmapFeature = function (arg) {
350
364
  };
351
365
  m_renderTime.modified();
352
366
  layer.renderer().clearCanvas(false);
367
+ m_lastRenderDuration = Date.now() - starttime;
353
368
  }
354
369
 
355
370
  return m_this;
@@ -440,6 +455,14 @@ var canvas_heatmapFeature = function (arg) {
440
455
  parseFloat((rotation - m_heatMapPosition.rotation).toFixed(4)) !== 0 ||
441
456
  parseFloat(origin.x.toFixed(1)) !== 0 ||
442
457
  parseFloat(origin.y.toFixed(1)) !== 0) {
458
+ let delay = m_this.updateDelay();
459
+ if (delay < 0 && m_lastRenderDuration) {
460
+ delay = m_lastRenderDuration - Math.floor(1000 / 60 * delay);
461
+ } else if (m_lastRenderDuration) {
462
+ delay = m_lastRenderDuration * 2;
463
+ } else {
464
+ delay = 100;
465
+ }
443
466
  m_heatMapPosition.timeout = window.setTimeout(function () {
444
467
  m_heatMapPosition.timeout = undefined;
445
468
  m_this.buildTime().modified();
@@ -209,8 +209,8 @@ var choroplethFeature = function (arg) {
209
209
  newFeature
210
210
  .polygon(function (d) {
211
211
  return {
212
- 'outer': d.coordinates[0],
213
- 'inner': d.coordinates[1] // undefined but ok
212
+ outer: d.coordinates[0],
213
+ inner: d.coordinates[1] // undefined but ok
214
214
  };
215
215
  })
216
216
  .position(function (d) {
@@ -220,7 +220,7 @@ var choroplethFeature = function (arg) {
220
220
  };
221
221
  })
222
222
  .style({
223
- 'fillColor': fillColor
223
+ fillColor: fillColor
224
224
  });
225
225
 
226
226
  return newFeature;
package/src/feature.js CHANGED
@@ -423,10 +423,10 @@ var feature = function (arg) {
423
423
  this._handleBrush = function (brush) {
424
424
  let corners = [brush.gcs.lowerLeft, brush.gcs.lowerRight, brush.gcs.upperRight, brush.gcs.upperLeft];
425
425
  if (m_this.layer()) {
426
- let map = m_this.layer().map();
426
+ const map = m_this.layer().map();
427
427
  corners = transform.transformCoordinates(map.gcs(), map.ingcs(), corners);
428
428
  }
429
- let search = m_this.polygonSearch(corners);
429
+ const search = m_this.polygonSearch(corners);
430
430
 
431
431
  feature.eventID += 1;
432
432
  search.index.forEach(function (idx, i) {
@@ -451,10 +451,10 @@ var feature = function (arg) {
451
451
  this._handleBrushend = function (brush) {
452
452
  let corners = [brush.gcs.lowerLeft, brush.gcs.lowerRight, brush.gcs.upperRight, brush.gcs.upperLeft];
453
453
  if (m_this.layer()) {
454
- let map = m_this.layer().map();
454
+ const map = m_this.layer().map();
455
455
  corners = transform.transformCoordinates(map.gcs(), map.ingcs(), corners);
456
456
  }
457
- let search = m_this.polygonSearch(corners);
457
+ const search = m_this.polygonSearch(corners);
458
458
 
459
459
  feature.eventID += 1;
460
460
  search.index.forEach(function (idx, i) {
@@ -324,7 +324,8 @@ var geojsonReader = function (arg) {
324
324
  reject(new Error('Failed to parse GeoJSON'));
325
325
  return;
326
326
  }
327
- let features, allFeatures = [], points, lines, polygons, feature;
327
+ let features, feature;
328
+ const allFeatures = [];
328
329
 
329
330
  try {
330
331
  features = m_this._featureArray(object);
@@ -334,7 +335,7 @@ var geojsonReader = function (arg) {
334
335
  }
335
336
 
336
337
  // process points
337
- points = features.filter(f => f.geometry.type === 'Point');
338
+ const points = features.filter(f => f.geometry.type === 'Point');
338
339
  if (points.length) {
339
340
  feature = m_this.layer().createFeature('point');
340
341
  if (feature) {
@@ -358,7 +359,7 @@ var geojsonReader = function (arg) {
358
359
  }
359
360
 
360
361
  // process lines
361
- lines = features.filter(f => f.geometry.type === 'LineString');
362
+ const lines = features.filter(f => f.geometry.type === 'LineString');
362
363
  if (lines.length) {
363
364
  feature = m_this.layer().createFeature('line');
364
365
  if (feature) {
@@ -383,7 +384,7 @@ var geojsonReader = function (arg) {
383
384
  }
384
385
 
385
386
  // process polygons
386
- polygons = features.filter(f => f.geometry.type === 'Polygon');
387
+ const polygons = features.filter(f => f.geometry.type === 'Polygon');
387
388
  if (polygons.length) {
388
389
  feature = m_this.layer().createFeature('polygon');
389
390
  if (feature) {
@@ -19,8 +19,11 @@ var transform = require('./transform');
19
19
  * @property {number} [minIntensity=null] Minimum intensity of the data.
20
20
  * Minimum intensity must be a positive real number and is used to normalize
21
21
  * all intensities within a dataset. If `null`, it is computed.
22
- * @property {number} [updateDelay=1000] Delay in milliseconds after a zoom,
23
- * rotate, or pan event before recomputing the heatmap.
22
+ * @property {number} [updateDelay=-1] Delay in milliseconds after a zoom,
23
+ * rotate, or pan event before recomputing the heatmap. If 0, this is double
24
+ * the last render time. If negative, it is roughly the last render time
25
+ * plus the absolute value of the specified number of refresh intervals.
26
+ * compute a delay based on the last heatmap render time.
24
27
  * @property {boolean|number|'auto'} [binned='auto'] If `true` or a number,
25
28
  * spatially bin data as part of producing the heatmap. If falsy, each
26
29
  * datapoint stands on its own. If `'auto'`, bin data if there are more data
@@ -37,6 +40,11 @@ var transform = require('./transform');
37
40
  * approximation. The total weight of the gaussian area is approximately the
38
41
  * `9/16 r^2`. The sum of `radius + blurRadius` is used as the radius for
39
42
  * the gaussian distribution.
43
+ * @property {boolean} [scaleWithZoom=false] If truthy, the value for radius
44
+ * and blurRadius scale with zoom. In this case, the values for radius and
45
+ * blurRadius are the values at zoom-level zero. If the scaled radius is
46
+ * less than 0.5 or more than 8192 screen pixels, the heatmap will not
47
+ * render.
40
48
  */
41
49
 
42
50
  /**
@@ -76,7 +84,7 @@ var heatmapFeature = function (arg) {
76
84
  m_maxIntensity = arg.maxIntensity !== undefined ? arg.maxIntensity : null;
77
85
  m_minIntensity = arg.minIntensity !== undefined ? arg.minIntensity : null;
78
86
  m_binned = arg.binned !== undefined ? arg.binned : 'auto';
79
- m_updateDelay = arg.updateDelay ? parseInt(arg.updateDelay, 10) : 1000;
87
+ m_updateDelay = (arg.updateDelay || arg.updateDelay === 0) ? parseInt(arg.updateDelay, 10) : -1;
80
88
 
81
89
  /**
82
90
  * Get/Set maxIntensity.
@@ -121,7 +129,9 @@ var heatmapFeature = function (arg) {
121
129
  *
122
130
  * @param {number} [val] If not specified, return the current update delay.
123
131
  * If specified, this is the delay in milliseconds after a zoom, rotate,
124
- * or pan event before recomputing the heatmap.
132
+ * or pan event before recomputing the heatmap. If 0, this is double the
133
+ * last render time. If negative, it is roughly the last render time plus
134
+ * the absolute value of the specified number of refresh intervals.
125
135
  * @returns {number|this}
126
136
  */
127
137
  this.updateDelay = function (val) {
@@ -233,7 +243,8 @@ var heatmapFeature = function (arg) {
233
243
  0.25: {r: 0, g: 0, b: 1, a: 0.5},
234
244
  0.5: {r: 0, g: 1, b: 1, a: 0.6},
235
245
  0.75: {r: 1, g: 1, b: 0, a: 0.7},
236
- 1: {r: 1, g: 0, b: 0, a: 0.8}}
246
+ 1: {r: 1, g: 0, b: 0, a: 0.8}},
247
+ scaleWithZoom: false
237
248
  },
238
249
  arg.style === undefined ? {} : arg.style
239
250
  );
package/src/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // License headers that will be preserved in distributed bundles.
2
2
  /**
3
3
  * GeoJS
4
- * @copyright 2013-2018, Kitware, Inc.
4
+ * @copyright 2013-2022, Kitware, Inc.
5
5
  * @license Apache-2.0
6
6
  * @namespace geo
7
7
  */
@@ -872,13 +872,13 @@ var isolineFeature = function (arg) {
872
872
  */
873
873
  isolineFeature.rotationFunction = function (mode, map) {
874
874
  var functionList = {
875
- 'higher': function (d) {
875
+ higher: function (d) {
876
876
  return d.rotation;
877
877
  },
878
- 'lower': function (d) {
878
+ lower: function (d) {
879
879
  return d.rotation + Math.PI;
880
880
  },
881
- 'map': function (d) {
881
+ map: function (d) {
882
882
  var r = d.rotation,
883
883
  rt = util.wrapAngle(r, true);
884
884
  if (rt > Math.PI / 2 || rt < -Math.PI / 2) {
@@ -886,7 +886,7 @@ isolineFeature.rotationFunction = function (mode, map) {
886
886
  }
887
887
  return r;
888
888
  },
889
- 'screen': function (d) {
889
+ screen: function (d) {
890
890
  var r = d.rotation,
891
891
  rt = util.wrapAngle(r + map.rotation(), true);
892
892
  if (rt > Math.PI / 2 || rt < -Math.PI / 2) {
@@ -313,8 +313,8 @@ var lineFeature = function (arg) {
313
313
  if (p.y > max.y) { max.y = p.y; }
314
314
  });
315
315
  m_this._updatePointSearchInfo();
316
- let scale = map.unitsPerPixel(map.zoom()),
317
- i, j, record, u, v, r;
316
+ const scale = map.unitsPerPixel(map.zoom());
317
+ let i, j, record, u, v, r;
318
318
  for (i = 0; i < m_pointSearchInfo.length; i += 1) {
319
319
  record = m_pointSearchInfo[i];
320
320
  if (!record.max ||
@@ -342,7 +342,7 @@ var lineFeature = function (arg) {
342
342
  (strokeWidthFunc(line[record[j].i], record[j].i, data[i], i) <= 0 && strokeWidthFunc(line[record[j].j], record[j].j, data[i], i) <= 0)) {
343
343
  continue;
344
344
  }
345
- let dist0 = util.distanceToPolygon2d(u, poly),
345
+ const dist0 = util.distanceToPolygon2d(u, poly),
346
346
  dist1 = util.distanceToPolygon2d(v, poly);
347
347
  if ((dist0 > -r * scale && dist0 < r * scale) || (dist1 > -r * scale && dist1 < r & scale) || dist0 * dist1 < 0) {
348
348
  partial = true;
@@ -354,7 +354,7 @@ var lineFeature = function (arg) {
354
354
  }
355
355
  // if a point of the polygon is near the line formed by u-v, this is
356
356
  // also partial
357
- let r2scaled = r * r * scale * scale;
357
+ const r2scaled = r * r * scale * scale;
358
358
  for (let k = 0; k < poly.outer.length && !partial; k += 1) {
359
359
  partial = util.distance2dToLineSquared(poly.outer[k], u, v) < r2scaled;
360
360
  }
package/src/map.js CHANGED
@@ -214,7 +214,7 @@ var map = function (arg) {
214
214
  * existing requestAnimationFrame. By using a property of window,
215
215
  * tests can override this if needed. */
216
216
  if (queue.length && queue[0] !== m_animationQueue[0]) {
217
- window['cancelAnimationFrame'](m_animationQueue[0]);
217
+ window['cancelAnimationFrame'](m_animationQueue[0]); // eslint-disable-line dot-notation
218
218
  }
219
219
  for (var i = queue.length ? 1 : 0; i < m_animationQueue.length; i += 1) {
220
220
  queue.push(m_animationQueue[i]);
@@ -1897,7 +1897,7 @@ var map = function (arg) {
1897
1897
  * explicitly using window.requestAnimationFrame, we prevent the
1898
1898
  * stripping of 'window' off of the reference and allow our tests to
1899
1899
  * override this if needed. */
1900
- m_animationQueue.push(window['requestAnimationFrame'](processAnimationFrame));
1900
+ m_animationQueue.push(window['requestAnimationFrame'](processAnimationFrame)); // eslint-disable-line dot-notation
1901
1901
  }
1902
1902
  var pos = m_animationQueue.indexOf(callback, 1);
1903
1903
  if (pos >= 0) {
@@ -718,6 +718,9 @@ var mapInteractor = function (args) {
718
718
  var Hammer;
719
719
  try {
720
720
  Hammer = require('hammerjs');
721
+ if (!Hammer || !Hammer.Manager) {
722
+ Hammer = undefined;
723
+ }
721
724
  } catch (_error) {}
722
725
  if (Hammer !== undefined) {
723
726
  var recog = [],