geojs 1.8.5 → 1.8.8

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/geo.js CHANGED
@@ -41,13 +41,11 @@ module.exports = geo_action;
41
41
 
42
42
  /***/ }),
43
43
 
44
- /***/ 7800:
44
+ /***/ 5784:
45
45
  /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
46
46
 
47
47
  var $ = __webpack_require__(5638);
48
48
 
49
- var inherit = __webpack_require__(5699);
50
-
51
49
  var geo_event = __webpack_require__(5108);
52
50
 
53
51
  var geo_action = __webpack_require__(7839);
@@ -56,16 +54,6 @@ var transform = __webpack_require__(6853);
56
54
 
57
55
  var util = __webpack_require__(4634);
58
56
 
59
- var registerAnnotation = (__webpack_require__(4647).registerAnnotation);
60
-
61
- var lineFeature = __webpack_require__(4708);
62
-
63
- var markerFeature = __webpack_require__(7098);
64
-
65
- var pointFeature = __webpack_require__(2557);
66
-
67
- var polygonFeature = __webpack_require__(4343);
68
-
69
57
  var textFeature = __webpack_require__(9757);
70
58
 
71
59
  var annotationId = 0;
@@ -1542,186 +1530,282 @@ function continuousVerticesProcessAction(m_this, evt, name) {
1542
1530
  }
1543
1531
  }
1544
1532
  /**
1545
- * Rectangle annotation specification. Extends {@link geo.annotation.spec}.
1533
+ * Return a function that can be used as a selectionConstraint that requires
1534
+ * that the aspect ratio of a rectangle-like selection is a specific value or
1535
+ * range of values.
1546
1536
  *
1547
- * @typedef {object} geo.rectangleAnnotation.spec
1548
- * @extends geo.annotation.spec
1549
- * @property {geo.geoPosition[]} [corners] A list of four corners in map gcs
1550
- * coordinates. These must be in order around the perimeter of the
1551
- * rectangle (in either direction).
1552
- * @property {geo.geoPosition[]} [coordinates] An alternate name for `corners`.
1553
- * @property {geo.polygonFeature.styleSpec} [style] The style to apply to a
1554
- * finished rectangle. This uses styles for {@link geo.polygonFeature}.
1555
- * @property {geo.polygonFeature.styleSpec} [editStyle] The style to apply to a
1556
- * rectangle in edit mode.
1557
- * @property {number|number[]|function} [constraint] If specified, an aspect
1558
- * ratio or list of aspect ratios to constraint the rectangle to. If a
1559
- * function, a selection constraint function to call to adjust the
1560
- * rectangle.
1537
+ * @param {number|number[]|geo.geoSize|geo.geoSize[]} ratio Either a single
1538
+ * aspect ratio, a single size, or a list of allowed aspect ratios and sizes.
1539
+ * For instance, 1 will require that the selection square, 2 would require
1540
+ * that it is twice as wide as tall, [2, 1/2] would allow it to be twice as
1541
+ * wide or half as wide as it is tall. Sizes (e.g., {width: 400, height:
1542
+ * 500}) snap to that size.
1543
+ * @returns {function} A function that can be passed to the mapIterator
1544
+ * selectionConstraint or to an annotation constraint function.
1561
1545
  */
1562
1546
 
1547
+
1548
+ function constrainAspectRatio(ratio) {
1549
+ var ratios = Array.isArray(ratio) ? ratio : [ratio];
1550
+ /**
1551
+ * Constrain a mouse action or annotation action to a list of aspect ratios.
1552
+ *
1553
+ * @param {geo.geoPosition} pos Mouse or new location in map gcs.
1554
+ * @param {geo.geoPosition} origin Origin in map gcs when the activity
1555
+ * started.
1556
+ * @param {geo.geoPosition} [corners] If specified, an array of corner
1557
+ * locations in mapgcs. This may be modified.
1558
+ * @param {string?} [mode] 'edge', 'vertex' or falsy. A falsy value implies
1559
+ * this is just the most recent point in the annotation, otherwise it is
1560
+ * the portion of the annotation being modified.
1561
+ * @param {number} [ang] A list of angles of each side of the polygon
1562
+ * represented by corners or the original annotation.
1563
+ * @param {integer} [index] The specific vertex or edge that is being
1564
+ * modified.
1565
+ * @returns {object} An object with the ``origin`` (this is what is passed
1566
+ * in), a new position as ``pos``, and the updated corners as ``corners``.
1567
+ */
1568
+
1569
+ function constraintFunction(pos, origin, corners, mode, ang, index) {
1570
+ var newpos = pos;
1571
+ var best;
1572
+
1573
+ if (!corners) {
1574
+ corners = [{
1575
+ x: origin.x,
1576
+ y: origin.y
1577
+ }, {
1578
+ x: pos.x,
1579
+ y: origin.y
1580
+ }, {
1581
+ x: pos.x,
1582
+ y: pos.y
1583
+ }, {
1584
+ x: origin.x,
1585
+ y: pos.y
1586
+ }];
1587
+ }
1588
+
1589
+ if (mode) {
1590
+ /* Edit a vertex or edge */
1591
+ var i1 = (index + 1) % 4;
1592
+ var i2 = (index + 2) % 4;
1593
+ var i3 = (index + 3) % 4;
1594
+ var dist1 = Math.pow(Math.pow(corners[index].x - corners[i1].x, 2) + Math.pow(corners[index].y - corners[i1].y, 2), 0.5);
1595
+ var dist3 = Math.pow(Math.pow(corners[index].x - corners[i3].x, 2) + Math.pow(corners[index].y - corners[i3].y, 2), 0.5);
1596
+ var area = Math.abs(dist1 * dist3);
1597
+ var shape, edge;
1598
+ ratios.forEach(function (ratio) {
1599
+ var width, height;
1600
+
1601
+ if (ratio.width) {
1602
+ width = ratio.width;
1603
+ height = ratio.height;
1604
+ } else {
1605
+ width = Math.pow(area * ratio, 0.5);
1606
+ height = width / ratio;
1607
+ }
1608
+
1609
+ if (width !== height && !(index % 2)) {
1610
+ var _ref = [height, width];
1611
+ width = _ref[0];
1612
+ height = _ref[1];
1613
+ }
1614
+
1615
+ var score = Math.pow(width - dist3, 2) + Math.pow(height - dist1, 2);
1616
+
1617
+ if (best === undefined || score < best) {
1618
+ best = score;
1619
+ shape = {
1620
+ w: width,
1621
+ h: height
1622
+ };
1623
+ }
1624
+ });
1625
+ var ang1 = ang[i1];
1626
+ var delta1 = {
1627
+ x: -shape.w * Math.cos(ang1),
1628
+ y: -shape.w * Math.sin(ang1)
1629
+ };
1630
+ var ang2 = ang[index];
1631
+ var delta2 = {
1632
+ x: -shape.h * Math.cos(ang2),
1633
+ y: -shape.h * Math.sin(ang2)
1634
+ };
1635
+
1636
+ switch (mode) {
1637
+ case 'vertex':
1638
+ corners[index].x = corners[i2].x + delta1.x + delta2.x;
1639
+ corners[index].y = corners[i2].y + delta1.y + delta2.y;
1640
+ corners[i1].x = corners[i2].x + delta1.x;
1641
+ corners[i1].y = corners[i2].y + delta1.y;
1642
+ corners[i3].x = corners[i2].x + delta2.x;
1643
+ corners[i3].y = corners[i2].y + delta2.y;
1644
+ break;
1645
+
1646
+ case 'edge':
1647
+ edge = {
1648
+ x: (corners[i2].x + corners[i3].x) * 0.5,
1649
+ y: (corners[i2].y + corners[i3].y) * 0.5
1650
+ };
1651
+ corners[i2].x = edge.x + delta2.x / 2;
1652
+ corners[i2].y = edge.y + delta2.y / 2;
1653
+ corners[index].x = edge.x + delta1.x - delta2.x / 2;
1654
+ corners[index].y = edge.y + delta1.y - delta2.y / 2;
1655
+ corners[i1].x = edge.x + delta1.x + delta2.x / 2;
1656
+ corners[i1].y = edge.y + delta1.y + delta2.y / 2;
1657
+ corners[i3].x = edge.x - delta2.x / 2;
1658
+ corners[i3].y = edge.y - delta2.y / 2;
1659
+ break;
1660
+ }
1661
+ } else {
1662
+ /* Not in edit vertex or edge mode */
1663
+ var _area = Math.abs((pos.x - origin.x) * (pos.y - origin.y));
1664
+
1665
+ ratios.forEach(function (ratio) {
1666
+ var width, height;
1667
+
1668
+ if (ratio.width) {
1669
+ width = ratio.width;
1670
+ height = ratio.height;
1671
+ } else {
1672
+ width = Math.pow(_area * ratio, 0.5);
1673
+ height = width / ratio;
1674
+ }
1675
+
1676
+ var adjusted = {
1677
+ x: origin.x + Math.sign(pos.x - origin.x) * width,
1678
+ y: origin.y + Math.sign(pos.y - origin.y) * height
1679
+ };
1680
+ var score = Math.pow(adjusted.x - pos.x, 2) + Math.pow(adjusted.y - pos.y, 2);
1681
+
1682
+ if (best === undefined || score < best) {
1683
+ best = score;
1684
+ newpos = adjusted;
1685
+ }
1686
+ });
1687
+ corners[0].y = corners[1].y = origin.y;
1688
+ corners[0].x = corners[3].x = origin.x;
1689
+ corners[1].x = corners[2].x = newpos.x;
1690
+ corners[2].y = corners[3].y = newpos.y;
1691
+ }
1692
+
1693
+ return {
1694
+ corners: corners,
1695
+ origin: origin,
1696
+ pos: newpos
1697
+ };
1698
+ }
1699
+
1700
+ return constraintFunction;
1701
+ }
1702
+
1703
+ module.exports = {
1704
+ state: annotationState,
1705
+ actionOwner: annotationActionOwner,
1706
+ annotation: annotation,
1707
+ _editHandleFeatureLevel: editHandleFeatureLevel,
1708
+ defaultEditHandleStyle: defaultEditHandleStyle,
1709
+ constrainAspectRatio: constrainAspectRatio,
1710
+ // these aren't exposed in index.js
1711
+ annotationActionOwner: annotationActionOwner,
1712
+ continuousVerticesActions: continuousVerticesActions,
1713
+ continuousVerticesProcessAction: continuousVerticesProcessAction
1714
+ };
1715
+
1716
+ /***/ }),
1717
+
1718
+ /***/ 7196:
1719
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
1720
+
1721
+ var $ = __webpack_require__(5638);
1722
+
1723
+ var inherit = __webpack_require__(5699);
1724
+
1725
+ var registerAnnotation = (__webpack_require__(4647).registerAnnotation);
1726
+
1727
+ var markerFeature = __webpack_require__(7098);
1728
+
1729
+ var ellipseAnnotation = __webpack_require__(7505);
1563
1730
  /**
1564
- * Rectangle annotation class.
1731
+ * Circle annotation class.
1565
1732
  *
1566
- * Rectangles are always rendered as polygons. This could be changed -- if no
1567
- * stroke is specified, the quad feature would be sufficient and work on more
1568
- * renderers.
1733
+ * Circles are a subset of rectangles with a fixed aspect ratio.
1569
1734
  *
1570
1735
  * @class
1571
- * @alias geo.rectangleAnnotation
1736
+ * @alias geo.circleAnnotation
1572
1737
  * @extends geo.annotation
1573
1738
  *
1574
- * @param {geo.rectangleAnnotation.spec?} [args] Options for the annotation.
1575
- * @param {string} [annotationName='rectangle'] Override the annotation name.
1739
+ * @param {geo.circleAnnotation.spec?} [args] Options for the annotation.
1740
+ * @param {string} [annotationName='circle'] Override the annotation name.
1576
1741
  */
1577
1742
 
1578
1743
 
1579
- var rectangleAnnotation = function rectangleAnnotation(args, annotationName) {
1744
+ var circleAnnotation = function circleAnnotation(args, annotationName) {
1580
1745
  'use strict';
1581
1746
 
1582
- if (!(this instanceof rectangleAnnotation)) {
1583
- return new rectangleAnnotation(args, annotationName);
1747
+ args = $.extend({}, args, {
1748
+ constraint: 1
1749
+ });
1750
+
1751
+ if (!(this instanceof circleAnnotation)) {
1752
+ return new circleAnnotation(args, annotationName);
1584
1753
  }
1585
1754
 
1586
- args = $.extend(true, {}, {
1587
- style: {
1588
- fill: true,
1589
- fillColor: {
1590
- r: 0,
1591
- g: 1,
1592
- b: 0
1593
- },
1594
- fillOpacity: 0.25,
1595
- polygon: function polygon(d) {
1596
- return d.polygon;
1597
- },
1598
- stroke: true,
1599
- strokeColor: {
1600
- r: 0,
1601
- g: 0,
1602
- b: 0
1603
- },
1604
- strokeOpacity: 1,
1605
- strokeWidth: 3,
1606
- uniformPolygon: true
1607
- },
1608
- highlightStyle: {
1609
- fillColor: {
1610
- r: 0,
1611
- g: 1,
1612
- b: 1
1613
- },
1614
- fillOpacity: 0.5,
1615
- strokeWidth: 5
1616
- },
1617
- createStyle: {
1618
- fillColor: {
1619
- r: 0.3,
1620
- g: 0.3,
1621
- b: 0.3
1622
- },
1623
- fillOpacity: 0.25,
1624
- strokeColor: {
1625
- r: 0,
1626
- g: 0,
1627
- b: 1
1628
- }
1629
- }
1630
- }, args || {});
1631
- args.corners = args.corners || args.coordinates || [];
1632
- delete args.coordinates;
1633
- annotation.call(this, annotationName || 'rectangle', args);
1634
- var m_this = this,
1635
- s_actions = this.actions,
1636
- s_processEditAction = this.processEditAction;
1637
- /**
1638
- * Return actions needed for the specified state of this annotation.
1639
- *
1640
- * @param {string} [state] The state to return actions for. Defaults to
1641
- * the current state.
1642
- * @returns {geo.actionRecord[]} A list of actions.
1643
- */
1755
+ ellipseAnnotation.call(this, args, annotationName || 'circle');
1756
+ };
1644
1757
 
1645
- this.actions = function (state) {
1646
- if (!state) {
1647
- state = m_this.state();
1648
- }
1758
+ inherit(circleAnnotation, ellipseAnnotation);
1759
+ var circleRequiredFeatures = {};
1760
+ circleRequiredFeatures[markerFeature.capabilities.feature] = true;
1761
+ registerAnnotation('circle', circleAnnotation, circleRequiredFeatures);
1762
+ module.exports = circleAnnotation;
1649
1763
 
1650
- switch (state) {
1651
- case annotationState.create:
1652
- return [{
1653
- action: geo_action.annotation_rectangle,
1654
- name: 'rectangle create',
1655
- owner: annotationActionOwner,
1656
- input: 'left',
1657
- modifiers: {
1658
- shift: false,
1659
- ctrl: false
1660
- },
1661
- selectionRectangle: true,
1662
- selectionConstraint: this._selectionConstraint
1663
- }];
1764
+ /***/ }),
1664
1765
 
1665
- default:
1666
- return s_actions.apply(m_this, arguments);
1667
- }
1668
- };
1669
- /**
1670
- * Process any actions for this annotation.
1671
- *
1672
- * @param {geo.event} evt The action event.
1673
- * @returns {boolean|string} `true` to update the annotation, `'done'` if the
1674
- * annotation was completed (changed from create to done state),
1675
- * `'remove'` if the annotation should be removed, falsy to not update
1676
- * anything.
1677
- */
1766
+ /***/ 7505:
1767
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
1678
1768
 
1769
+ var $ = __webpack_require__(5638);
1679
1770
 
