@mapcatch/util 1.0.0

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.
Files changed (71) hide show
  1. package/.eslintrc.js +53 -0
  2. package/.prettierrc +4 -0
  3. package/CHANGELOG.md +0 -0
  4. package/README.md +44 -0
  5. package/docs/Catolog.md +24 -0
  6. package/docs/Util.md +170 -0
  7. package/package.json +30 -0
  8. package/src/constants/cameras.js +5 -0
  9. package/src/constants/index.js +1 -0
  10. package/src/event.js +205 -0
  11. package/src/exif/exif.js +37 -0
  12. package/src/exif/gps_tags.js +33 -0
  13. package/src/exif/ifd1_tags.js +22 -0
  14. package/src/exif/index.js +16 -0
  15. package/src/exif/iptc_field_map.js +12 -0
  16. package/src/exif/parse_image.js +446 -0
  17. package/src/exif/string_values.js +137 -0
  18. package/src/exif/tags.js +75 -0
  19. package/src/exif/tiff_tags.js +35 -0
  20. package/src/exif/util.js +108 -0
  21. package/src/gl-operations/constants.js +11 -0
  22. package/src/gl-operations/default_options.js +98 -0
  23. package/src/gl-operations/index.js +594 -0
  24. package/src/gl-operations/reglCommands/contours.js +27 -0
  25. package/src/gl-operations/reglCommands/default.js +44 -0
  26. package/src/gl-operations/reglCommands/hillshading.js +332 -0
  27. package/src/gl-operations/reglCommands/index.js +6 -0
  28. package/src/gl-operations/reglCommands/multiLayers.js +301 -0
  29. package/src/gl-operations/reglCommands/transitions.js +109 -0
  30. package/src/gl-operations/reglCommands/util.js +71 -0
  31. package/src/gl-operations/renderer.js +193 -0
  32. package/src/gl-operations/shaders/fragment/convertDem.js +26 -0
  33. package/src/gl-operations/shaders/fragment/convolutionSmooth.js +55 -0
  34. package/src/gl-operations/shaders/fragment/diffCalc.js +34 -0
  35. package/src/gl-operations/shaders/fragment/drawResult.js +42 -0
  36. package/src/gl-operations/shaders/fragment/hillshading/hsAdvAmbientShadows.js +79 -0
  37. package/src/gl-operations/shaders/fragment/hillshading/hsAdvDirect.js +55 -0
  38. package/src/gl-operations/shaders/fragment/hillshading/hsAdvFinalBaselayer.js +31 -0
  39. package/src/gl-operations/shaders/fragment/hillshading/hsAdvFinalColorscale.js +56 -0
  40. package/src/gl-operations/shaders/fragment/hillshading/hsAdvMergeAndScaleTiles.js +27 -0
  41. package/src/gl-operations/shaders/fragment/hillshading/hsAdvNormals.js +26 -0
  42. package/src/gl-operations/shaders/fragment/hillshading/hsAdvSmooth.js +54 -0
  43. package/src/gl-operations/shaders/fragment/hillshading/hsAdvSoftShadows.js +81 -0
  44. package/src/gl-operations/shaders/fragment/hillshading/hsPregen.js +50 -0
  45. package/src/gl-operations/shaders/fragment/interpolateColor.js +63 -0
  46. package/src/gl-operations/shaders/fragment/interpolateColorOnly.js +47 -0
  47. package/src/gl-operations/shaders/fragment/interpolateValue.js +124 -0
  48. package/src/gl-operations/shaders/fragment/multiAnalyze1Calc.js +36 -0
  49. package/src/gl-operations/shaders/fragment/multiAnalyze2Calc.js +46 -0
  50. package/src/gl-operations/shaders/fragment/multiAnalyze3Calc.js +54 -0
  51. package/src/gl-operations/shaders/fragment/multiAnalyze4Calc.js +62 -0
  52. package/src/gl-operations/shaders/fragment/multiAnalyze5Calc.js +70 -0
  53. package/src/gl-operations/shaders/fragment/multiAnalyze6Calc.js +78 -0
  54. package/src/gl-operations/shaders/fragment/single.js +88 -0
  55. package/src/gl-operations/shaders/transform.js +22 -0
  56. package/src/gl-operations/shaders/util/computeColor.glsl +84 -0
  57. package/src/gl-operations/shaders/util/getTexelValue.glsl +10 -0
  58. package/src/gl-operations/shaders/util/isCloseEnough.glsl +9 -0
  59. package/src/gl-operations/shaders/util/rgbaToFloat.glsl +18 -0
  60. package/src/gl-operations/shaders/vertex/double.js +17 -0
  61. package/src/gl-operations/shaders/vertex/multi3.js +20 -0
  62. package/src/gl-operations/shaders/vertex/multi4.js +23 -0
  63. package/src/gl-operations/shaders/vertex/multi5.js +26 -0
  64. package/src/gl-operations/shaders/vertex/multi6.js +29 -0
  65. package/src/gl-operations/shaders/vertex/single.js +13 -0
  66. package/src/gl-operations/shaders/vertex/singleNotTransformed.js +12 -0
  67. package/src/gl-operations/texture_manager.js +141 -0
  68. package/src/gl-operations/util.js +336 -0
  69. package/src/index.js +10 -0
  70. package/src/util.js +332 -0
  71. package/vite.config.js +52 -0
