@mapcatch/util 2.0.6 → 2.0.7
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/dist/catchUtil.min.cjs.js +2928 -0
- package/dist/catchUtil.min.esm.js +44499 -42811
- package/dist/catchUtil.min.js +248 -248
- package/package.json +11 -2
- package/src/constants/annotation_color.js +0 -7
- package/src/constants/annotation_draw_style.js +0 -228
- package/src/constants/annotation_label_style.js +0 -76
- package/src/constants/annotation_style.js +0 -118
- package/src/constants/bmap_types.js +0 -44
- package/src/constants/cameras.js +0 -5
- package/src/constants/crs.js +0 -42099
- package/src/constants/crs_types.js +0 -22
- package/src/constants/default_layers.js +0 -149
- package/src/constants/dsm_colors.js +0 -10
- package/src/constants/error_codes.js +0 -44
- package/src/constants/height_colors.js +0 -1
- package/src/constants/index.js +0 -20
- package/src/constants/layer_folders.js +0 -6
- package/src/constants/layer_groups.js +0 -34
- package/src/constants/layer_groups_multispectral.js +0 -34
- package/src/constants/layer_icons.js +0 -19
- package/src/constants/map_style.js +0 -11
- package/src/constants/measurement_fields.js +0 -208
- package/src/constants/task_params.js +0 -33
- package/src/constants/tools.js +0 -20
- package/src/event/event.js +0 -191
- package/src/event/event_bus.js +0 -5
- package/src/event/index.js +0 -2
- package/src/gl-operations/constants.js +0 -9
- package/src/gl-operations/default_options.js +0 -98
- package/src/gl-operations/index.js +0 -533
- package/src/gl-operations/reglCommands/contours.js +0 -27
- package/src/gl-operations/reglCommands/default.js +0 -46
- package/src/gl-operations/reglCommands/hillshading.js +0 -340
- package/src/gl-operations/reglCommands/index.js +0 -6
- package/src/gl-operations/reglCommands/multiLayers.js +0 -303
- package/src/gl-operations/reglCommands/transitions.js +0 -111
- package/src/gl-operations/reglCommands/util.js +0 -71
- package/src/gl-operations/renderer.js +0 -210
- package/src/gl-operations/shaders/fragment/convertDem.js +0 -26
- package/src/gl-operations/shaders/fragment/convolutionSmooth.js +0 -55
- package/src/gl-operations/shaders/fragment/diffCalc.js +0 -34
- package/src/gl-operations/shaders/fragment/drawResult.js +0 -47
- package/src/gl-operations/shaders/fragment/hillshading/hsAdvAmbientShadows.js +0 -79
- package/src/gl-operations/shaders/fragment/hillshading/hsAdvDirect.js +0 -60
- package/src/gl-operations/shaders/fragment/hillshading/hsAdvFinalBaselayer.js +0 -31
- package/src/gl-operations/shaders/fragment/hillshading/hsAdvFinalColorscale.js +0 -61
- package/src/gl-operations/shaders/fragment/hillshading/hsAdvMergeAndScaleTiles.js +0 -27
- package/src/gl-operations/shaders/fragment/hillshading/hsAdvNormals.js +0 -26
- package/src/gl-operations/shaders/fragment/hillshading/hsAdvSmooth.js +0 -54
- package/src/gl-operations/shaders/fragment/hillshading/hsAdvSoftShadows.js +0 -81
- package/src/gl-operations/shaders/fragment/hillshading/hsPregen.js +0 -55
- package/src/gl-operations/shaders/fragment/interpolateColor.js +0 -66
- package/src/gl-operations/shaders/fragment/interpolateColorOnly.js +0 -50
- package/src/gl-operations/shaders/fragment/interpolateValue.js +0 -137
- package/src/gl-operations/shaders/fragment/multiAnalyze1Calc.js +0 -36
- package/src/gl-operations/shaders/fragment/multiAnalyze2Calc.js +0 -46
- package/src/gl-operations/shaders/fragment/multiAnalyze3Calc.js +0 -54
- package/src/gl-operations/shaders/fragment/multiAnalyze4Calc.js +0 -62
- package/src/gl-operations/shaders/fragment/multiAnalyze5Calc.js +0 -70
- package/src/gl-operations/shaders/fragment/multiAnalyze6Calc.js +0 -78
- package/src/gl-operations/shaders/fragment/single.js +0 -93
- package/src/gl-operations/shaders/transform.js +0 -22
- package/src/gl-operations/shaders/util/computeColor.glsl +0 -85
- package/src/gl-operations/shaders/util/getTexelValue.glsl +0 -10
- package/src/gl-operations/shaders/util/isCloseEnough.glsl +0 -9
- package/src/gl-operations/shaders/util/rgbaToFloat.glsl +0 -18
- package/src/gl-operations/shaders/vertex/double.js +0 -17
- package/src/gl-operations/shaders/vertex/multi3.js +0 -20
- package/src/gl-operations/shaders/vertex/multi4.js +0 -23
- package/src/gl-operations/shaders/vertex/multi5.js +0 -26
- package/src/gl-operations/shaders/vertex/multi6.js +0 -29
- package/src/gl-operations/shaders/vertex/single.js +0 -13
- package/src/gl-operations/shaders/vertex/singleNotTransformed.js +0 -12
- package/src/gl-operations/texture_manager.js +0 -141
- package/src/gl-operations/util.js +0 -336
- package/src/index.js +0 -20
- package/src/measure/index.js +0 -209
- package/src/measure/tile_cache.js +0 -88
- package/src/mvs/index.js +0 -26
- package/src/mvs/protos/index.js +0 -12
- package/src/mvs/protos/proto_10.js +0 -155
- package/src/observation_pretict.js +0 -168
- package/src/photo-parser/exif/gps_tags.js +0 -33
- package/src/photo-parser/exif/ifd1_tags.js +0 -22
- package/src/photo-parser/exif/index.js +0 -143
- package/src/photo-parser/exif/parse_image.js +0 -290
- package/src/photo-parser/exif/string_values.js +0 -137
- package/src/photo-parser/exif/tags.js +0 -75
- package/src/photo-parser/exif/tiff_tags.js +0 -35
- package/src/photo-parser/exif/util.js +0 -103
- package/src/photo-parser/image-size/detector.js +0 -24
- package/src/photo-parser/image-size/fromFile.js +0 -55
- package/src/photo-parser/image-size/index.js +0 -2
- package/src/photo-parser/image-size/lookup.js +0 -37
- package/src/photo-parser/image-size/types/bmp.js +0 -10
- package/src/photo-parser/image-size/types/cur.js +0 -16
- package/src/photo-parser/image-size/types/dds.js +0 -10
- package/src/photo-parser/image-size/types/gif.js +0 -11
- package/src/photo-parser/image-size/types/heif.js +0 -35
- package/src/photo-parser/image-size/types/icns.js +0 -112
- package/src/photo-parser/image-size/types/ico.js +0 -74
- package/src/photo-parser/image-size/types/index.js +0 -43
- package/src/photo-parser/image-size/types/j2c.js +0 -11
- package/src/photo-parser/image-size/types/jp2.js +0 -22
- package/src/photo-parser/image-size/types/jpg.js +0 -157
- package/src/photo-parser/image-size/types/ktx.js +0 -18
- package/src/photo-parser/image-size/types/png.js +0 -36
- package/src/photo-parser/image-size/types/pnm.js +0 -74
- package/src/photo-parser/image-size/types/psd.js +0 -10
- package/src/photo-parser/image-size/types/svg.js +0 -100
- package/src/photo-parser/image-size/types/tga.js +0 -14
- package/src/photo-parser/image-size/types/tiff.js +0 -92
- package/src/photo-parser/image-size/types/utils.js +0 -83
- package/src/photo-parser/image-size/types/webp.js +0 -67
- package/src/photo-parser/index.js +0 -185
- package/src/report/annotations_report.js +0 -446
- package/src/report/index.js +0 -2
- package/src/report/map_util.js +0 -81
- package/src/report/pdf_creator.js +0 -247
- package/src/report/report.js +0 -581
- package/src/transform.js +0 -207
- package/src/util.js +0 -671
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
flatMap,
|
|
3
|
-
isEmpty
|
|
4
|
-
} from 'lodash'
|
|
5
|
-
import * as util from './util'
|
|
6
|
-
|
|
7
|
-
export default class TextureManager {
|
|
8
|
-
constructor (
|
|
9
|
-
regl,
|
|
10
|
-
tileSize = 256,
|
|
11
|
-
maxTextureDimension,
|
|
12
|
-
flipY = false,
|
|
13
|
-
textureFormat = 'rgba',
|
|
14
|
-
textureType = 'uint8'
|
|
15
|
-
) {
|
|
16
|
-
const tilesAcross = Math.floor(maxTextureDimension / tileSize)
|
|
17
|
-
const pixelsAcross = tilesAcross * tileSize
|
|
18
|
-
const tileCapacity = tilesAcross * tilesAcross
|
|
19
|
-
|
|
20
|
-
const texture = regl.texture({
|
|
21
|
-
width: pixelsAcross,
|
|
22
|
-
height: pixelsAcross,
|
|
23
|
-
flipY: flipY,
|
|
24
|
-
format: textureFormat,
|
|
25
|
-
type: textureType
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
const contents = new Map()
|
|
29
|
-
const available = this.allTextureCoordinates(tilesAcross, tileSize)
|
|
30
|
-
|
|
31
|
-
Object.assign(this, {
|
|
32
|
-
tileSize,
|
|
33
|
-
tilesAcross,
|
|
34
|
-
pixelsAcross,
|
|
35
|
-
tileCapacity,
|
|
36
|
-
texture,
|
|
37
|
-
contents,
|
|
38
|
-
available
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
addTile (
|
|
43
|
-
tileCoordinates,
|
|
44
|
-
data
|
|
45
|
-
) {
|
|
46
|
-
const {
|
|
47
|
-
available,
|
|
48
|
-
contents,
|
|
49
|
-
texture,
|
|
50
|
-
tileSize
|
|
51
|
-
} = this
|
|
52
|
-
|
|
53
|
-
const hashKey = this.hashTileCoordinates(tileCoordinates)
|
|
54
|
-
if (contents.has(hashKey)) {
|
|
55
|
-
const textureCoordinates = contents.get(hashKey)
|
|
56
|
-
// We use a least-recently-used eviction policy for the tile cache. Map iterators are
|
|
57
|
-
// convenient for this, because they return entries in insertion order. But for this to work
|
|
58
|
-
// as expected, every time we access a tile, we need to reinsert it so that it moves to the
|
|
59
|
-
// end of that insertion-order list.
|
|
60
|
-
contents.delete(hashKey)
|
|
61
|
-
contents.set(hashKey, textureCoordinates)
|
|
62
|
-
return this.formatOutputTextureCoordinates(textureCoordinates)
|
|
63
|
-
}
|
|
64
|
-
if (isEmpty(available)) {
|
|
65
|
-
// Get the first key inserted. Map.prototype.keys() produces an iterable iterator over the keys
|
|
66
|
-
// in the order of insertion, so we can just use the iterator's first value.
|
|
67
|
-
const firstInsertedKey = contents.keys().next().value
|
|
68
|
-
this.removeByHashKey(firstInsertedKey)
|
|
69
|
-
}
|
|
70
|
-
// remove from list of available positions
|
|
71
|
-
const textureCoordinates = available.pop()
|
|
72
|
-
// store mapping of tile to texture coordinates
|
|
73
|
-
contents.set(hashKey, textureCoordinates)
|
|
74
|
-
|
|
75
|
-
const { x: textureX, y: textureY } = textureCoordinates
|
|
76
|
-
texture.subimage({
|
|
77
|
-
data,
|
|
78
|
-
width: tileSize,
|
|
79
|
-
height: tileSize
|
|
80
|
-
}, textureX, textureY)
|
|
81
|
-
|
|
82
|
-
return this.formatOutputTextureCoordinates(textureCoordinates)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
removeTile (tileCoordinates) {
|
|
86
|
-
this.removeByHashKey(this.hashTileCoordinates(tileCoordinates))
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
clearTiles () {
|
|
90
|
-
for (const hashKey of Array.from(this.contents.keys())) {
|
|
91
|
-
this.removeByHashKey(hashKey)
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
destroy () {
|
|
96
|
-
this.texture.destroy()
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
removeByHashKey (hashKey) {
|
|
100
|
-
// This method only removes the key. The pixel data remains in the texture.
|
|
101
|
-
if (this.contents.has(hashKey)) {
|
|
102
|
-
const textureCoordinates = this.contents.get(hashKey)
|
|
103
|
-
this.contents.delete(hashKey)
|
|
104
|
-
this.available.push(textureCoordinates)
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
formatOutputTextureCoordinates (textureCoordinates) {
|
|
109
|
-
const { x, y } = textureCoordinates
|
|
110
|
-
const { pixelsAcross, tileSize } = this
|
|
111
|
-
return [
|
|
112
|
-
{
|
|
113
|
-
x: x / pixelsAcross,
|
|
114
|
-
y: y / pixelsAcross
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
x: (x + tileSize) / pixelsAcross,
|
|
118
|
-
y: (y + tileSize) / pixelsAcross
|
|
119
|
-
}
|
|
120
|
-
]
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
hashTileCoordinates ({ x, y, z }) {
|
|
124
|
-
return `${x}:${y}:${z}`
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
getTextureCoordinates (tileCoordinates) {
|
|
128
|
-
const hashKey = this.hashTileCoordinates(tileCoordinates)
|
|
129
|
-
const textureCoordinates = this.contents.get(hashKey)
|
|
130
|
-
return this.formatOutputTextureCoordinates(textureCoordinates)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
allTextureCoordinates (tilesAcross, tileSize) {
|
|
134
|
-
return flatMap(util.range(tilesAcross), x =>
|
|
135
|
-
util.range(tilesAcross).map(y => ({
|
|
136
|
-
x: x * tileSize,
|
|
137
|
-
y: y * tileSize
|
|
138
|
-
}))
|
|
139
|
-
)
|
|
140
|
-
}
|
|
141
|
-
}
|
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
import { memoize } from 'lodash'
|
|
2
|
-
import { decode, toRGBA8 } from 'upng-js'
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
RGB_REGEX,
|
|
6
|
-
HEX_REGEX
|
|
7
|
-
} from './constants'
|
|
8
|
-
|
|
9
|
-
export function machineIsLittleEndian () {
|
|
10
|
-
const uint8Array = new Uint8Array([0xAA, 0xBB])
|
|
11
|
-
const uint16array = new Uint16Array(uint8Array.buffer)
|
|
12
|
-
return uint16array[0] === 0xBBAA
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Cribbed from Python's built-in `range` function.
|
|
17
|
-
*/
|
|
18
|
-
export function range (...args) {
|
|
19
|
-
if (args.length === 1) {
|
|
20
|
-
const [until] = args
|
|
21
|
-
return new Array(until).fill(undefined).map((_, i) => i)
|
|
22
|
-
} else {
|
|
23
|
-
const [from, until, step = 1] = args
|
|
24
|
-
if (step === 0) {
|
|
25
|
-
throw new Error('Argument step must be nonzero.')
|
|
26
|
-
}
|
|
27
|
-
const output = []
|
|
28
|
-
for (let val = from; (step > 0) ? val < until : val > until; val += step) {
|
|
29
|
-
output.push(val)
|
|
30
|
-
}
|
|
31
|
-
return output
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Fetch a png and decode data. If png does not exist return an array with nodataValue.
|
|
37
|
-
*/
|
|
38
|
-
export async function fetchPNGData (url, nodataValue, tileDimension) {
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
const xhr = new XMLHttpRequest()
|
|
41
|
-
xhr.open('GET', url, true)
|
|
42
|
-
xhr.responseType = 'arraybuffer'
|
|
43
|
-
xhr.addEventListener('load', () => {
|
|
44
|
-
resolve(xhr.response)
|
|
45
|
-
})
|
|
46
|
-
xhr.addEventListener('error', reject)
|
|
47
|
-
xhr.send(null)
|
|
48
|
-
}).then((data) => {
|
|
49
|
-
const img = decode(data)
|
|
50
|
-
const rgba = toRGBA8(img)[0]
|
|
51
|
-
return new Uint8Array(rgba)
|
|
52
|
-
}).catch(() => createNoDataTile(nodataValue, tileDimension))
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Check if two TypedArrays are equal
|
|
57
|
-
*/
|
|
58
|
-
export function typedArraysAreEqual (a, b) {
|
|
59
|
-
if (a.byteLength !== b.byteLength) return false
|
|
60
|
-
return a.every((val, i) => val === b[i])
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* The matrix output by this function transforms coordinates in pixel space within the drawing
|
|
65
|
-
* buffer (with upper left corner (0, 0) and lower right corner (buffer width, buffer height))
|
|
66
|
-
* to WebGL "clipspace", with upper left corner (-1, 1) and lower right corner (1, -1).
|
|
67
|
-
*/
|
|
68
|
-
export function getTransformMatrix (drawingBufferWidth, drawingBufferHeight) {
|
|
69
|
-
// To scale horizontally, divide by width (in pixels) and multiply by 2, because width is 2 in clipspace.
|
|
70
|
-
const sx = 2 / drawingBufferWidth
|
|
71
|
-
// To scale vertically, divide by height (in pixels) and multiply by -2, because height is 2 in clipspace,
|
|
72
|
-
// and the direction is flipped (positive is up, negative is down).
|
|
73
|
-
const sy = -2 / drawingBufferHeight
|
|
74
|
-
// We translate by -1 horizontally (so the range 0 to 2 maps to the range -1 to 1).
|
|
75
|
-
const tx = -1
|
|
76
|
-
// We translate by 1 horizontally (so the range -2 to 0 maps to the range -1 to 1).
|
|
77
|
-
const ty = 1
|
|
78
|
-
// Matrix must be in column-major order for WebGL.
|
|
79
|
-
return [
|
|
80
|
-
sx, 0, 0, 0,
|
|
81
|
-
0, sy, 0, 0,
|
|
82
|
-
0, 0, 1, 0,
|
|
83
|
-
tx, ty, 0, 1
|
|
84
|
-
]
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* From a TextureBounds object, this function generates the four vertices WebGL needs to draw the
|
|
89
|
-
* corresponding rectangle (as two conjoined triangles generated with the triangle strip primitive).
|
|
90
|
-
*/
|
|
91
|
-
export function getTexCoordVerticesTriangleStripQuad (textureBounds) {
|
|
92
|
-
const [{ x: left, y: top }, { x: right, y: bottom }] = textureBounds
|
|
93
|
-
return [
|
|
94
|
-
[left, top ],
|
|
95
|
-
[right, top ],
|
|
96
|
-
[left, bottom],
|
|
97
|
-
[right, bottom]
|
|
98
|
-
]
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* From a TextureBounds object, this function generates the six vertices WebGL needs to draw the
|
|
103
|
-
* corresponding rectangle (as two triangles).
|
|
104
|
-
*/
|
|
105
|
-
export function getTexCoordVerticesTriangleQuad (textureBounds) {
|
|
106
|
-
const [{ x: left, y: top }, { x: right, y: bottom }] = textureBounds
|
|
107
|
-
return [
|
|
108
|
-
[left, top ],
|
|
109
|
-
[right, top ],
|
|
110
|
-
[left, bottom],
|
|
111
|
-
[right, bottom],
|
|
112
|
-
[right, top ],
|
|
113
|
-
[left, bottom]
|
|
114
|
-
]
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Produces a Promise that resolves when the desired `duration` has expired.
|
|
119
|
-
*/
|
|
120
|
-
export function Timer (duration) {
|
|
121
|
-
return new Promise((resolve) => setTimeout(resolve, duration))
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Useful for sorting TileCoordinates objects.
|
|
126
|
-
*/
|
|
127
|
-
export function compareTileCoordinates (a, b) {
|
|
128
|
-
const z = a.z - b.z
|
|
129
|
-
const x = a.x - b.x
|
|
130
|
-
const y = a.y - b.y
|
|
131
|
-
if (z !== 0) {
|
|
132
|
-
// First compare z values.
|
|
133
|
-
return z
|
|
134
|
-
} else if (x !== 0) {
|
|
135
|
-
// If z values are the same, compare x values.
|
|
136
|
-
return x
|
|
137
|
-
} else {
|
|
138
|
-
// If x values are the same, compare y values.
|
|
139
|
-
return y
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Determines whether two arrays of TileCoordinates are the same.
|
|
145
|
-
*/
|
|
146
|
-
export function sameTiles (a, b) {
|
|
147
|
-
return (
|
|
148
|
-
// arrays are of the same length
|
|
149
|
-
a.length === b.length
|
|
150
|
-
// and corresponding elements have the same tile coordinates
|
|
151
|
-
&& a.every((tileA, index) => compareTileCoordinates(tileA, b[index]) === 0)
|
|
152
|
-
)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export const createNoDataTile = memoize((nodataValue, tileDimension = 256) => {
|
|
156
|
-
// Create a float 32 array.
|
|
157
|
-
const float32Tile = new Float32Array(tileDimension * tileDimension)
|
|
158
|
-
// Fill the tile array with the no data value
|
|
159
|
-
float32Tile.fill(nodataValue)
|
|
160
|
-
// return the no data tile.
|
|
161
|
-
return new Uint8Array(float32Tile.buffer)
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Force TypeScript to interpret value `val` as type `T`.
|
|
166
|
-
*/
|
|
167
|
-
export function staticCast (val) {
|
|
168
|
-
return val
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Add one or more macro definitions to a GLSL source string.
|
|
173
|
-
*/
|
|
174
|
-
export function defineMacros (src, macros) {
|
|
175
|
-
const defs = Object.keys(macros).map((key) => `#define ${key} ${macros[key]}\n`).join('')
|
|
176
|
-
return `${defs}\n${src}`
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Ping-pong technique. Render to a destination framebuffer,
|
|
181
|
-
* then use it as a source texture in our next iteration.
|
|
182
|
-
* Then swap them and continue. Used for advanced hillshading.
|
|
183
|
-
*/
|
|
184
|
-
export function PingPong (regl, opts) {
|
|
185
|
-
const fbos = [regl.framebuffer(opts), regl.framebuffer(opts)]
|
|
186
|
-
|
|
187
|
-
let index = 0
|
|
188
|
-
|
|
189
|
-
function ping () {
|
|
190
|
-
return fbos[index]
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function pong () {
|
|
194
|
-
return fbos[1 - index]
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function swap () {
|
|
198
|
-
index = 1 - index
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function destroy () {
|
|
202
|
-
fbos[0].destroy()
|
|
203
|
-
fbos[1].destroy()
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return {
|
|
207
|
-
ping,
|
|
208
|
-
pong,
|
|
209
|
-
swap,
|
|
210
|
-
destroy
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* hexToRGB converts a color from hex format to rgba.
|
|
216
|
-
* const [r, g, b, a] = hexToRGB("#ffeeaaff")
|
|
217
|
-
*/
|
|
218
|
-
export const hexToRGB = (hex) => {
|
|
219
|
-
const hasAlpha = hex.length === 9
|
|
220
|
-
const start = hasAlpha ? 24 : 16
|
|
221
|
-
const bigint = parseInt(hex.slice(1), 16)
|
|
222
|
-
const r = (bigint >> start) & 255
|
|
223
|
-
const g = (bigint >> (start - 8)) & 255
|
|
224
|
-
const b = (bigint >> (start - 16)) & 255
|
|
225
|
-
const a = hasAlpha ? (bigint >> (start - 24)) & 255 : 255
|
|
226
|
-
return [r, g, b, a]
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Parses a color string of the form 'rgb({rVal}, {gVal}, {bVal})' and converts the resulting values
|
|
231
|
-
* to an array with ints 0 - 255.
|
|
232
|
-
*/
|
|
233
|
-
export function colorStringToInts (colorstring) {
|
|
234
|
-
if (colorstring === 'transparent') {
|
|
235
|
-
return [0, 0, 0, 0]
|
|
236
|
-
}
|
|
237
|
-
const rgbmatch = colorstring.match(RGB_REGEX)
|
|
238
|
-
const hexmatch = colorstring.match(HEX_REGEX)
|
|
239
|
-
if (rgbmatch !== null) {
|
|
240
|
-
const [, r, g, b] = rgbmatch
|
|
241
|
-
return [+r, +g, +b, 255]
|
|
242
|
-
} else if (hexmatch !== null) {
|
|
243
|
-
return hexToRGB(colorstring)
|
|
244
|
-
} else {
|
|
245
|
-
throw new Error(`'${colorstring}' is not a valid RGB or hex color expression.`)
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* colormapToFlatArray takes the input colormap and returns a flat array to be
|
|
251
|
-
* used as input to a texture. The first row in the array contains the colors.
|
|
252
|
-
* The second row contains the encoded offset values.
|
|
253
|
-
*/
|
|
254
|
-
export const colormapToFlatArray = (colormap) => {
|
|
255
|
-
const offsets = []
|
|
256
|
-
let colors = []
|
|
257
|
-
for (let i = 0; i < colormap.length; i++) {
|
|
258
|
-
offsets.push(colormap[i].offset)
|
|
259
|
-
const colorsnew = colorStringToInts(colormap[i].color)
|
|
260
|
-
colors = colors.concat(colorsnew)
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
const floatOffsets = new Float32Array(offsets)
|
|
264
|
-
const uintOffsets = new Uint8Array(floatOffsets.buffer)
|
|
265
|
-
const normalOffsets = Array.from(uintOffsets)
|
|
266
|
-
const colormapArray = colors.concat(normalOffsets)
|
|
267
|
-
|
|
268
|
-
return colormapArray
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Creates a texture with colors on first row and offsets on second row
|
|
273
|
-
*/
|
|
274
|
-
export function createColormapTexture (colormapInput, regl) {
|
|
275
|
-
const colormapFlatArray = colormapToFlatArray(colormapInput)
|
|
276
|
-
let colormapTexture
|
|
277
|
-
if (colormapInput.length === 0) {
|
|
278
|
-
// empty texture
|
|
279
|
-
colormapTexture = regl.texture({
|
|
280
|
-
shape: [2, 2]
|
|
281
|
-
})
|
|
282
|
-
} else {
|
|
283
|
-
colormapTexture = regl.texture({
|
|
284
|
-
width: colormapInput.length,
|
|
285
|
-
height: 2,
|
|
286
|
-
data: colormapFlatArray
|
|
287
|
-
})
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return colormapTexture
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* Fetch 8 adjacent tiles, if not already existing in tileManager.
|
|
295
|
-
* Return array with texture coord vertices for all tiles.
|
|
296
|
-
*/
|
|
297
|
-
export async function getAdjacentTilesTexCoords (gloperations, textureManager, coords, url) {
|
|
298
|
-
// Get existing tiles in TextureManager
|
|
299
|
-
const textureContents = textureManager.contents
|
|
300
|
-
|
|
301
|
-
// use 3x3 tiles for adv. hillshading
|
|
302
|
-
// TODO: add as plugin option?
|
|
303
|
-
const adjacentTiles = 3
|
|
304
|
-
let textureCoords = []
|
|
305
|
-
|
|
306
|
-
for (let i = 0; i < adjacentTiles; i++) {
|
|
307
|
-
const _x = coords['x'] + (i - 1)
|
|
308
|
-
for (let j = 0; j < adjacentTiles; j++) {
|
|
309
|
-
const _y = coords['y'] + (j - 1)
|
|
310
|
-
const coordsAdjacent = {
|
|
311
|
-
x: _x,
|
|
312
|
-
y: _y,
|
|
313
|
-
z: coords['z']
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// Fetch data for adjacent tile if not already existing in TextureManager
|
|
317
|
-
const hashKey = textureManager.hashTileCoordinates(coordsAdjacent)
|
|
318
|
-
if (!textureContents.has(hashKey)) {
|
|
319
|
-
// Retrieve and add data to TextureManager
|
|
320
|
-
const pixelDataAdjacent = await gloperations._fetchTileData(coordsAdjacent, url)
|
|
321
|
-
const textureBounds = gloperations._renderer.textureManager.addTile(coordsAdjacent, pixelDataAdjacent)
|
|
322
|
-
textureCoords = textureCoords.concat(getTexCoordVerticesTriangleQuad(textureBounds))
|
|
323
|
-
} else {
|
|
324
|
-
const textureBounds = gloperations._renderer.textureManager.getTextureCoordinates(coordsAdjacent)
|
|
325
|
-
textureCoords = textureCoords.concat(getTexCoordVerticesTriangleQuad(textureBounds))
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
return textureCoords
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
export function delay (ms) {
|
|
333
|
-
return new Promise(function (resolve) {
|
|
334
|
-
setTimeout(resolve, ms)
|
|
335
|
-
})
|
|
336
|
-
}
|
package/src/index.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
// 常用公共函数和工具函数
|
|
2
|
-
export * from './util'
|
|
3
|
-
// 事件处理类
|
|
4
|
-
export * from './event'
|
|
5
|
-
// dsm瓦片渲染类
|
|
6
|
-
export {default as GLOperations} from './gl-operations'
|
|
7
|
-
// 常量
|
|
8
|
-
export * from './constants'
|
|
9
|
-
// 照片解析
|
|
10
|
-
export * from './photo-parser'
|
|
11
|
-
// 刺点预测
|
|
12
|
-
export * from './observation_pretict'
|
|
13
|
-
// 坐标转换
|
|
14
|
-
export * as transform from './transform'
|
|
15
|
-
// 空三解析
|
|
16
|
-
export * from './mvs'
|
|
17
|
-
// 生成报告
|
|
18
|
-
export * from './report'
|
|
19
|
-
// 标注测量
|
|
20
|
-
export {default as Measurement} from './measure'
|
package/src/measure/index.js
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import cdt2d from 'cdt2d'
|
|
2
|
-
import _ from 'lodash'
|
|
3
|
-
import TileCache from './tile_cache'
|
|
4
|
-
import { getTileCoord, getTilePixelCoord, geographicToCartesian } from '../transform'
|
|
5
|
-
import { rgbaToFloat } from '../util'
|
|
6
|
-
|
|
7
|
-
class Measurement {
|
|
8
|
-
constructor (options) {
|
|
9
|
-
if (!options.loadTileImage) {
|
|
10
|
-
throw new Error('未指定加载瓦片数据的方法')
|
|
11
|
-
}
|
|
12
|
-
this.tileCache = new TileCache({
|
|
13
|
-
loadTileImage: options.loadTileImage,
|
|
14
|
-
maxCacheSize: options.maxCacheSize || 200
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// 从dsm中获取指定位置的高程
|
|
20
|
-
async getFloatValue (lngLat, options) {
|
|
21
|
-
if (lngLat[2]) {
|
|
22
|
-
// 如果传入的坐标本身带有高程,则不用去dsm中获取高程
|
|
23
|
-
return _.round(lngLat[2], 4)
|
|
24
|
-
}
|
|
25
|
-
let {tilejson} = options
|
|
26
|
-
if (!tilejson) {
|
|
27
|
-
// 没有dsm
|
|
28
|
-
return 0
|
|
29
|
-
}
|
|
30
|
-
let { max_zoom } = tilejson
|
|
31
|
-
let { min, max } = tilejson.metadata
|
|
32
|
-
let tileCoord = getTileCoord(max_zoom, lngLat)
|
|
33
|
-
let pixelCoord = getTilePixelCoord(max_zoom, lngLat)
|
|
34
|
-
let tile = this.tileCache.getTile(tileCoord, options)
|
|
35
|
-
if (!tile) {
|
|
36
|
-
tile = this.tileCache.addTile(tileCoord, options)
|
|
37
|
-
}
|
|
38
|
-
if (!tile.loaded) {
|
|
39
|
-
await tile.tileData
|
|
40
|
-
}
|
|
41
|
-
if (!tile.tileData) {
|
|
42
|
-
// 没找到瓦片,说明该点超出瓦片范围,默认给一个平均值
|
|
43
|
-
return _.round((min + max) / 2, 4)
|
|
44
|
-
}
|
|
45
|
-
let pixelIndex = (pixelCoord.y * 512 + pixelCoord.x) * 4
|
|
46
|
-
let value = rgbaToFloat([
|
|
47
|
-
tile.tileData[pixelIndex],
|
|
48
|
-
tile.tileData[pixelIndex + 1],
|
|
49
|
-
tile.tileData[pixelIndex + 2],
|
|
50
|
-
tile.tileData[pixelIndex + 3]
|
|
51
|
-
])
|
|
52
|
-
if (Math.abs(value + 99999) <= Math.max(Math.abs(value), Math.abs(-99999)) * 0.0001) {
|
|
53
|
-
// 无效值
|
|
54
|
-
return _.round((min + max) / 2, 4)
|
|
55
|
-
}
|
|
56
|
-
return _.round(value, 4)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async getMeasureInfo (options) {
|
|
60
|
-
let { data_type, geometry } = options
|
|
61
|
-
let type = geometry.type
|
|
62
|
-
let properties = {}
|
|
63
|
-
if (type === 'Point') {
|
|
64
|
-
// 点要素
|
|
65
|
-
let value = await this.getFloatValue(geometry.coordinates, options)
|
|
66
|
-
if (data_type === 'infrared') {
|
|
67
|
-
// 红外
|
|
68
|
-
properties.temprature = _.round(value, 4)
|
|
69
|
-
properties.lng = geometry.coordinates[0]
|
|
70
|
-
properties.lat = geometry.coordinates[1]
|
|
71
|
-
} else {
|
|
72
|
-
geometry.coordinates[2] = value
|
|
73
|
-
properties.height = value
|
|
74
|
-
properties.lng = geometry.coordinates[0]
|
|
75
|
-
properties.lat = geometry.coordinates[1]
|
|
76
|
-
}
|
|
77
|
-
} else if (type === 'LineString') {
|
|
78
|
-
let coordinates = geometry.coordinates
|
|
79
|
-
let slopes = []
|
|
80
|
-
let values = await Promise.all(coordinates.map(coord => this.getFloatValue(coord, options)))
|
|
81
|
-
if (data_type === 'infrared') {
|
|
82
|
-
// 红外
|
|
83
|
-
properties.distance2d = this.getDistance2D(coordinates)
|
|
84
|
-
properties.temprature_min = _.round(_.min(values), 4)
|
|
85
|
-
properties.temprature_max = _.round(_.max(values), 4)
|
|
86
|
-
} else {
|
|
87
|
-
coordinates.forEach((coord, index) => {
|
|
88
|
-
coord[2] = values[index]
|
|
89
|
-
if (index > 0) {
|
|
90
|
-
slopes.push(this.getSlope(coordinates[index - 1], coordinates[index]))
|
|
91
|
-
}
|
|
92
|
-
})
|
|
93
|
-
properties.distance2d = this.getDistance2D(coordinates)
|
|
94
|
-
properties.distance3d = this.getDistance3D(coordinates)
|
|
95
|
-
properties.height_min = _.min(values)
|
|
96
|
-
properties.height_max = _.max(values)
|
|
97
|
-
properties.slope_min = _.min(slopes)
|
|
98
|
-
properties.slope_max = _.max(slopes)
|
|
99
|
-
}
|
|
100
|
-
} else if (type === 'Polygon') {
|
|
101
|
-
let coordinates = geometry.coordinates[0]
|
|
102
|
-
let values = await Promise.all(coordinates.map(coord => this.getFloatValue(coord, options)))
|
|
103
|
-
if (data_type === 'infrared') {
|
|
104
|
-
// 红外
|
|
105
|
-
properties.distance2d = this.getDistance2D(coordinates)
|
|
106
|
-
properties.area2d = this.getArea(coordinates).area2d
|
|
107
|
-
properties.temprature_min = _.round(_.min(values), 4)
|
|
108
|
-
properties.temprature_max = _.round(_.max(values), 4)
|
|
109
|
-
} else {
|
|
110
|
-
coordinates.forEach((coord, index) => {
|
|
111
|
-
coord[2] = values[index]
|
|
112
|
-
})
|
|
113
|
-
properties.distance2d = this.getDistance2D(coordinates)
|
|
114
|
-
properties.distance3d = this.getDistance3D(coordinates)
|
|
115
|
-
properties.height_min = _.min(values)
|
|
116
|
-
properties.height_max = _.max(values)
|
|
117
|
-
let area = this.getArea(coordinates)
|
|
118
|
-
properties.area2d = area.area2d
|
|
119
|
-
properties.area3d = area.area3d
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return { geometry, properties }
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
getSlope (from, to) {
|
|
126
|
-
let d = this.getDistance3D([from, to])
|
|
127
|
-
let hDiff = Math.abs(from[2] - to[2]) // 高差
|
|
128
|
-
return _.round((Math.asin(hDiff / d) * 180) / Math.PI, 4)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
getDistance2D (coordinates) {
|
|
132
|
-
let d = 0
|
|
133
|
-
for (let i = 1; i < coordinates.length; i++) {
|
|
134
|
-
let p1 = geographicToCartesian([coordinates[i - 1][0], coordinates[i - 1][1], 0])
|
|
135
|
-
let p2 = geographicToCartesian([coordinates[i][0], coordinates[i][1], 0])
|
|
136
|
-
d += Math.sqrt(
|
|
137
|
-
Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2) + Math.pow(p1[2] - p2[2], 2)
|
|
138
|
-
)
|
|
139
|
-
}
|
|
140
|
-
return _.round(d, 4)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
getDistance3D (coordinates) {
|
|
144
|
-
let d = 0
|
|
145
|
-
for (let i = 1; i < coordinates.length; i++) {
|
|
146
|
-
let p1 = geographicToCartesian(coordinates[i - 1])
|
|
147
|
-
let p2 = geographicToCartesian(coordinates[i])
|
|
148
|
-
d += Math.sqrt(
|
|
149
|
-
Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2) + Math.pow(p1[2] - p2[2], 2)
|
|
150
|
-
)
|
|
151
|
-
}
|
|
152
|
-
return _.round(d, 4)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
getArea (coordinates) {
|
|
156
|
-
let triangles = []
|
|
157
|
-
let flatCoordinates
|
|
158
|
-
let projs = [coordinates.map(d => [d[0], d[1]]), coordinates.map(d => [d[0], d[2]]), coordinates.map(d => [d[1], d[2]])] // 三个投影平面
|
|
159
|
-
let flatCoordinates2d = projs[0] // 2D地图的投影平面
|
|
160
|
-
|
|
161
|
-
while (!triangles.length && projs.length) { // 寻找可成功分解的投影平面
|
|
162
|
-
flatCoordinates = projs.shift()
|
|
163
|
-
flatCoordinates = this._reduceCoordinates(flatCoordinates)
|
|
164
|
-
let edges = []
|
|
165
|
-
flatCoordinates.forEach((coord, index) => {
|
|
166
|
-
if (index === flatCoordinates.length - 1) {
|
|
167
|
-
edges.push([index, 0])
|
|
168
|
-
} else {
|
|
169
|
-
edges.push([index, index + 1])
|
|
170
|
-
}
|
|
171
|
-
})
|
|
172
|
-
triangles = cdt2d(flatCoordinates, edges, { exterior: false })
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
let area2d = 0,
|
|
176
|
-
area3d = 0
|
|
177
|
-
triangles.forEach(triangle => {
|
|
178
|
-
let [i1, i2, i3] = triangle
|
|
179
|
-
area2d += this.getTriangleArea(
|
|
180
|
-
[flatCoordinates2d[i1][0], flatCoordinates2d[i1][1], 0],
|
|
181
|
-
[flatCoordinates2d[i2][0], flatCoordinates2d[i2][1], 0],
|
|
182
|
-
[flatCoordinates2d[i3][0], flatCoordinates2d[i3][1], 0]
|
|
183
|
-
)
|
|
184
|
-
area3d += this.getTriangleArea(coordinates[i1], coordinates[i2], coordinates[i3])
|
|
185
|
-
})
|
|
186
|
-
return { area2d: _.round(area2d, 4), area3d: _.round(area3d, 4) }
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// 海伦公式:空间中三角形三个顶点坐标(经纬度),计算三角形面积
|
|
190
|
-
getTriangleArea (p1, p2, p3) {
|
|
191
|
-
let a = this.getDistance3D([p1, p2])
|
|
192
|
-
let b = this.getDistance3D([p2, p3])
|
|
193
|
-
let c = this.getDistance3D([p3, p1])
|
|
194
|
-
return Math.sqrt((a + b + c) * (a + b - c) * (a + c - b) * (b + c - a)) / 4
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
_reduceCoordinates (coords) { // 去重
|
|
198
|
-
for(let i = 0;i < coords.length; i++) {
|
|
199
|
-
let nextIndex = i === coords.length - 1 ? 0 : (i + 1)
|
|
200
|
-
if (_.isEqual(coords[i], coords[nextIndex])) {
|
|
201
|
-
coords.splice(i, 1)
|
|
202
|
-
i--
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return coords
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
export default Measurement
|