1680
- this.processAction = function (evt) {
1681
- var layer = m_this.layer();
1771
+ var inherit = __webpack_require__(5699);
1682
1772
 
1683
- if (m_this.state() !== annotationState.create || !layer || evt.event !== geo_event.actionselection || evt.state.action !== geo_action.annotation_rectangle) {
1684
- return;
1685
- }
1773
+ var registerAnnotation = (__webpack_require__(4647).registerAnnotation);
1686
1774
 
1687
- var map = layer.map(),
1688
- corners = [
1689
- /* Keep in map gcs, not interface gcs to avoid wrapping issues */
1690
- map.displayToGcs({
1691
- x: evt.lowerLeft.x,
1692
- y: evt.lowerLeft.y
1693
- }, null), map.displayToGcs({
1694
- x: evt.lowerLeft.x,
1695
- y: evt.upperRight.y
1696
- }, null), map.displayToGcs({
1697
- x: evt.upperRight.x,
1698
- y: evt.upperRight.y
1699
- }, null), map.displayToGcs({
1700
- x: evt.upperRight.x,
1701
- y: evt.lowerLeft.y
1702
- }, null)];
1775
+ var markerFeature = __webpack_require__(7098);
1703
1776
 
1704
- if (this._selectionConstraint && evt.mouse && evt.state.origin) {
1705
- this._selectionConstraint(evt.mouse.mapgcs, evt.state.origin.mapgcs, corners);
1706
- }
1707
- /* Don't keep rectangles that have nearly zero area in display pixels */
1777
+ var annotationState = (__webpack_require__(5784).state);
1708
1778
 
1779
+ var rectangleAnnotation = __webpack_require__(3442);
1780
+ /**
1781
+ * Ellipse annotation class.
1782
+ *
1783
+ * Ellipses are always rendered as markers.
1784
+ *
1785
+ * @class
1786
+ * @alias geo.ellipseAnnotation
1787
+ * @extends geo.annotation
1788
+ *
1789
+ * @param {geo.ellipseAnnotation.spec?} [args] Options for the annotation.
1790
+ * @param {string} [annotationName='ellipse'] Override the annotation name.
1791
+ */
1709
1792
 
1710
- if (layer.displayDistance(corners[0], null, corners[1], null) * layer.displayDistance(corners[0], null, corners[3], null) < 0.01) {
1711
- return 'remove';
1712
- }
1713
1793
 
1714
- m_this.options('corners', corners);
1715
- m_this.state(annotationState.done);
1716
- return 'done';
1717
- };
1794
+ var ellipseAnnotation = function ellipseAnnotation(args, annotationName) {
1795
+ 'use strict';
1796
+
1797
+ if (!(this instanceof ellipseAnnotation)) {
1798
+ return new ellipseAnnotation(args, annotationName);
1799
+ }
1800
+
1801
+ rectangleAnnotation.call(this, args, annotationName || 'ellipse');
1802
+ var m_this = this;
1718
1803
  /**
1719
1804
  * Get a list of renderable features for this annotation.
1720
1805
  *
1721
1806
  * @returns {array} An array of features.
1722
1807
  */
1723
1808
 
1724
-
1725
1809
  this.features = function () {
1726
1810
  var opt = m_this.options(),
1727
1811
  state = m_this.state(),
@@ -1729,10 +1813,27 @@ var rectangleAnnotation = function rectangleAnnotation(args, annotationName) {
1729
1813
  features = [];
1730
1814
 
1731
1815
  if (opt.corners && opt.corners.length >= 4) {
1816
+ var style = m_this.styleForState(state);
1817
+ var w = Math.pow(Math.pow(opt.corners[0].x - opt.corners[1].x, 2) + Math.pow(opt.corners[0].y - opt.corners[1].y, 2), 0.5);
1818
+ var h = Math.pow(Math.pow(opt.corners[0].x - opt.corners[3].x, 2) + Math.pow(opt.corners[0].y - opt.corners[3].y, 2), 0.5);
1819
+ var radius = Math.max(w, h) / 2 / m_this.layer().map().unitsPerPixel(0);
1820
+ var aspect = w ? h / w : 1e20;
1821
+ var rotation = -Math.atan2(opt.corners[1].y - opt.corners[0].y, opt.corners[1].x - opt.corners[0].x);
1732
1822
  features = [{
1733
- polygon: {
1734
- polygon: opt.corners,
1735
- style: m_this.styleForState(state)
1823
+ marker: {
1824
+ x: (opt.corners[0].x + opt.corners[1].x + opt.corners[2].x + opt.corners[3].x) / 4,
1825
+ y: (opt.corners[0].y + opt.corners[1].y + opt.corners[2].y + opt.corners[3].y) / 4,
1826
+ style: $.extend({}, style, {
1827
+ radius: radius,
1828
+ symbolValue: aspect,
1829
+ rotation: rotation,
1830
+ strokeOffset: 0,
1831
+ radiusIncludesStroke: false,
1832
+ scaleWithZoom: markerFeature.scaleMode.fill,
1833
+ rotateWithMap: true,
1834
+ strokeOpacity: style.stroke === false ? 0 : style.strokeOpacity,
1835
+ fillOpacity: style.fill === false ? 0 : style.fillOpacity
1836
+ })
1736
1837
  }
1737
1838
  }];
1738
1839
  }
@@ -1743,467 +1844,107 @@ var rectangleAnnotation = function rectangleAnnotation(args, annotationName) {
1743
1844
 
1744
1845
  return features;
1745
1846
  };
1746
- /**
1747
- * Get and optionally set coordinates associated with this annotation in the
1748
- * map gcs coordinate system.
1749
- *
1750
- * @param {geo.geoPosition[]} [coordinates] An optional array of coordinates
1751
- * to set.
1752
- * @returns {geo.geoPosition[]} The current array of coordinates.
1753
- */
1754
-
1847
+ };
1755
1848
 
1756
- this._coordinates = function (coordinates) {
1757
- if (coordinates && coordinates.length >= 4) {
1758
- m_this.options('corners', coordinates.slice(0, 4));
1759
- /* Should we ensure that the four points form a rectangle in the current
1760
- * projection, though this might not be rectangular in another gcs? */
1761
- }
1849
+ inherit(ellipseAnnotation, rectangleAnnotation);
1850
+ var ellipseRequiredFeatures = {};
1851
+ ellipseRequiredFeatures[markerFeature.capabilities.feature] = true;
1852
+ registerAnnotation('ellipse', ellipseAnnotation, ellipseRequiredFeatures);
1853
+ module.exports = ellipseAnnotation;
1762
1854
 
1763
- return m_this.options('corners');
1764
- };
1855
+ /***/ }),
1765
1856
 
1766
- this._coordinateOption = 'corners';
1767
- /**
1768
- * Return the coordinates to be stored in a geojson geometry object.
1769
- *
1770
- * @param {string|geo.transform|null} [gcs] `undefined` to use the interface
1771
- * gcs, `null` to use the map gcs, or any other transform.
1772
- * @returns {array} An array of flattened coordinates in the interface gcs
1773
- * coordinate system. `undefined` if this annotation is incomplete.
1774
- */
1857
+ /***/ 4213:
1858
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
1775
1859
 
1776
- this._geojsonCoordinates = function (gcs) {
1777
- var src = m_this.coordinates(gcs);
1860
+ var annotation = __webpack_require__(5784);
1861
+ /**
1862
+ * @namespace geo.annotation
1863
+ */
1778
1864
 
1779
- if (!src || m_this.state() === annotationState.create || src.length < 4) {
1780
- return;
1781
- }
1782
1865
 
1783
- var coord = [];
1866
+ module.exports = {
1867
+ state: annotation.state,
1868
+ actionOwner: annotation.actionOwner,
1869
+ annotation: annotation.annotation,
1870
+ _editHandleFeatureLevel: annotation._editHandleFeatureLevel,
1871
+ defaultEditHandleStyle: annotation.defaultEditHandleStyle,
1872
+ constrainAspectRatio: annotation.constrainAspectRatio,
1873
+ baseAnnotation: annotation,
1874
+ circleAnnotation: __webpack_require__(7196),
1875
+ ellipseAnnotation: __webpack_require__(7505),
1876
+ lineAnnotation: __webpack_require__(3984),
1877
+ pointAnnotation: __webpack_require__(8296),
1878
+ polygonAnnotation: __webpack_require__(56),
1879
+ rectangleAnnotation: __webpack_require__(3442),
1880
+ squareAnnotation: __webpack_require__(4932)
1881
+ };
1784
1882
 
1785
- for (var i = 0; i < 4; i += 1) {
1786
- coord.push([src[i].x, src[i].y]);
1787
- }
1883
+ /***/ }),
1788
1884
 
1789
- coord.push([src[0].x, src[0].y]);
1790
- return [coord];
1791
- };
1792
- /**
1793
- * Return the geometry type that is used to store this annotation in geojson.
1794
- *
1795
- * @returns {string} A geojson geometry type.
1796
- */
1885
+ /***/ 3984:
1886
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
1797
1887
 
1888
+ var $ = __webpack_require__(5638);
1798
1889
 
1799
- this._geojsonGeometryType = function () {
1800
- return 'Polygon';
1801
- };
1802
- /**
1803
- * Return a list of styles that should be preserved in a geojson
1804
- * representation of the annotation.
1805
- *
1806
- * @returns {string[]} A list of style names to store.
1807
- */
1890
+ var inherit = __webpack_require__(5699);
1808
1891
 
1892
+ var registerAnnotation = (__webpack_require__(4647).registerAnnotation);
1809
1893
 
1810
- this._geojsonStyles = function () {
1811
- return ['fill', 'fillColor', 'fillOpacity', 'lineCap', 'lineJoin', 'stroke', 'strokeColor', 'strokeOffset', 'strokeOpacity', 'strokeWidth'];
1812
- };
1813
- /**
1814
- * Set three corners based on an initial corner and a mouse event.
1815
- *
1816
- * @param {geo.geoPosition} corners An array of four corners to update.
1817
- * @param {geo.event} evt The mouse move event.
1818
- */
1894
+ var lineFeature = __webpack_require__(4708);
1819
1895
 
1896
+ var annotation = (__webpack_require__(5784).annotation);
1820
1897
 
1821
- this._setCornersFromMouse = function (corners, evt) {
1822
- var map = m_this.layer().map(),
1823
- c0 = map.gcsToDisplay({
1824
- x: corners[0].x,
1825
- y: corners[0].y
1826
- }, null),
1827
- c2 = map.gcsToDisplay(evt.mapgcs, null),
1828
- c1 = {
1829
- x: c2.x,
1830
- y: c0.y
1831
- },
1832
- c3 = {
1833
- x: c0.x,
1834
- y: c2.y
1835
- };
1836
- corners[2] = $.extend({}, evt.mapgcs);
1837
- corners[1] = map.displayToGcs(c1, null);
1838
- corners[3] = map.displayToGcs(c3, null);
1898
+ var annotationState = (__webpack_require__(5784).state);
1839
1899
 
1840
- if (this._selectionConstraint) {
1841
- this._selectionConstraint(evt.mapgcs, corners[0], corners);
1842
- }
1843
- };
1844
- /**
1845
- * Handle a mouse move on this annotation.
1846
- *
1847
- * @param {geo.event} evt The mouse move event.
1848
- * @returns {boolean} Truthy to update the annotation, falsy to not
1849
- * update anything.
1850
- */
1900
+ var continuousVerticesActions = (__webpack_require__(5784).continuousVerticesActions);
1851
1901
 
1902
+ var continuousVerticesProcessAction = (__webpack_require__(5784).continuousVerticesProcessAction);
1903
+ /**
1904
+ * Line annotation specification. Extends {@link geo.annotation.spec}.
1905
+ *
1906
+ * @typedef {object} geo.lineAnnotation.spec
1907
+ * @extends geo.annotation.spec
1908
+ * @property {geo.geoPosition[]} [vertices] A list of vertices in map gcs
1909
+ * coordinates.
1910
+ * @property {geo.geoPosition[]} [coordinates] An alternate name for
1911
+ * `vertices`.
1912
+ * @property {geo.lineFeature.styleSpec} [style] The style to apply to a
1913
+ * finished line. This uses styles for {@link geo.lineFeature}.
1914
+ * @property {geo.lineFeature.styleSpec} [editStyle] The style to apply to a
1915
+ * line in edit mode.
1916
+ */
1852
1917
 
