my-openlayer 2.0.0 → 2.1.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.
- package/MyOl.d.ts +135 -128
- package/MyOl.js +401 -381
- package/README.md +0 -21
- package/core/ConfigManager.d.ts +88 -88
- package/core/ConfigManager.js +112 -112
- package/core/EventManager.d.ts +141 -141
- package/core/EventManager.js +316 -316
- package/core/Line.d.ts +130 -109
- package/core/Line.js +512 -288
- package/core/MapBaseLayers.d.ts +234 -234
- package/core/MapBaseLayers.js +573 -573
- package/core/MapTools.d.ts +68 -68
- package/core/MapTools.js +202 -201
- package/core/MeasureHandler.d.ts +65 -65
- package/core/MeasureHandler.js +312 -312
- package/core/Point.d.ts +94 -94
- package/core/Point.js +348 -348
- package/core/Polygon.d.ts +157 -139
- package/core/Polygon.js +605 -529
- package/core/SelectHandler.d.ts +138 -0
- package/core/SelectHandler.js +395 -0
- package/core/VueTemplatePoint.d.ts +51 -51
- package/core/VueTemplatePoint.js +529 -529
- package/index.d.ts +19 -18
- package/index.js +18 -17
- package/package.json +1 -1
- package/types.d.ts +340 -302
- package/types.js +11 -11
- package/utils/ErrorHandler.d.ts +102 -102
- package/utils/ErrorHandler.js +191 -191
- package/utils/ValidationUtils.d.ts +163 -163
- package/utils/ValidationUtils.js +312 -312
package/core/MeasureHandler.js
CHANGED
|
@@ -1,312 +1,312 @@
|
|
|
1
|
-
import Draw from 'ol/interaction/Draw.js';
|
|
2
|
-
import Overlay from 'ol/Overlay.js';
|
|
3
|
-
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style.js';
|
|
4
|
-
import { LineString, Polygon } from 'ol/geom.js';
|
|
5
|
-
import { Vector as VectorSource } from 'ol/source.js';
|
|
6
|
-
import { Vector as VectorLayer } from 'ol/layer.js';
|
|
7
|
-
import { getArea, getLength } from 'ol/sphere.js';
|
|
8
|
-
import { unByKey } from 'ol/Observable.js';
|
|
9
|
-
import { ValidationUtils } from '../utils/ValidationUtils';
|
|
10
|
-
/**
|
|
11
|
-
* 测量工具处理类
|
|
12
|
-
* 提供距离和面积测量功能
|
|
13
|
-
*/
|
|
14
|
-
export default class MeasureHandler {
|
|
15
|
-
/**
|
|
16
|
-
* 构造函数
|
|
17
|
-
* @param map OpenLayers地图实例
|
|
18
|
-
* @throws 当地图实例无效时抛出错误
|
|
19
|
-
*/
|
|
20
|
-
constructor(map) {
|
|
21
|
-
this._draw = null;
|
|
22
|
-
ValidationUtils.validateMap(map);
|
|
23
|
-
this._map = map;
|
|
24
|
-
this.source = new VectorSource();
|
|
25
|
-
this.vector = new VectorLayer({
|
|
26
|
-
source: this.source,
|
|
27
|
-
style: new Style({
|
|
28
|
-
fill: new Fill({
|
|
29
|
-
color: 'rgba(255, 255, 255, 0.2)',
|
|
30
|
-
}),
|
|
31
|
-
stroke: new Stroke({
|
|
32
|
-
color: 'rgba(0, 255, 0, 0.8)',
|
|
33
|
-
lineDash: [10, 10],
|
|
34
|
-
width: 2,
|
|
35
|
-
}),
|
|
36
|
-
image: new CircleStyle({
|
|
37
|
-
radius: 5,
|
|
38
|
-
stroke: new Stroke({
|
|
39
|
-
color: 'rgba(0, 255, 0, 0.8)'
|
|
40
|
-
}),
|
|
41
|
-
fill: new Fill({
|
|
42
|
-
color: 'rgba(255, 255, 255, 0.2)',
|
|
43
|
-
}),
|
|
44
|
-
}),
|
|
45
|
-
}),
|
|
46
|
-
zIndex: 999,
|
|
47
|
-
});
|
|
48
|
-
/**
|
|
49
|
-
* Currently drawn feature.
|
|
50
|
-
* @type {import("ol/Feature.js").default}
|
|
51
|
-
*/
|
|
52
|
-
this.sketch = null;
|
|
53
|
-
/**
|
|
54
|
-
* The help tooltip element.
|
|
55
|
-
* @type {HTMLElement}
|
|
56
|
-
*/
|
|
57
|
-
this.helpTooltipElement = null;
|
|
58
|
-
/**
|
|
59
|
-
* Overlay to show the help messages.
|
|
60
|
-
* @type {Overlay}
|
|
61
|
-
*/
|
|
62
|
-
this.helpTooltip = null;
|
|
63
|
-
/**
|
|
64
|
-
* The measure tooltip element.
|
|
65
|
-
* @type {HTMLElement}
|
|
66
|
-
*/
|
|
67
|
-
this.measureTooltipElement = null;
|
|
68
|
-
/**
|
|
69
|
-
* Overlay to show the measurement.
|
|
70
|
-
* @type {Overlay}
|
|
71
|
-
*/
|
|
72
|
-
this.measureTooltip = null;
|
|
73
|
-
/**
|
|
74
|
-
* Message to show when the user is drawing a polygon.
|
|
75
|
-
* @type {string}
|
|
76
|
-
*/
|
|
77
|
-
this.continuePolygonMsg = '双击结束绘制';
|
|
78
|
-
/**
|
|
79
|
-
* Message to show when the user is drawing a line.
|
|
80
|
-
* @type {string}
|
|
81
|
-
*/
|
|
82
|
-
this.continueLineMsg = '双击结束绘制';
|
|
83
|
-
/**
|
|
84
|
-
* contain the the overlays of tips
|
|
85
|
-
* @type {Array}
|
|
86
|
-
*/
|
|
87
|
-
this._tipsCollection = [];
|
|
88
|
-
/**
|
|
89
|
-
*
|
|
90
|
-
* @param evt
|
|
91
|
-
* @private
|
|
92
|
-
*/
|
|
93
|
-
this._mouseListener = (evt) => {
|
|
94
|
-
if (evt.dragging) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
/** @type {string} */
|
|
98
|
-
let helpMsg = '单击开始绘制';
|
|
99
|
-
if (this.sketch) {
|
|
100
|
-
const geom = this.sketch.getGeometry();
|
|
101
|
-
if (geom instanceof Polygon) {
|
|
102
|
-
helpMsg = this.continuePolygonMsg;
|
|
103
|
-
}
|
|
104
|
-
else if (geom instanceof LineString) {
|
|
105
|
-
helpMsg = this.continueLineMsg;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
if (this.helpTooltipElement) {
|
|
109
|
-
this.helpTooltipElement.innerHTML = helpMsg;
|
|
110
|
-
}
|
|
111
|
-
this.helpTooltip?.setPosition(evt.coordinate);
|
|
112
|
-
this._map?.addLayer(this.vector);
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* destory the object
|
|
117
|
-
*/
|
|
118
|
-
destory() {
|
|
119
|
-
this.clean();
|
|
120
|
-
this._map?.removeLayer(this.vector);
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Format length output.
|
|
124
|
-
* @param {LineString} line The line.
|
|
125
|
-
* @return {string} The formatted length.
|
|
126
|
-
*/
|
|
127
|
-
formatLength(line) {
|
|
128
|
-
const length = getLength(line, {
|
|
129
|
-
projection: "EPSG:4326"
|
|
130
|
-
});
|
|
131
|
-
let output;
|
|
132
|
-
if (length > 100) {
|
|
133
|
-
output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
output = Math.round(length * 100) / 100 + ' ' + 'm';
|
|
137
|
-
}
|
|
138
|
-
return output;
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Format area output.
|
|
142
|
-
* @param {Polygon} polygon The polygon.
|
|
143
|
-
* @return {string} Formatted area.
|
|
144
|
-
*/
|
|
145
|
-
formatArea(polygon) {
|
|
146
|
-
const area = getArea(polygon, {
|
|
147
|
-
projection: "EPSG:4326"
|
|
148
|
-
});
|
|
149
|
-
let output;
|
|
150
|
-
if (area > 10000) {
|
|
151
|
-
output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>';
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>';
|
|
155
|
-
}
|
|
156
|
-
return output;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* 开始测量
|
|
160
|
-
* @param type 测量类型
|
|
161
|
-
* @throws 当测量类型无效时抛出错误
|
|
162
|
-
*/
|
|
163
|
-
start(type) {
|
|
164
|
-
ValidationUtils.validateMeasureType(type);
|
|
165
|
-
ValidationUtils.validateMap(this._map);
|
|
166
|
-
try {
|
|
167
|
-
this.createMeasureTooltip();
|
|
168
|
-
this.createHelpTooltip();
|
|
169
|
-
if (this._draw) {
|
|
170
|
-
this._map.removeInteraction(this._draw);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
catch (error) {
|
|
174
|
-
console.error('Error starting measurement:', error);
|
|
175
|
-
throw new Error('Failed to start measurement');
|
|
176
|
-
}
|
|
177
|
-
this._draw = new Draw({
|
|
178
|
-
source: this.source,
|
|
179
|
-
type: type,
|
|
180
|
-
style: (feature) => {
|
|
181
|
-
const geometryType = feature.getGeometry()?.getType();
|
|
182
|
-
if (geometryType === type || geometryType === 'Point') {
|
|
183
|
-
return new Style({
|
|
184
|
-
fill: new Fill({
|
|
185
|
-
color: 'rgba(220, 255, 255, 0.2)',
|
|
186
|
-
}),
|
|
187
|
-
stroke: new Stroke({
|
|
188
|
-
color: 'rgba(255, 0, 0, 0.7)',
|
|
189
|
-
lineDash: [10, 10],
|
|
190
|
-
width: 2,
|
|
191
|
-
}),
|
|
192
|
-
image: new CircleStyle({
|
|
193
|
-
radius: 5,
|
|
194
|
-
stroke: new Stroke({
|
|
195
|
-
color: 'rgba(255, 0, 0, 0.7)',
|
|
196
|
-
}),
|
|
197
|
-
fill: new Fill({
|
|
198
|
-
color: 'rgba(255, 255, 255, 0.2)',
|
|
199
|
-
}),
|
|
200
|
-
}),
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
},
|
|
204
|
-
});
|
|
205
|
-
this._map.addInteraction(this._draw);
|
|
206
|
-
let listener;
|
|
207
|
-
this._draw.on('drawstart', (evt) => {
|
|
208
|
-
// set sketch
|
|
209
|
-
this.sketch = evt.feature;
|
|
210
|
-
/** @type {import("ol/coordinate.js").Coordinate|undefined} */
|
|
211
|
-
let tooltipCoord = evt?.coordinate;
|
|
212
|
-
const geometry = this.sketch?.getGeometry();
|
|
213
|
-
if (geometry) {
|
|
214
|
-
listener = geometry.on('change', (evt) => {
|
|
215
|
-
const geom = evt.target;
|
|
216
|
-
let output;
|
|
217
|
-
if (geom instanceof Polygon) {
|
|
218
|
-
output = this.formatArea(geom);
|
|
219
|
-
tooltipCoord = geom.getInteriorPoint().getCoordinates();
|
|
220
|
-
}
|
|
221
|
-
else if (geom instanceof LineString) {
|
|
222
|
-
output = this.formatLength(geom);
|
|
223
|
-
tooltipCoord = geom.getLastCoordinate();
|
|
224
|
-
}
|
|
225
|
-
if (this.measureTooltipElement) {
|
|
226
|
-
this.measureTooltipElement.innerHTML = output;
|
|
227
|
-
}
|
|
228
|
-
this.measureTooltip?.setPosition(tooltipCoord);
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
this._draw.on('drawend', () => {
|
|
233
|
-
if (this.measureTooltipElement) {
|
|
234
|
-
this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static';
|
|
235
|
-
}
|
|
236
|
-
this.measureTooltip?.setOffset([0, -7]);
|
|
237
|
-
// unset sketch
|
|
238
|
-
this.sketch = null;
|
|
239
|
-
// unset tooltip so that a new one can be created
|
|
240
|
-
this.measureTooltipElement = null;
|
|
241
|
-
this.createMeasureTooltip();
|
|
242
|
-
unByKey(listener);
|
|
243
|
-
});
|
|
244
|
-
this._map.on('pointermove', this._mouseListener);
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* end the measure drawing
|
|
248
|
-
*/
|
|
249
|
-
end() {
|
|
250
|
-
if (this._draw) {
|
|
251
|
-
this._map?.removeInteraction(this._draw);
|
|
252
|
-
}
|
|
253
|
-
if (this.helpTooltipElement) {
|
|
254
|
-
this.helpTooltipElement.parentNode?.removeChild(this.helpTooltipElement);
|
|
255
|
-
this.helpTooltipElement = null;
|
|
256
|
-
}
|
|
257
|
-
if (this.measureTooltipElement) {
|
|
258
|
-
this.measureTooltipElement.parentNode?.removeChild(this.measureTooltipElement);
|
|
259
|
-
this.measureTooltipElement = null;
|
|
260
|
-
}
|
|
261
|
-
this._map?.un("pointermove", this._mouseListener);
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Creates a new help tooltip
|
|
265
|
-
*/
|
|
266
|
-
createHelpTooltip() {
|
|
267
|
-
if (this.helpTooltipElement) {
|
|
268
|
-
this.helpTooltipElement.parentNode?.removeChild(this.helpTooltipElement);
|
|
269
|
-
}
|
|
270
|
-
this.helpTooltipElement = document.createElement('div');
|
|
271
|
-
this.helpTooltipElement.className = 'ol-tooltip';
|
|
272
|
-
this.helpTooltip = new Overlay({
|
|
273
|
-
element: this.helpTooltipElement,
|
|
274
|
-
offset: [15, 0],
|
|
275
|
-
positioning: 'center-left',
|
|
276
|
-
});
|
|
277
|
-
this._map?.addOverlay(this.helpTooltip);
|
|
278
|
-
this._tipsCollection.push(this.helpTooltip);
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Creates a new measure tooltip
|
|
282
|
-
*/
|
|
283
|
-
createMeasureTooltip() {
|
|
284
|
-
if (this.measureTooltipElement) {
|
|
285
|
-
this.measureTooltipElement.parentNode?.removeChild(this.measureTooltipElement);
|
|
286
|
-
}
|
|
287
|
-
this.measureTooltipElement = document.createElement('div');
|
|
288
|
-
this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
|
|
289
|
-
this.measureTooltip = new Overlay({
|
|
290
|
-
element: this.measureTooltipElement,
|
|
291
|
-
offset: [0, -15],
|
|
292
|
-
positioning: 'bottom-center',
|
|
293
|
-
stopEvent: false,
|
|
294
|
-
insertFirst: false,
|
|
295
|
-
});
|
|
296
|
-
this._tipsCollection.push(this.measureTooltip);
|
|
297
|
-
this._map?.addOverlay(this.measureTooltip);
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* clean the all result of measure
|
|
301
|
-
*/
|
|
302
|
-
clean() {
|
|
303
|
-
this._tipsCollection.forEach((item) => {
|
|
304
|
-
this._map?.removeOverlay(item);
|
|
305
|
-
});
|
|
306
|
-
this.source.clear(true);
|
|
307
|
-
if (this._draw) {
|
|
308
|
-
this._map?.removeInteraction(this._draw);
|
|
309
|
-
}
|
|
310
|
-
this._tipsCollection = [];
|
|
311
|
-
}
|
|
312
|
-
}
|
|
1
|
+
import Draw from 'ol/interaction/Draw.js';
|
|
2
|
+
import Overlay from 'ol/Overlay.js';
|
|
3
|
+
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style.js';
|
|
4
|
+
import { LineString, Polygon } from 'ol/geom.js';
|
|
5
|
+
import { Vector as VectorSource } from 'ol/source.js';
|
|
6
|
+
import { Vector as VectorLayer } from 'ol/layer.js';
|
|
7
|
+
import { getArea, getLength } from 'ol/sphere.js';
|
|
8
|
+
import { unByKey } from 'ol/Observable.js';
|
|
9
|
+
import { ValidationUtils } from '../utils/ValidationUtils';
|
|
10
|
+
/**
|
|
11
|
+
* 测量工具处理类
|
|
12
|
+
* 提供距离和面积测量功能
|
|
13
|
+
*/
|
|
14
|
+
export default class MeasureHandler {
|
|
15
|
+
/**
|
|
16
|
+
* 构造函数
|
|
17
|
+
* @param map OpenLayers地图实例
|
|
18
|
+
* @throws 当地图实例无效时抛出错误
|
|
19
|
+
*/
|
|
20
|
+
constructor(map) {
|
|
21
|
+
this._draw = null;
|
|
22
|
+
ValidationUtils.validateMap(map);
|
|
23
|
+
this._map = map;
|
|
24
|
+
this.source = new VectorSource();
|
|
25
|
+
this.vector = new VectorLayer({
|
|
26
|
+
source: this.source,
|
|
27
|
+
style: new Style({
|
|
28
|
+
fill: new Fill({
|
|
29
|
+
color: 'rgba(255, 255, 255, 0.2)',
|
|
30
|
+
}),
|
|
31
|
+
stroke: new Stroke({
|
|
32
|
+
color: 'rgba(0, 255, 0, 0.8)',
|
|
33
|
+
lineDash: [10, 10],
|
|
34
|
+
width: 2,
|
|
35
|
+
}),
|
|
36
|
+
image: new CircleStyle({
|
|
37
|
+
radius: 5,
|
|
38
|
+
stroke: new Stroke({
|
|
39
|
+
color: 'rgba(0, 255, 0, 0.8)'
|
|
40
|
+
}),
|
|
41
|
+
fill: new Fill({
|
|
42
|
+
color: 'rgba(255, 255, 255, 0.2)',
|
|
43
|
+
}),
|
|
44
|
+
}),
|
|
45
|
+
}),
|
|
46
|
+
zIndex: 999,
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* Currently drawn feature.
|
|
50
|
+
* @type {import("ol/Feature.js").default}
|
|
51
|
+
*/
|
|
52
|
+
this.sketch = null;
|
|
53
|
+
/**
|
|
54
|
+
* The help tooltip element.
|
|
55
|
+
* @type {HTMLElement}
|
|
56
|
+
*/
|
|
57
|
+
this.helpTooltipElement = null;
|
|
58
|
+
/**
|
|
59
|
+
* Overlay to show the help messages.
|
|
60
|
+
* @type {Overlay}
|
|
61
|
+
*/
|
|
62
|
+
this.helpTooltip = null;
|
|
63
|
+
/**
|
|
64
|
+
* The measure tooltip element.
|
|
65
|
+
* @type {HTMLElement}
|
|
66
|
+
*/
|
|
67
|
+
this.measureTooltipElement = null;
|
|
68
|
+
/**
|
|
69
|
+
* Overlay to show the measurement.
|
|
70
|
+
* @type {Overlay}
|
|
71
|
+
*/
|
|
72
|
+
this.measureTooltip = null;
|
|
73
|
+
/**
|
|
74
|
+
* Message to show when the user is drawing a polygon.
|
|
75
|
+
* @type {string}
|
|
76
|
+
*/
|
|
77
|
+
this.continuePolygonMsg = '双击结束绘制';
|
|
78
|
+
/**
|
|
79
|
+
* Message to show when the user is drawing a line.
|
|
80
|
+
* @type {string}
|
|
81
|
+
*/
|
|
82
|
+
this.continueLineMsg = '双击结束绘制';
|
|
83
|
+
/**
|
|
84
|
+
* contain the the overlays of tips
|
|
85
|
+
* @type {Array}
|
|
86
|
+
*/
|
|
87
|
+
this._tipsCollection = [];
|
|
88
|
+
/**
|
|
89
|
+
*
|
|
90
|
+
* @param evt
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
this._mouseListener = (evt) => {
|
|
94
|
+
if (evt.dragging) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
/** @type {string} */
|
|
98
|
+
let helpMsg = '单击开始绘制';
|
|
99
|
+
if (this.sketch) {
|
|
100
|
+
const geom = this.sketch.getGeometry();
|
|
101
|
+
if (geom instanceof Polygon) {
|
|
102
|
+
helpMsg = this.continuePolygonMsg;
|
|
103
|
+
}
|
|
104
|
+
else if (geom instanceof LineString) {
|
|
105
|
+
helpMsg = this.continueLineMsg;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (this.helpTooltipElement) {
|
|
109
|
+
this.helpTooltipElement.innerHTML = helpMsg;
|
|
110
|
+
}
|
|
111
|
+
this.helpTooltip?.setPosition(evt.coordinate);
|
|
112
|
+
this._map?.addLayer(this.vector);
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* destory the object
|
|
117
|
+
*/
|
|
118
|
+
destory() {
|
|
119
|
+
this.clean();
|
|
120
|
+
this._map?.removeLayer(this.vector);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Format length output.
|
|
124
|
+
* @param {LineString} line The line.
|
|
125
|
+
* @return {string} The formatted length.
|
|
126
|
+
*/
|
|
127
|
+
formatLength(line) {
|
|
128
|
+
const length = getLength(line, {
|
|
129
|
+
projection: "EPSG:4326"
|
|
130
|
+
});
|
|
131
|
+
let output;
|
|
132
|
+
if (length > 100) {
|
|
133
|
+
output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
output = Math.round(length * 100) / 100 + ' ' + 'm';
|
|
137
|
+
}
|
|
138
|
+
return output;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Format area output.
|
|
142
|
+
* @param {Polygon} polygon The polygon.
|
|
143
|
+
* @return {string} Formatted area.
|
|
144
|
+
*/
|
|
145
|
+
formatArea(polygon) {
|
|
146
|
+
const area = getArea(polygon, {
|
|
147
|
+
projection: "EPSG:4326"
|
|
148
|
+
});
|
|
149
|
+
let output;
|
|
150
|
+
if (area > 10000) {
|
|
151
|
+
output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>';
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>';
|
|
155
|
+
}
|
|
156
|
+
return output;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 开始测量
|
|
160
|
+
* @param type 测量类型
|
|
161
|
+
* @throws 当测量类型无效时抛出错误
|
|
162
|
+
*/
|
|
163
|
+
start(type) {
|
|
164
|
+
ValidationUtils.validateMeasureType(type);
|
|
165
|
+
ValidationUtils.validateMap(this._map);
|
|
166
|
+
try {
|
|
167
|
+
this.createMeasureTooltip();
|
|
168
|
+
this.createHelpTooltip();
|
|
169
|
+
if (this._draw) {
|
|
170
|
+
this._map.removeInteraction(this._draw);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
console.error('Error starting measurement:', error);
|
|
175
|
+
throw new Error('Failed to start measurement');
|
|
176
|
+
}
|
|
177
|
+
this._draw = new Draw({
|
|
178
|
+
source: this.source,
|
|
179
|
+
type: type,
|
|
180
|
+
style: (feature) => {
|
|
181
|
+
const geometryType = feature.getGeometry()?.getType();
|
|
182
|
+
if (geometryType === type || geometryType === 'Point') {
|
|
183
|
+
return new Style({
|
|
184
|
+
fill: new Fill({
|
|
185
|
+
color: 'rgba(220, 255, 255, 0.2)',
|
|
186
|
+
}),
|
|
187
|
+
stroke: new Stroke({
|
|
188
|
+
color: 'rgba(255, 0, 0, 0.7)',
|
|
189
|
+
lineDash: [10, 10],
|
|
190
|
+
width: 2,
|
|
191
|
+
}),
|
|
192
|
+
image: new CircleStyle({
|
|
193
|
+
radius: 5,
|
|
194
|
+
stroke: new Stroke({
|
|
195
|
+
color: 'rgba(255, 0, 0, 0.7)',
|
|
196
|
+
}),
|
|
197
|
+
fill: new Fill({
|
|
198
|
+
color: 'rgba(255, 255, 255, 0.2)',
|
|
199
|
+
}),
|
|
200
|
+
}),
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
this._map.addInteraction(this._draw);
|
|
206
|
+
let listener;
|
|
207
|
+
this._draw.on('drawstart', (evt) => {
|
|
208
|
+
// set sketch
|
|
209
|
+
this.sketch = evt.feature;
|
|
210
|
+
/** @type {import("ol/coordinate.js").Coordinate|undefined} */
|
|
211
|
+
let tooltipCoord = evt?.coordinate;
|
|
212
|
+
const geometry = this.sketch?.getGeometry();
|
|
213
|
+
if (geometry) {
|
|
214
|
+
listener = geometry.on('change', (evt) => {
|
|
215
|
+
const geom = evt.target;
|
|
216
|
+
let output;
|
|
217
|
+
if (geom instanceof Polygon) {
|
|
218
|
+
output = this.formatArea(geom);
|
|
219
|
+
tooltipCoord = geom.getInteriorPoint().getCoordinates();
|
|
220
|
+
}
|
|
221
|
+
else if (geom instanceof LineString) {
|
|
222
|
+
output = this.formatLength(geom);
|
|
223
|
+
tooltipCoord = geom.getLastCoordinate();
|
|
224
|
+
}
|
|
225
|
+
if (this.measureTooltipElement) {
|
|
226
|
+
this.measureTooltipElement.innerHTML = output;
|
|
227
|
+
}
|
|
228
|
+
this.measureTooltip?.setPosition(tooltipCoord);
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
this._draw.on('drawend', () => {
|
|
233
|
+
if (this.measureTooltipElement) {
|
|
234
|
+
this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static';
|
|
235
|
+
}
|
|
236
|
+
this.measureTooltip?.setOffset([0, -7]);
|
|
237
|
+
// unset sketch
|
|
238
|
+
this.sketch = null;
|
|
239
|
+
// unset tooltip so that a new one can be created
|
|
240
|
+
this.measureTooltipElement = null;
|
|
241
|
+
this.createMeasureTooltip();
|
|
242
|
+
unByKey(listener);
|
|
243
|
+
});
|
|
244
|
+
this._map.on('pointermove', this._mouseListener);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* end the measure drawing
|
|
248
|
+
*/
|
|
249
|
+
end() {
|
|
250
|
+
if (this._draw) {
|
|
251
|
+
this._map?.removeInteraction(this._draw);
|
|
252
|
+
}
|
|
253
|
+
if (this.helpTooltipElement) {
|
|
254
|
+
this.helpTooltipElement.parentNode?.removeChild(this.helpTooltipElement);
|
|
255
|
+
this.helpTooltipElement = null;
|
|
256
|
+
}
|
|
257
|
+
if (this.measureTooltipElement) {
|
|
258
|
+
this.measureTooltipElement.parentNode?.removeChild(this.measureTooltipElement);
|
|
259
|
+
this.measureTooltipElement = null;
|
|
260
|
+
}
|
|
261
|
+
this._map?.un("pointermove", this._mouseListener);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Creates a new help tooltip
|
|
265
|
+
*/
|
|
266
|
+
createHelpTooltip() {
|
|
267
|
+
if (this.helpTooltipElement) {
|
|
268
|
+
this.helpTooltipElement.parentNode?.removeChild(this.helpTooltipElement);
|
|
269
|
+
}
|
|
270
|
+
this.helpTooltipElement = document.createElement('div');
|
|
271
|
+
this.helpTooltipElement.className = 'ol-tooltip';
|
|
272
|
+
this.helpTooltip = new Overlay({
|
|
273
|
+
element: this.helpTooltipElement,
|
|
274
|
+
offset: [15, 0],
|
|
275
|
+
positioning: 'center-left',
|
|
276
|
+
});
|
|
277
|
+
this._map?.addOverlay(this.helpTooltip);
|
|
278
|
+
this._tipsCollection.push(this.helpTooltip);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Creates a new measure tooltip
|
|
282
|
+
*/
|
|
283
|
+
createMeasureTooltip() {
|
|
284
|
+
if (this.measureTooltipElement) {
|
|
285
|
+
this.measureTooltipElement.parentNode?.removeChild(this.measureTooltipElement);
|
|
286
|
+
}
|
|
287
|
+
this.measureTooltipElement = document.createElement('div');
|
|
288
|
+
this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
|
|
289
|
+
this.measureTooltip = new Overlay({
|
|
290
|
+
element: this.measureTooltipElement,
|
|
291
|
+
offset: [0, -15],
|
|
292
|
+
positioning: 'bottom-center',
|
|
293
|
+
stopEvent: false,
|
|
294
|
+
insertFirst: false,
|
|
295
|
+
});
|
|
296
|
+
this._tipsCollection.push(this.measureTooltip);
|
|
297
|
+
this._map?.addOverlay(this.measureTooltip);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* clean the all result of measure
|
|
301
|
+
*/
|
|
302
|
+
clean() {
|
|
303
|
+
this._tipsCollection.forEach((item) => {
|
|
304
|
+
this._map?.removeOverlay(item);
|
|
305
|
+
});
|
|
306
|
+
this.source.clear(true);
|
|
307
|
+
if (this._draw) {
|
|
308
|
+
this._map?.removeInteraction(this._draw);
|
|
309
|
+
}
|
|
310
|
+
this._tipsCollection = [];
|
|
311
|
+
}
|
|
312
|
+
}
|