ParsePolygon.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. "use strict";
  2. var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
  3. var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
  4. _Object$defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.default = void 0;
  8. var _isArray = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/array/is-array"));
  9. var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
  10. var _ParseGeoPoint = _interopRequireDefault(require("./ParseGeoPoint"));
  11. /**
  12. * Creates a new Polygon with any of the following forms:<br>
  13. * <pre>
  14. * new Polygon([[0,0],[0,1],[1,1],[1,0]])
  15. * new Polygon([GeoPoint, GeoPoint, GeoPoint])
  16. * </pre>
  17. *
  18. * <p>Represents a coordinates that may be associated
  19. * with a key in a ParseObject or used as a reference point for geo queries.
  20. * This allows proximity-based queries on the key.</p>
  21. *
  22. * <p>Example:<pre>
  23. * var polygon = new Parse.Polygon([[0,0],[0,1],[1,1],[1,0]]);
  24. * var object = new Parse.Object("PlaceObject");
  25. * object.set("area", polygon);
  26. * object.save();</pre></p>
  27. *
  28. * @alias Parse.Polygon
  29. */
  30. class ParsePolygon {
  31. /**
  32. * @param {(Coordinates | Parse.GeoPoint[])} coordinates An Array of coordinate pairs
  33. */
  34. constructor(coordinates) {
  35. (0, _defineProperty2.default)(this, "_coordinates", void 0);
  36. this._coordinates = ParsePolygon._validate(coordinates);
  37. }
  38. /**
  39. * Coordinates value for this Polygon.
  40. * Throws an exception if not valid type.
  41. *
  42. * @property {(Coordinates | Parse.GeoPoint[])} coordinates list of coordinates
  43. * @returns {Coordinates}
  44. */
  45. get coordinates() {
  46. return this._coordinates;
  47. }
  48. set coordinates(coords) {
  49. this._coordinates = ParsePolygon._validate(coords);
  50. }
  51. /**
  52. * Returns a JSON representation of the Polygon, suitable for Parse.
  53. *
  54. * @returns {object}
  55. */
  56. toJSON() {
  57. ParsePolygon._validate(this._coordinates);
  58. return {
  59. __type: 'Polygon',
  60. coordinates: this._coordinates
  61. };
  62. }
  63. /**
  64. * Checks if two polygons are equal
  65. *
  66. * @param {(Parse.Polygon | object)} other
  67. * @returns {boolean}
  68. */
  69. equals(other) {
  70. if (!(other instanceof ParsePolygon) || this.coordinates.length !== other.coordinates.length) {
  71. return false;
  72. }
  73. let isEqual = true;
  74. for (let i = 1; i < this._coordinates.length; i += 1) {
  75. if (this._coordinates[i][0] != other.coordinates[i][0] || this._coordinates[i][1] != other.coordinates[i][1]) {
  76. isEqual = false;
  77. break;
  78. }
  79. }
  80. return isEqual;
  81. }
  82. /**
  83. *
  84. * @param {Parse.GeoPoint} point
  85. * @returns {boolean} Returns if the point is contained in the polygon
  86. */
  87. containsPoint(point) {
  88. let minX = this._coordinates[0][0];
  89. let maxX = this._coordinates[0][0];
  90. let minY = this._coordinates[0][1];
  91. let maxY = this._coordinates[0][1];
  92. for (let i = 1; i < this._coordinates.length; i += 1) {
  93. const p = this._coordinates[i];
  94. minX = Math.min(p[0], minX);
  95. maxX = Math.max(p[0], maxX);
  96. minY = Math.min(p[1], minY);
  97. maxY = Math.max(p[1], maxY);
  98. }
  99. const outside = point.latitude < minX || point.latitude > maxX || point.longitude < minY || point.longitude > maxY;
  100. if (outside) {
  101. return false;
  102. }
  103. let inside = false;
  104. for (let i = 0, j = this._coordinates.length - 1; i < this._coordinates.length; j = i++) {
  105. const startX = this._coordinates[i][0];
  106. const startY = this._coordinates[i][1];
  107. const endX = this._coordinates[j][0];
  108. const endY = this._coordinates[j][1];
  109. const intersect = startY > point.longitude != endY > point.longitude && point.latitude < (endX - startX) * (point.longitude - startY) / (endY - startY) + startX;
  110. if (intersect) {
  111. inside = !inside;
  112. }
  113. }
  114. return inside;
  115. }
  116. /**
  117. * Validates that the list of coordinates can form a valid polygon
  118. *
  119. * @param {Array} coords the list of coordinates to validate as a polygon
  120. * @throws {TypeError}
  121. * @returns {number[][]} Array of coordinates if validated.
  122. */
  123. static _validate(coords) {
  124. if (!(0, _isArray.default)(coords)) {
  125. throw new TypeError('Coordinates must be an Array');
  126. }
  127. if (coords.length < 3) {
  128. throw new TypeError('Polygon must have at least 3 GeoPoints or Points');
  129. }
  130. const points = [];
  131. for (let i = 0; i < coords.length; i += 1) {
  132. const coord = coords[i];
  133. let geoPoint;
  134. if (coord instanceof _ParseGeoPoint.default) {
  135. geoPoint = coord;
  136. } else if ((0, _isArray.default)(coord) && coord.length === 2) {
  137. geoPoint = new _ParseGeoPoint.default(coord[0], coord[1]);
  138. } else {
  139. throw new TypeError('Coordinates must be an Array of GeoPoints or Points');
  140. }
  141. points.push([geoPoint.latitude, geoPoint.longitude]);
  142. }
  143. return points;
  144. }
  145. }
  146. var _default = exports.default = ParsePolygon;