af-mobile-client-vue3 1.1.43 → 1.1.45
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 +115 -115
- package/src/components/core/ImageUploader/index.vue +160 -160
- package/src/components/data/XBadge/index.vue +2 -2
- package/src/components/data/XCellList/index.vue +1 -1
- package/src/components/data/XOlMap/index.vue +162 -1
- package/src/components/data/XOlMap/types.ts +11 -0
- package/src/components/data/XOlMap/utils/wgs84ToGcj02.js +154 -154
- package/src/styles/fontawesome-icons.ts +7 -7
- package/src/utils/queryFormDefaultRangePicker.ts +57 -57
- package/src/views/component/XCellListView/index.vue +136 -13
- package/src/views/component/XFormGroupView/index.vue +42 -2
- package/src/views/component/XFormView/index.vue +3 -6
- package/src/views/component/XOlMapView/XLocationPicker/index.vue +118 -118
- package/src/views/component/XOlMapView/index.vue +17 -0
- package/src/views/component/XOlMapView/testData.ts +64 -0
- package/vite.config.ts +11 -11
- package/src/views/component/XFormView/oldindex.vue +0 -70
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
WebGLPointOptions,
|
|
16
16
|
WMSLayerConfig,
|
|
17
17
|
WMSOptions,
|
|
18
|
+
TrackData,
|
|
18
19
|
} from './types'
|
|
19
20
|
import locationIcon from '@af-mobile-client-vue3/assets/img/component/positioning.png'
|
|
20
21
|
import { getConfigByName } from '@af-mobile-client-vue3/services/api/common'
|
|
@@ -23,11 +24,12 @@ import { Map, View } from 'ol'
|
|
|
23
24
|
import { defaults as defaultControls, ScaleLine } from 'ol/control'
|
|
24
25
|
import Feature from 'ol/Feature'
|
|
25
26
|
import Point from 'ol/geom/Point'
|
|
27
|
+
import LineString from 'ol/geom/LineString'
|
|
26
28
|
import { defaults as defaultInteractions } from 'ol/interaction'
|
|
27
29
|
import { Image as ImageLayer, Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
|
|
28
30
|
import { fromLonLat, toLonLat } from 'ol/proj'
|
|
29
31
|
import { ImageWMS, Vector as VectorSource, XYZ } from 'ol/source'
|
|
30
|
-
import { Fill, Icon, Stroke, Style, Text } from 'ol/style'
|
|
32
|
+
import { Fill, Icon, Stroke, Style, Text, Circle } from 'ol/style'
|
|
31
33
|
import { Button } from 'vant'
|
|
32
34
|
import { getCurrentInstance, onUnmounted, ref } from 'vue'
|
|
33
35
|
import { wgs84ToGcj02Projection } from './utils/wgs84ToGcj02'
|
|
@@ -83,6 +85,10 @@ let locationTimer: ReturnType<typeof setInterval> | null = null
|
|
|
83
85
|
/** 位置图标图层 */
|
|
84
86
|
let locationLayer: VectorLayer<VectorSource> | null = null
|
|
85
87
|
|
|
88
|
+
/** 存储轨迹图层 */
|
|
89
|
+
const trackLayers: Record<number, VectorLayer<VectorSource>> = {}
|
|
90
|
+
const trackLayerStatus = ref<TrackData[]>([])
|
|
91
|
+
|
|
86
92
|
/**
|
|
87
93
|
* 创建位置图标图层
|
|
88
94
|
*/
|
|
@@ -890,6 +896,139 @@ function navigationHandleLocation() {
|
|
|
890
896
|
}
|
|
891
897
|
}
|
|
892
898
|
|
|
899
|
+
/**
|
|
900
|
+
* 添加轨迹图层
|
|
901
|
+
* @param trackData - 轨迹数据
|
|
902
|
+
*/
|
|
903
|
+
function addTrackLayer(trackData: TrackData): void {
|
|
904
|
+
if (!map)
|
|
905
|
+
return
|
|
906
|
+
|
|
907
|
+
const vectorSource = new VectorSource()
|
|
908
|
+
const vectorLayer = new VectorLayer({
|
|
909
|
+
source: vectorSource,
|
|
910
|
+
visible: true,
|
|
911
|
+
zIndex: 2,
|
|
912
|
+
})
|
|
913
|
+
|
|
914
|
+
// 创建轨迹线要素
|
|
915
|
+
const coordinates = trackData.trackData.map(coord => fromLonLat(coord))
|
|
916
|
+
const lineString = new Feature({
|
|
917
|
+
geometry: new LineString(coordinates),
|
|
918
|
+
})
|
|
919
|
+
|
|
920
|
+
// 设置轨迹线样式
|
|
921
|
+
const lineStyle = new Style({
|
|
922
|
+
stroke: new Stroke({
|
|
923
|
+
color: trackData.color,
|
|
924
|
+
width: 3,
|
|
925
|
+
}),
|
|
926
|
+
})
|
|
927
|
+
lineString.setStyle(lineStyle)
|
|
928
|
+
|
|
929
|
+
// 创建起点和终点图标
|
|
930
|
+
const startPoint = new Feature({
|
|
931
|
+
geometry: new Point(coordinates[0]),
|
|
932
|
+
})
|
|
933
|
+
const endPoint = new Feature({
|
|
934
|
+
geometry: new Point(coordinates[coordinates.length - 1]),
|
|
935
|
+
})
|
|
936
|
+
|
|
937
|
+
// 设置起点图标样式 - 使用绿色圆形图标
|
|
938
|
+
const startStyle = new Style({
|
|
939
|
+
image: new Circle({
|
|
940
|
+
radius: 8,
|
|
941
|
+
fill: new Fill({
|
|
942
|
+
color: '#4CAF50',
|
|
943
|
+
}),
|
|
944
|
+
stroke: new Stroke({
|
|
945
|
+
color: '#fff',
|
|
946
|
+
width: 2,
|
|
947
|
+
}),
|
|
948
|
+
}),
|
|
949
|
+
text: new Text({
|
|
950
|
+
text: '起点',
|
|
951
|
+
offsetY: -15,
|
|
952
|
+
font: '12px sans-serif',
|
|
953
|
+
fill: new Fill({
|
|
954
|
+
color: '#333',
|
|
955
|
+
}),
|
|
956
|
+
stroke: new Stroke({
|
|
957
|
+
color: '#fff',
|
|
958
|
+
width: 2,
|
|
959
|
+
}),
|
|
960
|
+
}),
|
|
961
|
+
})
|
|
962
|
+
|
|
963
|
+
// 设置终点图标样式 - 使用红色圆形图标
|
|
964
|
+
const endStyle = new Style({
|
|
965
|
+
image: new Circle({
|
|
966
|
+
radius: 8,
|
|
967
|
+
fill: new Fill({
|
|
968
|
+
color: '#F44336',
|
|
969
|
+
}),
|
|
970
|
+
stroke: new Stroke({
|
|
971
|
+
color: '#fff',
|
|
972
|
+
width: 2,
|
|
973
|
+
}),
|
|
974
|
+
}),
|
|
975
|
+
text: new Text({
|
|
976
|
+
text: '终点',
|
|
977
|
+
offsetY: -15,
|
|
978
|
+
font: '12px sans-serif',
|
|
979
|
+
fill: new Fill({
|
|
980
|
+
color: '#333',
|
|
981
|
+
}),
|
|
982
|
+
stroke: new Stroke({
|
|
983
|
+
color: '#fff',
|
|
984
|
+
width: 2,
|
|
985
|
+
}),
|
|
986
|
+
}),
|
|
987
|
+
})
|
|
988
|
+
|
|
989
|
+
startPoint.setStyle(startStyle)
|
|
990
|
+
endPoint.setStyle(endStyle)
|
|
991
|
+
|
|
992
|
+
// 添加要素到图层
|
|
993
|
+
vectorSource.addFeatures([lineString, startPoint, endPoint])
|
|
994
|
+
|
|
995
|
+
// 添加到地图
|
|
996
|
+
map.addLayer(vectorLayer)
|
|
997
|
+
trackLayers[trackData.id] = vectorLayer
|
|
998
|
+
|
|
999
|
+
// 更新图层状态,确保 show 属性被正确设置
|
|
1000
|
+
const trackDataWithShow = {
|
|
1001
|
+
...trackData,
|
|
1002
|
+
show: true, // 默认显示
|
|
1003
|
+
}
|
|
1004
|
+
trackLayerStatus.value.push(trackDataWithShow)
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* 控制轨迹图层显示/隐藏
|
|
1009
|
+
* @param trackId - 轨迹ID
|
|
1010
|
+
* @param visible - 是否显示
|
|
1011
|
+
*/
|
|
1012
|
+
function setTrackLayerVisible(trackId: number, visible: boolean): void {
|
|
1013
|
+
const layer = trackLayers[trackId]
|
|
1014
|
+
if (layer) {
|
|
1015
|
+
layer.setVisible(visible)
|
|
1016
|
+
// 更新图层状态
|
|
1017
|
+
const layerIndex = trackLayerStatus.value.findIndex(layer => layer.id === trackId)
|
|
1018
|
+
if (layerIndex !== -1) {
|
|
1019
|
+
trackLayerStatus.value[layerIndex].show = visible
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
/**
|
|
1025
|
+
* 切换轨迹图层显示状态
|
|
1026
|
+
*/
|
|
1027
|
+
function handleToggleTrackLayer(track: TrackData): void {
|
|
1028
|
+
track.show = !track.show
|
|
1029
|
+
setTrackLayerVisible(track.id, track.show)
|
|
1030
|
+
}
|
|
1031
|
+
|
|
893
1032
|
// 暴露方法给父组件
|
|
894
1033
|
defineExpose({
|
|
895
1034
|
init,
|
|
@@ -909,6 +1048,9 @@ defineExpose({
|
|
|
909
1048
|
handleLocation,
|
|
910
1049
|
startNavigation,
|
|
911
1050
|
stopNavigation,
|
|
1051
|
+
addTrackLayer,
|
|
1052
|
+
setTrackLayerVisible,
|
|
1053
|
+
handleToggleTrackLayer,
|
|
912
1054
|
})
|
|
913
1055
|
|
|
914
1056
|
// 组件卸载时清理地图实例
|
|
@@ -1008,6 +1150,25 @@ onUnmounted(() => {
|
|
|
1008
1150
|
</div>
|
|
1009
1151
|
</div>
|
|
1010
1152
|
</div>
|
|
1153
|
+
|
|
1154
|
+
<!-- 轨迹图层 -->
|
|
1155
|
+
<div v-if="trackLayerStatus.length > 0" class="control-panel layer-control">
|
|
1156
|
+
<div class="control-title">
|
|
1157
|
+
<i class="van-icon van-icon-location-o" /> 轨迹图层
|
|
1158
|
+
</div>
|
|
1159
|
+
<div class="layer-list">
|
|
1160
|
+
<div
|
|
1161
|
+
v-for="track in trackLayerStatus"
|
|
1162
|
+
:key="track.id"
|
|
1163
|
+
class="layer-item"
|
|
1164
|
+
:class="{ active: track.show }"
|
|
1165
|
+
@click="handleToggleTrackLayer(track)"
|
|
1166
|
+
>
|
|
1167
|
+
<i class="van-icon" :class="track.show ? 'van-icon-eye' : 'van-icon-closed-eye'" />
|
|
1168
|
+
<span>{{ track.name }}</span>
|
|
1169
|
+
</div>
|
|
1170
|
+
</div>
|
|
1171
|
+
</div>
|
|
1011
1172
|
</div>
|
|
1012
1173
|
</div>
|
|
1013
1174
|
</div>
|
|
@@ -132,3 +132,14 @@ export interface WMSOptions {
|
|
|
132
132
|
/** WMS 服务配置 */
|
|
133
133
|
wms: WMSConfig
|
|
134
134
|
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* 轨迹数据类型
|
|
138
|
+
*/
|
|
139
|
+
export interface TrackData {
|
|
140
|
+
id: number
|
|
141
|
+
name: string
|
|
142
|
+
trackData: [number, number][] // 经纬度数组
|
|
143
|
+
color: string
|
|
144
|
+
show?: boolean // 是否显示
|
|
145
|
+
}
|
|
@@ -1,154 +1,154 @@
|
|
|
1
|
-
// 导入proj控件
|
|
2
|
-
import * as proj from 'ol/proj'
|
|
3
|
-
|
|
4
|
-
function forEachPoint(func) {
|
|
5
|
-
return function (input, opt_output, opt_dimension) {
|
|
6
|
-
const len = input.length
|
|
7
|
-
|
|
8
|
-
const dimension = opt_dimension || 2
|
|
9
|
-
let output
|
|
10
|
-
|
|
11
|
-
if (opt_output) {
|
|
12
|
-
output = opt_output
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
if (dimension !== 2) {
|
|
16
|
-
output = input.slice()
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
output = [len]
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
for (let offset = 0; offset < len; offset += dimension) {
|
|
23
|
-
func(input, output, offset)
|
|
24
|
-
}
|
|
25
|
-
return output
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const gcj02 = {}
|
|
30
|
-
const PI = Math.PI
|
|
31
|
-
const AXIS = 6378245.0
|
|
32
|
-
// eslint-disable-next-line no-loss-of-precision
|
|
33
|
-
const OFFSET = 0.00669342162296594323 // (a^2 - b^2) / a^2
|
|
34
|
-
|
|
35
|
-
function delta(wgLon, wgLat) {
|
|
36
|
-
let dLat = transformLat(wgLon - 105.0, wgLat - 35.0)
|
|
37
|
-
let dLon = transformLon(wgLon - 105.0, wgLat - 35.0)
|
|
38
|
-
const radLat = (wgLat / 180.0) * PI
|
|
39
|
-
let magic = Math.sin(radLat)
|
|
40
|
-
magic = 1 - OFFSET * magic * magic
|
|
41
|
-
const sqrtMagic = Math.sqrt(magic)
|
|
42
|
-
dLat = (dLat * 180.0) / (((AXIS * (1 - OFFSET)) / (magic * sqrtMagic)) * PI)
|
|
43
|
-
dLon = (dLon * 180.0) / ((AXIS / sqrtMagic) * Math.cos(radLat) * PI)
|
|
44
|
-
return [dLon, dLat]
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function outOfChina(lon, lat) {
|
|
48
|
-
if (lon < 72.004 || lon > 137.8347) {
|
|
49
|
-
return true
|
|
50
|
-
}
|
|
51
|
-
return lat < 0.8293 || lat > 55.8271
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function transformLat(x, y) {
|
|
55
|
-
let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x))
|
|
56
|
-
ret += ((20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0) / 3.0
|
|
57
|
-
ret += ((20.0 * Math.sin(y * PI) + 40.0 * Math.sin((y / 3.0) * PI)) * 2.0) / 3.0
|
|
58
|
-
ret += ((160.0 * Math.sin((y / 12.0) * PI) + 320 * Math.sin((y * PI) / 30.0)) * 2.0) / 3.0
|
|
59
|
-
return ret
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function transformLon(x, y) {
|
|
63
|
-
let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x))
|
|
64
|
-
ret += ((20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0) / 3.0
|
|
65
|
-
ret += ((20.0 * Math.sin(x * PI) + 40.0 * Math.sin((x / 3.0) * PI)) * 2.0) / 3.0
|
|
66
|
-
ret += ((150.0 * Math.sin((x / 12.0) * PI) + 300.0 * Math.sin((x / 30.0) * PI)) * 2.0) / 3.0
|
|
67
|
-
return ret
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
gcj02.toWGS84 = forEachPoint((input, output, offset) => {
|
|
71
|
-
let lng = input[offset]
|
|
72
|
-
let lat = input[offset + 1]
|
|
73
|
-
if (!outOfChina(lng, lat)) {
|
|
74
|
-
const deltaD = delta(lng, lat)
|
|
75
|
-
lng = lng - deltaD[0] // 改回减法
|
|
76
|
-
lat = lat - deltaD[1] // 改回减法
|
|
77
|
-
}
|
|
78
|
-
output[offset] = lng
|
|
79
|
-
output[offset + 1] = lat
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
gcj02.fromWGS84 = forEachPoint((input, output, offset) => {
|
|
83
|
-
let lng = input[offset]
|
|
84
|
-
let lat = input[offset + 1]
|
|
85
|
-
if (!outOfChina(lng, lat)) {
|
|
86
|
-
const deltaD = delta(lng, lat)
|
|
87
|
-
lng = lng + deltaD[0] // 改回加法
|
|
88
|
-
lat = lat + deltaD[1] // 改回加法
|
|
89
|
-
}
|
|
90
|
-
output[offset] = lng
|
|
91
|
-
output[offset + 1] = lat
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
const sphericalMercator = {}
|
|
95
|
-
const RADIUS = 6378137
|
|
96
|
-
const MAX_LATITUDE = 85.0511287798
|
|
97
|
-
const RAD_PER_DEG = Math.PI / 180
|
|
98
|
-
|
|
99
|
-
sphericalMercator.forward = forEachPoint((input, output, offset) => {
|
|
100
|
-
const lat = Math.max(Math.min(MAX_LATITUDE, input[offset + 1]), -MAX_LATITUDE)
|
|
101
|
-
const sin = Math.sin(lat * RAD_PER_DEG)
|
|
102
|
-
output[offset] = RADIUS * input[offset] * RAD_PER_DEG
|
|
103
|
-
output[offset + 1] = (RADIUS * Math.log((1 + sin) / (1 - sin))) / 2
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
sphericalMercator.inverse = forEachPoint((input, output, offset) => {
|
|
107
|
-
output[offset] = input[offset] / RADIUS / RAD_PER_DEG
|
|
108
|
-
output[offset + 1] = (2 * Math.atan(Math.exp(input[offset + 1] / RADIUS)) - Math.PI / 2) / RAD_PER_DEG
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
const projzh = {}
|
|
112
|
-
|
|
113
|
-
projzh.ll2gmerc = function (input, opt_output, opt_dimension) {
|
|
114
|
-
const output = gcj02.toWGS84(input, opt_output, opt_dimension) // 改用 toWGS84
|
|
115
|
-
return projzh.ll2smerc(output, output, opt_dimension)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
projzh.gmerc2ll = function (input, opt_output, opt_dimension) {
|
|
119
|
-
const output = projzh.smerc2ll(input, input, opt_dimension)
|
|
120
|
-
return gcj02.fromWGS84(output, opt_output, opt_dimension) // 改用 fromWGS84
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// smerc2gmerc 需要修改
|
|
124
|
-
|
|
125
|
-
projzh.smerc2gmerc = function (input, opt_output, opt_dimension) {
|
|
126
|
-
let output = projzh.smerc2ll(input, input, opt_dimension)
|
|
127
|
-
output = gcj02.toWGS84(output, output, opt_dimension) // 这里应该用 toWGS84
|
|
128
|
-
return projzh.ll2smerc(output, output, opt_dimension)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// gmerc2smerc 需要修改
|
|
132
|
-
|
|
133
|
-
projzh.gmerc2smerc = function (input, opt_output, opt_dimension) {
|
|
134
|
-
let output = projzh.smerc2ll(input, input, opt_dimension)
|
|
135
|
-
output = gcj02.fromWGS84(output, output, opt_dimension) // 这里应该用 fromWGS84
|
|
136
|
-
return projzh.ll2smerc(output, output, opt_dimension)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
projzh.ll2smerc = sphericalMercator.forward
|
|
140
|
-
projzh.smerc2ll = sphericalMercator.inverse
|
|
141
|
-
|
|
142
|
-
// 定义WGS84转GCJ02的投影
|
|
143
|
-
const extent = [-20037508.342789244, -20037508.342789244, 20037508.342789244, 20037508.342789244]
|
|
144
|
-
export const wgs84ToGcj02Projection = new proj.Projection({
|
|
145
|
-
code: 'WGS84-TO-GCJ02',
|
|
146
|
-
extent,
|
|
147
|
-
units: 'm',
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
// 添加投影和转换方法
|
|
151
|
-
proj.addProjection(wgs84ToGcj02Projection)
|
|
152
|
-
// 注意这里转换方法的顺序与原来相反
|
|
153
|
-
proj.addCoordinateTransforms('EPSG:4326', wgs84ToGcj02Projection, projzh.ll2gmerc, projzh.gmerc2ll)
|
|
154
|
-
proj.addCoordinateTransforms('EPSG:3857', wgs84ToGcj02Projection, projzh.smerc2gmerc, projzh.gmerc2smerc)
|
|
1
|
+
// 导入proj控件
|
|
2
|
+
import * as proj from 'ol/proj'
|
|
3
|
+
|
|
4
|
+
function forEachPoint(func) {
|
|
5
|
+
return function (input, opt_output, opt_dimension) {
|
|
6
|
+
const len = input.length
|
|
7
|
+
|
|
8
|
+
const dimension = opt_dimension || 2
|
|
9
|
+
let output
|
|
10
|
+
|
|
11
|
+
if (opt_output) {
|
|
12
|
+
output = opt_output
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
if (dimension !== 2) {
|
|
16
|
+
output = input.slice()
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
output = [len]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
for (let offset = 0; offset < len; offset += dimension) {
|
|
23
|
+
func(input, output, offset)
|
|
24
|
+
}
|
|
25
|
+
return output
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const gcj02 = {}
|
|
30
|
+
const PI = Math.PI
|
|
31
|
+
const AXIS = 6378245.0
|
|
32
|
+
// eslint-disable-next-line no-loss-of-precision
|
|
33
|
+
const OFFSET = 0.00669342162296594323 // (a^2 - b^2) / a^2
|
|
34
|
+
|
|
35
|
+
function delta(wgLon, wgLat) {
|
|
36
|
+
let dLat = transformLat(wgLon - 105.0, wgLat - 35.0)
|
|
37
|
+
let dLon = transformLon(wgLon - 105.0, wgLat - 35.0)
|
|
38
|
+
const radLat = (wgLat / 180.0) * PI
|
|
39
|
+
let magic = Math.sin(radLat)
|
|
40
|
+
magic = 1 - OFFSET * magic * magic
|
|
41
|
+
const sqrtMagic = Math.sqrt(magic)
|
|
42
|
+
dLat = (dLat * 180.0) / (((AXIS * (1 - OFFSET)) / (magic * sqrtMagic)) * PI)
|
|
43
|
+
dLon = (dLon * 180.0) / ((AXIS / sqrtMagic) * Math.cos(radLat) * PI)
|
|
44
|
+
return [dLon, dLat]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function outOfChina(lon, lat) {
|
|
48
|
+
if (lon < 72.004 || lon > 137.8347) {
|
|
49
|
+
return true
|
|
50
|
+
}
|
|
51
|
+
return lat < 0.8293 || lat > 55.8271
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function transformLat(x, y) {
|
|
55
|
+
let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x))
|
|
56
|
+
ret += ((20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0) / 3.0
|
|
57
|
+
ret += ((20.0 * Math.sin(y * PI) + 40.0 * Math.sin((y / 3.0) * PI)) * 2.0) / 3.0
|
|
58
|
+
ret += ((160.0 * Math.sin((y / 12.0) * PI) + 320 * Math.sin((y * PI) / 30.0)) * 2.0) / 3.0
|
|
59
|
+
return ret
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function transformLon(x, y) {
|
|
63
|
+
let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x))
|
|
64
|
+
ret += ((20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0) / 3.0
|
|
65
|
+
ret += ((20.0 * Math.sin(x * PI) + 40.0 * Math.sin((x / 3.0) * PI)) * 2.0) / 3.0
|
|
66
|
+
ret += ((150.0 * Math.sin((x / 12.0) * PI) + 300.0 * Math.sin((x / 30.0) * PI)) * 2.0) / 3.0
|
|
67
|
+
return ret
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
gcj02.toWGS84 = forEachPoint((input, output, offset) => {
|
|
71
|
+
let lng = input[offset]
|
|
72
|
+
let lat = input[offset + 1]
|
|
73
|
+
if (!outOfChina(lng, lat)) {
|
|
74
|
+
const deltaD = delta(lng, lat)
|
|
75
|
+
lng = lng - deltaD[0] // 改回减法
|
|
76
|
+
lat = lat - deltaD[1] // 改回减法
|
|
77
|
+
}
|
|
78
|
+
output[offset] = lng
|
|
79
|
+
output[offset + 1] = lat
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
gcj02.fromWGS84 = forEachPoint((input, output, offset) => {
|
|
83
|
+
let lng = input[offset]
|
|
84
|
+
let lat = input[offset + 1]
|
|
85
|
+
if (!outOfChina(lng, lat)) {
|
|
86
|
+
const deltaD = delta(lng, lat)
|
|
87
|
+
lng = lng + deltaD[0] // 改回加法
|
|
88
|
+
lat = lat + deltaD[1] // 改回加法
|
|
89
|
+
}
|
|
90
|
+
output[offset] = lng
|
|
91
|
+
output[offset + 1] = lat
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const sphericalMercator = {}
|
|
95
|
+
const RADIUS = 6378137
|
|
96
|
+
const MAX_LATITUDE = 85.0511287798
|
|
97
|
+
const RAD_PER_DEG = Math.PI / 180
|
|
98
|
+
|
|
99
|
+
sphericalMercator.forward = forEachPoint((input, output, offset) => {
|
|
100
|
+
const lat = Math.max(Math.min(MAX_LATITUDE, input[offset + 1]), -MAX_LATITUDE)
|
|
101
|
+
const sin = Math.sin(lat * RAD_PER_DEG)
|
|
102
|
+
output[offset] = RADIUS * input[offset] * RAD_PER_DEG
|
|
103
|
+
output[offset + 1] = (RADIUS * Math.log((1 + sin) / (1 - sin))) / 2
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
sphericalMercator.inverse = forEachPoint((input, output, offset) => {
|
|
107
|
+
output[offset] = input[offset] / RADIUS / RAD_PER_DEG
|
|
108
|
+
output[offset + 1] = (2 * Math.atan(Math.exp(input[offset + 1] / RADIUS)) - Math.PI / 2) / RAD_PER_DEG
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
const projzh = {}
|
|
112
|
+
|
|
113
|
+
projzh.ll2gmerc = function (input, opt_output, opt_dimension) {
|
|
114
|
+
const output = gcj02.toWGS84(input, opt_output, opt_dimension) // 改用 toWGS84
|
|
115
|
+
return projzh.ll2smerc(output, output, opt_dimension)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
projzh.gmerc2ll = function (input, opt_output, opt_dimension) {
|
|
119
|
+
const output = projzh.smerc2ll(input, input, opt_dimension)
|
|
120
|
+
return gcj02.fromWGS84(output, opt_output, opt_dimension) // 改用 fromWGS84
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// smerc2gmerc 需要修改
|
|
124
|
+
|
|
125
|
+
projzh.smerc2gmerc = function (input, opt_output, opt_dimension) {
|
|
126
|
+
let output = projzh.smerc2ll(input, input, opt_dimension)
|
|
127
|
+
output = gcj02.toWGS84(output, output, opt_dimension) // 这里应该用 toWGS84
|
|
128
|
+
return projzh.ll2smerc(output, output, opt_dimension)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// gmerc2smerc 需要修改
|
|
132
|
+
|
|
133
|
+
projzh.gmerc2smerc = function (input, opt_output, opt_dimension) {
|
|
134
|
+
let output = projzh.smerc2ll(input, input, opt_dimension)
|
|
135
|
+
output = gcj02.fromWGS84(output, output, opt_dimension) // 这里应该用 fromWGS84
|
|
136
|
+
return projzh.ll2smerc(output, output, opt_dimension)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
projzh.ll2smerc = sphericalMercator.forward
|
|
140
|
+
projzh.smerc2ll = sphericalMercator.inverse
|
|
141
|
+
|
|
142
|
+
// 定义WGS84转GCJ02的投影
|
|
143
|
+
const extent = [-20037508.342789244, -20037508.342789244, 20037508.342789244, 20037508.342789244]
|
|
144
|
+
export const wgs84ToGcj02Projection = new proj.Projection({
|
|
145
|
+
code: 'WGS84-TO-GCJ02',
|
|
146
|
+
extent,
|
|
147
|
+
units: 'm',
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// 添加投影和转换方法
|
|
151
|
+
proj.addProjection(wgs84ToGcj02Projection)
|
|
152
|
+
// 注意这里转换方法的顺序与原来相反
|
|
153
|
+
proj.addCoordinateTransforms('EPSG:4326', wgs84ToGcj02Projection, projzh.ll2gmerc, projzh.gmerc2ll)
|
|
154
|
+
proj.addCoordinateTransforms('EPSG:3857', wgs84ToGcj02Projection, projzh.smerc2gmerc, projzh.gmerc2smerc)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { library } from '@fortawesome/fontawesome-svg-core'
|
|
2
|
-
import { faFilter, faFlag, faPhone, faQrcode, faUser } from '@fortawesome/free-solid-svg-icons'
|
|
3
|
-
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
|
4
|
-
|
|
5
|
-
library.add(faPhone, faUser, faFlag, faFilter, faQrcode)
|
|
6
|
-
|
|
7
|
-
export default FontAwesomeIcon
|
|
1
|
+
import { library } from '@fortawesome/fontawesome-svg-core'
|
|
2
|
+
import { faFilter, faFlag, faPhone, faQrcode, faUser } from '@fortawesome/free-solid-svg-icons'
|
|
3
|
+
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
|
4
|
+
|
|
5
|
+
library.add(faPhone, faUser, faFlag, faFilter, faQrcode)
|
|
6
|
+
|
|
7
|
+
export default FontAwesomeIcon
|
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 根据类型获取日期区间字符串
|
|
3
|
-
* @param type '当年' | 'curMonth' | '当日'
|
|
4
|
-
* @param show 区分实际值还是显示值, true为实际值, false为显示值
|
|
5
|
-
* @returns [start, end] 例:['2024-01-01 00:00:00', '2024-12-31 23:59:59']
|
|
6
|
-
*/
|
|
7
|
-
export function getRangeByType(type: string, show: boolean): [string, string] {
|
|
8
|
-
const now = new Date()
|
|
9
|
-
const year = now.getFullYear()
|
|
10
|
-
const month = (now.getMonth() + 1).toString().padStart(2, '0')
|
|
11
|
-
const day = now.getDate().toString().padStart(2, '0')
|
|
12
|
-
|
|
13
|
-
if (!show) {
|
|
14
|
-
if (type === 'curYear') {
|
|
15
|
-
return [
|
|
16
|
-
`${year}-01-01 00:00:00`,
|
|
17
|
-
`${year}-12-31 23:59:59`,
|
|
18
|
-
]
|
|
19
|
-
}
|
|
20
|
-
if (type === 'curMonth') {
|
|
21
|
-
const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
|
|
22
|
-
return [
|
|
23
|
-
`${year}-${month}-01 00:00:00`,
|
|
24
|
-
`${year}-${month}-${lastDay.toString().padStart(2, '0')} 23:59:59`,
|
|
25
|
-
]
|
|
26
|
-
}
|
|
27
|
-
if (type === 'curDay') {
|
|
28
|
-
return [
|
|
29
|
-
`${year}-${month}-${day} 00:00:00`,
|
|
30
|
-
`${year}-${month}-${day} 23:59:59`,
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
if (show) {
|
|
35
|
-
if (type === 'curYear') {
|
|
36
|
-
return [
|
|
37
|
-
`${year}-01-01`,
|
|
38
|
-
`${year}-12-31`,
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
if (type === 'curMonth') {
|
|
42
|
-
const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
|
|
43
|
-
return [
|
|
44
|
-
`${year}-${month}-01`,
|
|
45
|
-
`${year}-${month}-${lastDay.toString().padStart(2, '0')}`,
|
|
46
|
-
]
|
|
47
|
-
}
|
|
48
|
-
if (type === 'curDay') {
|
|
49
|
-
return [
|
|
50
|
-
`${year}-${month}-${day}`,
|
|
51
|
-
`${year}-${month}-${day}`,
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// 兜底返回空字符串数组
|
|
56
|
-
return ['', '']
|
|
57
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 根据类型获取日期区间字符串
|
|
3
|
+
* @param type '当年' | 'curMonth' | '当日'
|
|
4
|
+
* @param show 区分实际值还是显示值, true为实际值, false为显示值
|
|
5
|
+
* @returns [start, end] 例:['2024-01-01 00:00:00', '2024-12-31 23:59:59']
|
|
6
|
+
*/
|
|
7
|
+
export function getRangeByType(type: string, show: boolean): [string, string] {
|
|
8
|
+
const now = new Date()
|
|
9
|
+
const year = now.getFullYear()
|
|
10
|
+
const month = (now.getMonth() + 1).toString().padStart(2, '0')
|
|
11
|
+
const day = now.getDate().toString().padStart(2, '0')
|
|
12
|
+
|
|
13
|
+
if (!show) {
|
|
14
|
+
if (type === 'curYear') {
|
|
15
|
+
return [
|
|
16
|
+
`${year}-01-01 00:00:00`,
|
|
17
|
+
`${year}-12-31 23:59:59`,
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
if (type === 'curMonth') {
|
|
21
|
+
const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
|
|
22
|
+
return [
|
|
23
|
+
`${year}-${month}-01 00:00:00`,
|
|
24
|
+
`${year}-${month}-${lastDay.toString().padStart(2, '0')} 23:59:59`,
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
if (type === 'curDay') {
|
|
28
|
+
return [
|
|
29
|
+
`${year}-${month}-${day} 00:00:00`,
|
|
30
|
+
`${year}-${month}-${day} 23:59:59`,
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (show) {
|
|
35
|
+
if (type === 'curYear') {
|
|
36
|
+
return [
|
|
37
|
+
`${year}-01-01`,
|
|
38
|
+
`${year}-12-31`,
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
if (type === 'curMonth') {
|
|
42
|
+
const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
|
|
43
|
+
return [
|
|
44
|
+
`${year}-${month}-01`,
|
|
45
|
+
`${year}-${month}-${lastDay.toString().padStart(2, '0')}`,
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
if (type === 'curDay') {
|
|
49
|
+
return [
|
|
50
|
+
`${year}-${month}-${day}`,
|
|
51
|
+
`${year}-${month}-${day}`,
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// 兜底返回空字符串数组
|
|
56
|
+
return ['', '']
|
|
57
|
+
}
|