1853
- this.mouseMove = function (evt) {
1854
- if (m_this.state() !== annotationState.create) {
1855
- return;
1856
- }
1857
-
1858
- var corners = m_this.options('corners');
1859
-
1860
- if (corners.length) {
1861
- m_this._setCornersFromMouse(corners, evt);
1862
-
1863
- return true;
1864
- }
1865
- };
1866
- /**
1867
- * Handle a mouse click on this annotation. If the event is processed,
1868
- * evt.handled should be set to `true` to prevent further processing.
1869
- *
1870
- * @param {geo.event} evt The mouse click event.
1871
- * @returns {boolean|string} `true` to update the annotation, `'done'` if
1872
- * the annotation was completed (changed from create to done state),
1873
- * `'remove'` if the annotation should be removed, falsy to not update
1874
- * anything.
1875
- */
1876
-
1877
-
1878
- this.mouseClick = function (evt) {
1879
- var layer = m_this.layer();
1880
-
1881
- if (m_this.state() !== annotationState.create || !layer) {
1882
- return;
1883
- }
1884
-
1885
- if (!evt.buttonsDown.left && !evt.buttonsDown.right) {
1886
- return;
1887
- }
1888
-
1889
- var corners = m_this.options('corners');
1890
-
1891
- if (evt.buttonsDown.right && !corners.length) {
1892
- return;
1893
- }
1894
-
1895
- evt.handled = true;
1896
-
1897
- if (corners.length) {
1898
- m_this._setCornersFromMouse(corners, evt);
1899
- /* Don't keep rectangles that have nearly zero area in display pixels */
1900
-
1901
-
1902
- if (layer.displayDistance(corners[0], null, corners[1], null) * layer.displayDistance(corners[0], null, corners[3], null) < 0.01) {
1903
- return 'remove';
1904
- }
1905
-
1906
- m_this.state(annotationState.done);
1907
- return 'done';
1908
- }
1909
-
1910
- if (evt.buttonsDown.left) {
1911
- corners.push($.extend({}, evt.mapgcs));
1912
- corners.push($.extend({}, evt.mapgcs));
1913
- corners.push($.extend({}, evt.mapgcs));
1914
- corners.push($.extend({}, evt.mapgcs));
1915
- return true;
1916
- }
1917
- };
1918
- /**
1919
- * Process any edit actions for this annotation.
1920
- *
1921
- * @param {geo.event} evt The action event.
1922
- * @returns {boolean|string} `true` to update the annotation, falsy to not
1923
- * update anything.
1924
- */
1925
-
1926
-
1927
- this.processEditAction = function (evt) {
1928
- var start = m_this._editHandle.startCoordinates,
1929
- delta = {
1930
- x: evt.mouse.mapgcs.x - evt.state.origin.mapgcs.x,
1931
- y: evt.mouse.mapgcs.y - evt.state.origin.mapgcs.y
1932
- },
1933
- type = m_this._editHandle.handle.type,
1934
- index = m_this._editHandle.handle.index,
1935
- ang = [Math.atan2(start[1].y - start[0].y, start[1].x - start[0].x), Math.atan2(start[2].y - start[1].y, start[2].x - start[1].x), Math.atan2(start[3].y - start[2].y, start[3].x - start[2].x), Math.atan2(start[0].y - start[3].y, start[0].x - start[3].x)],
1936
- corners,
1937
- delta1,
1938
- delta2,
1939
- ang1,
1940
- ang2; // an angle can be zero because it is horizontal or undefined. If opposite
1941
- // angles are both zero, this is a degenerate rectangle (a line or a point)
1942
-
1943
- if (!ang[0] && !ang[1] && !ang[2] && !ang[3]) {
1944
- ang[1] = Math.PI / 2;
1945
- ang[2] = Math.PI;
1946
- ang[3] = -Math.PI / 2;
1947
- }
1948
-
1949
- if (!ang[0] && !ang[2]) {
1950
- ang[0] = ang[1] - Math.PI / 2;
1951
- ang[2] = ang[1] + Math.PI / 2;
1952
- }
1953
-
1954
- if (!ang[1] && !ang[3]) {
1955
- ang[1] = ang[2] - Math.PI / 2;
1956
- ang[3] = ang[2] + Math.PI / 2;
1957
- }
1958
-
1959
- switch (type) {
1960
- case 'vertex':
1961
- corners = start.map(function (elem) {
1962
- return {
1963
- x: elem.x,
1964
- y: elem.y
1965
- };
1966
- });
1967
- ang1 = ang[(index + 1) % 4];
1968
- delta1 = {
1969
- x: (delta.x * Math.cos(ang1) + delta.y * Math.sin(ang1)) * Math.cos(ang1),
1970
- y: (delta.y * Math.sin(ang1) + delta.x * Math.cos(ang1)) * Math.sin(ang1)
1971
- };
1972
- ang2 = ang[index];
1973
- delta2 = {
1974
- x: (delta.x * Math.cos(ang2) + delta.y * Math.sin(ang2)) * Math.cos(ang2),
1975
- y: (delta.y * Math.sin(ang2) + delta.x * Math.cos(ang2)) * Math.sin(ang2)
1976
- };
1977
- corners[index].x += delta.x;
1978
- corners[index].y += delta.y;
1979
- corners[(index + 1) % 4].x += delta1.x;
1980
- corners[(index + 1) % 4].y += delta1.y;
1981
- corners[(index + 3) % 4].x += delta2.x;
1982
- corners[(index + 3) % 4].y += delta2.y;
1983
-
1984
- if (this._selectionConstraint) {
1985
- corners = this._selectionConstraint(evt.mouse.mapgcs, evt.state.origin.mapgcs, corners, 'vertex', ang, index).corners;
1986
- }
1987
-
1988
- m_this.options('corners', corners);
1989
- return true;
1990
-
1991
- case 'edge':
1992
- corners = start.map(function (elem) {
1993
- return {
1994
- x: elem.x,
1995
- y: elem.y
1996
- };
1997
- });
1998
- ang1 = ang[(index + 1) % 4];
1999
- delta = {
2000
- x: (delta.x * Math.cos(ang1) + delta.y * Math.sin(ang1)) * Math.cos(ang1),
2001
- y: (delta.y * Math.sin(ang1) + delta.x * Math.cos(ang1)) * Math.sin(ang1)
2002
- };
2003
- corners[index].x += delta.x;
2004
- corners[index].y += delta.y;
2005
- corners[(index + 1) % 4].x += delta.x;
2006
- corners[(index + 1) % 4].y += delta.y;
2007
-
2008
- if (this._selectionConstraint) {
2009
- corners = this._selectionConstraint(evt.mouse.mapgcs, evt.state.origin.mapgcs, corners, 'edge', ang, index).corners;
2010
- }
2011
-
2012
- m_this.options('corners', corners);
2013
- return true;
2014
- }
2015
-
2016
- return s_processEditAction.apply(m_this, arguments);
2017
- };
2018
- };
2019
-
2020
- inherit(rectangleAnnotation, annotation);
2021
- var rectangleRequiredFeatures = {};
2022
- rectangleRequiredFeatures[polygonFeature.capabilities.feature] = true;
2023
- registerAnnotation('rectangle', rectangleAnnotation, rectangleRequiredFeatures);
2024
1918
  /**
2025
- * Square annotation class.
2026
- *
2027
- * Squares are a subset of rectangles with a fixed aspect ratio.
2028
- *
2029
- * @class
2030
- * @alias geo.squareAnnotation
2031
- * @extends geo.annotation
2032
- *
2033
- * @param {geo.squareAnnotation.spec?} [args] Options for the annotation.
2034
- * @param {string} [annotationName='square'] Override the annotation name.
2035
- */
2036
-
2037
- var squareAnnotation = function squareAnnotation(args, annotationName) {
2038
- 'use strict';
2039
-
2040
- args = $.extend({}, args, {
2041
- constraint: 1
2042
- });
2043
-
2044
- if (!(this instanceof squareAnnotation)) {
2045
- return new squareAnnotation(args, annotationName);
2046
- }
2047
-
2048
- rectangleAnnotation.call(this, args, annotationName || 'square');
2049
- };
2050
-
2051
- inherit(squareAnnotation, rectangleAnnotation);
2052
- var squareRequiredFeatures = {};
2053
- squareRequiredFeatures[polygonFeature.capabilities.feature] = true;
2054
- registerAnnotation('square', squareAnnotation, squareRequiredFeatures);
2055
- /**
2056
- * Ellipse annotation class.
2057
- *
2058
- * Ellipses are always rendered as markers.
2059
- *
2060
- * @class
2061
- * @alias geo.ellipseAnnotation
2062
- * @extends geo.annotation
2063
- *
2064
- * @param {geo.ellipseAnnotation.spec?} [args] Options for the annotation.
2065
- * @param {string} [annotationName='ellipse'] Override the annotation name.
2066
- */
2067
-
2068
- var ellipseAnnotation = function ellipseAnnotation(args, annotationName) {
2069
- 'use strict';
2070
-
2071
- if (!(this instanceof ellipseAnnotation)) {
2072
- return new ellipseAnnotation(args, annotationName);
2073
- }
2074
-
2075
- rectangleAnnotation.call(this, args, annotationName || 'ellipse');
2076
- var m_this = this;
2077
- /**
2078
- * Get a list of renderable features for this annotation.
2079
- *
2080
- * @returns {array} An array of features.
2081
- */
2082
-
2083
- this.features = function () {
2084
- var opt = m_this.options(),
2085
- state = m_this.state(),
2086
- features;
2087
- features = [];
2088
-
2089
- if (opt.corners && opt.corners.length >= 4) {
2090
- var style = m_this.styleForState(state);
2091
- var w = Math.pow(Math.pow(opt.corners[0].x - opt.corners[1].x, 2) + Math.pow(opt.corners[0].y - opt.corners[1].y, 2), 0.5);
2092
- var h = Math.pow(Math.pow(opt.corners[0].x - opt.corners[3].x, 2) + Math.pow(opt.corners[0].y - opt.corners[3].y, 2), 0.5);
2093
- var radius = Math.max(w, h) / 2 / m_this.layer().map().unitsPerPixel(0);
2094
- var aspect = w ? h / w : 1e20;
2095
- var rotation = -Math.atan2(opt.corners[1].y - opt.corners[0].y, opt.corners[1].x - opt.corners[0].x);
2096
- features = [{
2097
- marker: {
2098
- x: (opt.corners[0].x + opt.corners[1].x + opt.corners[2].x + opt.corners[3].x) / 4,
2099
- y: (opt.corners[0].y + opt.corners[1].y + opt.corners[2].y + opt.corners[3].y) / 4,
2100
- style: $.extend({}, style, {
2101
- radius: radius,
2102
- symbolValue: aspect,
2103
- rotation: rotation,
2104
- strokeOffset: 0,
2105
- radiusIncludesStroke: false,
2106
- scaleWithZoom: markerFeature.scaleMode.fill,
2107
- rotateWithMap: true,
2108
- strokeOpacity: style.stroke === false ? 0 : style.strokeOpacity,
2109
- fillOpacity: style.fill === false ? 0 : style.fillOpacity
2110
- })
2111
- }
2112
- }];
2113
- }
2114
-
2115
- if (state === annotationState.edit) {
2116
- m_this._addEditHandles(features, opt.corners);
2117
- }
2118
-
2119
- return features;
2120
- };
2121
- };
2122
-
2123
- inherit(ellipseAnnotation, rectangleAnnotation);
2124
- var ellipseRequiredFeatures = {};
2125
- ellipseRequiredFeatures[markerFeature.capabilities.feature] = true;
2126
- registerAnnotation('ellipse', ellipseAnnotation, ellipseRequiredFeatures);
2127
- /**
2128
- * Circle annotation class.
2129
- *
2130
- * Circles are a subset of rectangles with a fixed aspect ratio.
1919
+ * Line annotation class.
2131
1920
  *
2132
1921
  * @class
2133
- * @alias geo.circleAnnotation
1922
+ * @alias geo.lineAnnotation
2134
1923
  * @extends geo.annotation
2135
1924
  *
2136
- * @param {geo.circleAnnotation.spec?} [args] Options for the annotation.
2137
- * @param {string} [annotationName='circle'] Override the annotation name.
2138
- */
2139
-
2140
- var circleAnnotation = function circleAnnotation(args, annotationName) {
2141
- 'use strict';
2142
-
2143
- args = $.extend({}, args, {
2144
- constraint: 1
2145
- });
2146
-
2147
- if (!(this instanceof circleAnnotation)) {
2148
- return new circleAnnotation(args, annotationName);
2149
- }
2150
-
2151
- ellipseAnnotation.call(this, args, annotationName || 'circle');
2152
- };
2153
-
2154
- inherit(circleAnnotation, ellipseAnnotation);
2155
- var circleRequiredFeatures = {};
2156
- circleRequiredFeatures[markerFeature.capabilities.feature] = true;
2157
- registerAnnotation('circle', circleAnnotation, circleRequiredFeatures);
2158
- /**
2159
- * Polygon annotation specification. Extends {@link geo.annotation.spec}.
2160
- *
2161
- * @typedef {object} geo.polygonAnnotation.spec
2162
- * @extends geo.annotation.spec
2163
- * @property {geo.geoPosition[]} [vertices] A list of vertices in map gcs
2164
- * coordinates. These must be in order around the perimeter of the polygon
2165
- * (in either direction).
2166
- * @property {geo.geoPosition[]} [coordinates] An alternate name for
2167
- * `vertices`.
2168
- * @property {geo.polygonFeature.styleSpec} [style] The style to apply to a
2169
- * finished polygon. This uses styles for {@link geo.polygonFeature}.
2170
- * @property {geo.polygonFeature.styleSpec} [editStyle] The style to apply to ai
2171
- * polygon in edit mode.
1925
+ * @param {geo.lineAnnotation.spec?} [args] Options for the annotation.
2172
1926
  */
2173
1927
 
2174
- /**
2175
- * Polygon annotation class
2176
- *
2177
- * When complete, polygons are rendered as polygons. During creation they are
2178
- * rendered as lines and polygons.
2179
- *
2180
- * @class
2181
- * @alias geo.polygonAnnotation
2182
- * @extends geo.annotation
2183
- *
2184
- * @param {geo.polygonAnnotation.spec?} [args] Options for the annotation.
2185
- */
2186
1928
 
