geojs 1.8.2 → 1.8.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geojs",
3
- "version": "1.8.2",
3
+ "version": "1.8.3",
4
4
  "description": "JavaScript Geo Visualization and Analysis Library",
5
5
  "homepage": "https://github.com/OpenGeoscience/geojs",
6
6
  "license": "Apache-2.0",
@@ -51,7 +51,7 @@
51
51
  "expose-loader": "^3.1.0",
52
52
  "express": "^4.17.2",
53
53
  "fs-extra": "^10.0.0",
54
- "glob": "^7.2.0",
54
+ "glob": "^8.0.1",
55
55
  "glslang-validator-prebuilt": "^0.0.7",
56
56
  "imports-loader": "^3.1.1",
57
57
  "jaguarjs-jsdoc": "^1.0.2",
@@ -65,11 +65,11 @@
65
65
  "karma-chrome-launcher": "^3.1.0",
66
66
  "karma-coverage": "^2.1.1",
67
67
  "karma-firefox-launcher": "^2.1.2",
68
- "karma-jasmine": "^4.0.1",
68
+ "karma-jasmine": "^5.0.0",
69
69
  "karma-jasmine-html-reporter": "^1.7.0",
70
70
  "karma-sinon": "^1.0.5",
71
71
  "karma-sourcemap-loader": "^0.3.8",
72
- "karma-spec-reporter": "^0.0.33",
72
+ "karma-spec-reporter": "^0.0.34",
73
73
  "karma-webpack": "^5.0.0",
74
74
  "nib": "^1.1.2",
75
75
  "npm-run-all": "^4.1.5",
@@ -82,17 +82,17 @@
82
82
  "semantic-release": "^19.0.2",
83
83
  "serve-index": "^1.9.1",
84
84
  "shader-loader": "^1.3.1",
85
- "sinon": "^13.0.1",
86
- "string-replace-webpack-plugin": "^0.1.3",
85
+ "sinon": "^14.0.0",
87
86
  "style-loader": "^3.3.1",
88
- "stylus": "^0.56.0",
87
+ "stylus": "^0.57.0",
89
88
  "stylus-loader": "^6.2.0",
90
89
  "terser-webpack-plugin": "^5.3.1",
91
90
  "touch-emulator": "^1.0.0",
92
91
  "typeface-lato": "^1.1.13",
93
92
  "webpack": "^5.68.0",
94
93
  "webpack-cli": "^4.9.1",
95
- "webpack-merge": "^5.8.0"
94
+ "webpack-merge": "^5.8.0",
95
+ "webpack-string-replacer": "^0.0.20"
96
96
  },
