geo-advanced.test.ts 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. import * as assert from 'power-assert'
  2. import * as Mock from './mock'
  3. import tcb from '../../../src/index'
  4. import * as config from '../../config.local'
  5. import * as common from '../../common/index'
  6. describe('GEO高级功能', () => {
  7. const app = tcb.init(config)
  8. const db = app.database()
  9. const { Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon } = db.Geo
  10. const collName = 'db-test-geo-advanced'
  11. const collection = db.collection(collName)
  12. function randomPoint() {
  13. return new Point(180 - 360 * Math.random(), 90 - 180 * Math.random())
  14. }
  15. const geoNearPoint = new Point(0, 0)
  16. const line = new LineString([randomPoint(), randomPoint()])
  17. // “回”字的外环
  18. const point1 = new Point(-2, -2)
  19. const point2 = new Point(2, -2)
  20. const point3 = new Point(2, 2)
  21. const point4 = new Point(-2, 2)
  22. // “回”字的内环
  23. const point5 = new Point(-1, -1)
  24. const point6 = new Point(1, -1)
  25. const point7 = new Point(1, 1)
  26. const point8 = new Point(-1, 1)
  27. const polygon = new Polygon([
  28. new LineString([point1, point2, point3, point4, point1]),
  29. new LineString([point5, point6, point7, point8, point5])
  30. ])
  31. const multiPoint = new MultiPoint([randomPoint(), randomPoint(), randomPoint(), randomPoint()])
  32. const multiLineString = new MultiLineString([
  33. new LineString([randomPoint(), randomPoint()]),
  34. new LineString([randomPoint(), randomPoint()]),
  35. new LineString([randomPoint(), randomPoint()]),
  36. new LineString([randomPoint(), randomPoint()])
  37. ])
  38. const multiPolygon = new MultiPolygon([
  39. new Polygon([new LineString([point1, point2, point3, point4, point1])]),
  40. new Polygon([new LineString([point5, point6, point7, point8, point5])])
  41. ])
  42. const initialData = {
  43. point: randomPoint(),
  44. geoNearPoint,
  45. line,
  46. polygon,
  47. multiPoint,
  48. multiLineString,
  49. multiPolygon
  50. }
  51. beforeEach(async () => {
  52. await common.safeCollection(db, collName)
  53. await db
  54. .collection(collName)
  55. .where({
  56. _id: /.*/
  57. })
  58. .remove()
  59. })
  60. afterAll(async () => {
  61. await db
  62. .collection(collName)
  63. .where({
  64. _id: /.*/
  65. })
  66. .remove()
  67. })
  68. // it.skip('Document - createCollection()', async () => {
  69. // await common.safeCollection(db, collName)
  70. // })
  71. it('GEO Advanced - CRUD', async () => {
  72. // Create
  73. const res = await collection.add(initialData)
  74. // const id = res.ids[0]
  75. const id = res.id
  76. assert(id)
  77. assert(res.requestId)
  78. // // Read
  79. const readRes = await collection
  80. .where({
  81. _id: id
  82. })
  83. .get()
  84. assert(readRes.data.length > 0)
  85. const data = readRes.data[0]
  86. assert(data.point instanceof Point)
  87. assert(data.line instanceof LineString)
  88. assert(data.polygon instanceof Polygon)
  89. assert(data.multiPoint instanceof MultiPoint)
  90. assert(data.multiLineString instanceof MultiLineString)
  91. assert(data.multiPolygon instanceof MultiPolygon)
  92. assert.deepStrictEqual(data.point, initialData.point)
  93. assert.deepStrictEqual(data.line, line)
  94. assert.deepStrictEqual(data.polygon, polygon)
  95. assert.deepStrictEqual(data.multiPoint, multiPoint)
  96. assert.deepStrictEqual(data.multiLineString, multiLineString)
  97. assert.deepStrictEqual(data.multiPolygon, multiPolygon)
  98. // Update
  99. let result = await collection.doc(id).set(initialData)
  100. assert.strictEqual(result.updated, 1)
  101. assert(result.requestId)
  102. // Delete
  103. const deleteRes = await collection
  104. .where({
  105. _id: id
  106. })
  107. .remove()
  108. assert.strictEqual(deleteRes.deleted, 1)
  109. })
  110. it('GEO - bad create', () => {
  111. // bad Point
  112. assert.throws(() => new Point())
  113. assert.throws(() => new Point([], {}))
  114. // bad LineString
  115. assert.throws(() => new LineString({}))
  116. assert.throws(() => new LineString([]))
  117. assert.throws(() => new LineString([123, []]))
  118. // bad Polygon
  119. assert.throws(() => new Polygon(null))
  120. assert.throws(() => new Polygon([]))
  121. assert.throws(() => new Polygon([666, 789]))
  122. assert.throws(() => new Polygon([new LineString([point1, point2, point3, point4, point8])]))
  123. // bad MultiPoint
  124. assert.throws(() => new MultiPoint({}))
  125. assert.throws(() => new MultiPoint([]))
  126. assert.throws(() => new MultiPoint([{}, {}]))
  127. // bad MultiLineString
  128. assert.throws(() => new MultiLineString({}))
  129. assert.throws(() => new MultiLineString([]))
  130. assert.throws(() => new MultiLineString([123, null]))
  131. // bad MultiPolygon
  132. assert.throws(() => new MultiPolygon(123))
  133. assert.throws(() => new MultiPolygon([]))
  134. assert.throws(() => new MultiPolygon([666, 666]))
  135. })
  136. it('GEO - geoNear', async () => {
  137. // Create
  138. const geoPoint = new Point(22, 33)
  139. const res = await collection.add({
  140. ...initialData,
  141. point: geoPoint
  142. })
  143. // const id = res.ids[0]
  144. const id = res.id
  145. assert(id)
  146. assert(res.requestId)
  147. // Read
  148. const readRes = await collection
  149. .where({
  150. point: db.command.geoNear({
  151. geometry: geoPoint,
  152. maxDistance: 1,
  153. minDistance: 0
  154. })
  155. })
  156. .get()
  157. assert(readRes.data.length > 0)
  158. assert.deepStrictEqual(readRes.data[0].point, geoPoint)
  159. // 验证geoNear 不填maxDistance minDistance
  160. const readRes1 = await collection
  161. .where({
  162. point: db.command.geoNear({
  163. geometry: geoPoint
  164. })
  165. })
  166. .get()
  167. assert(readRes1.data.length > 0)
  168. assert.deepStrictEqual(readRes1.data[0].point, geoPoint)
  169. // Delete
  170. // const deleteRes = await collection
  171. // .where({
  172. // _id: id
  173. // })
  174. // .remove()
  175. // console.log(deleteRes)
  176. // assert.strictEqual(deleteRes.deleted, 1)
  177. })
  178. it('GEO - geoWithin geometry', async () => {
  179. const res = await collection.add({
  180. ...initialData,
  181. point: new Point(0, 0)
  182. })
  183. // const id = res.ids[0]
  184. const id = res.id
  185. assert(id)
  186. assert(res.requestId)
  187. // Read
  188. const readRes = await collection
  189. .where({
  190. point: db.command.geoWithin({
  191. geometry: new Polygon([
  192. new LineString([point1, point2, point3, point4, point1])
  193. ])
  194. })
  195. })
  196. .get()
  197. assert(readRes.data.length > 0)
  198. assert.deepStrictEqual(readRes.data[0].point, new Point(0, 0))
  199. // Delete
  200. const deleteRes = await collection
  201. .where({
  202. point: db.command.geoWithin({
  203. geometry: new Polygon([
  204. new LineString([point1, point2, point3, point4, point1])
  205. ])
  206. })
  207. })
  208. .remove()
  209. assert(deleteRes.deleted >= 1)
  210. })
  211. it('GEO - geoWithin centerSphere', async () => {
  212. const res = await collection.add({
  213. ...initialData,
  214. point: new Point(-88, 30.001)
  215. })
  216. const id = res.id
  217. assert(id)
  218. assert(res.requestId)
  219. // Read
  220. const readRes = await collection
  221. .where({
  222. point: db.command.geoWithin({
  223. centerSphere: [new Point(-88, 30), 10 / 6378.1]
  224. })
  225. })
  226. .get()
  227. assert(readRes.data.length > 0)
  228. assert.deepStrictEqual(readRes.data[0].point, new Point(-88, 30.001))
  229. // 校验第一个参数传二维数组
  230. const readRes1 = await collection
  231. .where({
  232. point: db.command.geoWithin({
  233. centerSphere: [[-88, 30], 10 / 6378.1]
  234. })
  235. })
  236. .get()
  237. assert(readRes1.data.length > 0)
  238. assert.deepStrictEqual(readRes1.data[0].point, new Point(-88, 30.001))
  239. // 校验第一个参数传 不符合地理位置规范 二维数组
  240. try {
  241. await collection
  242. .where({
  243. point: db.command.geoWithin({
  244. centerSphere: [[-288, 30], 10 / 6378.1]
  245. })
  246. })
  247. .get()
  248. } catch (e) {
  249. assert(e !== undefined)
  250. }
  251. // 校验第二个参数不传数字
  252. try {
  253. await collection
  254. .where({
  255. point: db.command.geoWithin({
  256. centerSphere: [new Point(-88, 30), '10']
  257. })
  258. })
  259. .get()
  260. } catch (e) {
  261. assert(e !== undefined)
  262. }
  263. })
  264. })