bajo-spatial 0.3.2 → 1.0.2
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/bajo/.alias +1 -0
- package/bajo/config.json +1 -2
- package/bajo/hook/dobo@before-record-find.js +11 -0
- package/bajo/method/angleIn90Deg.js +3 -0
- package/bajo/method/boundsToTiles.js +31 -0
- package/bajo/{helper → method}/build-bbox-query.js +2 -3
- package/bajo/method/ddToDms.js +13 -0
- package/bajo/method/divideBounds.js +17 -0
- package/bajo/method/dmsToDd.js +5 -0
- package/bajo/method/enlargeBounds.js +12 -0
- package/bajo/method/getTileBounds.js +10 -0
- package/bajo/method/isCoordInBounds.js +3 -0
- package/bajo/method/isValidCoord.js +5 -0
- package/bajo/method/latSizeOf.js +3 -0
- package/bajo/method/latToDms.js +7 -0
- package/bajo/method/latToTile.js +5 -0
- package/bajo/method/lngSizeOf.js +3 -0
- package/bajo/method/lngToDms.js +7 -0
- package/bajo/method/lngToTile.js +5 -0
- package/bajo/{helper → method}/parse-bbox.js +7 -8
- package/bajo/method/sanitizeBounds.js +14 -0
- package/bajo/method/tileToLat.js +6 -0
- package/bajo/method/tileToLng.js +5 -0
- package/bajo/method/tilesToBounds.js +15 -0
- package/package.json +2 -1
- package/waibuStatic/virtual.json +4 -0
- package/bajo/hook/bajoDb@on-before-record-find.js +0 -12
package/bajo/.alias
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
spatial
|
package/bajo/config.json
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
}
|
|
1
|
+
{}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const beforeRecordFind = {
|
|
2
|
+
level: 1001,
|
|
3
|
+
handler: async function (name, filter, options) {
|
|
4
|
+
if (!filter.bbox) return
|
|
5
|
+
const { getSchema } = this.app.dobo
|
|
6
|
+
const schema = getSchema(name)
|
|
7
|
+
filter.query = await this.buildBboxQuery({ bbox: filter.bbox, query: filter.query, schema, options })
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default beforeRecordFind
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import lngToTile from './lngToTile.js'
|
|
2
|
+
import latToTile from './latToTile.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,10 +1,9 @@
|
|
|
1
1
|
async function buildBboxQuery ({ bbox, query, schema, options = {} } = {}) {
|
|
2
|
-
const { merge, isEmpty } = this.bajo.
|
|
3
|
-
const { parseBbox } = this.bajoSpatial.helper
|
|
2
|
+
const { merge, isEmpty } = this.app.bajo.lib._
|
|
4
3
|
const props = schema.properties.map(item => item.name)
|
|
5
4
|
const { bboxLatField = 'lat', bboxLngField = 'lng' } = options
|
|
6
5
|
if (props.includes(bboxLatField) && props.includes(bboxLngField)) {
|
|
7
|
-
const [minx, miny, maxx, maxy] = await parseBbox(bbox)
|
|
6
|
+
const [minx, miny, maxx, maxy] = await this.parseBbox(bbox)
|
|
8
7
|
const q = {}
|
|
9
8
|
q[bboxLngField] = { $gte: minx, $lte: maxx }
|
|
10
9
|
q[bboxLatField] = { $gte: miny, $lte: maxy }
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import tileToLng from './tileToLng.js'
|
|
2
|
+
import tileToLat from './tileToLat.js'
|
|
3
|
+
import boundsToTiles from './boundsToTiles.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
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import tileToLng from './tileToLng.js'
|
|
2
|
+
import tileToLat from './tileToLat.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
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
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,23 +1,22 @@
|
|
|
1
1
|
async function getCountryBbox (item) {
|
|
2
2
|
item = item + ''
|
|
3
3
|
if (item.includes(',')) return
|
|
4
|
-
if (!this.bajoCommonDb || !this.
|
|
5
|
-
const {
|
|
6
|
-
const { recordGet } = this.bajoDb.helper
|
|
4
|
+
if (!this.app.bajoCommonDb || !this.app.dobo) return
|
|
5
|
+
const { recordGet } = this.app.dobo
|
|
7
6
|
const country = await recordGet('CdbCountry', item, { thrownNotFound: false })
|
|
8
7
|
if (country) return country.bbox
|
|
9
|
-
throw error('Invalid country bbox \'%s\'', item, { statusCode: 400 })
|
|
8
|
+
throw this.error('Invalid country bbox \'%s\'', item, { statusCode: 400 })
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
async function parseBbox (input) {
|
|
13
|
-
const { isSet
|
|
12
|
+
const { isSet } = this.app.bajo
|
|
14
13
|
if (input.length === 2 && !input.includes(',')) return await getCountryBbox.call(this, input)
|
|
15
14
|
const [minx, miny, maxx, maxy] = input.split(',').map(b => parseFloat(b) || null)
|
|
16
15
|
const valid = (isSet(minx) && isSet(miny) && isSet(maxx) && isSet(maxy)) &&
|
|
17
|
-
(minx >= -180 && maxx <= 180 && miny >= -90 && maxy <= 90)
|
|
18
|
-
(minx <= maxx && miny <= maxy)
|
|
16
|
+
(minx >= -180 && maxx <= 180 && miny >= -90 && maxy <= 90)
|
|
17
|
+
// (minx <= maxx && miny <= maxy)
|
|
19
18
|
if (valid) return [minx, miny, maxx, maxy]
|
|
20
|
-
throw error('Invalid bbox \'%s\'', input)
|
|
19
|
+
throw this.error('Invalid bbox \'%s\'', input)
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
export default parseBbox
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import tileToLng from './tileToLng.js'
|
|
2
|
+
import tileToLat from './tileToLat.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
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bajo-spatial",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Spatial functions for Bajo Framework",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -24,5 +24,6 @@
|
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://github.com/ardhi/bajo-spatial#readme",
|
|
26
26
|
"dependencies": {
|
|
27
|
+
"geolib": "^3.3.4"
|
|
27
28
|
}
|
|
28
29
|
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const onBeforeRecordFind = {
|
|
2
|
-
level: 1001,
|
|
3
|
-
handler: async function (name, filter, options) {
|
|
4
|
-
const { buildBboxQuery } = this.bajoSpatial.helper
|
|
5
|
-
if (!filter.bbox) return
|
|
6
|
-
const { getSchema } = this.bajoDb.helper
|
|
7
|
-
const schema = getSchema(name)
|
|
8
|
-
filter.query = await buildBboxQuery({ bbox: filter.bbox, query: filter.query, schema, options })
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export default onBeforeRecordFind
|