Envelope.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. import Coordinate from './Coordinate'
  2. import Comparable from '../../../../java/lang/Comparable'
  3. import Serializable from '../../../../java/io/Serializable'
  4. export default class Envelope {
  5. constructor() {
  6. Envelope.constructor_.apply(this, arguments)
  7. }
  8. static constructor_() {
  9. this._minx = null
  10. this._maxx = null
  11. this._miny = null
  12. this._maxy = null
  13. if (arguments.length === 0) {
  14. this.init()
  15. } else if (arguments.length === 1) {
  16. if (arguments[0] instanceof Coordinate) {
  17. const p = arguments[0]
  18. this.init(p.x, p.x, p.y, p.y)
  19. } else if (arguments[0] instanceof Envelope) {
  20. const env = arguments[0]
  21. this.init(env)
  22. }
  23. } else if (arguments.length === 2) {
  24. const p1 = arguments[0], p2 = arguments[1]
  25. this.init(p1.x, p2.x, p1.y, p2.y)
  26. } else if (arguments.length === 4) {
  27. const x1 = arguments[0], x2 = arguments[1], y1 = arguments[2], y2 = arguments[3]
  28. this.init(x1, x2, y1, y2)
  29. }
  30. }
  31. static intersects() {
  32. if (arguments.length === 3) {
  33. const p1 = arguments[0], p2 = arguments[1], q = arguments[2]
  34. if (q.x >= (p1.x < p2.x ? p1.x : p2.x) && q.x <= (p1.x > p2.x ? p1.x : p2.x) && (q.y >= (p1.y < p2.y ? p1.y : p2.y) && q.y <= (p1.y > p2.y ? p1.y : p2.y)))
  35. return true
  36. return false
  37. } else if (arguments.length === 4) {
  38. const p1 = arguments[0], p2 = arguments[1], q1 = arguments[2], q2 = arguments[3]
  39. let minq = Math.min(q1.x, q2.x)
  40. let maxq = Math.max(q1.x, q2.x)
  41. let minp = Math.min(p1.x, p2.x)
  42. let maxp = Math.max(p1.x, p2.x)
  43. if (minp > maxq) return false
  44. if (maxp < minq) return false
  45. minq = Math.min(q1.y, q2.y)
  46. maxq = Math.max(q1.y, q2.y)
  47. minp = Math.min(p1.y, p2.y)
  48. maxp = Math.max(p1.y, p2.y)
  49. if (minp > maxq) return false
  50. if (maxp < minq) return false
  51. return true
  52. }
  53. }
  54. getArea() {
  55. return this.getWidth() * this.getHeight()
  56. }
  57. equals(other) {
  58. if (!(other instanceof Envelope))
  59. return false
  60. const otherEnvelope = other
  61. if (this.isNull())
  62. return otherEnvelope.isNull()
  63. return this._maxx === otherEnvelope.getMaxX() && this._maxy === otherEnvelope.getMaxY() && this._minx === otherEnvelope.getMinX() && this._miny === otherEnvelope.getMinY()
  64. }
  65. intersection(env) {
  66. if (this.isNull() || env.isNull() || !this.intersects(env)) return new Envelope()
  67. const intMinX = this._minx > env._minx ? this._minx : env._minx
  68. const intMinY = this._miny > env._miny ? this._miny : env._miny
  69. const intMaxX = this._maxx < env._maxx ? this._maxx : env._maxx
  70. const intMaxY = this._maxy < env._maxy ? this._maxy : env._maxy
  71. return new Envelope(intMinX, intMaxX, intMinY, intMaxY)
  72. }
  73. isNull() {
  74. return this._maxx < this._minx
  75. }
  76. getMaxX() {
  77. return this._maxx
  78. }
  79. covers() {
  80. if (arguments.length === 1) {
  81. if (arguments[0] instanceof Coordinate) {
  82. const p = arguments[0]
  83. return this.covers(p.x, p.y)
  84. } else if (arguments[0] instanceof Envelope) {
  85. const other = arguments[0]
  86. if (this.isNull() || other.isNull())
  87. return false
  88. return other.getMinX() >= this._minx && other.getMaxX() <= this._maxx && other.getMinY() >= this._miny && other.getMaxY() <= this._maxy
  89. }
  90. } else if (arguments.length === 2) {
  91. const x = arguments[0], y = arguments[1]
  92. if (this.isNull()) return false
  93. return x >= this._minx && x <= this._maxx && y >= this._miny && y <= this._maxy
  94. }
  95. }
  96. intersects() {
  97. if (arguments.length === 1) {
  98. if (arguments[0] instanceof Envelope) {
  99. const other = arguments[0]
  100. if (this.isNull() || other.isNull())
  101. return false
  102. return !(other._minx > this._maxx || other._maxx < this._minx || other._miny > this._maxy || other._maxy < this._miny)
  103. } else if (arguments[0] instanceof Coordinate) {
  104. const p = arguments[0]
  105. return this.intersects(p.x, p.y)
  106. }
  107. } else if (arguments.length === 2) {
  108. if (arguments[0] instanceof Coordinate && arguments[1] instanceof Coordinate) {
  109. const a = arguments[0], b = arguments[1]
  110. if (this.isNull())
  111. return false
  112. const envminx = a.x < b.x ? a.x : b.x
  113. if (envminx > this._maxx) return false
  114. const envmaxx = a.x > b.x ? a.x : b.x
  115. if (envmaxx < this._minx) return false
  116. const envminy = a.y < b.y ? a.y : b.y
  117. if (envminy > this._maxy) return false
  118. const envmaxy = a.y > b.y ? a.y : b.y
  119. if (envmaxy < this._miny) return false
  120. return true
  121. } else if (typeof arguments[0] === 'number' && typeof arguments[1] === 'number') {
  122. const x = arguments[0], y = arguments[1]
  123. if (this.isNull()) return false
  124. return !(x > this._maxx || x < this._minx || y > this._maxy || y < this._miny)
  125. }
  126. }
  127. }
  128. getMinY() {
  129. return this._miny
  130. }
  131. getDiameter() {
  132. if (this.isNull())
  133. return 0
  134. const w = this.getWidth()
  135. const h = this.getHeight()
  136. return Math.sqrt(w * w + h * h)
  137. }
  138. getMinX() {
  139. return this._minx
  140. }
  141. expandToInclude() {
  142. if (arguments.length === 1) {
  143. if (arguments[0] instanceof Coordinate) {
  144. const p = arguments[0]
  145. this.expandToInclude(p.x, p.y)
  146. } else if (arguments[0] instanceof Envelope) {
  147. const other = arguments[0]
  148. if (other.isNull())
  149. return null
  150. if (this.isNull()) {
  151. this._minx = other.getMinX()
  152. this._maxx = other.getMaxX()
  153. this._miny = other.getMinY()
  154. this._maxy = other.getMaxY()
  155. } else {
  156. if (other._minx < this._minx)
  157. this._minx = other._minx
  158. if (other._maxx > this._maxx)
  159. this._maxx = other._maxx
  160. if (other._miny < this._miny)
  161. this._miny = other._miny
  162. if (other._maxy > this._maxy)
  163. this._maxy = other._maxy
  164. }
  165. }
  166. } else if (arguments.length === 2) {
  167. const x = arguments[0], y = arguments[1]
  168. if (this.isNull()) {
  169. this._minx = x
  170. this._maxx = x
  171. this._miny = y
  172. this._maxy = y
  173. } else {
  174. if (x < this._minx)
  175. this._minx = x
  176. if (x > this._maxx)
  177. this._maxx = x
  178. if (y < this._miny)
  179. this._miny = y
  180. if (y > this._maxy)
  181. this._maxy = y
  182. }
  183. }
  184. }
  185. minExtent() {
  186. if (this.isNull()) return 0.0
  187. const w = this.getWidth()
  188. const h = this.getHeight()
  189. if (w < h) return w
  190. return h
  191. }
  192. getWidth() {
  193. if (this.isNull())
  194. return 0
  195. return this._maxx - this._minx
  196. }
  197. compareTo(o) {
  198. const env = o
  199. if (this.isNull()) {
  200. if (env.isNull()) return 0
  201. return -1
  202. } else {
  203. if (env.isNull()) return 1
  204. }
  205. if (this._minx < env._minx) return -1
  206. if (this._minx > env._minx) return 1
  207. if (this._miny < env._miny) return -1
  208. if (this._miny > env._miny) return 1
  209. if (this._maxx < env._maxx) return -1
  210. if (this._maxx > env._maxx) return 1
  211. if (this._maxy < env._maxy) return -1
  212. if (this._maxy > env._maxy) return 1
  213. return 0
  214. }
  215. translate(transX, transY) {
  216. if (this.isNull())
  217. return null
  218. this.init(this.getMinX() + transX, this.getMaxX() + transX, this.getMinY() + transY, this.getMaxY() + transY)
  219. }
  220. copy() {
  221. return new Envelope(this)
  222. }
  223. toString() {
  224. return 'Env[' + this._minx + ' : ' + this._maxx + ', ' + this._miny + ' : ' + this._maxy + ']'
  225. }
  226. setToNull() {
  227. this._minx = 0
  228. this._maxx = -1
  229. this._miny = 0
  230. this._maxy = -1
  231. }
  232. disjoint(other) {
  233. if (this.isNull() || other.isNull())
  234. return true
  235. return other._minx > this._maxx || other._maxx < this._minx || other._miny > this._maxy || other._maxy < this._miny
  236. }
  237. getHeight() {
  238. if (this.isNull())
  239. return 0
  240. return this._maxy - this._miny
  241. }
  242. maxExtent() {
  243. if (this.isNull()) return 0.0
  244. const w = this.getWidth()
  245. const h = this.getHeight()
  246. if (w > h) return w
  247. return h
  248. }
  249. expandBy() {
  250. if (arguments.length === 1) {
  251. const distance = arguments[0]
  252. this.expandBy(distance, distance)
  253. } else if (arguments.length === 2) {
  254. const deltaX = arguments[0], deltaY = arguments[1]
  255. if (this.isNull()) return null
  256. this._minx -= deltaX
  257. this._maxx += deltaX
  258. this._miny -= deltaY
  259. this._maxy += deltaY
  260. if (this._minx > this._maxx || this._miny > this._maxy) this.setToNull()
  261. }
  262. }
  263. contains() {
  264. if (arguments.length === 1) {
  265. if (arguments[0] instanceof Envelope) {
  266. const other = arguments[0]
  267. return this.covers(other)
  268. } else if (arguments[0] instanceof Coordinate) {
  269. const p = arguments[0]
  270. return this.covers(p)
  271. }
  272. } else if (arguments.length === 2) {
  273. const x = arguments[0], y = arguments[1]
  274. return this.covers(x, y)
  275. }
  276. }
  277. centre() {
  278. if (this.isNull()) return null
  279. return new Coordinate((this.getMinX() + this.getMaxX()) / 2.0, (this.getMinY() + this.getMaxY()) / 2.0)
  280. }
  281. init() {
  282. if (arguments.length === 0) {
  283. this.setToNull()
  284. } else if (arguments.length === 1) {
  285. if (arguments[0] instanceof Coordinate) {
  286. const p = arguments[0]
  287. this.init(p.x, p.x, p.y, p.y)
  288. } else if (arguments[0] instanceof Envelope) {
  289. const env = arguments[0]
  290. this._minx = env._minx
  291. this._maxx = env._maxx
  292. this._miny = env._miny
  293. this._maxy = env._maxy
  294. }
  295. } else if (arguments.length === 2) {
  296. const p1 = arguments[0], p2 = arguments[1]
  297. this.init(p1.x, p2.x, p1.y, p2.y)
  298. } else if (arguments.length === 4) {
  299. const x1 = arguments[0], x2 = arguments[1], y1 = arguments[2], y2 = arguments[3]
  300. if (x1 < x2) {
  301. this._minx = x1
  302. this._maxx = x2
  303. } else {
  304. this._minx = x2
  305. this._maxx = x1
  306. }
  307. if (y1 < y2) {
  308. this._miny = y1
  309. this._maxy = y2
  310. } else {
  311. this._miny = y2
  312. this._maxy = y1
  313. }
  314. }
  315. }
  316. getMaxY() {
  317. return this._maxy
  318. }
  319. distance(env) {
  320. if (this.intersects(env)) return 0
  321. let dx = 0.0
  322. if (this._maxx < env._minx) dx = env._minx - this._maxx; else if (this._minx > env._maxx) dx = this._minx - env._maxx
  323. let dy = 0.0
  324. if (this._maxy < env._miny) dy = env._miny - this._maxy; else if (this._miny > env._maxy) dy = this._miny - env._maxy
  325. if (dx === 0.0) return dy
  326. if (dy === 0.0) return dx
  327. return Math.sqrt(dx * dx + dy * dy)
  328. }
  329. hashCode() {
  330. let result = 17
  331. result = 37 * result + Coordinate.hashCode(this._minx)
  332. result = 37 * result + Coordinate.hashCode(this._maxx)
  333. result = 37 * result + Coordinate.hashCode(this._miny)
  334. result = 37 * result + Coordinate.hashCode(this._maxy)
  335. return result
  336. }
  337. get interfaces_() {
  338. return [Comparable, Serializable]
  339. }
  340. }