2187
- var polygonAnnotation = function polygonAnnotation(args) {
1929
+ var lineAnnotation = function lineAnnotation(args) {
2188
1930
  'use strict';
2189
1931
 
2190
- if (!(this instanceof polygonAnnotation)) {
2191
- return new polygonAnnotation(args);
1932
+ if (!(this instanceof lineAnnotation)) {
1933
+ return new lineAnnotation(args);
2192
1934
  }
2193
1935
 
2194
1936
  args = $.extend(true, {}, {
2195
1937
  style: {
2196
- fill: true,
2197
- fillColor: {
2198
- r: 0,
2199
- g: 1,
2200
- b: 0
1938
+ line: function line(d) {
1939
+ /* Return an array that has the same number of items as we have
1940
+ * vertices. */
1941
+ return Array.apply(null, Array(m_this.options('vertices').length)).map(function () {
1942
+ return d;
1943
+ });
2201
1944
  },
2202
- fillOpacity: 0.25,
2203
- polygon: function polygon(d) {
2204
- return d.polygon;
1945
+ position: function position(d, i) {
1946
+ return m_this.options('vertices')[i];
2205
1947
  },
2206
- stroke: true,
2207
1948
  strokeColor: {
2208
1949
  r: 0,
2209
1950
  g: 0,
@@ -2211,59 +1952,44 @@ var polygonAnnotation = function polygonAnnotation(args) {
2211
1952
  },
2212
1953
  strokeOpacity: 1,
2213
1954
  strokeWidth: 3,
2214
- uniformPolygon: true
1955
+ closed: false,
1956
+ lineCap: 'butt',
1957
+ lineJoin: 'miter'
2215
1958
  },
2216
1959
  highlightStyle: {
2217
- fillColor: {
2218
- r: 0,
2219
- g: 1,
2220
- b: 1
2221
- },
2222
- fillOpacity: 0.5,
2223
1960
  strokeWidth: 5
2224
1961
  },
2225
1962
  createStyle: {
2226
- closed: false,
2227
- fillColor: {
2228
- r: 0.3,
2229
- g: 0.3,
2230
- b: 0.3
2231
- },
2232
- fillOpacity: 0.25,
2233
1963
  line: function line(d) {
2234
- var coord = m_this._coordinates();
2235
1964
  /* Return an array that has the same number of items as we have
2236
1965
  * vertices. */
2237
-
2238
-
2239
- return Array.apply(null, Array((coord.outer || coord).length)).map(function () {
1966
+ return Array.apply(null, Array(m_this.options('vertices').length)).map(function () {
2240
1967
  return d;
2241
1968
  });
2242
1969
  },
2243
1970
  position: function position(d, i) {
2244
- if (d.x !== undefined) {
2245
- return d.x;
2246
- }
2247
-
2248
1971
  return m_this.options('vertices')[i];
2249
1972
  },
2250
- stroke: false,
2251
1973
  strokeColor: {
2252
1974
  r: 0,
2253
1975
  g: 0,
2254
1976
  b: 1
2255
- }
1977
+ },
1978
+ strokeOpacity: 1,
1979
+ strokeWidth: 3,
1980
+ closed: false,
1981
+ lineCap: 'butt',
1982
+ lineJoin: 'miter'
2256
1983
  }
2257
1984
  }, args || {});
2258
1985
  args.vertices = args.vertices || args.coordinates || [];
2259
1986
  delete args.coordinates;
2260
- annotation.call(this, 'polygon', args);
1987
+ annotation.call(this, 'line', args);
2261
1988
  var m_this = this,
2262
- s_actions = this.actions;
1989
+ s_actions = this.actions,
1990
+ s_processEditAction = this.processEditAction;
2263
1991
  /**
2264
- * Get a list of renderable features for this annotation. When the polygon
2265
- * is done, this is just a single polygon. During creation this can be a
2266
- * polygon and line at z-levels 1 and 2.
1992
+ * Get a list of renderable features for this annotation.
2267
1993
  *
2268
1994
  * @returns {array} An array of features.
2269
1995
  */
@@ -2271,43 +1997,28 @@ var polygonAnnotation = function polygonAnnotation(args) {
2271
1997
  this.features = function () {
2272
1998
  var opt = m_this.options(),
2273
1999
  state = m_this.state(),
2274
- style = m_this.styleForState(state),
2275
2000
  features;
2276
2001
 
2277
2002
  switch (state) {
2278
2003
  case annotationState.create:
2279
- features = [];
2280
-
2281
- if (opt.vertices && (opt.vertices.outer || opt.vertices.length >= 3)) {
2282
- features[1] = {
2283
- polygon: {
2284
- polygon: opt.vertices,
2285
- style: style
2286
- }
2287
- };
2288
- }
2289
-
2290
- if (opt.vertices && opt.vertices.length >= 2) {
2291
- features[2] = {
2292
- line: {
2293
- line: opt.vertices,
2294
- style: style
2295
- }
2296
- };
2297
- }
2298
-
2004
+ features = [{
2005
+ line: {
2006
+ line: opt.vertices,
2007
+ style: m_this.styleForState(state)
2008
+ }
2009
+ }];
2299
2010
  break;
2300
2011
 
2301
2012
  default:
2302
2013
  features = [{
2303
- polygon: {
2304
- polygon: opt.vertices,
2305
- style: style
2014
+ line: {
2015
+ line: opt.vertices,
2016
+ style: m_this.styleForState(state)
2306
2017
  }
2307
2018
  }];
2308
2019
 
2309
2020
  if (state === annotationState.edit) {
2310
- m_this._addEditHandles(features, opt.vertices);
2021
+ m_this._addEditHandles(features, opt.vertices, undefined, !m_this.style('closed'));
2311
2022
  }
2312
2023
 
2313
2024
  break;
@@ -2396,7 +2107,7 @@ var polygonAnnotation = function polygonAnnotation(args) {
2396
2107
  end = true;
2397
2108
  }
2398
2109
  } else if (vertices.length >= 2 && layer.displayDistance(vertices[0], null, evt.map, 'display') <= layer.options('finalPointProximity')) {
2399
- end = true;
2110
+ end = 'close';
2400
2111
  } else {
2401
2112
  vertices[vertices.length - 1] = evt.mapgcs;
2402
2113
  }
@@ -2413,11 +2124,12 @@ var polygonAnnotation = function polygonAnnotation(args) {
2413
2124
  }
2414
2125
 
2415
2126
  if (end) {
2416
- if (vertices.length < 4) {
2127
+ if (vertices.length < 3) {
2417
2128
  return 'remove';
2418
2129
  }
2419
2130
 
2420
2131
  vertices.pop();
2132
+ m_this.options('style').closed = end === 'close';
2421
2133
  m_this.state(annotationState.done);
2422
2134
  return 'done';
2423
2135
  }
@@ -2425,30 +2137,375 @@ var polygonAnnotation = function polygonAnnotation(args) {
2425
2137
  return !skip;
2426
2138
  };
2427
2139
  /**
2428
- * Return actions needed for the specified state of this annotation.
2140
+ * Return actions needed for the specified state of this annotation.
2141
+ *
2142
+ * @param {string} [state] The state to return actions for. Defaults to
2143
+ * the current state.
2144
+ * @returns {geo.actionRecord[]} A list of actions.
2145
+ */
2146
+
2147
+
2148
+ this.actions = function (state) {
2149
+ return continuousVerticesActions(m_this, s_actions, state, 'line', arguments);
2150
+ };
2151
+ /**
2152
+ * Process any actions for this annotation.
2153
+ *
2154
+ * @param {geo.event} evt The action event.
2155
+ * @returns {boolean|string} `true` to update the annotation, `'done'` if the
2156
+ * annotation was completed (changed from create to done state),
2157
+ * `'remove'` if the annotation should be removed, falsy to not update
2158
+ * anything.
2159
+ */
2160
+
2161
+
2162
+ this.processAction = function (evt) {
2163
+ return continuousVerticesProcessAction(m_this, evt, 'line');
2164
+ };
2165
+ /**
2166
+ * Return the coordinates to be stored in a geojson geometry object.
2167
+ *
2168
+ * @param {string|geo.transform|null} [gcs] `undefined` to use the interface
2169
+ * gcs, `null` to use the map gcs, or any other transform.
2170
+ * @returns {array} An array of flattened coordinates in the interface gcs
2171
+ * coordinate system. `undefined` if this annotation is incomplete.
2172
+ */
2173
+
2174
+
2175
+ this._geojsonCoordinates = function (gcs) {
2176
+ var src = m_this.coordinates(gcs);
2177
+
2178
+ if (!src || src.length < 2 || m_this.state() === annotationState.create) {
2179
+ return;
2180
+ }
2181
+
2182
+ var coord = [];
2183
+
2184
+ for (var i = 0; i < src.length; i += 1) {
2185
+ coord.push([src[i].x, src[i].y]);
2186
+ }
2187
+
2188
+ return coord;
2189
+ };
2190
+ /**
2191
+ * Return the geometry type that is used to store this annotation in geojson.
2192
+ *
2193
+ * @returns {string} A geojson geometry type.
2194
+ */
2195
+
2196
+
2197
+ this._geojsonGeometryType = function () {
2198
+ return 'LineString';
2199
+ };
2200
+ /**
2201
+ * Return a list of styles that should be preserved in a geojson
2202
+ * representation of the annotation.
2203
+ *
2204
+ * @returns {string[]} A list of style names to store.
2205
+ */
2206
+
2207
+
2208
+ this._geojsonStyles = function () {
2209
+ return ['closed', 'lineCap', 'lineJoin', 'strokeColor', 'strokeOffset', 'strokeOpacity', 'strokeWidth'];
2210
+ };
2211
+ /**
2212
+ * Process any edit actions for this annotation.
2213
+ *
2214
+ * @param {geo.event} evt The action event.
2215
+ * @returns {boolean|string} `true` to update the annotation, falsy to not
2216
+ * update anything.
2217
+ */
2218
+
2219
+
2220
+ this.processEditAction = function (evt) {
2221
+ switch (m_this._editHandle.handle.type) {
2222
+ case 'vertex':
2223
+ return m_this._processEditActionVertex(evt, true);
2224
+ }
2225
+
2226
+ return s_processEditAction.apply(m_this, arguments);
2227
+ };
2228
+ /**
2229
+ * Handle a mouse click on this annotation when in edit mode. If the event
2230
+ * is processed, evt.handled should be set to `true` to prevent further
2231
+ * processing.
2232
+ *
2233
+ * @param {geo.event} evt The mouse click event.
2234
+ * @returns {boolean|string} `true` to update the annotation, `'done'` if
2235
+ * the annotation was completed (changed from create to done state),
2236
+ * `'remove'` if the annotation should be removed, falsy to not update
2237
+ * anything.
2238
+ */
2239
+
2240
+
2241
+ this.mouseClickEdit = function (evt) {
2242
+ // if we get a left double click on an edge on a closed line, break the
2243
+ // line at that edge
2244
+ var layer = m_this.layer(),
2245
+ handle = m_this._editHandle,
2246
+ split; // ensure we are in edit mode and this is a left click
2247
+
2248
+ if (m_this.state() !== annotationState.edit || !layer || !evt.buttonsDown.left) {
2249
+ return;
2250
+ } // ensure this is an edge on a closed line
2251
+
2252
+
2253
+ if (!handle || !handle.handle.selected || handle.handle.type !== 'edge' || !m_this.options('style').closed) {
2254
+ return;
2255
+ }
2256
+
2257
+ evt.handled = true;
2258
+
2259
+ if (m_this._lastClick && evt.time - m_this._lastClick < layer.options('dblClickTime')) {
2260
+ split = true;
2261
+ }
2262
+
2263
+ m_this._lastClick = evt.time;
2264
+
2265
+ if (split) {
2266
+ var index = handle.handle.index,
2267
+ curPts = m_this._coordinates(),
2268
+ pts = curPts.slice(index + 1).concat(curPts.slice(0, index + 1));
2269
+
2270
+ m_this._coordinates(pts);
2271
+
2272
+ m_this.options('style').closed = false;
2273
+ handle.handle.index = undefined;
2274
+ return true;
2275
+ }
2276
+ };
2277
+ };
2278
+
2279
+ inherit(lineAnnotation, annotation);
2280
+ var lineRequiredFeatures = {};
2281
+ lineRequiredFeatures[lineFeature.capabilities.basic] = [annotationState.create];
2282
+ registerAnnotation('line', lineAnnotation, lineRequiredFeatures);
2283
+ module.exports = lineAnnotation;
2284
+
2285
+ /***/ }),
2286
+
2287
+ /***/ 8296:
2288
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
2289
+
2290
+ var $ = __webpack_require__(5638);
2291
+
2292
+ var inherit = __webpack_require__(5699);
2293
+
2294
+ var util = __webpack_require__(4634);
2295
+
2296
+ var registerAnnotation = (__webpack_require__(4647).registerAnnotation);
2297
+
2298
+ var pointFeature = __webpack_require__(2557);
2299
+
2300
+ var annotation = (__webpack_require__(5784).annotation);
2301
+
2302
+ var annotationState = (__webpack_require__(5784).state);
2303
+ /**
2304
+ * Point annotation specification. Extends {@link geo.annotation.spec}.
2305
+ *
2306
+ * @typedef {object} geo.pointAnnotation.spec
2307
+ * @extends geo.annotation.spec
2308
+ * @property {geo.geoPosition} [position] A coordinate in map gcs coordinates.
2309
+ * @property {geo.geoPosition[]} [coordinates] An array with one coordinate to
2310
+ * use in place of `position`.
2311
+ * @property {geo.pointFeature.styleSpec} [style] The style to apply to a
2312
+ * finished point. This uses styles for {@link geo.pointFeature}.
2313
+ * @property {boolean|number} [style.scaled=false] If `false`, the point is not
2314
+ * scaled with zoom level. If `true`, the radius is based on the zoom level
2315
+ * at first instantiation. If a number, the radius is used at the `scaled`
2316
+ * zoom level.
2317
+ * @property {geo.pointFeature.styleSpec} [editStyle] The style to apply to a
2318
+ * point in edit mode.
2319
+ */
2320
+
2321
+ /**
2322
+ * Point annotation class.
2323
+ *
2324
+ * @class
2325
+ * @alias geo.pointAnnotation
2326
+ * @extends geo.annotation
2327
+ *
2328
+ * @param {geo.pointAnnotation.spec?} [args] Options for the annotation.
2329
+ */
2330
+
2331
+
2332
+ var pointAnnotation = function pointAnnotation(args) {
2333
+ 'use strict';
2334
+
2335
+ if (!(this instanceof pointAnnotation)) {
2336
+ return new pointAnnotation(args);
2337
+ }
2338
+
2339
+ args = $.extend(true, {}, {
2340
+ style: {
2341
+ fill: true,
2342
+ fillColor: {
2343
+ r: 0,
2344
+ g: 1,
2345
+ b: 0
2346
+ },
2347
+ fillOpacity: 0.25,
2348
+ radius: 10,
2349
+ scaled: false,
2350
+ stroke: true,
2351
+ strokeColor: {
2352
+ r: 0,
2353
+ g: 0,
2354
+ b: 0
2355
+ },
2356
+ strokeOpacity: 1,
2357
+ strokeWidth: 3
2358
+ },
2359
+ createStyle: {
2360
+ fillColor: {
2361
+ r: 0.3,
2362
+ g: 0.3,
2363
+ b: 0.3
2364
+ },
2365
+ fillOpacity: 0.25,
2366
+ strokeColor: {
2367
+ r: 0,
2368
+ g: 0,
2369
+ b: 1
2370
+ }
2371
+ },
2372
+ highlightStyle: {
2373
+ fillColor: {
2374
+ r: 0,
2375
+ g: 1,
2376
+ b: 1
2377
+ },
2378
+ fillOpacity: 0.5,
2379
+ strokeWidth: 5
2380
+ }
2381
+ }, args || {});
2382
+ args.position = args.position || (args.coordinates ? args.coordinates[0] : undefined);
2383
+ delete args.coordinates;
2384
+ annotation.call(this, 'point', args);
2385
+ var m_this = this;
2386
+ /**
2387
+ * Get a list of renderable features for this annotation.
2388
+ *
2389
+ * @returns {array} An array of features.
2390
+ */
2391
+
2392
+ this.features = function () {
2393
+ var opt = m_this.options(),
2394
+ state = m_this.state(),
2395
+ features,
2396
+ style,
2397
+ scaleOnZoom;
2398
+
2399
+ switch (state) {
2400
+ case annotationState.create:
2401
+ features = [];
2402
+ break;
2403
+
2404
+ default:
2405
+ style = m_this.styleForState(state);
2406
+
2407
+ if (opt.style.scaled || opt.style.scaled === 0) {
2408
+ if (opt.style.scaled === true) {
2409
+ opt.style.scaled = m_this.layer().map().zoom();
2410
+ }
2411
+
2412
+ style = $.extend({}, style, {
2413
+ radius: function radius() {
2414
+ var radius = opt.style.radius,
2415
+ zoom = m_this.layer().map().zoom();
2416
+
2417
+ if (util.isFunction(radius)) {
2418
+ radius = radius.apply(m_this, arguments);
2419
+ }
2420
+
2421
+ radius *= Math.pow(2, zoom - opt.style.scaled);
2422
+ return radius;
2423
+ }
2424
+ });
2425
+ scaleOnZoom = true;
2426
+ }
2427
+
2428
+ features = [{
2429
+ point: {
2430
+ x: opt.position.x,
2431
+ y: opt.position.y,
2432
+ style: style,
2433
+ scaleOnZoom: scaleOnZoom
2434
+ }
2435
+ }];
2436
+
2437
+ if (state === annotationState.edit) {
2438
+ m_this._addEditHandles(features, [opt.position], {
2439
+ edge: false,
2440
+ center: false,
2441
+ resize: false,
2442
+ rotate: false
2443
+ });
2444
+ }
2445
+
2446
+ break;
2447
+ }
2448
+
2449
+ return features;
2450
+ };
2451
+ /**
2452
+ * Get and optionally set coordinates associated with this annotation in the
2453
+ * map gcs coordinate system.
2454
+ *
2455
+ * @param {geo.geoPosition[]} [coordinates] An optional array of coordinates
2456
+ * to set.
2457
+ * @returns {geo.geoPosition[]} The current array of coordinates.
2458
+ */
2459
+
2460
+
2461
+ this._coordinates = function (coordinates) {
2462
+ if (coordinates && coordinates.length >= 1) {
2463
+ m_this.options('position', coordinates[0]);
2464
+ }
2465
+
2466
+ if (m_this.state() === annotationState.create) {
2467
+ return [];
2468
+ }
2469
+
2470
+ return [m_this.options('position')];
2471
+ };
2472
+
2473
+ this._coordinateOption = 'position';
2474
+ /**
2475
+ * Handle a mouse click on this annotation. If the event is processed,
2476
+ * evt.handled should be set to `true` to prevent further processing.
2429
2477
  *
2430
- * @param {string} [state] The state to return actions for. Defaults to
2431
- * the current state.
2432
- * @returns {geo.actionRecord[]} A list of actions.
2478
+ * @param {geo.event} evt The mouse click event.
2479
+ * @returns {boolean|string} `true` to update the annotation, `'done'` if
2480
+ * the annotation was completed (changed from create to done state),
2481
+ * `'remove'` if the annotation should be removed, falsy to not update
2482
+ * anything.
2433
2483
  */
2434
2484
 
2485
+ this.mouseClick = function (evt) {
2486
+ if (m_this.state() !== annotationState.create) {
2487
+ return;
2488
+ }
2489
+
2490
+ if (!evt.buttonsDown.left) {
2491
+ return;
2492
+ }
2435
2493
 
2436
- this.actions = function (state) {
2437
- return continuousVerticesActions(m_this, s_actions, state, 'polygon', arguments);
2494
+ evt.handled = true;
2495
+ m_this.options('position', evt.mapgcs);
2496
+ m_this.state(annotationState.done);
2497
+ return 'done';
2438
2498
  };
2439
2499
  /**
2440
- * Process any actions for this annotation.
2500
+ * Return a list of styles that should be preserved in a geojson
2501
+ * representation of the annotation.
2441
2502
  *
2442
- * @param {geo.event} evt The action event.
2443
- * @returns {boolean|string} `true` to update the annotation, `'done'` if the
2444
- * annotation was completed (changed from create to done state),
2445
- * `'remove'` if the annotation should be removed, falsy to not update
2446
- * anything.
2503
+ * @returns {string[]} A list of style names to store.
2447
2504
  */
2448
2505
 
2449
2506
 
2450
- this.processAction = function (evt) {
2451
- return continuousVerticesProcessAction(m_this, evt, 'polygon');
2507
+ this._geojsonStyles = function () {
2508
+ return ['fill', 'fillColor', 'fillOpacity', 'radius', 'scaled', 'stroke', 'strokeColor', 'strokeOpacity', 'strokeWidth'];
2452
2509
  };
2453
2510
  /**
2454
2511
  * Return the coordinates to be stored in a geojson geometry object.
@@ -2463,32 +2520,11 @@ var polygonAnnotation = function polygonAnnotation(args) {
2463
2520
  this._geojsonCoordinates = function (gcs) {
2464
2521
  var src = m_this.coordinates(gcs);
2465
2522
 
2466
- if (!src || !src.outer && src.length < 3 || m_this.state() === annotationState.create) {
2523
+ if (!src || m_this.state() === annotationState.create || src.length < 1 || src[0] === undefined) {
2467
2524
  return;
2468
2525
  }
2469
2526
 
2470
- var coord = [];
2471
-
2472
- if (!src.outer) {
2473
- coord = [src.map(function (pt) {
2474
- return [pt.x, pt.y];
2475
- })];
2476
- coord[0].push(coord[0][0].slice());
2477
- } else {
2478
- coord = [src.outer.map(function (pt) {
2479
- return [pt.x, pt.y];
2480
- })];
2481
- coord[0].push(coord[0][0].slice());
2482
- (src.inner || []).forEach(function (h) {
2483
- var poly = h.map(function (pt) {
2484
- return [pt.x, pt.y];
2485
- });
2486
- poly.push(poly[0].slice());
2487
- coord.push(poly);
2488
- });
2489
- }
2490
-
2491
- return coord;
2527
+ return [src[0].x, src[0].y];
2492
2528
  };
2493
2529
  /**
2494
2530
  * Return the geometry type that is used to store this annotation in geojson.
@@ -2498,70 +2534,88 @@ var polygonAnnotation = function polygonAnnotation(args) {
2498
2534
 
2499
2535
 
2500
2536
  this._geojsonGeometryType = function () {
2501
- return 'Polygon';
2537
+ return 'Point';
2502
2538
  };
2503
- /**
2504
- * Return a list of styles that should be preserved in a geojson
2505
- * representation of the annotation.
2506
- *
2507
- * @returns {string[]} A list of style names to store.
2508
- */
2539
+ };
2509
2540
 
2541
+ inherit(pointAnnotation, annotation);
2542
+ var pointRequiredFeatures = {};
2543
+ pointRequiredFeatures[pointFeature.capabilities.feature] = true;
2544
+ registerAnnotation('point', pointAnnotation, pointRequiredFeatures);
2545
+ module.exports = pointAnnotation;
2510
2546
 
2511
- this._geojsonStyles = function () {
2512
- return ['fill', 'fillColor', 'fillOpacity', 'lineCap', 'lineJoin', 'stroke', 'strokeColor', 'strokeOffset', 'strokeOpacity', 'strokeWidth'];
2513
- };
2514
- };
2547
+ /***/ }),
2515
2548
 
2516
- inherit(polygonAnnotation, annotation);
2517
- var polygonRequiredFeatures = {};
2518
- polygonRequiredFeatures[polygonFeature.capabilities.feature] = true;
2519
- polygonRequiredFeatures[lineFeature.capabilities.basic] = [annotationState.create];
2520
- registerAnnotation('polygon', polygonAnnotation, polygonRequiredFeatures);
2549
+ /***/ 56:
2550
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
2551
+
2552
+ var $ = __webpack_require__(5638);
2553
+
2554
+ var inherit = __webpack_require__(5699);
2555
+
2556
+ var registerAnnotation = (__webpack_require__(4647).registerAnnotation);
2557
+
2558
+ var lineFeature = __webpack_require__(4708);
2559
+
2560
+ var polygonFeature = __webpack_require__(4343);
2561
+
2562
+ var annotation = (__webpack_require__(5784).annotation);
2563
+
2564
+ var annotationState = (__webpack_require__(5784).state);
2565
+
2566
+ var continuousVerticesActions = (__webpack_require__(5784).continuousVerticesActions);
2567
+
2568
+ var continuousVerticesProcessAction = (__webpack_require__(5784).continuousVerticesProcessAction);
2521
2569
  /**
2522
- * Line annotation specification. Extends {@link geo.annotation.spec}.
2570
+ * Polygon annotation specification. Extends {@link geo.annotation.spec}.
2523
2571
  *
2524
- * @typedef {object} geo.lineAnnotation.spec
2572
+ * @typedef {object} geo.polygonAnnotation.spec
2525
2573
  * @extends geo.annotation.spec
2526
2574
  * @property {geo.geoPosition[]} [vertices] A list of vertices in map gcs
2527
- * coordinates.
2575
+ * coordinates. These must be in order around the perimeter of the polygon
2576
+ * (in either direction).
2528
2577
  * @property {geo.geoPosition[]} [coordinates] An alternate name for
2529
2578
  * `vertices`.
2530
- * @property {geo.lineFeature.styleSpec} [style] The style to apply to a
2531
- * finished line. This uses styles for {@link geo.lineFeature}.
2532
- * @property {geo.lineFeature.styleSpec} [editStyle] The style to apply to a
2533
- * line in edit mode.
2579
+ * @property {geo.polygonFeature.styleSpec} [style] The style to apply to a
2580
+ * finished polygon. This uses styles for {@link geo.polygonFeature}.
2581
+ * @property {geo.polygonFeature.styleSpec} [editStyle] The style to apply to ai
2582
+ * polygon in edit mode.
2534
2583
  */
2535
2584
 
2536
2585
  /**
2537
- * Line annotation class.
2586
+ * Polygon annotation class
2587
+ *
2588
+ * When complete, polygons are rendered as polygons. During creation they are
2589
+ * rendered as lines and polygons.
2538
2590
  *
2539
2591
  * @class
2540
- * @alias geo.lineAnnotation
2592
+ * @alias geo.polygonAnnotation
2541
2593
  * @extends geo.annotation
2542
2594
  *
2543
- * @param {geo.lineAnnotation.spec?} [args] Options for the annotation.
2595
+ * @param {geo.polygonAnnotation.spec?} [args] Options for the annotation.
2544
2596
  */
2545
2597
 
2546
- var lineAnnotation = function lineAnnotation(args) {
2598
+
2599
+ var polygonAnnotation = function polygonAnnotation(args) {
2547
2600
  'use strict';
2548
2601
 
2549
- if (!(this instanceof lineAnnotation)) {
2550
- return new lineAnnotation(args);
2602
+ if (!(this instanceof polygonAnnotation)) {
2603
+ return new polygonAnnotation(args);
2551
2604
  }
2552
2605
 
2553
2606
  args = $.extend(true, {}, {
2554
2607
  style: {
2555
- line: function line(d) {
2556
- /* Return an array that has the same number of items as we have
2557
- * vertices. */
2558
- return Array.apply(null, Array(m_this.options('vertices').length)).map(function () {
2559
- return d;
2560
- });
2608
+ fill: true,
2609
+ fillColor: {
2610
+ r: 0,
2611
+ g: 1,
2612
+ b: 0
2561
2613
  },
2562
- position: function position(d, i) {
2563
- return m_this.options('vertices')[i];
2614
+ fillOpacity: 0.25,
2615
+ polygon: function polygon(d) {
2616
+ return d.polygon;
2564
2617
  },
2618
+ stroke: true,
2565
2619
  strokeColor: {
2566
2620
  r: 0,
2567
2621
  g: 0,
@@ -2569,44 +2623,59 @@ var lineAnnotation = function lineAnnotation(args) {
2569
2623
  },
2570
2624
  strokeOpacity: 1,
2571
2625
  strokeWidth: 3,
2572
- closed: false,
2573
- lineCap: 'butt',
2574
- lineJoin: 'miter'
2626
+ uniformPolygon: true
2575
2627
  },
2576
2628
  highlightStyle: {
2629
+ fillColor: {
2630
+ r: 0,
2631
+ g: 1,
2632
+ b: 1
2633
+ },
2634
+ fillOpacity: 0.5,
2577
2635
  strokeWidth: 5
2578
2636
  },
2579
2637
  createStyle: {
2638
+ closed: false,
2639
+ fillColor: {
2640
+ r: 0.3,
2641
+ g: 0.3,
2642
+ b: 0.3
2643
+ },
2644
+ fillOpacity: 0.25,
2580
2645
  line: function line(d) {
2646
+ var coord = m_this._coordinates();
2581
2647
  /* Return an array that has the same number of items as we have
2582
2648
  * vertices. */
2583
- return Array.apply(null, Array(m_this.options('vertices').length)).map(function () {
2649
+
2650
+
2651
+ return Array.apply(null, Array((coord.outer || coord).length)).map(function () {
2584
2652
  return d;
2585
2653
  });
2586
2654
  },
2587
2655
  position: function position(d, i) {
2656
+ if (d.x !== undefined) {
2657
+ return d.x;
2658
+ }
2659
+
2588
2660
  return m_this.options('vertices')[i];
2589
2661
  },
2662
+ stroke: false,
2590
2663
  strokeColor: {
2591
2664
  r: 0,
2592
2665
  g: 0,
2593
2666
  b: 1
2594
- },
2595
- strokeOpacity: 1,
2596
- strokeWidth: 3,
2597
- closed: false,
2598
- lineCap: 'butt',
2599
- lineJoin: 'miter'
2667
+ }
2600
2668
  }
2601
2669
  }, args || {});
2602
2670
  args.vertices = args.vertices || args.coordinates || [];
2603
2671
  delete args.coordinates;
2604
- annotation.call(this, 'line', args);
2672
+ annotation.call(this, 'polygon', args);
2605
2673
  var m_this = this,
2606
- s_actions = this.actions,
2607
- s_processEditAction = this.processEditAction;
2674
+ s_actions = this.actions;
2608
2675
  /**
2609
- * Get a list of renderable features for this annotation.
2676
+ * Get a list of renderable features for this annotation. When the polygon
2677
+ * is done, this is just a single polygon. During creation this can be a
2678
+ * polygon and line at z-levels 1 and 2.
2610
2679
  *
2611
2680
  * @returns {array} An array of features.
2612
2681
  */
@@ -2614,28 +2683,43 @@ var lineAnnotation = function lineAnnotation(args) {
2614
2683
  this.features = function () {
2615
2684
  var opt = m_this.options(),
2616
2685
  state = m_this.state(),
2686
+ style = m_this.styleForState(state),
2617
2687
  features;
2618
2688
 
2619
2689
  switch (state) {
2620
2690
  case annotationState.create:
2621
- features = [{
2622
- line: {
2623
- line: opt.vertices,
2624
- style: m_this.styleForState(state)
2625
- }
2626
- }];
2691
+ features = [];
2692
+
2693
+ if (opt.vertices && (opt.vertices.outer || opt.vertices.length >= 3)) {
2694
+ features[1] = {
2695
+ polygon: {
2696
+ polygon: opt.vertices,
2697
+ style: style
2698
+ }
2699
+ };
2700
+ }
2701
+
2702
+ if (opt.vertices && opt.vertices.length >= 2) {
2703
+ features[2] = {
2704
+ line: {
2705
+ line: opt.vertices,
2706
+ style: style
2707
+ }
2708
+ };
2709
+ }
2710
+
2627
2711
  break;
2628
2712
 
2629
2713
  default:
2630
2714
  features = [{
2631
- line: {
2632
- line: opt.vertices,
2633
- style: m_this.styleForState(state)
2715
+ polygon: {
2716
+ polygon: opt.vertices,
2717
+ style: style
2634
2718
  }
2635
2719
  }];
2636
2720
 
2637
2721
  if (state === annotationState.edit) {
2638
- m_this._addEditHandles(features, opt.vertices, undefined, !m_this.style('closed'));
2722
+ m_this._addEditHandles(features, opt.vertices);
2639
2723
  }
2640
2724
 
2641
2725
  break;
@@ -2724,7 +2808,7 @@ var lineAnnotation = function lineAnnotation(args) {
2724
2808
  end = true;
2725
2809
  }
2726
2810
  } else if (vertices.length >= 2 && layer.displayDistance(vertices[0], null, evt.map, 'display') <= layer.options('finalPointProximity')) {
2727
- end = 'close';
2811
+ end = true;
2728
2812
  } else {
2729
2813
  vertices[vertices.length - 1] = evt.mapgcs;
2730
2814
  }
@@ -2741,12 +2825,11 @@ var lineAnnotation = function lineAnnotation(args) {
2741
2825
  }
2742
2826
 
2743
2827
  if (end) {
2744
- if (vertices.length < 3) {
2828
+ if (vertices.length < 4) {
2745
2829
  return 'remove';
2746
2830
  }
2747
2831
 
2748
2832
  vertices.pop();
2749
- m_this.options('style').closed = end === 'close';
2750
2833
  m_this.state(annotationState.done);
2751
2834
  return 'done';
2752
2835
  }
@@ -2763,7 +2846,7 @@ var lineAnnotation = function lineAnnotation(args) {
2763
2846
 
2764
2847
 
2765
2848
  this.actions = function (state) {
2766
- return continuousVerticesActions(m_this, s_actions, state, 'line', arguments);
2849
+ return continuousVerticesActions(m_this, s_actions, state, 'polygon', arguments);
2767
2850
  };
2768
2851
  /**
2769
2852
  * Process any actions for this annotation.
@@ -2777,7 +2860,7 @@ var lineAnnotation = function lineAnnotation(args) {
2777
2860
 
2778
2861
 
2779
2862
  this.processAction = function (evt) {
2780
- return continuousVerticesProcessAction(m_this, evt, 'line');
2863
+ return continuousVerticesProcessAction(m_this, evt, 'polygon');
2781
2864
  };
2782
2865
  /**
2783
2866
  * Return the coordinates to be stored in a geojson geometry object.
@@ -2792,14 +2875,29 @@ var lineAnnotation = function lineAnnotation(args) {
2792
2875
  this._geojsonCoordinates = function (gcs) {
2793
2876
  var src = m_this.coordinates(gcs);
2794
2877
 
2795
- if (!src || src.length < 2 || m_this.state() === annotationState.create) {
2878
+ if (!src || !src.outer && src.length < 3 || m_this.state() === annotationState.create) {
2796
2879
  return;
2797
2880
  }
2798
2881
 
2799
2882
  var coord = [];
2800
2883
 
2801
- for (var i = 0; i < src.length; i += 1) {
2802
- coord.push([src[i].x, src[i].y]);
2884
+ if (!src.outer) {
2885
+ coord = [src.map(function (pt) {
2886
+ return [pt.x, pt.y];
2887
+ })];
2888
+ coord[0].push(coord[0][0].slice());
2889
+ } else {
2890
+ coord = [src.outer.map(function (pt) {
2891
+ return [pt.x, pt.y];
2892
+ })];
2893
+ coord[0].push(coord[0][0].slice());
2894
+ (src.inner || []).forEach(function (h) {
2895
+ var poly = h.map(function (pt) {
2896
+ return [pt.x, pt.y];
2897
+ });
2898
+ poly.push(poly[0].slice());
2899
+ coord.push(poly);
2900
+ });
2803
2901
  }
2804
2902
 
2805
2903
  return coord;
@@ -2812,7 +2910,7 @@ var lineAnnotation = function lineAnnotation(args) {
2812
2910
 
2813
2911
 
2814
2912
  this._geojsonGeometryType = function () {
2815
- return 'LineString';
2913
+ return 'Polygon';
2816
2914
  };
2817
2915
  /**
2818
2916
  * Return a list of styles that should be preserved in a geojson
@@ -2823,113 +2921,79 @@ var lineAnnotation = function lineAnnotation(args) {
2823
2921
 
2824
2922
 
2825
2923
  this._geojsonStyles = function () {
2826
- return ['closed', 'lineCap', 'lineJoin', 'strokeColor', 'strokeOffset', 'strokeOpacity', 'strokeWidth'];
2827
- };
2828
- /**
2829
- * Process any edit actions for this annotation.
2830
- *
2831
- * @param {geo.event} evt The action event.
2832
- * @returns {boolean|string} `true` to update the annotation, falsy to not
2833
- * update anything.
2834
- */
2835
-
2836
-
2837
- this.processEditAction = function (evt) {
2838
- switch (m_this._editHandle.handle.type) {
2839
- case 'vertex':
2840
- return m_this._processEditActionVertex(evt, true);
2841
- }
2842
-
2843
- return s_processEditAction.apply(m_this, arguments);
2924
+ return ['fill', 'fillColor', 'fillOpacity', 'lineCap', 'lineJoin', 'stroke', 'strokeColor', 'strokeOffset', 'strokeOpacity', 'strokeWidth'];
2844
2925
  };
2845
- /**
2846
- * Handle a mouse click on this annotation when in edit mode. If the event
2847
- * is processed, evt.handled should be set to `true` to prevent further
2848
- * processing.
2849
- *
2850
- * @param {geo.event} evt The mouse click event.
2851
- * @returns {boolean|string} `true` to update the annotation, `'done'` if
2852
- * the annotation was completed (changed from create to done state),
2853
- * `'remove'` if the annotation should be removed, falsy to not update
2854
- * anything.
2855
- */
2926
+ };
2856
2927
 
2928
+ inherit(polygonAnnotation, annotation);
2929
+ var polygonRequiredFeatures = {};
2930
+ polygonRequiredFeatures[polygonFeature.capabilities.feature] = true;
2931
+ polygonRequiredFeatures[lineFeature.capabilities.basic] = [annotationState.create];
2932
+ registerAnnotation('polygon', polygonAnnotation, polygonRequiredFeatures);
2933
+ module.exports = polygonAnnotation;
2857
2934
 
2858
- this.mouseClickEdit = function (evt) {
2859
- // if we get a left double click on an edge on a closed line, break the
2860
- // line at that edge
2861
- var layer = m_this.layer(),
2862
- handle = m_this._editHandle,
2863
- split; // ensure we are in edit mode and this is a left click
2935
+ /***/ }),
2864
2936
 
2865
- if (m_this.state() !== annotationState.edit || !layer || !evt.buttonsDown.left) {
2866
- return;
2867
- } // ensure this is an edge on a closed line
2937
+ /***/ 3442:
2938
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
2868
2939
 
2940
+ var $ = __webpack_require__(5638);
2869
2941
 
2870
- if (!handle || !handle.handle.selected || handle.handle.type !== 'edge' || !m_this.options('style').closed) {
2871
- return;
2872
- }
2942
+ var inherit = __webpack_require__(5699);
2873
2943
 
2874
- evt.handled = true;
2944
+ var geo_event = __webpack_require__(5108);
2875
2945
 
2876
- if (m_this._lastClick && evt.time - m_this._lastClick < layer.options('dblClickTime')) {
2877
- split = true;
2878
- }
2946
+ var geo_action = __webpack_require__(7839);
2879
2947
 
2880
- m_this._lastClick = evt.time;
2948
+ var registerAnnotation = (__webpack_require__(4647).registerAnnotation);
2881
2949
 
2882
- if (split) {
2883
- var index = handle.handle.index,
2884
- curPts = m_this._coordinates(),
2885
- pts = curPts.slice(index + 1).concat(curPts.slice(0, index + 1));
2950
+ var polygonFeature = __webpack_require__(4343);
2886
2951
 
2887
- m_this._coordinates(pts);
2952
+ var annotation = (__webpack_require__(5784).annotation);
2888
2953
 
2889
- m_this.options('style').closed = false;
2890
- handle.handle.index = undefined;
2891
- return true;
2892
- }
2893
- };
2894
- };
2954
+ var annotationState = (__webpack_require__(5784).state);
2895
2955
 
2896
- inherit(lineAnnotation, annotation);
2897
- var lineRequiredFeatures = {};
2898
- lineRequiredFeatures[lineFeature.capabilities.basic] = [annotationState.create];
2899
- registerAnnotation('line', lineAnnotation, lineRequiredFeatures);
2956
+ var annotationActionOwner = (__webpack_require__(5784).annotationActionOwner);
2900
2957
  /**
2901
- * Point annotation specification. Extends {@link geo.annotation.spec}.
2958
+ * Rectangle annotation specification. Extends {@link geo.annotation.spec}.
2902
2959
  *
2903
- * @typedef {object} geo.pointAnnotation.spec
2960
+ * @typedef {object} geo.rectangleAnnotation.spec
2904
2961
  * @extends geo.annotation.spec
2905
- * @property {geo.geoPosition} [position] A coordinate in map gcs coordinates.
2906
- * @property {geo.geoPosition[]} [coordinates] An array with one coordinate to
2907
- * use in place of `position`.
2908
- * @property {geo.pointFeature.styleSpec} [style] The style to apply to a
2909
- * finished point. This uses styles for {@link geo.pointFeature}.
2910
- * @property {boolean|number} [style.scaled=false] If `false`, the point is not
2911
- * scaled with zoom level. If `true`, the radius is based on the zoom level
2912
- * at first instantiation. If a number, the radius is used at the `scaled`
2913
- * zoom level.
2914
- * @property {geo.pointFeature.styleSpec} [editStyle] The style to apply to a
2915
- * point in edit mode.
2962
+ * @property {geo.geoPosition[]} [corners] A list of four corners in map gcs
2963
+ * coordinates. These must be in order around the perimeter of the
2964
+ * rectangle (in either direction).
2965
+ * @property {geo.geoPosition[]} [coordinates] An alternate name for `corners`.
2966
+ * @property {geo.polygonFeature.styleSpec} [style] The style to apply to a
2967
+ * finished rectangle. This uses styles for {@link geo.polygonFeature}.
2968
+ * @property {geo.polygonFeature.styleSpec} [editStyle] The style to apply to a
2969
+ * rectangle in edit mode.
2970
+ * @property {number|number[]|function} [constraint] If specified, an aspect
2971
+ * ratio or list of aspect ratios to constraint the rectangle to. If a
2972
+ * function, a selection constraint function to call to adjust the
2973
+ * rectangle.
2916
2974
  */
2917
2975
 
2918
2976
  /**
2919
- * Point annotation class.
2977
+ * Rectangle annotation class.
2978
+ *
2979
+ * Rectangles are always rendered as polygons. This could be changed -- if no
2980
+ * stroke is specified, the quad feature would be sufficient and work on more
2981
+ * renderers.
2920
2982
  *
2921
2983
  * @class
2922
- * @alias geo.pointAnnotation
2984
+ * @alias geo.rectangleAnnotation
2923
2985
  * @extends geo.annotation
2924
2986
  *
2925
- * @param {geo.pointAnnotation.spec?} [args] Options for the annotation.
2987
+ * @param {geo.rectangleAnnotation.spec?} [args] Options for the annotation.
2988
+ * @param {string} [annotationName='rectangle'] Override the annotation name.
2926
2989
  */
2927
2990
 
2928
- var pointAnnotation = function pointAnnotation(args) {
2991
+
2992
+ var rectangleAnnotation = function rectangleAnnotation(args, annotationName) {
2929
2993
  'use strict';
2930
2994
 
2931
- if (!(this instanceof pointAnnotation)) {
2932
- return new pointAnnotation(args);
2995
+ if (!(this instanceof rectangleAnnotation)) {
2996
+ return new rectangleAnnotation(args, annotationName);
2933
2997
  }
2934
2998
 
2935
2999
  args = $.extend(true, {}, {
@@ -2941,8 +3005,9 @@ var pointAnnotation = function pointAnnotation(args) {
2941
3005
  b: 0
2942
3006
  },
2943
3007
  fillOpacity: 0.25,
2944
- radius: 10,
2945
- scaled: false,
3008
+ polygon: function polygon(d) {
3009
+ return d.polygon;
3010
+ },
2946
3011
  stroke: true,
2947
3012
  strokeColor: {
2948
3013
  r: 0,
@@ -2950,7 +3015,17 @@ var pointAnnotation = function pointAnnotation(args) {
2950
3015
  b: 0
2951
3016
  },
2952
3017
  strokeOpacity: 1,
2953
- strokeWidth: 3
3018
+ strokeWidth: 3,
3019
+ uniformPolygon: true
3020
+ },
3021
+ highlightStyle: {
3022
+ fillColor: {
3023
+ r: 0,
3024
+ g: 1,
3025
+ b: 1
3026
+ },
3027
+ fillOpacity: 0.5,
3028
+ strokeWidth: 5
2954
3029
  },
2955
3030
  createStyle: {
2956
3031
  fillColor: {
@@ -2964,82 +3039,119 @@ var pointAnnotation = function pointAnnotation(args) {
2964
3039
  g: 0,
2965
3040
  b: 1
2966
3041
  }
2967
- },
2968
- highlightStyle: {
2969
- fillColor: {
2970
- r: 0,
2971
- g: 1,
2972
- b: 1
2973
- },
2974
- fillOpacity: 0.5,
2975
- strokeWidth: 5
2976
3042
  }
2977
3043
  }, args || {});
2978
- args.position = args.position || (args.coordinates ? args.coordinates[0] : undefined);
3044
+ args.corners = args.corners || args.coordinates || [];
2979
3045
  delete args.coordinates;
2980
- annotation.call(this, 'point', args);
2981
- var m_this = this;
3046
+ annotation.call(this, annotationName || 'rectangle', args);
3047
+ var m_this = this,
3048
+ s_actions = this.actions,
3049
+ s_processEditAction = this.processEditAction;
2982
3050
  /**
2983
- * Get a list of renderable features for this annotation.
3051
+ * Return actions needed for the specified state of this annotation.
2984
3052
  *
2985
- * @returns {array} An array of features.
3053
+ * @param {string} [state] The state to return actions for. Defaults to
3054
+ * the current state.
3055
+ * @returns {geo.actionRecord[]} A list of actions.
2986
3056
  */
2987
3057
 
2988
- this.features = function () {
2989
- var opt = m_this.options(),
2990
- state = m_this.state(),
2991
- features,
2992
- style,
2993
- scaleOnZoom;
3058
+ this.actions = function (state) {
3059
+ if (!state) {
3060
+ state = m_this.state();
3061
+ }
2994
3062
 
2995
3063
  switch (state) {
2996
3064
  case annotationState.create:
2997
- features = [];
2998
- break;
3065
+ return [{
3066
+ action: geo_action.annotation_rectangle,
3067
+ name: 'rectangle create',
3068
+ owner: annotationActionOwner,
3069
+ input: 'left',
3070
+ modifiers: {
3071
+ shift: false,
3072
+ ctrl: false
3073
+ },
3074
+ selectionRectangle: true,
3075
+ selectionConstraint: this._selectionConstraint
3076
+ }];
2999
3077
 
3000
3078
  default:
3001
- style = m_this.styleForState(state);
3079
+ return s_actions.apply(m_this, arguments);
3080
+ }
3081
+ };
3082
+ /**
3083
+ * Process any actions for this annotation.
3084
+ *
3085
+ * @param {geo.event} evt The action event.
3086
+ * @returns {boolean|string} `true` to update the annotation, `'done'` if the
3087
+ * annotation was completed (changed from create to done state),
3088
+ * `'remove'` if the annotation should be removed, falsy to not update
3089
+ * anything.
3090
+ */
3002
3091
 
3003
- if (opt.style.scaled || opt.style.scaled === 0) {
3004
- if (opt.style.scaled === true) {
3005
- opt.style.scaled = m_this.layer().map().zoom();
3006
- }
3007
3092
 
3008
- style = $.extend({}, style, {
3009
- radius: function radius() {
3010
- var radius = opt.style.radius,
3011
- zoom = m_this.layer().map().zoom();
3093
+ this.processAction = function (evt) {
3094
+ var layer = m_this.layer();
3012
3095
 
3013
- if (util.isFunction(radius)) {
3014
- radius = radius.apply(m_this, arguments);
3015
- }
3096
+ if (m_this.state() !== annotationState.create || !layer || evt.event !== geo_event.actionselection || evt.state.action !== geo_action.annotation_rectangle) {
3097
+ return;
3098
+ }
3099
+
3100
+ var map = layer.map(),
3101
+ corners = [
3102
+ /* Keep in map gcs, not interface gcs to avoid wrapping issues */
3103
+ map.displayToGcs({
3104
+ x: evt.lowerLeft.x,
3105
+ y: evt.lowerLeft.y
3106
+ }, null), map.displayToGcs({
3107
+ x: evt.lowerLeft.x,
3108
+ y: evt.upperRight.y
3109
+ }, null), map.displayToGcs({
3110
+ x: evt.upperRight.x,
3111
+ y: evt.upperRight.y
3112
+ }, null), map.displayToGcs({
3113
+ x: evt.upperRight.x,
3114
+ y: evt.lowerLeft.y
3115
+ }, null)];
3116
+
3117
+ if (this._selectionConstraint && evt.mouse && evt.state.origin) {
3118
+ this._selectionConstraint(evt.mouse.mapgcs, evt.state.origin.mapgcs, corners);
3119
+ }
3120
+ /* Don't keep rectangles that have nearly zero area in display pixels */
3121
+
3122
+
3123
+ if (layer.displayDistance(corners[0], null, corners[1], null) * layer.displayDistance(corners[0], null, corners[3], null) < 0.01) {
3124
+ return 'remove';
3125
+ }
3126
+
3127
+ m_this.options('corners', corners);
3128
+ m_this.state(annotationState.done);
3129
+ return 'done';
3130
+ };
3131
+ /**
3132
+ * Get a list of renderable features for this annotation.
3133
+ *
3134
+ * @returns {array} An array of features.
3135
+ */
3016
3136
 
3017
- radius *= Math.pow(2, zoom - opt.style.scaled);
3018
- return radius;
3019
- }
3020
- });
3021
- scaleOnZoom = true;
3022
- }
3023
3137
 
3024
- features = [{
3025
- point: {
3026
- x: opt.position.x,
3027
- y: opt.position.y,
3028
- style: style,
3029
- scaleOnZoom: scaleOnZoom
3030
- }
3031
- }];
3138
+ this.features = function () {
3139
+ var opt = m_this.options(),
3140
+ state = m_this.state(),
3141
+ features;
3142
+ features = [];
3032
3143
 
3033
- if (state === annotationState.edit) {
3034
- m_this._addEditHandles(features, [opt.position], {
3035
- edge: false,
3036
- center: false,
3037
- resize: false,
3038
- rotate: false
3039
- });
3144
+ if (opt.corners && opt.corners.length >= 4) {
3145
+ features = [{
3146
+ polygon: {
3147
+ polygon: opt.corners,
3148
+ style: m_this.styleForState(state)
3040
3149
  }
3150
+ }];
3151
+ }
3041
3152
 
3042
- break;
3153
+ if (state === annotationState.edit) {
3154
+ m_this._addEditHandles(features, opt.corners);
3043
3155
  }
3044
3156
 
3045
3157
  return features;
@@ -3055,42 +3167,50 @@ var pointAnnotation = function pointAnnotation(args) {
3055
3167
 
3056
3168
 
3057
3169
  this._coordinates = function (coordinates) {
3058
- if (coordinates && coordinates.length >= 1) {
3059
- m_this.options('position', coordinates[0]);
3060
- }
3061
-
3062
- if (m_this.state() === annotationState.create) {
3063
- return [];
3170
+ if (coordinates && coordinates.length >= 4) {
3171
+ m_this.options('corners', coordinates.slice(0, 4));
3172
+ /* Should we ensure that the four points form a rectangle in the current
3173
+ * projection, though this might not be rectangular in another gcs? */
3064
3174
  }
3065
3175
 
3066
- return [m_this.options('position')];
3176
+ return m_this.options('corners');
3067
3177
  };
3068
3178
 
3069
- this._coordinateOption = 'position';
3179
+ this._coordinateOption = 'corners';
3070
3180
  /**
3071
- * Handle a mouse click on this annotation. If the event is processed,
3072
- * evt.handled should be set to `true` to prevent further processing.
3181
+ * Return the coordinates to be stored in a geojson geometry object.
3073
3182
  *
3074
- * @param {geo.event} evt The mouse click event.
3075
- * @returns {boolean|string} `true` to update the annotation, `'done'` if
3076
- * the annotation was completed (changed from create to done state),
3077
- * `'remove'` if the annotation should be removed, falsy to not update
3078
- * anything.
3183
+ * @param {string|geo.transform|null} [gcs] `undefined` to use the interface
3184
+ * gcs, `null` to use the map gcs, or any other transform.
3185
+ * @returns {array} An array of flattened coordinates in the interface gcs
3186
+ * coordinate system. `undefined` if this annotation is incomplete.
3079
3187
  */
3080
3188
 
3081
- this.mouseClick = function (evt) {
3082
- if (m_this.state() !== annotationState.create) {
3189
+ this._geojsonCoordinates = function (gcs) {
3190
+ var src = m_this.coordinates(gcs);
3191
+
3192
+ if (!src || m_this.state() === annotationState.create || src.length < 4) {
3083
3193
  return;
3084
3194
  }
3085
3195
 
3086
- if (!evt.buttonsDown.left) {
3087
- return;
3196
+ var coord = [];
3197
+
3198
+ for (var i = 0; i < 4; i += 1) {
3199
+ coord.push([src[i].x, src[i].y]);
3088
3200
  }
3089
3201
 
3090
- evt.handled = true;
3091
- m_this.options('position', evt.mapgcs);
3092
- m_this.state(annotationState.done);
3093
- return 'done';
3202
+ coord.push([src[0].x, src[0].y]);
3203
+ return [coord];
3204
+ };
3205
+ /**
3206
+ * Return the geometry type that is used to store this annotation in geojson.
3207
+ *
3208
+ * @returns {string} A geojson geometry type.
3209
+ */
3210
+
3211
+
3212
+ this._geojsonGeometryType = function () {
3213
+ return 'Polygon';
3094
3214
  };
3095
3215
  /**
3096
3216
  * Return a list of styles that should be preserved in a geojson
@@ -3101,207 +3221,269 @@ var pointAnnotation = function pointAnnotation(args) {
3101
3221
 
3102
3222
 
3103
3223
  this._geojsonStyles = function () {
3104
- return ['fill', 'fillColor', 'fillOpacity', 'radius', 'scaled', 'stroke', 'strokeColor', 'strokeOpacity', 'strokeWidth'];
3224
+ return ['fill', 'fillColor', 'fillOpacity', 'lineCap', 'lineJoin', 'stroke', 'strokeColor', 'strokeOffset', 'strokeOpacity', 'strokeWidth'];
3105
3225
  };
3106
3226
  /**
3107
- * Return the coordinates to be stored in a geojson geometry object.
3227
+ * Set three corners based on an initial corner and a mouse event.
3108
3228
  *
3109
- * @param {string|geo.transform|null} [gcs] `undefined` to use the interface
3110
- * gcs, `null` to use the map gcs, or any other transform.
3111
- * @returns {array} An array of flattened coordinates in the interface gcs
3112
- * coordinate system. `undefined` if this annotation is incomplete.
3229
+ * @param {geo.geoPosition} corners An array of four corners to update.
3230
+ * @param {geo.event} evt The mouse move event.
3113
3231
  */
3114
3232
 
3115
3233
 
3116
- this._geojsonCoordinates = function (gcs) {
3117
- var src = m_this.coordinates(gcs);
3234
+ this._setCornersFromMouse = function (corners, evt) {
3235
+ var map = m_this.layer().map(),
3236
+ c0 = map.gcsToDisplay({
3237
+ x: corners[0].x,
3238
+ y: corners[0].y
3239
+ }, null),
3240
+ c2 = map.gcsToDisplay(evt.mapgcs, null),
3241
+ c1 = {
3242
+ x: c2.x,
3243
+ y: c0.y
3244
+ },
3245
+ c3 = {
3246
+ x: c0.x,
3247
+ y: c2.y
3248
+ };
3249
+ corners[2] = $.extend({}, evt.mapgcs);
3250
+ corners[1] = map.displayToGcs(c1, null);
3251
+ corners[3] = map.displayToGcs(c3, null);
3118
3252
 
3119
- if (!src || m_this.state() === annotationState.create || src.length < 1 || src[0] === undefined) {
3253
+ if (this._selectionConstraint) {
3254
+ this._selectionConstraint(evt.mapgcs, corners[0], corners);
3255
+ }
3256
+ };
3257
+ /**
3258
+ * Handle a mouse move on this annotation.
3259
+ *
3260
+ * @param {geo.event} evt The mouse move event.
3261
+ * @returns {boolean} Truthy to update the annotation, falsy to not
3262
+ * update anything.
3263
+ */
3264
+
3265
+
3266
+ this.mouseMove = function (evt) {
3267
+ if (m_this.state() !== annotationState.create) {
3120
3268
  return;
3121
3269
  }
3122
3270
 
3123
- return [src[0].x, src[0].y];
3271
+ var corners = m_this.options('corners');
3272
+
3273
+ if (corners.length) {
3274
+ m_this._setCornersFromMouse(corners, evt);
3275
+
3276
+ return true;
3277
+ }
3124
3278
  };
3125
3279
  /**
3126
- * Return the geometry type that is used to store this annotation in geojson.
3280
+ * Handle a mouse click on this annotation. If the event is processed,
3281
+ * evt.handled should be set to `true` to prevent further processing.
3127
3282
  *
3128
- * @returns {string} A geojson geometry type.
3283
+ * @param {geo.event} evt The mouse click event.
3284
+ * @returns {boolean|string} `true` to update the annotation, `'done'` if
3285
+ * the annotation was completed (changed from create to done state),
3286
+ * `'remove'` if the annotation should be removed, falsy to not update
3287
+ * anything.
3129
3288
  */
3130
3289
 
3131
3290
 
3132
- this._geojsonGeometryType = function () {
3133
- return 'Point';
3134
- };
3135
- };
3291
+ this.mouseClick = function (evt) {
3292
+ var layer = m_this.layer();
3136
3293
 
3137
- inherit(pointAnnotation, annotation);
3138
- var pointRequiredFeatures = {};
3139
- pointRequiredFeatures[pointFeature.capabilities.feature] = true;
3140
- registerAnnotation('point', pointAnnotation, pointRequiredFeatures);
3141
- /**
3142
- * Return a function that can be used as a selectionConstraint that requires
3143
- * that the aspect ratio of a rectangle-like selection is a specific value or
3144
- * range of values.
3145
- *
3146
- * @param {number|number[]} ratio Either a single aspect ratio or a list of
3147
- * allowed aspect ratios. For instance, 1 will require that the selection
3148
- * square, 2 would require that it is twice as wide as tall, [2, 1/2] would
3149
- * allow it to be twice as wide or half as wide as it is tall.
3150
- * @returns {function} A function that can be passed to the mapIterator
3151
- * selectionConstraint or to an annotation constraint function.
3152
- */
3294
+ if (m_this.state() !== annotationState.create || !layer) {
3295
+ return;
3296
+ }
3153
3297
 
3154
- function constrainAspectRatio(ratio) {
3155
- var ratios = Array.isArray(ratio) ? ratio : [ratio];
3298
+ if (!evt.buttonsDown.left && !evt.buttonsDown.right) {
3299
+ return;
3300
+ }
3301
+
3302
+ var corners = m_this.options('corners');
3303
+
3304
+ if (evt.buttonsDown.right && !corners.length) {
3305
+ return;
3306
+ }
3307
+
3308
+ evt.handled = true;
3309
+
3310
+ if (corners.length) {
3311
+ m_this._setCornersFromMouse(corners, evt);
3312
+ /* Don't keep rectangles that have nearly zero area in display pixels */
3313
+
3314
+
3315
+ if (layer.displayDistance(corners[0], null, corners[1], null) * layer.displayDistance(corners[0], null, corners[3], null) < 0.01) {
3316
+ return 'remove';
3317
+ }
3318
+
3319
+ m_this.state(annotationState.done);
3320
+ return 'done';
3321
+ }
3322
+
3323
+ if (evt.buttonsDown.left) {
3324
+ corners.push($.extend({}, evt.mapgcs));
3325
+ corners.push($.extend({}, evt.mapgcs));
3326
+ corners.push($.extend({}, evt.mapgcs));
3327
+ corners.push($.extend({}, evt.mapgcs));
3328
+ return true;
3329
+ }
3330
+ };
3156
3331
  /**
3157
- * Constrain a mouse action or annotation action to a list of aspect ratios.
3332
+ * Process any edit actions for this annotation.
3158
3333
  *
3159
- * @param {geo.geoPosition} pos Mouse or new location in map gcs.
3160
- * @param {geo.geoPosition} origin Origin in map gcs when the activity
3161
- * started.
3162
- * @param {geo.geoPosition} [corners] If specified, an array of corner
3163
- * locations in mapgcs. This may be modified.
3164
- * @param {string?} [mode] 'edge', 'vertex' or falsy. A falsy value implies
3165
- * this is just the most recent point in the annotation, otherwise it is
3166
- * the portion of the annotation being modified.
3167
- * @param {number} [ang] A list of angles of each side of the polygon
3168
- * represented by corners or the original annotation.
3169
- * @param {integer} [index] The specific vertex or edge that is being
3170
- * modified.
3171
- * @returns {object} An object with the ``origin`` (this is what is passed
3172
- * in), a new position as ``pos``, and the updated corners as ``corners``.
3334
+ * @param {geo.event} evt The action event.
3335
+ * @returns {boolean|string} `true` to update the annotation, falsy to not
3336
+ * update anything.
3173
3337
  */
3174
3338
 
3175
- function constraintFunction(pos, origin, corners, mode, ang, index) {
3176
- var newpos = pos;
3177
- var best;
3178
3339
 
3179
- if (!corners) {
3180
- corners = [{
3181
- x: origin.x,
3182
- y: origin.y
3183
- }, {
3184
- x: pos.x,
3185
- y: origin.y
3186
- }, {
3187
- x: pos.x,
3188
- y: pos.y
3189
- }, {
3190
- x: origin.x,
3191
- y: pos.y
3192
- }];
3340
+ this.processEditAction = function (evt) {
3341
+ var start = m_this._editHandle.startCoordinates,
3342
+ delta = {
3343
+ x: evt.mouse.mapgcs.x - evt.state.origin.mapgcs.x,
3344
+ y: evt.mouse.mapgcs.y - evt.state.origin.mapgcs.y
3345
+ },
3346
+ type = m_this._editHandle.handle.type,
3347
+ index = m_this._editHandle.handle.index,
3348
+ ang = [Math.atan2(start[1].y - start[0].y, start[1].x - start[0].x), Math.atan2(start[2].y - start[1].y, start[2].x - start[1].x), Math.atan2(start[3].y - start[2].y, start[3].x - start[2].x), Math.atan2(start[0].y - start[3].y, start[0].x - start[3].x)],
3349
+ corners,
3350
+ delta1,
3351
+ delta2,
3352
+ ang1,
3353
+ ang2; // an angle can be zero because it is horizontal or undefined. If opposite
3354
+ // angles are both zero, this is a degenerate rectangle (a line or a point)
3355
+
3356
+ if (!ang[0] && !ang[1] && !ang[2] && !ang[3]) {
3357
+ ang[1] = Math.PI / 2;
3358
+ ang[2] = Math.PI;
3359
+ ang[3] = -Math.PI / 2;
3193
3360
  }
3194
3361
 
3195
- if (mode) {
3196
- /* Edit a vertex or edge */
3197
- var i1 = (index + 1) % 4;
3198
- var i2 = (index + 2) % 4;
3199
- var i3 = (index + 3) % 4;
3200
- var dist1 = Math.pow(Math.pow(corners[index].x - corners[i1].x, 2) + Math.pow(corners[index].y - corners[i1].y, 2), 0.5);
3201
- var dist3 = Math.pow(Math.pow(corners[index].x - corners[i3].x, 2) + Math.pow(corners[index].y - corners[i3].y, 2), 0.5);
3202
- var area = Math.abs(dist1 * dist3);
3203
- var shape, edge;
3204
- ratios.forEach(function (ratio) {
3205
- if (ratio !== 1 && !(index % 2)) {
3206
- ratio = 1.0 / ratio;
3207
- }
3362
+ if (!ang[0] && !ang[2]) {
3363
+ ang[0] = ang[1] - Math.PI / 2;
3364
+ ang[2] = ang[1] + Math.PI / 2;
3365
+ }
3208
3366
 
3209
- var width = Math.pow(area * ratio, 0.5);
3210
- var score = Math.pow(width - dist3, 2) + Math.pow(width / ratio - dist1, 2);
3367
+ if (!ang[1] && !ang[3]) {
3368
+ ang[1] = ang[2] - Math.PI / 2;
3369
+ ang[3] = ang[2] + Math.PI / 2;
3370
+ }
3211
3371
 
3212
- if (best === undefined || score < best) {
3213
- best = score;
3214
- shape = {
3215
- w: width,
3216
- h: width / ratio
3372
+ switch (type) {
3373
+ case 'vertex':
3374
+ corners = start.map(function (elem) {
3375
+ return {
3376
+ x: elem.x,
3377
+ y: elem.y
3217
3378
  };
3379
+ });
3380
+ ang1 = ang[(index + 1) % 4];
3381
+ delta1 = {
3382
+ x: (delta.x * Math.cos(ang1) + delta.y * Math.sin(ang1)) * Math.cos(ang1),
3383
+ y: (delta.y * Math.sin(ang1) + delta.x * Math.cos(ang1)) * Math.sin(ang1)
3384
+ };
3385
+ ang2 = ang[index];
3386
+ delta2 = {
3387
+ x: (delta.x * Math.cos(ang2) + delta.y * Math.sin(ang2)) * Math.cos(ang2),
3388
+ y: (delta.y * Math.sin(ang2) + delta.x * Math.cos(ang2)) * Math.sin(ang2)
3389
+ };
3390
+ corners[index].x += delta.x;
3391
+ corners[index].y += delta.y;
3392
+ corners[(index + 1) % 4].x += delta1.x;
3393
+ corners[(index + 1) % 4].y += delta1.y;
3394
+ corners[(index + 3) % 4].x += delta2.x;
3395
+ corners[(index + 3) % 4].y += delta2.y;
3396
+
3397
+ if (this._selectionConstraint) {
3398
+ corners = this._selectionConstraint(evt.mouse.mapgcs, evt.state.origin.mapgcs, corners, 'vertex', ang, index).corners;
3218
3399
  }
3219
- });
3220
- var ang1 = ang[i1];
3221
- var delta1 = {
3222
- x: -shape.w * Math.cos(ang1),
3223
- y: -shape.w * Math.sin(ang1)
3224
- };
3225
- var ang2 = ang[index];
3226
- var delta2 = {
3227
- x: -shape.h * Math.cos(ang2),
3228
- y: -shape.h * Math.sin(ang2)
3229
- };
3230
3400
 
3231
- switch (mode) {
3232
- case 'vertex':
3233
- corners[index].x = corners[i2].x + delta1.x + delta2.x;
3234
- corners[index].y = corners[i2].y + delta1.y + delta2.y;
3235
- corners[i1].x = corners[i2].x + delta1.x;
3236
- corners[i1].y = corners[i2].y + delta1.y;
3237
- corners[i3].x = corners[i2].x + delta2.x;
3238
- corners[i3].y = corners[i2].y + delta2.y;
3239
- break;
3401
+ m_this.options('corners', corners);
3402
+ return true;
3240
3403
 
3241
- case 'edge':
3242
- edge = {
3243
- x: (corners[i2].x + corners[i3].x) * 0.5,
3244
- y: (corners[i2].y + corners[i3].y) * 0.5
3404
+ case 'edge':
3405
+ corners = start.map(function (elem) {
3406
+ return {
3407
+ x: elem.x,
3408
+ y: elem.y
3245
3409
  };
3246
- corners[i2].x = edge.x + delta2.x / 2;
3247
- corners[i2].y = edge.y + delta2.y / 2;
3248
- corners[index].x = edge.x + delta1.x - delta2.x / 2;
3249
- corners[index].y = edge.y + delta1.y - delta2.y / 2;
3250
- corners[i1].x = edge.x + delta1.x + delta2.x / 2;
3251
- corners[i1].y = edge.y + delta1.y + delta2.y / 2;
3252
- corners[i3].x = edge.x - delta2.x / 2;
3253
- corners[i3].y = edge.y - delta2.y / 2;
3254
- break;
3255
- }
3256
- } else {
3257
- /* Not in edit vertex or edge mode */
3258
- var _area = Math.abs((pos.x - origin.x) * (pos.y - origin.y));
3259
-
3260
- ratios.forEach(function (ratio) {
3261
- var width = Math.pow(_area * ratio, 0.5);
3262
- var adjusted = {
3263
- x: origin.x + Math.sign(pos.x - origin.x) * width,
3264
- y: origin.y + Math.sign(pos.y - origin.y) * width / ratio
3410
+ });
3411
+ ang1 = ang[(index + 1) % 4];
3412
+ delta = {
3413
+ x: (delta.x * Math.cos(ang1) + delta.y * Math.sin(ang1)) * Math.cos(ang1),
3414
+ y: (delta.y * Math.sin(ang1) + delta.x * Math.cos(ang1)) * Math.sin(ang1)
3265
3415
  };
3266
- var score = Math.pow(adjusted.x - pos.x, 2) + Math.pow(adjusted.y - pos.y, 2);
3416
+ corners[index].x += delta.x;
3417
+ corners[index].y += delta.y;
3418
+ corners[(index + 1) % 4].x += delta.x;
3419
+ corners[(index + 1) % 4].y += delta.y;
3267
3420
 
3268
- if (best === undefined || score < best) {
3269
- best = score;
3270
- newpos = adjusted;
3421
+ if (this._selectionConstraint) {
3422
+ corners = this._selectionConstraint(evt.mouse.mapgcs, evt.state.origin.mapgcs, corners, 'edge', ang, index).corners;
3271
3423
  }
3272
- });
3273
- corners[0].y = corners[1].y = origin.y;
3274
- corners[0].x = corners[3].x = origin.x;
3275
- corners[1].x = corners[2].x = newpos.x;
3276
- corners[2].y = corners[3].y = newpos.y;
3424
+
3425
+ m_this.options('corners', corners);
3426
+ return true;
3277
3427
  }
3278
3428
 
3279
- return {
3280
- corners: corners,
3281
- origin: origin,
3282
- pos: newpos
3283
- };
3284
- }
3429
+ return s_processEditAction.apply(m_this, arguments);
3430
+ };
3431
+ };
3285
3432
 
3286
- return constraintFunction;
3287
- }
3433
+ inherit(rectangleAnnotation, annotation);
3434
+ var rectangleRequiredFeatures = {};
3435
+ rectangleRequiredFeatures[polygonFeature.capabilities.feature] = true;
3436
+ registerAnnotation('rectangle', rectangleAnnotation, rectangleRequiredFeatures);
3437
+ module.exports = rectangleAnnotation;
3288
3438
 
3289
- module.exports = {
3290
- state: annotationState,
3291
- actionOwner: annotationActionOwner,
3292
- annotation: annotation,
3293
- lineAnnotation: lineAnnotation,
3294
- pointAnnotation: pointAnnotation,
3295
- polygonAnnotation: polygonAnnotation,
3296
- rectangleAnnotation: rectangleAnnotation,
3297
- squareAnnotation: squareAnnotation,
3298
- ellipseAnnotation: ellipseAnnotation,
3299
- circleAnnotation: circleAnnotation,
3300
- _editHandleFeatureLevel: editHandleFeatureLevel,
3301
- defaultEditHandleStyle: defaultEditHandleStyle,
3302
- constrainAspectRatio: constrainAspectRatio
3439
+ /***/ }),
3440
+
3441
+ /***/ 4932:
3442
+ /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
3443
+
3444
+ var $ = __webpack_require__(5638);
3445
+
3446
+ var inherit = __webpack_require__(5699);
3447
+
3448
+ var registerAnnotation = (__webpack_require__(4647).registerAnnotation);
3449
+
3450
+ var polygonFeature = __webpack_require__(4343);
3451
+
3452
+ var rectangleAnnotation = __webpack_require__(3442);
3453
+ /**
3454
+ * Square annotation class.
3455
+ *
3456
+ * Squares are a subset of rectangles with a fixed aspect ratio.
3457
+ *
3458
+ * @class
3459
+ * @alias geo.squareAnnotation
3460
+ * @extends geo.annotation
3461
+ *
3462
+ * @param {geo.squareAnnotation.spec?} [args] Options for the annotation.
3463
+ * @param {string} [annotationName='square'] Override the annotation name.
3464
+ */
3465
+
3466
+
3467
+ var squareAnnotation = function squareAnnotation(args, annotationName) {
3468
+ 'use strict';
3469
+
3470
+ args = $.extend({}, args, {
3471
+ constraint: 1
3472
+ });
3473
+
3474
+ if (!(this instanceof squareAnnotation)) {
3475
+ return new squareAnnotation(args, annotationName);
3476
+ }
3477
+
3478
+ rectangleAnnotation.call(this, args, annotationName || 'square');
3303
3479
  };
3304
3480
 
3481
+ inherit(squareAnnotation, rectangleAnnotation);
3482
+ var squareRequiredFeatures = {};
3483
+ squareRequiredFeatures[polygonFeature.capabilities.feature] = true;
3484
+ registerAnnotation('square', squareAnnotation, squareRequiredFeatures);
3485
+ module.exports = squareAnnotation;
3486
+
3305
3487
  /***/ }),
3306
3488
 
3307
3489
  /***/ 836:
@@ -3311,7 +3493,7 @@ var inherit = __webpack_require__(5699);
3311
3493
 
3312
3494
  var featureLayer = __webpack_require__(3715);
3313
3495
 
3314
- var geo_annotation = __webpack_require__(7800);
3496
+ var geo_annotation = __webpack_require__(4213);
3315
3497
 
3316
3498
  var geo_event = __webpack_require__(5108);
3317
3499
 
@@ -11860,9 +12042,7 @@ var graphFeature = function graphFeature(arg) {
11860
12042
 
11861
12043
  }, arg.style === undefined ? {} : arg.style);
11862
12044
  m_this.style(defaultStyle);
11863
- m_this.nodes(function (d) {
11864
- return d;
11865
- });
12045
+ m_this.nodes(util.identityFunction);
11866
12046
  return m_this;
11867
12047
  };
11868
12048
  /**
@@ -12284,6 +12464,8 @@ var inherit = __webpack_require__(5699);
12284
12464
  var feature = __webpack_require__(6837);
12285
12465
 
12286
12466
  var transform = __webpack_require__(6853);
12467
+
12468
+ var util = __webpack_require__(4634);
12287
12469
  /**
12288
12470
  * Heatmap feature specification.
12289
12471
  *
@@ -12362,10 +12544,7 @@ var heatmapFeature = function heatmapFeature(arg) {
12362
12544
  m_gcsPosition,
12363
12545
  s_init = this._init;
12364
12546
  this.featureType = 'heatmap';
12365
-
12366
- m_position = arg.position || function (d) {
12367
- return d;
12368
- };
12547
+ m_position = arg.position || util.identityFunction;
12369
12548
 
12370
12549
  m_intensity = arg.intensity || function (d) {
12371
12550
  return 1;
@@ -12816,7 +12995,6 @@ $.htmlPrefilter = function (html) {
12816
12995
  __webpack_require__(8701);
12817
12996
 
12818
12997
  module.exports = $.extend({
12819
- annotation: __webpack_require__(7800),
12820
12998
  annotationLayer: __webpack_require__(836),
12821
12999
  camera: __webpack_require__(9986),
12822
13000
  choroplethFeature: __webpack_require__(8719),
@@ -12862,6 +13040,7 @@ module.exports = $.extend({
12862
13040
  inherit: __webpack_require__(5699),
12863
13041
  version: __webpack_require__(2978),
12864
13042
  sha: __webpack_require__(5381),
13043
+ annotation: __webpack_require__(4213),
12865
13044
  util: __webpack_require__(4634),
12866
13045
  jQuery: $,
12867
13046
  canvas: __webpack_require__(7562),
@@ -15486,12 +15665,8 @@ var lineFeature = function lineFeature(arg) {
15486
15665
  });
15487
15666
  /* Set the reduced lines as the data and use simple accessors. */
15488
15667
 
15489
- m_this.style('position', function (d) {
15490
- return d;
15491
- });
15492
- m_this.style('line', function (d) {
15493
- return d;
15494
- });
15668
+ m_this.style('position', util.identityFunction);
15669
+ m_this.style('line', util.identityFunction);
15495
15670
  m_this.data(data);
15496
15671
  return m_this;
15497
15672
  };
@@ -15519,9 +15694,7 @@ var lineFeature = function lineFeature(arg) {
15519
15694
  // Values of 2 and above appear smoothest.
15520
15695
  antialiasing: 2.0,
15521
15696
  closed: false,
15522
- line: function line(d) {
15523
- return d;
15524
- },
15697
+ line: util.identityFunction,
15525
15698
  position: function position(d) {
15526
15699
  return Array.isArray(d) ? {
15527
15700
  x: d[0],
@@ -23142,9 +23315,7 @@ var pixelmapFeature = function pixelmapFeature(arg) {
23142
23315
  a: 1
23143
23316
  };
23144
23317
  },
23145
- position: function position(d) {
23146
- return d;
23147
- }
23318
+ position: util.identityFunction
23148
23319
  }, arg.style === undefined ? {} : arg.style);
23149
23320
 
23150
23321
  if (arg.position !== undefined) {
@@ -24840,12 +25011,8 @@ var polygonFeature = function polygonFeature(arg) {
24840
25011
  });
24841
25012
  /* Set the reduced polgons as the data and use simple accessors. */
24842
25013
 
24843
- m_this.style('position', function (d) {
24844
- return d;
24845
- });
24846
- m_this.style('polygon', function (d) {
24847
- return d;
24848
- });
25014
+ m_this.style('position', util.identityFunction);
25015
+ m_this.style('polygon', util.identityFunction);
24849
25016
  m_this.data(data);
24850
25017
  return m_this;
24851
25018
  };
@@ -24941,9 +25108,7 @@ var polygonFeature = function polygonFeature(arg) {
24941
25108
  b: 1.0
24942
25109
  },
24943
25110
  strokeOpacity: 1.0,
24944
- polygon: function polygon(d) {
24945
- return d;
24946
- },
25111
+ polygon: util.identityFunction,
24947
25112
  position: function position(d) {
24948
25113
  return Array.isArray(d) ? {
24949
25114
  x: d[0],
@@ -25832,9 +25997,7 @@ var quadFeature = function quadFeature(arg) {
25832
25997
  video: function video(d) {
25833
25998
  return d.video;
25834
25999
  },
25835
- position: function position(d) {
25836
- return d;
25837
- }
26000
+ position: util.identityFunction
25838
26001
  }, arg.style === undefined ? {} : arg.style);
25839
26002
 
25840
26003
  if (arg.position !== undefined) {
@@ -26871,7 +27034,7 @@ module.exports = sceneObject;
26871
27034
  * @constant
26872
27035
  * @type {string}
26873
27036
  */
26874
- module.exports = "c8c9edda606de6cb2990b41bfdfe2c4a82c885cb";
27037
+ module.exports = "e4988e06092d4bee858b11f2d0109a6bfe77dfbb";
26875
27038
 
26876
27039
  /***/ }),
26877
27040
 
@@ -32745,12 +32908,8 @@ var trackFeature = function trackFeature(arg) {
32745
32908
  arg = arg || {};
32746
32909
  s_init.call(m_this, arg);
32747
32910
  var style = $.extend(true, {}, {
32748
- track: function track(d) {
32749
- return d;
32750
- },
32751
- position: function position(d) {
32752
- return d;
32753
- },
32911
+ track: util.identityFunction,
32912
+ position: util.identityFunction,
32754
32913
  time: function time(d, i) {
32755
32914
  return d.t !== undefined ? d.t : i;
32756
32915
  }
@@ -32825,7 +32984,7 @@ var maxTransformCacheSize = 10;
32825
32984
  /* A RegExp to detect if two transforms only different by the middle axis's
32826
32985
  * direction. */
32827
32986
 
32828
- var axisPattern = /^(.* |)\\+axis=e(n|s)u(| .*)$/;
32987
+ var axisPattern = /^(.* |)\+axis=e(n|s)u(| .*)$/;
32829
32988
  var affinePattern = /(^|\s)\+(s[1-3][1-3]|[xyz]off)=\S/;
32830
32989
  /**
32831
32990
  * This purpose of this class is to provide a generic interface for computing
@@ -33739,6 +33898,22 @@ transform.vincentyDistance = function (pt1, pt2, gcs, baseGcs, ellipsoid, maxIte
33739
33898
  alpha2: Math.atan2(cosU1 * Math.sin(lambda), -sinU1 * cosU2 + cosU1 * sinU2 * Math.cos(lambda))
33740
33899
  };
33741
33900
  };
33901
+ /**
33902
+ * Return a boolean indicating if the projections only differ in their y
33903
+ * coordinate.
33904
+ *
33905
+ * @param {string} srcPrj The source projection.
33906
+ * @param {string} tgtPrj The destination projection.
33907
+ * @returns {boolean} truthy if only the y coordinate is different between
33908
+ * projections.
33909
+ */
33910
+
33911
+
33912
+ transform.onlyInvertedY = function (srcPrj, tgtPrj) {
33913
+ var smatch = srcPrj.match(axisPattern),
33914
+ tmatch = tgtPrj.match(axisPattern);
33915
+ return smatch && tmatch && smatch[1] === tmatch[1] && smatch[3] === tmatch[3];
33916
+ };
33742
33917
  /* Expose proj4 to make it easier to debug */
33743
33918
 
33744
33919
 
@@ -33826,6 +34001,15 @@ module.exports = transform;
33826
34001
  * @property {number} [z=0] Altitude coordinate, often zero.
33827
34002
  */
33828
34003
 
34004
+ /**
34005
+ * Represention of a size in gcs coordinates.
34006
+ *
34007
+ * @typedef geo.geoSize
34008
+ * @type {object}
34009
+ * @property {number} width Width in gcs coordinates.
34010
+ * @property {number} height Height in gcs coordinates.
34011
+ */
34012
+
33829
34013
  /**
33830
34014
  * Represention of a size in pixels.
33831
34015
  *
@@ -38372,6 +38556,17 @@ var util = {
38372
38556
 
38373
38557
  return value !== null && value !== undefined && (type === 'object' || type === 'function');
38374
38558
  },
38559
+
38560
+ /**
38561
+ * Return the first value passed to the function. Using this function for
38562
+ * identity calls can allow some code to bypass making such a call entirely.
38563
+ *
38564
+ * @param {*} d Any value.
38565
+ * @returns {*} The passed value.
38566
+ */
38567
+ identityFunction: function identityFunction(d) {
38568
+ return d;
38569
+ },
38375
38570
  ///////////////////////////////////////////////////////////////////////////
38376
38571
 
38377
38572
  /*
@@ -39201,6 +39396,8 @@ module.exports = {
39201
39396
  var inherit = __webpack_require__(5699);
39202
39397
 
39203
39398
  var feature = __webpack_require__(6837);
39399
+
39400
+ var util = __webpack_require__(4634);
39204
39401
  /**
39205
39402
  * Object specification for a graph feature.
39206
39403
  *
@@ -39327,9 +39524,7 @@ var vectorFeature = function vectorFeature(arg) {
39327
39524
  y: 0,
39328
39525
  z: 0
39329
39526
  },
39330
- delta: function delta(d) {
39331
- return d;
39332
- },
39527
+ delta: util.identityFunction,
39333
39528
  scale: null // size scaling factor (null -> renderer decides)
39334
39529
 
39335
39530
  }, arg.style === undefined ? {} : arg.style);
@@ -39361,7 +39556,7 @@ module.exports = vectorFeature;
39361
39556
  * @constant
39362
39557
  * @type {string}
39363
39558
  */
39364
- module.exports = "1.8.5";
39559
+ module.exports = "1.8.8";
39365
39560
 
39366
39561
  /***/ }),
39367
39562
 
@@ -40592,6 +40787,9 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40592
40787
  negStrokeOffset: 0
40593
40788
  }],
40594
40789
  v = vert[1],
40790
+ target_gcs = m_this.gcs(),
40791
+ map_gcs = m_this.layer().map().gcs(),
40792
+ simpleInverse = transform.onlyInvertedY(target_gcs, map_gcs),
40595
40793
  pos,
40596
40794
  posIdx3,
40597
40795
  firstpos,
@@ -40655,6 +40853,7 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40655
40853
  if (!onlyStyle) {
40656
40854
  var position = [],
40657
40855
  posFunc = m_this.position();
40856
+ posFunc = posFunc === util.identityFunction ? null : posFunc;
40658
40857
  lineItemList = new Array(data.length);
40659
40858
  closed = new Array(data.length);
40660
40859
 
@@ -40670,9 +40869,9 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40670
40869
  numSegments += lineItem.length - 1;
40671
40870
 
40672
40871
  for (j = 0; j < lineItem.length; j += 1) {
40673
- pos = posFunc(lineItem[j], j, d, i);
40872
+ pos = posFunc ? posFunc(lineItem[j], j, d, i) : lineItem[j];
40674
40873
  position.push(pos.x);
40675
- position.push(pos.y);
40874
+ position.push(simpleInverse ? -pos.y : pos.y);
40676
40875
  position.push(pos.z || 0.0);
40677
40876
 
40678
40877
  if (!j) {
@@ -40695,7 +40894,10 @@ var webgl_lineFeature = function webgl_lineFeature(arg) {
40695
40894
  }
40696
40895
  }
40697
40896
 
40698
- position = transform.transformCoordinates(m_this.gcs(), m_this.layer().map().gcs(), position, 3);
40897
+ if (!simpleInverse) {
40898
+ position = transform.transformCoordinates(target_gcs, map_gcs, position, 3);
40899
+ }
40900
+
40699
40901
  m_origin = new Float32Array(m_this.style.get('origin')(position));
40700
40902
 
40701
40903
  if (m_origin[0] || m_origin[1] || m_origin[2]) {
@@ -43219,6 +43421,7 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43219
43421
  items = [],
43220
43422
  target_gcs = m_this.gcs(),
43221
43423
  map_gcs = m_this.layer().map().gcs(),
43424
+ simpleInverse = transform.onlyInvertedY(target_gcs, map_gcs),
43222
43425
  numPts = 0,
43223
43426
  geom = m_mapper.geometryData(),
43224
43427
  color,
@@ -43245,10 +43448,12 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43245
43448
 
43246
43449
  if (!onlyStyle) {
43247
43450
  posFunc = m_this.style.get('position');
43451
+ posFunc = posFunc === util.identityFunction ? null : posFunc;
43248
43452
  polyFunc = m_this.style.get('polygon');
43453
+ polyFunc = polyFunc === util.identityFunction ? null : polyFunc;
43249
43454
  m_this.data().forEach(function (item, itemIndex) {
43250
43455
  var polygon, outer, geometry, c;
43251
- polygon = polyFunc(item, itemIndex);
43456
+ polygon = polyFunc ? polyFunc(item, itemIndex) : item;
43252
43457
 
43253
43458
  if (!polygon) {
43254
43459
  return;
@@ -43267,9 +43472,9 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43267
43472
  geometry = new Array(outer.length * 3);
43268
43473
 
43269
43474
  for (i = d3 = 0; i < outer.length; i += 1, d3 += 3) {
43270
- c = posFunc(outer[i], i, item, itemIndex);
43475
+ c = posFunc ? posFunc(outer[i], i, item, itemIndex) : outer[i];
43271
43476
  geometry[d3] = c.x;
43272
- geometry[d3 + 1] = c.y; // ignore the z values until we support them
43477
+ geometry[d3 + 1] = simpleInverse ? -c.y : c.y; // ignore the z values until we support them
43273
43478
 
43274
43479
  geometry[d3 + 2] = 0; // c.z || 0;
43275
43480
  }
@@ -43291,9 +43496,9 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43291
43496
  geometry.holes.push(d3 / 3);
43292
43497
 
43293
43498
  for (i = 0; i < hole.length; i += 1, d3 += 3) {
43294
- c = posFunc(hole[i], i, item, itemIndex);
43499
+ c = posFunc ? posFunc(hole[i], i, item, itemIndex) : hole[i];
43295
43500
  geometry.vertices[d3] = c.x;
43296
- geometry.vertices[d3 + 1] = c.y; // ignore the z values until we support them
43501
+ geometry.vertices[d3 + 1] = simpleInverse ? -c.y : c.y; // ignore the z values until we support them
43297
43502
 
43298
43503
  geometry.vertices[d3 + 2] = 0; // c.z || 0;
43299
43504
  }
@@ -43301,7 +43506,10 @@ var webgl_polygonFeature = function webgl_polygonFeature(arg) {
43301
43506
  } // transform to map gcs
43302
43507
 
43303
43508
 
43304
- geometry.vertices = transform.transformCoordinates(target_gcs, map_gcs, geometry.vertices, geometry.dimensions);
43509
+ if (!simpleInverse) {
43510
+ geometry.vertices = transform.transformCoordinates(target_gcs, map_gcs, geometry.vertices, geometry.dimensions);
43511
+ }
43512
+
43305
43513
  record = {
43306
43514
  // triangulate
43307
43515
  triangles: earcut(geometry.vertices, geometry.holes, geometry.dimensions),