97
97
  "release": {
98
98
  "plugins": [
package/src/annotation.js CHANGED
@@ -215,7 +215,7 @@ var annotation = function (type, args) {
215
215
  */
216
216
  this._rotateHandlePosition = function (offset, rotation) {
217
217
  var map = m_this.layer().map(),
218
- coor = m_this._coordinates(),
218
+ coord = m_this._coordinates(),
219
219
  center = util.centerFromPerimeter(m_this._coordinates()),
220
220
  dispCenter = center ? map.gcsToDisplay(center, null) : undefined,
221
221
  i, pos, maxr2 = 0, r;
@@ -224,8 +224,9 @@ var annotation = function (type, args) {
224
224
  }
225
225
  offset = offset || 0;
226
226
  rotation = rotation || 0;
227
- for (i = 0; i < coor.length; i += 1) {
228
- pos = map.gcsToDisplay(coor[i], null);
227
+ coord = coord.outer ? coord.outer : coord;
228
+ for (i = 0; i < coord.length; i += 1) {
229
+ pos = map.gcsToDisplay(coord[i], null);
229
230
  maxr2 = Math.max(maxr2, Math.pow(pos.x - dispCenter.x, 2) + Math.pow(pos.y - dispCenter.y, 2));
230
231
  }
231
232
  r = Math.sqrt(maxr2) + offset;
@@ -390,6 +391,22 @@ var annotation = function (type, args) {
390
391
  }
391
392
  };
392
393
 
394
+ /**
395
+ * Return a copy of the _coordinates or a geo.polygon record so that it
396
+ * doesn't share memory with the original.
397
+ *
398
+ * @param {geo.polygon} [coord] if specified, return a copy of this object.
399
+ * Otherwise, return a copy of this._coordinates.
400
+ * @returns {geo.polygon}
401
+ */
402
+ this._copyOfCoordinates = function (coord) {
403
+ coord = coord || m_this._coordinates();
404
+ if (!coord.outer) {
405
+ return coord.slice();
406
+ }
407
+ return {outer: coord.outer.slice(), inner: (coord.inner || []).map((h) => h.slice())};
408
+ };
409
+
393
410
  /**
394
411
  * When an edit handle is selected or deselected (for instance, by moving the
395
412
  * mouse on or off of it), mark if it is selected and record the current
@@ -409,7 +426,7 @@ var annotation = function (type, args) {
409
426
  var amountRotated = (m_this._editHandle || {}).amountRotated || 0;
410
427
  m_this._editHandle = {
411
428
  handle: handle,
412
- startCoordinates: m_this._coordinates().slice(),
429
+ startCoordinates: m_this._copyOfCoordinates(),
413
430
  center: util.centerFromPerimeter(m_this._coordinates()),
414
431
  rotatePosition: m_this._rotateHandlePosition(
415
432
  handle.style.rotateHandleOffset, handle.style.rotateHandleRotation + amountRotated),
@@ -465,9 +482,9 @@ var annotation = function (type, args) {
465
482
  m_options[arg1] = arg2;
466
483
  }
467
484
  if (m_options.coordinates) {
468
- var coor = m_options.coordinates;
485
+ var coord = m_options.coordinates;
469
486
  delete m_options.coordinates;
470
- m_this._coordinates(coor);
487
+ m_this._coordinates(coord);
471
488
  }
472
489
  if (m_options.name !== undefined) {
473
490
  var name = m_options.name;
@@ -676,7 +693,7 @@ var annotation = function (type, args) {
676
693
  gcs = (gcs === null ? map.gcs() : (
677
694
  gcs === undefined ? map.ingcs() : gcs));
678
695
  if (gcs !== map.gcs()) {
679
- coord = transform.transformCoordinates(map.gcs(), gcs, coord);
696
+ coord = m_this._convertCoordinates(map.gcs(), gcs, coord);
680
697
  }
681
698
  }
682
699
  return coord;
@@ -752,20 +769,20 @@ var annotation = function (type, args) {
752
769
  * should not be represented (for instance, while it is being created).
753
770
  */
754
771
  this.geojson = function (gcs, includeCrs) {
755
- var coor = m_this._geojsonCoordinates(gcs),
772
+ var coord = m_this._geojsonCoordinates(gcs),
756
773
  geotype = m_this._geojsonGeometryType(),
757
774
  styles = m_this._geojsonStyles(),
758
775
  objStyle = m_this.options('style') || {},
759
776
  objLabelStyle = m_this.labelStyle() || {},
760
777
  i, key, value;
761
- if (!coor || !coor.length || !geotype) {
778
+ if (!coord || !coord.length || !geotype) {
762
779
  return;
763
780
  }
764
781
  var obj = {
765
782
  type: 'Feature',
766
783
  geometry: {
767
784
  type: geotype,
768
- coordinates: coor
785
+ coordinates: coord
769
786
  },
770
787
  properties: {
771
788
  annotationType: m_type,
@@ -850,22 +867,25 @@ var annotation = function (type, args) {
850
867
  features[editHandleFeatureLevel] = {point: []};
851
868
  }
852
869
  editPoints = features[editHandleFeatureLevel].point;
853
- vertices.forEach(function (pt, idx) {
854
- if (opts.vertex !== false) {
855
- editPoints.push($.extend({}, pt, {type: 'vertex', index: idx, style: style, editHandle: true}));
856
- }
857
- if (opts.edge !== false && idx !== vertices.length - 1 && (pt.x !== vertices[idx + 1].x || pt.y !== vertices[idx + 1].y)) {
858
- editPoints.push($.extend({
859
- x: (pt.x + vertices[idx + 1].x) / 2,
860
- y: (pt.y + vertices[idx + 1].y) / 2
861
- }, {type: 'edge', index: idx, style: style, editHandle: true}));
862
- }
863
- if (opts.edge !== false && !isOpen && idx === vertices.length - 1 && (pt.x !== vertices[0].x || pt.y !== vertices[0].y)) {
864
- editPoints.push($.extend({
865
- x: (pt.x + vertices[0].x) / 2,
866
- y: (pt.y + vertices[0].y) / 2
867
- }, {type: 'edge', index: idx, style: style, editHandle: true}));
868
- }
870
+ const vertexList = vertices.outer ? [vertices.outer].concat(vertices.inner || []) : [vertices];
871
+ vertexList.forEach((vert, vidx) => {
872
+ vert.forEach(function (pt, idx) {
873
+ if (opts.vertex !== false) {
874
+ editPoints.push($.extend({}, pt, {type: 'vertex', index: idx, vindex: vidx, style: style, editHandle: true}));
875
+ }
876
+ if (opts.edge !== false && idx !== vert.length - 1 && (pt.x !== vert[idx + 1].x || pt.y !== vert[idx + 1].y)) {
877
+ editPoints.push($.extend({
878
+ x: (pt.x + vert[idx + 1].x) / 2,
879
+ y: (pt.y + vert[idx + 1].y) / 2
880
+ }, {type: 'edge', index: idx, vindex: vidx, style: style, editHandle: true}));
881
+ }
882
+ if (opts.edge !== false && !isOpen && idx === vert.length - 1 && (pt.x !== vert[0].x || pt.y !== vert[0].y)) {
883
+ editPoints.push($.extend({
884
+ x: (pt.x + vert[0].x) / 2,
885
+ y: (pt.y + vert[0].y) / 2
886
+ }, {type: 'edge', index: idx, vindex: vidx, style: style, editHandle: true}));
887
+ }
888
+ });
869
889
  });
870
890
  if (opts.center !== false) {
871
891
  editPoints.push($.extend({}, util.centerFromPerimeter(m_this._coordinates()), {type: 'center', style: style, editHandle: true}));
@@ -887,13 +907,43 @@ var annotation = function (type, args) {
887
907
  }
888
908
  if (selected) {
889
909
  editPoints.forEach(function (pt) {
890
- if (pt.type === selected.type && pt.index === selected.index) {
910
+ if (pt.type === selected.type && pt.index === selected.index && pt.vindex === selected.vindex) {
891
911
  pt.selected = true;
892
912
  }
893
913
  });
894
914
  }
895
915
  };
896
916
 
917
+ /**
918
+ * Apply a map function of a geo.polygon.
919
+ *
920
+ * @param {geo.polygon} coord The polygon to apply the function to.
921
+ * @param {function} func The function to apply.
922
+ * @returns {array} The map results.
923
+ */
924
+ this._coordinatesMapFunc = function (coord, func) {
925
+ if (!coord.outer) {
926
+ return coord.map(func);
927
+ }
928
+ return {
929
+ outer: coord.outer.map(func),
930
+ inner: (coord.inner || []).map((h) => h.map(func))
931
+ };
932
+ };
933
+
934
+ /**
935
+ * Check if two geo.polygons differ in their first point.
936
+ *
937
+ * @param {geo.polygon} coord1 One polygon to compare.
938
+ * @param {geo.polygon} coord2 A second polygon to compare.
939
+ * @returns {boolean} true if the first point matches.
940
+ */
941
+ this._firstPointDifferent = function (coord1, coord2) {
942
+ coord1 = coord1.outer ? coord1.outer : coord1;
943
+ coord2 = coord2.outer ? coord2.outer : coord2;
944
+ return (coord1[0].x !== coord2[0].x || coord1[0].y !== coord2[0].y);
945
+ };
946
+
897
947
  /**
898
948
  * Process the edit center action for a general annotation.
899
949
  *
@@ -908,10 +958,10 @@ var annotation = function (type, args) {
908
958
  y: evt.mouse.mapgcs.y - evt.state.origin.mapgcs.y
909
959
  },
910
960
  curPts = m_this._coordinates();
911
- var pts = start.map(function (elem) {
961
+ var pts = m_this._coordinatesMapFunc(start, function (elem) {
912
962
  return {x: elem.x + delta.x, y: elem.y + delta.y};
913
963
  });
914
- if (pts[0].x !== curPts[0].x || pts[0].y !== curPts[0].y) {
964
+ if (m_this._firstPointDifferent(pts, curPts)) {
915
965
  m_this._coordinates(pts);
916
966
  return true;
917
967
  }
@@ -940,14 +990,14 @@ var annotation = function (type, args) {
940
990
  handle.rotatePosition.x + delta.x - handle.center.x),
941
991
  ang = ang2 - ang1,
942
992
  curPts = m_this._coordinates();
943
- var pts = start.map(function (elem) {
993
+ var pts = m_this._coordinatesMapFunc(start, function (elem) {
944
994
  var delta = {x: elem.x - handle.center.x, y: elem.y - handle.center.y};
945
995
  return {
946
996
  x: delta.x * Math.cos(ang) - delta.y * Math.sin(ang) + handle.center.x,
947
997
  y: delta.x * Math.sin(ang) + delta.y * Math.cos(ang) + handle.center.y
948
998
  };
949
999
  });
950
- if (pts[0].x !== curPts[0].x || pts[0].y !== curPts[0].y) {
1000
+ if (m_this._firstPointDifferent(pts, curPts)) {
951
1001
  m_this._coordinates(pts);
952
1002
  handle.amountRotated = handle.startAmountRotated + ang;
953
1003
  return true;
@@ -985,13 +1035,13 @@ var annotation = function (type, args) {
985
1035
  curPts = m_this._coordinates();
986
1036
  if (d02 && d01) {
987
1037
  var scale = d02 / d01;
988
- var pts = start.map(function (elem) {
1038
+ var pts = m_this._coordinatesMapFunc(start, function (elem) {
989
1039
  return {
990
1040
  x: (elem.x - handle.center.x) * scale + handle.center.x,
991
1041
  y: (elem.y - handle.center.y) * scale + handle.center.y
992
1042
  };
993
1043
  });
994
- if (pts[0].x !== curPts[0].x || pts[0].y !== curPts[0].y) {
1044
+ if (m_this._firstPointDifferent(pts, curPts)) {
995
1045
  m_this._coordinates(pts);
996
1046
  return true;
997
1047
  }
@@ -1009,11 +1059,17 @@ var annotation = function (type, args) {
1009
1059
  this._processEditActionEdge = function (evt) {
1010
1060
  var handle = m_this._editHandle,
1011
1061
  index = handle.handle.index,
1062
+ vindex = handle.handle.vindex,
1012
1063
  curPts = m_this._coordinates();
1013
- curPts.splice(index + 1, 0, {x: handle.handle.x, y: handle.handle.y});
1064
+ if (!curPts.outer) {
1065
+ curPts.splice(index + 1, 0, {x: handle.handle.x, y: handle.handle.y});
1066
+ } else {
1067
+ const loop = vindex ? curPts.inner[vindex - 1] : curPts.outer;
1068
+ loop.splice(index + 1, 0, {x: handle.handle.x, y: handle.handle.y});
1069
+ }
1014
1070
  handle.handle.type = 'vertex';
1015
1071
  handle.handle.index += 1;
1016
- handle.startCoordinates = curPts.slice();
1072
+ handle.startCoordinates = m_this._copyOfCoordinates(curPts);
1017
1073
  m_this.modified();
1018
1074
  return true;
1019
1075
  };
@@ -1031,8 +1087,10 @@ var annotation = function (type, args) {
1031
1087
  this._processEditActionVertex = function (evt, canClose) {
1032
1088
  var handle = m_this._editHandle,
1033
1089
  index = handle.handle.index,
1090
+ vindex = handle.handle.vindex,
1034
1091
  start = handle.startCoordinates,
1035
- curPts = m_this._coordinates(),
1092
+ ptsRef = m_this._coordinates(),
1093
+ curPts = ptsRef.outer ? (vindex ? ptsRef.inner[vindex - 1] : ptsRef.outer) : ptsRef,
1036
1094
  origLen = curPts.length,
1037
1095
  origPt = curPts[index],
1038
1096
  delta = {
@@ -1043,6 +1101,9 @@ var annotation = function (type, args) {
1043
1101
  aPP = layer.options('adjacentPointProximity'),
1044
1102
  near, atEnd;
1045
1103
 
1104
+ if (start.outer) {
1105
+ start = vindex ? start.inner[vindex - 1] : start.outer;
1106
+ }
1046
1107
  curPts[index] = {
1047
1108
  x: start[index].x + delta.x,
1048
1109
  y: start[index].y + delta.y
@@ -1078,9 +1139,37 @@ var annotation = function (type, args) {
1078
1139
  curPts[index].x === origPt.x && curPts[index].y === origPt.y) {
1079
1140
  return false;
1080
1141
  }
1081
- m_this._coordinates(curPts);
1142
+
1143
+ m_this._coordinates(ptsRef);
1082
1144
  return true;
1083
1145
  };
1146
+
1147
+ /**
1148
+ * Transform the annotations coordinates from one gcs to another.
1149
+ *
1150
+ * @param {string|geo.transform} oldgcs The current gcs.
1151
+ * @param {string|geo.transform} newgcs The new gcs.
1152
+ * @param {geo.polygon} [coord] If not specified, convert the coordinates in
1153
+ * place. If specified, convert these coordinates and return them (don't
1154
+ * alter the existing values).
1155
+ * @returns {geo.polygon}
1156
+ */
1157
+ this._convertCoordinates = function (oldgcs, newgcs, coord) {
1158
+ const store = !coord;
1159
+ coord = coord || m_this._coordinates();
1160
+ if (!coord.outer) {
1161
+ coord = transform.transformCoordinates(oldgcs, newgcs, coord);
1162
+ } else {
1163
+ coord = {
1164
+ outer: transform.transformCoordinates(oldgcs, newgcs, coord.outer),
1165
+ inner: (coord.inner || []).map((h) => transform.transformCoordinates(oldgcs, newgcs, h))
1166
+ };
1167
+ }
1168
+ if (store) {
1169
+ m_this._coordinates(coord);
1170
+ }
1171
+ return coord;
1172
+ };
1084
1173
  };
1085
1174
 
1086
1175
  /* Functions used by multiple annotations */
@@ -1368,12 +1457,12 @@ var rectangleAnnotation = function (args, annotationName) {
1368
1457
  if (!src || m_this.state() === annotationState.create || src.length < 4) {
1369
1458
  return;
1370
1459
  }
1371
- var coor = [];
1460
+ var coord = [];
1372
1461
  for (var i = 0; i < 4; i += 1) {
1373
- coor.push([src[i].x, src[i].y]);
1462
+ coord.push([src[i].x, src[i].y]);
1374
1463
  }
1375
- coor.push([src[0].x, src[0].y]);
1376
- return [coor];
1464
+ coord.push([src[0].x, src[0].y]);
1465
+ return [coord];
1377
1466
  };
1378
1467
 
1379
1468
  /**
@@ -1745,12 +1834,16 @@ var polygonAnnotation = function (args) {
1745
1834
  fillColor: {r: 0.3, g: 0.3, b: 0.3},
1746
1835
  fillOpacity: 0.25,
1747
1836
  line: function (d) {
1837
+ const coord = m_this._coordinates();
1748
1838
  /* Return an array that has the same number of items as we have
1749
1839
  * vertices. */
1750
- return Array.apply(null, Array(m_this.options('vertices').length)).map(
1840
+ return Array.apply(null, Array((coord.outer || coord).length)).map(
1751
1841
  function () { return d; });
1752
1842
  },
1753
1843
  position: function (d, i) {
1844
+ if (d.x !== undefined) {
1845
+ return d.x;
1846
+ }
1754
1847
  return m_this.options('vertices')[i];
1755
1848
  },
1756
1849
  stroke: false,
@@ -1779,7 +1872,7 @@ var polygonAnnotation = function (args) {
1779
1872
  switch (state) {
1780
1873
  case annotationState.create:
1781
1874
  features = [];
1782
- if (opt.vertices && opt.vertices.length >= 3) {
1875
+ if (opt.vertices && (opt.vertices.outer || opt.vertices.length >= 3)) {
1783
1876
  features[1] = {
1784
1877
  polygon: {
1785
1878
  polygon: opt.vertices,
@@ -1939,15 +2032,23 @@ var polygonAnnotation = function (args) {
1939
2032
  */
1940
2033
  this._geojsonCoordinates = function (gcs) {
1941
2034
  var src = m_this.coordinates(gcs);
1942
- if (!src || src.length < 3 || m_this.state() === annotationState.create) {
2035
+ if (!src || (!src.outer && src.length < 3) || m_this.state() === annotationState.create) {
1943
2036
  return;
1944
2037
  }
1945
- var coor = [];
1946
- for (var i = 0; i < src.length; i += 1) {
1947
- coor.push([src[i].x, src[i].y]);
2038
+ var coord = [];
2039
+ if (!src.outer) {
2040
+ coord = [src.map((pt) => [pt.x, pt.y])];
2041
+ coord[0].push(coord[0][0].slice());
2042
+ } else {
2043
+ coord = [src.outer.map((pt) => [pt.x, pt.y])];
2044
+ coord[0].push(coord[0][0].slice());
2045
+ (src.inner || []).forEach((h) => {
2046
+ const poly = h.map((pt) => [pt.x, pt.y]);
2047
+ poly.push(poly[0].slice());
2048
+ coord.push(poly);
2049
+ });
1948
2050
  }
1949
- coor.push([src[0].x, src[0].y]);
1950
- return [coor];
2051
+ return coord;
1951
2052
  };
1952
2053
 
1953
2054
  /**
@@ -2220,11 +2321,11 @@ var lineAnnotation = function (args) {
2220
2321
  if (!src || src.length < 2 || m_this.state() === annotationState.create) {
2221
2322
  return;
2222
2323
  }
2223
- var coor = [];
2324
+ var coord = [];
2224
2325
  for (var i = 0; i < src.length; i += 1) {
2225
- coor.push([src[i].x, src[i].y]);
2326
+ coord.push([src[i].x, src[i].y]);
2226
2327
  }
2227
- return coor;
2328
+ return coord;
2228
2329
  };
2229
2330
 
2230
2331
  /**
@@ -417,8 +417,7 @@ var annotationLayer = function (arg) {
417
417
  gcs = (gcs === null ? map.gcs() : (
418
418
  gcs === undefined ? map.ingcs() : gcs));
419
419
  if (gcs !== map.gcs()) {
420
- annotation._coordinates(transform.transformCoordinates(
421
- gcs, map.gcs(), annotation._coordinates()));
420
+ annotation._convertCoordinates(gcs, map.gcs());
422
421
  }
423
422
  if (update !== false) {
424
423
  m_this.modified();
@@ -603,13 +603,18 @@ var util = {
603
603
  * this is the same as the average of all the points of the lines of the
604
604
  * perimeter.
605
605
  *
606
- * @param {geo.geoPosition[]} coor An array of coordinates.
606
+ * @param {geo.geoPolygon} coor An array of coordinates. This can also be
607
+ * a polygon object with an ``outer`` element with an array of
608
+ * coordinates.
607
609
  * @returns {geo.geoPosition|undefined} The position for the center, or
608
610
  * `undefined` if no such position exists.
609
611
  * @memberof geo.util
610
612
  */
611
613
  centerFromPerimeter: function (coor) {
612
614
  var position, p0, p1, w, sumw, i;
615
+ if (coor && coor.outer) {
616
+ coor = coor.outer;
617
+ }
613
618
  if (!coor || !coor.length) {
614
619
  return;
615
620
  }