bajo-spatial 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/plugin/factory.js +42 -0
- package/plugin/method/angle-in-90-deg.js +0 -3
- package/plugin/method/bounds-to-tiles.js +0 -31
- package/plugin/method/build-bbox-query.js +0 -20
- package/plugin/method/dd-to-dms.js +0 -13
- package/plugin/method/divide-bounds.js +0 -17
- package/plugin/method/dms-to-dd.js +0 -5
- package/plugin/method/enlarge-bounds.js +0 -12
- package/plugin/method/get-tile-bounds.js +0 -10
- package/plugin/method/is-coord-in-bounds.js +0 -3
- package/plugin/method/is-valid-coord.js +0 -5
- package/plugin/method/lat-size-of.js +0 -3
- package/plugin/method/lat-to-dms.js +0 -7
- package/plugin/method/lat-to-tile.js +0 -5
- package/plugin/method/lng-size-of.js +0 -3
- package/plugin/method/lng-to-dms.js +0 -7
- package/plugin/method/lng-to-tile.js +0 -5
- package/plugin/method/parse-bbox.js +0 -22
- package/plugin/method/sanitize-bounds.js +0 -14
- package/plugin/method/tile-to-lat.js +0 -6
- package/plugin/method/tile-to-lng.js +0 -5
- package/plugin/method/tiles-to-bounds.js +0 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bajo-spatial",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "Spatial functions for Bajo Framework",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"homepage": "https://github.com/ardhi/bajo-spatial#readme",
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@turf/turf": "^7.2.0",
|
|
28
|
+
"aneka-spatial": "^0.0.3",
|
|
28
29
|
"geolib": "^3.3.4"
|
|
29
30
|
}
|
|
30
31
|
}
|
package/plugin/factory.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as turf from '@turf/turf'
|
|
2
|
+
import anekaSpatial from 'aneka-spatial/index.js'
|
|
2
3
|
|
|
3
4
|
async function factory (pkgName) {
|
|
4
5
|
const me = this
|
|
@@ -9,6 +10,47 @@ async function factory (pkgName) {
|
|
|
9
10
|
this.alias = 'spatial'
|
|
10
11
|
this.config = {}
|
|
11
12
|
this.lib.turf = turf
|
|
13
|
+
this.lib.anekaSpatial = anekaSpatial
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
buildBboxQuery = async ({ bbox, query, schema, options = {} } = {}) => {
|
|
17
|
+
const { merge, isEmpty } = this.lib._
|
|
18
|
+
const props = schema.properties.map(item => item.name)
|
|
19
|
+
const { bboxLatField = 'lat', bboxLngField = 'lng' } = options
|
|
20
|
+
if (props.includes(bboxLatField) && props.includes(bboxLngField)) {
|
|
21
|
+
const [minx, miny, maxx, maxy] = await this.parseBbox(bbox)
|
|
22
|
+
const q = {}
|
|
23
|
+
q[bboxLngField] = { $gte: minx, $lte: maxx }
|
|
24
|
+
q[bboxLatField] = { $gte: miny, $lte: maxy }
|
|
25
|
+
if (isEmpty(query)) query = q
|
|
26
|
+
else {
|
|
27
|
+
const $or = query.$or
|
|
28
|
+
if ($or) query = merge(q, { $or })
|
|
29
|
+
else merge(query, q)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return query
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getCountryBbox = async (item) => {
|
|
36
|
+
item = item + ''
|
|
37
|
+
if (item.includes(',')) return
|
|
38
|
+
if (!this.app.bajoCommonDb || !this.app.dobo) return
|
|
39
|
+
const { recordGet } = this.app.dobo
|
|
40
|
+
const country = await recordGet('CdbCountry', item, { thrownNotFound: false })
|
|
41
|
+
if (country) return country.bbox
|
|
42
|
+
throw this.error('Invalid country bbox \'%s\'', item, { statusCode: 400 })
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
parseBbox = async (input) => {
|
|
46
|
+
const { isSet } = this.lib.aneka
|
|
47
|
+
if (input.length === 2 && !input.includes(',')) return await this.getCountryBbox(input)
|
|
48
|
+
const [minx, miny, maxx, maxy] = input.split(',').map(b => parseFloat(b) || null)
|
|
49
|
+
const valid = (isSet(minx) && isSet(miny) && isSet(maxx) && isSet(maxy)) &&
|
|
50
|
+
(minx >= -180 && maxx <= 180 && miny >= -90 && maxy <= 90)
|
|
51
|
+
// (minx <= maxx && miny <= maxy)
|
|
52
|
+
if (valid) return [minx, miny, maxx, maxy]
|
|
53
|
+
throw this.error('Invalid bbox \'%s\'', input)
|
|
12
54
|
}
|
|
13
55
|
}
|
|
14
56
|
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import lngToTile from './lng-to-tile.js'
|
|
2
|
-
import latToTile from './lat-to-tile.js'
|
|
3
|
-
|
|
4
|
-
export default function (bounds, zoom, allTiles, withZ) {
|
|
5
|
-
const x1 = lngToTile(bounds[0], zoom)
|
|
6
|
-
const y1 = latToTile(bounds[1], zoom)
|
|
7
|
-
const x2 = lngToTile(bounds[2], zoom)
|
|
8
|
-
const y2 = latToTile(bounds[3], zoom)
|
|
9
|
-
if (allTiles) {
|
|
10
|
-
const all = []
|
|
11
|
-
for (let i = x1; i <= x2; i++) {
|
|
12
|
-
for (let j = y2; j <= y1; j++) {
|
|
13
|
-
let item
|
|
14
|
-
switch (allTiles) {
|
|
15
|
-
case 'array':
|
|
16
|
-
item = [i, j]
|
|
17
|
-
if (withZ) item.unshift(zoom)
|
|
18
|
-
break
|
|
19
|
-
case 'object':
|
|
20
|
-
item = { x: i, y: j }
|
|
21
|
-
if (withZ) item.zoom = zoom
|
|
22
|
-
break
|
|
23
|
-
default: item = `${withZ ? (zoom + '/') : ''}${i}/${j}`
|
|
24
|
-
}
|
|
25
|
-
all.push(item)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return all
|
|
29
|
-
}
|
|
30
|
-
return [x1, y1, x2, y2]
|
|
31
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
async function buildBboxQuery ({ bbox, query, schema, options = {} } = {}) {
|
|
2
|
-
const { merge, isEmpty } = this.lib._
|
|
3
|
-
const props = schema.properties.map(item => item.name)
|
|
4
|
-
const { bboxLatField = 'lat', bboxLngField = 'lng' } = options
|
|
5
|
-
if (props.includes(bboxLatField) && props.includes(bboxLngField)) {
|
|
6
|
-
const [minx, miny, maxx, maxy] = await this.parseBbox(bbox)
|
|
7
|
-
const q = {}
|
|
8
|
-
q[bboxLngField] = { $gte: minx, $lte: maxx }
|
|
9
|
-
q[bboxLatField] = { $gte: miny, $lte: maxy }
|
|
10
|
-
if (isEmpty(query)) query = q
|
|
11
|
-
else {
|
|
12
|
-
const $or = query.$or
|
|
13
|
-
if ($or) query = merge(q, { $or })
|
|
14
|
-
else merge(query, q)
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return query
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export default buildBboxQuery
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { decimalToSexagesimal } from 'geolib'
|
|
2
|
-
|
|
3
|
-
export default function (val, secPrecision = 2) {
|
|
4
|
-
val = val + ''
|
|
5
|
-
const minus = val.substr(0, 1) === '-' ? '-' : ''
|
|
6
|
-
const parts = decimalToSexagesimal(val).split(' ')
|
|
7
|
-
const last = parts[parts.length - 1]
|
|
8
|
-
const floats = last.slice(0, last.length - 1).split('.')
|
|
9
|
-
if (floats.length === 1) floats[1] = 0
|
|
10
|
-
floats[1] = parseFloat('0.' + floats[1]).toFixed(secPrecision).split('.')[1]
|
|
11
|
-
parts[parts.length - 1] = floats.join('.') + '"'
|
|
12
|
-
return minus + parts.join(' ')
|
|
13
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export default function (bounds, count) {
|
|
2
|
-
const originX = bounds[0]
|
|
3
|
-
const originY = bounds[1]
|
|
4
|
-
const dw = (bounds[2] - bounds[0]) / count
|
|
5
|
-
const dh = (bounds[3] - bounds[1]) / count
|
|
6
|
-
const result = []
|
|
7
|
-
for (let y = count - 1; y >= 0; y--) {
|
|
8
|
-
for (let x = 0; x < count; x++) {
|
|
9
|
-
const x1 = originX + x * dw
|
|
10
|
-
const y1 = originY + y * dh
|
|
11
|
-
const x2 = x1 + dw
|
|
12
|
-
const y2 = y1 + dh
|
|
13
|
-
result.push([x1, y1, x2, y2])
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
return result
|
|
17
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import tileToLng from './tile-to-lng.js'
|
|
2
|
-
import tileToLat from './tile-to-lat.js'
|
|
3
|
-
import boundsToTiles from './bounds-to-tiles.js'
|
|
4
|
-
|
|
5
|
-
export default function (bounds, zoom) {
|
|
6
|
-
const tiles = boundsToTiles(bounds, zoom)
|
|
7
|
-
const lng1 = tileToLng(tiles[0], zoom)
|
|
8
|
-
const lat1 = tileToLat(tiles[1] + 1, zoom)
|
|
9
|
-
const lng2 = tileToLng(tiles[2] + 1, zoom)
|
|
10
|
-
const lat2 = tileToLat(tiles[3], zoom)
|
|
11
|
-
return [lng1, lat1, lng2, lat2]
|
|
12
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import tileToLng from './tile-to-lng.js'
|
|
2
|
-
import tileToLat from './tile-to-lat.js'
|
|
3
|
-
|
|
4
|
-
export default function (x, y, zoom) {
|
|
5
|
-
const lng1 = tileToLng(x, zoom)
|
|
6
|
-
const lat1 = tileToLat(y, zoom)
|
|
7
|
-
const lng2 = tileToLng(x + 1, zoom)
|
|
8
|
-
const lat2 = tileToLat(y + 1, zoom)
|
|
9
|
-
return [lng1, lat2, lng2, lat1]
|
|
10
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
// source: https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_.28JavaScript.2FActionScript.2C_etc..29
|
|
2
|
-
|
|
3
|
-
export default function (lat, zoom) {
|
|
4
|
-
return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom)))
|
|
5
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
async function getCountryBbox (item) {
|
|
2
|
-
item = item + ''
|
|
3
|
-
if (item.includes(',')) return
|
|
4
|
-
if (!this.app.bajoCommonDb || !this.app.dobo) return
|
|
5
|
-
const { recordGet } = this.app.dobo
|
|
6
|
-
const country = await recordGet('CdbCountry', item, { thrownNotFound: false })
|
|
7
|
-
if (country) return country.bbox
|
|
8
|
-
throw this.error('Invalid country bbox \'%s\'', item, { statusCode: 400 })
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async function parseBbox (input) {
|
|
12
|
-
const { isSet } = this.app.bajo
|
|
13
|
-
if (input.length === 2 && !input.includes(',')) return await getCountryBbox.call(this, input)
|
|
14
|
-
const [minx, miny, maxx, maxy] = input.split(',').map(b => parseFloat(b) || null)
|
|
15
|
-
const valid = (isSet(minx) && isSet(miny) && isSet(maxx) && isSet(maxy)) &&
|
|
16
|
-
(minx >= -180 && maxx <= 180 && miny >= -90 && maxy <= 90)
|
|
17
|
-
// (minx <= maxx && miny <= maxy)
|
|
18
|
-
if (valid) return [minx, miny, maxx, maxy]
|
|
19
|
-
throw this.error('Invalid bbox \'%s\'', input)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default parseBbox
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export default function (bounds) {
|
|
2
|
-
if (typeof bounds === 'string') {
|
|
3
|
-
bounds = bounds.trim()
|
|
4
|
-
if (bounds.substr(0, 1) === '[') {
|
|
5
|
-
try {
|
|
6
|
-
bounds = JSON.parse(bounds)
|
|
7
|
-
} catch (err) {}
|
|
8
|
-
} else {
|
|
9
|
-
bounds = bounds.split(',')
|
|
10
|
-
}
|
|
11
|
-
bounds = bounds.map(val => parseFloat(val))
|
|
12
|
-
}
|
|
13
|
-
return bounds
|
|
14
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
// source: https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_.28JavaScript.2FActionScript.2C_etc..29
|
|
2
|
-
|
|
3
|
-
export default function (y, zoom) {
|
|
4
|
-
const n = Math.PI - 2 * Math.PI * y / Math.pow(2, zoom)
|
|
5
|
-
return (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))))
|
|
6
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import tileToLng from './tile-to-lng.js'
|
|
2
|
-
import tileToLat from './tile-to-lat.js'
|
|
3
|
-
|
|
4
|
-
export default function (x1, y1, x2, y2, zoom, extra) {
|
|
5
|
-
const lng1 = tileToLng(x1, zoom)
|
|
6
|
-
const lat1 = tileToLat(y1 + 1, zoom)
|
|
7
|
-
const lng2 = tileToLng(x2 + 1, zoom)
|
|
8
|
-
const lat2 = tileToLat(y2, zoom)
|
|
9
|
-
const ret = [lng1, lat1, lng2, lat2]
|
|
10
|
-
if (!extra) return ret
|
|
11
|
-
return {
|
|
12
|
-
bounds: ret,
|
|
13
|
-
sqd: (lng2 - lng1) * (lat2 - lat1)
|
|
14
|
-
}
|
|
15
|
-
}
|