package/src/util.js ADDED
@@ -0,0 +1,332 @@
1
+ import { v4 as uuidv4 } from 'uuid'
2
+ import moment from 'moment'
3
+ import SparkMD5 from 'spark-md5'
4
+ import _ from 'lodash'
5
+ import {getPhotoTags} from './exif'
6
+ import cameras from './constants/cameras'
7
+ import * as turf from '@turf/turf'
8
+
9
+ export function generateId() { // 生成随机id
10
+ return uuidv4()
11
+ }
12
+ export function formatDate(date) {
13
+ if (!date) {
14
+ return '-'
15
+ }
16
+ return moment().format('YYYY-MM-DD HH:mm:ss')
17
+ }
18
+ export function formatLocalDate() {
19
+ return moment().format('YYYY/M/D HH:mm:ss')
20
+ }
21
+ export function formatFileSize (value) { // 文件大小格式化,自动换算kb\mb\gb
22
+ value = parseInt(value)
23
+ value = value.toString()
24
+ const length = value.length
25
+ if (length > 6) {
26
+ value = (Number(value) / 1000000).toFixed(2)
27
+ return value + ' MB'
28
+ } else {
29
+ value = (Number(value) / 1000).toFixed(2)
30
+ return value + ' KB'
31
+ }
32
+ }
33
+ export async function getPhotoInfo(file) { // 获取照片的经纬度
34
+ let sliceFile = file.slice(0, 65536)
35
+ sliceFile.name = file.name
36
+ let exif = await getPhotoTags(sliceFile)
37
+ let {GPSAltitude, GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef, DateTimeOriginal, Model} = exif
38
+ if (!GPSLongitude || !GPSLatitude) {
39
+ return {}
40
+ }
41
+ let date = DateTimeOriginal.split(' ')[0].replaceAll(':', '-')
42
+ return {
43
+ date,
44
+ Model,
45
+ position: {
46
+ lng: getGeoCoordOperator(GPSLongitudeRef) * toRadian(GPSLongitude),
47
+ lat: getGeoCoordOperator(GPSLatitudeRef) * toRadian(GPSLatitude),
48
+ alt: +GPSAltitude
49
+ }
50
+ }
51
+ }
52
+ export function getPhotoMeta(file) { // 获取照片的元数据,包括exif和md5,为了提高计算效率,只取前64k进行计算
53
+ return new Promise((resolve, reject) => {
54
+ let md5, exif
55
+ let sliceFile = file.slice(0, 65536)
56
+ sliceFile.name = file.name
57
+ getPhotoTags(sliceFile).then(data => {
58
+ exif = data
59
+ done()
60
+ })
61
+ let fileReader = new FileReader()
62
+ let spark = new SparkMD5.ArrayBuffer()
63
+ fileReader.readAsArrayBuffer(sliceFile)
64
+ fileReader.onload = e => {
65
+ spark.append(e.target.result)
66
+ md5 = spark.end()
67
+ done()
68
+ }
69
+ function done() {
70
+ if (!md5 || !exif) {
71
+ return
72
+ }
73
+ resolve({md5, exif})
74
+ fileReader = null
75
+ spark = null
76
+ }
77
+ })
78
+ }
79
+ export function getGeoCoordOperator(flag) { // 将照片的中的经纬度方位字母换成正负号
80
+ if (flag === 'N' || flag === 'E') {
81
+ return 1
82
+ }
83
+ return -1
84
+ }
85
+ export function toRadian(arr) { // 度分秒转弧度
86
+ return arr[0] + (arr[1] / 60) + (arr[2] / 3600)
87
+ }
88
+ export function diffLayers(newList, oldList = []) { // 任务详情中的任务成果树进行差异计算,获取图层更新的操作
89
+ newList = _formatTree(newList)
90
+ oldList = _formatTree(oldList)
91
+ let cmds = []
92
+ for(let group of newList) {
93
+ let {visible: groupVisible} = group
94
+ for(let layer of group.items || []) {
95
+ let {id, type, opacity, visible, color, geometry} = layer
96
+ if (!groupVisible) {
97
+ visible = false
98
+ }
99
+ if (['point', 'line', 'polygon'].includes(type) && cmds.find(d => d[0] === 'updateAnnotations')) {
100
+ continue
101
+ }
102
+ let oldNode = findNodeInTree(id, oldList)
103
+ if (!oldNode && !visible) {
104
+ continue
105
+ }
106
+ if (!oldNode) {
107
+ if (['point', 'line', 'polygon'].includes(type)) {
108
+ cmds.push(['updateAnnotations', layer])
109
+ } else {
110
+ cmds.push(['addLayer', layer])
111
+ }
112
+ continue
113
+ }
114
+ let {opacity: oldOpacity, visible: oldVisible} = oldNode
115
+ if (_.isEqual(layer, oldNode)) {
116
+ continue
117
+ }
118
+ if (['point', 'line', 'polygon'].includes(type)) {
119
+ cmds.push(['updateAnnotations', layer])
120
+ } if (opacity !== oldOpacity) {
121
+ cmds.push(['updateLayer', layer])
122
+ } else if (visible !== oldVisible){
123
+ cmds.push([visible?'addLayer':'removeLayer', layer])
124
+ }
125
+ }
126
+ }
127
+ for(let group of oldList) {
128
+ for(let layer of group.items || []) {
129
+ let {id, type} = layer
130
+ let newNode = findNodeInTree(id, newList)
131
+ if (!newNode) {
132
+ if (!['point', 'line', 'polygon'].includes(type)) {
133
+ cmds.push(['removeLayer', layer])
134
+ } else if (!cmds.find(d => d[0] === 'updateAnnotations')){
135
+ cmds.push(['updateAnnotations', layer])
136
+ }
137
+ }
138
+ }
139
+ }
140
+ return cmds
141
+ }
142
+ export function findNodeInTree(id, tree) { // 从图层树中查找指定
143
+ for(let node of tree) {
144
+ if (node.id === id) {
145
+ return node
146
+ }
147
+ if (node.items?.length) {
148
+ let subNode = findNodeInTree(id, node.items)
149
+ if (subNode) {
150
+ return subNode
151
+ }
152
+ }
153
+ }
154
+ return null
155
+ }
156
+ function _formatTree(treeList) {
157
+ let tree = _.cloneDeep(treeList)
158
+ for(let group of tree) {
159
+ for(let layer of group.items || []) {
160
+ if (!group.visible) {
161
+ layer.visible = false
162
+ }
163
+ }
164
+ }
165
+ return tree
166
+ }
167
+ // 获取比当前图层,层级更低的图层id
168
+ export function getBeforeId (map,layer){
169
+ let layersForFilter = map.style._layers
170
+ let orders = map.style.order
171
+ let {layerType:insertType} = layer.metadata
172
+ // 获取到level比当前大的
173
+ // 如果同级,则添加到最后
174
+ let beforeLayer = orders.find(id=>{
175
+ let targetData = layersForFilter[id].metadata
176
+ if(_.isEmpty(targetData)) {
177
+ targetData = {
178
+ layerType: 'dsm'
179
+ }
180
+ }
181
+ return getLevelByLayerType(insertType,layer.id) < getLevelByLayerType(targetData.layerType,id) ? true : false
182
+ })
183
+ return beforeLayer || ''
184
+
185
+ function getLevelByLayerType (type,id){
186
+ // 此数组维护一个图层类型的先后关系
187
+ // 越在前,则代表此图层层级越低
188
+ const layerTypeLevel = [
189
+ ['bmap'],
190
+ ['dom'],
191
+ ['ndvi'],
192
+ ['dsm'],
193
+ ['circle'],
194
+ ['annotation'],
195
+ ['label']
196
+ ]
197
+ let level = -1
198
+ if (id.startsWith('gl-draw')) {
199
+ level = 5
200
+ } else {
201
+ level = layerTypeLevel.findIndex(types=>{
202
+ return types.includes(type)
203
+ })
204
+ }
205
+
206
+ if(level === -1){
207
+ //console.error(`id为${id}的图层层级未知`)
208
+ return 100
209
+ }
210
+ return level
211
+ }
212
+ }
213
+ export function isTokenExpired(response) {
214
+ if (!response) {
215
+ return false
216
+ }
217
+ let {message = '', msg =''} = response.data
218
+ return response.status == 401 && (msg.toLowerCase().includes('expired') || message.toLowerCase().includes('expired'))
219
+ }
220
+ export function getDataType(model) { // 根据相机型号获取照片的类型
221
+ for(let type in cameras) {
222
+ if (cameras[type].includes(model)) {
223
+ return type
224
+ }
225
+ }
226
+ return 'normal'
227
+ }
228
+ export function downloadImage(base64) {
229
+ let filename = `快照${moment().format('YYYYMMDD')}${new Date().getTime()}.png`
230
+ let a = document.createElement('a')
231
+ a.href = base64
232
+ a.download = filename
233
+ document.body.appendChild(a)
234
+ a.click()
235
+ document.body.removeChild(a)
236
+ }
237
+ export function getGeometryType(feature) {
238
+ let type = turf.getType(feature)
239
+ if (['Point', 'MultiPoint'].includes(type)) {
240
+ return 'point'
241
+ } else if (['LineString', 'MultiLineString'].includes(type)) {
242
+ return 'line'
243
+ } else {
244
+ return 'polygon'
245
+ }
246
+ }
247
+ export function rgbaToFloat(v) {
248
+ let a = v[3] > 128.0 ? 0 : 1
249
+ let sign = -1 * (1 - a) + a;
250
+ let expo = Math.floor((v[3] + 0.1) % 128.0) * 2.0 + Math.floor((v[2] + 0.1) / 128.0) - 127.0;
251
+ let sig = v[0] + v[1] * 256.0 + Math.floor((v[2] + 0.1) % 128.0) * 256.0 * 256.0;
252
+ return sign * (1.0 + sig / 8388607.0) * Math.pow(2.0, expo);
253
+ }
254
+ export function getAnnotationFeature(annotationItem) {
255
+ let {geometry} = annotationItem
256
+ let properties = _.cloneDeep(annotationItem)
257
+ delete properties.geometry
258
+ return {
259
+ id: properties.id,
260
+ type: 'Feature',
261
+ properties,
262
+ geometry: _.cloneDeep(geometry)
263
+ }
264
+ }
265
+ export function getAnnotationName(annotations, type) {
266
+ let indexs = []
267
+ let name = type === 'point' ? '点注记' : (type === 'line' ? '线注记' : '面注记')
268
+ annotations.forEach(item => {
269
+ if (item.name === name) {
270
+ indexs.push(0)
271
+ return
272
+ }
273
+ if (item.name.startsWith(`${name} `)) {
274
+ let i = Number(item.name.split(' ').pop())
275
+ if (!Number.isNaN(i)) {
276
+ indexs.push(i)
277
+ }
278
+ }
279
+ })
280
+ indexs = indexs.sort((a, b) => a-b)
281
+ for(let i = 0;i < indexs.length;i++) {
282
+ if (indexs[i] !== i) {
283
+ return i === 0 ? name : `${name} ${i}`
284
+ }
285
+ }
286
+ return indexs.length === 0 ? name : `${name} ${indexs.length}`
287
+ }
288
+ export function getLineLabelFeature(lineFeature) {
289
+ let coordinates = lineFeature.geometry.coordinates
290
+ let temps = []
291
+ for(let i = 1;i < coordinates.length;i++) {
292
+ let distance = turf.distance(coordinates[i-1], coordinates[i], {units: 'meters'})
293
+ if (distance > 30) {
294
+ temps.push([coordinates[i-1], coordinates[i]])
295
+ }
296
+ }
297
+ let labelLine = []
298
+ if (!temps.length) {
299
+ let mid = Math.floor(coordinates.length / 2 - 1)
300
+ labelLine = [coordinates[mid], coordinates[mid+1]]
301
+ } else {
302
+ let mid = Math.floor(temps.length / 2)
303
+ labelLine = temps[mid]
304
+ }
305
+ let start = project(labelLine[0])
306
+ let end = project(labelLine[1])
307
+ let angle = 360 - (Math.atan((start.y - end.y) / (end.x - start.x)) * 180) / Math.PI
308
+ let midPoint = turf.midpoint(labelLine[0], labelLine[1])
309
+ midPoint.properties = lineFeature.properties
310
+ midPoint.properties.angle = angle
311
+ midPoint.geometry.coordinates.push(((labelLine[0][2] || 0) + (labelLine[1][2] || 0)) / 2)
312
+ return midPoint
313
+ }
314
+ export function project(lngLat) { // 经纬度转墨卡托像素坐标
315
+ let [lng, lat] = lngLat
316
+ let x = (180 + lng) / 360
317
+ let y = (180 - (180 / Math.PI) * Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 360))) / 360
318
+ return {
319
+ x: x * Math.pow(2, 12) * 512,
320
+ y: y * Math.pow(2, 12) * 512
321
+ }
322
+ }
323
+ export function addIcons2Map (map, icons) {
324
+ icons.forEach(path => {
325
+ map.loadImage(path, (error, image) => {
326
+ let iconName = path.split('/').pop().split('.')[0]
327
+ if(map.hasImage(iconName)) return
328
+ if (error) throw error
329
+ map.addImage(iconName, image)
330
+ })
331
+ })
332
+ }
package/vite.config.js ADDED
@@ -0,0 +1,52 @@
1
+ import { defineConfig } from "vite";
2
+ import glslify from 'vite-plugin-glslify'
3
+
4
+ const path = require("path");
5
+
6
+ const config = defineConfig({
7
+ target: "es2015",
8
+ plugins: [glslify()],
9
+ server: {
10
+ port: 5173,
11
+ },
12
+ build: {
13
+ outDir: path.resolve(__dirname, "./dist"),
14
+ lib: {
15
+ entry: path.resolve(__dirname, "./src/index.js"),
16
+ name: "catchUtil",
17
+ },
18
+ rollupOptions: {
19
+ context: "globalThis",
20
+ preserveEntrySignatures: "strict",
21
+ output: [
22
+ {
23
+ format: "umd",
24
+ exports: "named",
25
+ sourcemap: false,
26
+ entryFileNames: "catchUtil.min.js",
27
+ chunkFileNames: "[name].js",
28
+ assetFileNames: "[name].[ext]",
29
+ namespaceToStringTag: true,
30
+ inlineDynamicImports: false,
31
+ manualChunks: undefined
32
+ },
33
+ {
34
+ format: "es",
35
+ exports: "named",
36
+ sourcemap: false,
37
+ entryFileNames: "catchUtil.min.esm.js",
38
+ chunkFileNames: "[name].js",
39
+ assetFileNames: "[name].[ext]",
40
+ namespaceToStringTag: true,
41
+ inlineDynamicImports: false,
42
+ manualChunks: undefined
43
+ },
44
+ ],
45
+ },
46
+ },
47
+ resolve: {
48
+ extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"],
49
+ },
50
+ });
51
+
52
+ export default config;