my-openlayer 2.0.0 → 2.0.1

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.
@@ -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
+ }