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.
package/core/Point.js CHANGED
@@ -1,348 +1,348 @@
1
- "use strict";
2
- import Overlay from 'ol/Overlay';
3
- import Feature from "ol/Feature";
4
- import { Point as olPoint } from "ol/geom";
5
- import { Text, Style, Fill, Stroke, Icon } from "ol/style";
6
- import VectorLayer from "ol/layer/Vector";
7
- import VectorSource from "ol/source/Vector";
8
- import { Cluster } from 'ol/source';
9
- import * as turf from '@turf/turf';
10
- import GeoJSON from "ol/format/GeoJSON";
11
- import VueTemplatePoint from './VueTemplatePoint';
12
- import MapTools from "./MapTools";
13
- import { ValidationUtils } from '../utils/ValidationUtils';
14
- export default class Point {
15
- constructor(map) {
16
- this.map = map;
17
- }
18
- /**
19
- * 创建文本样式
20
- * @private
21
- * @param options 选项
22
- * @param text 文本内容
23
- * @returns 文本样式
24
- */
25
- createTextStyle(options, text) {
26
- return new Text({
27
- text: text,
28
- font: options.textFont || '12px Calibri,sans-serif',
29
- fill: new Fill({
30
- color: options.textFillColor || '#FFF'
31
- }),
32
- stroke: new Stroke({
33
- color: options.textStrokeColor || '#000',
34
- width: options.textStrokeWidth || 3
35
- }),
36
- offsetY: options.textOffsetY || 20,
37
- });
38
- }
39
- /**
40
- * 创建图标样式
41
- * @private
42
- * @param options 选项
43
- * @returns 图标样式
44
- */
45
- createIconStyle(options) {
46
- const iconOptions = {
47
- src: options.img,
48
- scale: options.scale ?? 1,
49
- };
50
- if (options.iconColor) {
51
- iconOptions.color = options.iconColor;
52
- }
53
- return new Icon(iconOptions);
54
- }
55
- /**
56
- * 创建点样式
57
- * @private
58
- * @param options 选项
59
- * @param item 数据项
60
- * @returns 样式对象
61
- */
62
- createPointStyle(options, item) {
63
- const style = {};
64
- if (options.textKey && item) {
65
- style.text = this.createTextStyle(options, item[options.textKey]);
66
- }
67
- if (options.img) {
68
- style.image = this.createIconStyle(options);
69
- }
70
- return new Style(style);
71
- }
72
- /**
73
- * 创建集群样式
74
- * @private
75
- * @param options 选项
76
- * @param name 名称
77
- * @returns 样式对象
78
- */
79
- createClusterStyle(options, name) {
80
- const style = {};
81
- if (options.textKey) {
82
- style.text = this.createTextStyle(options, name);
83
- }
84
- if (options.img) {
85
- style.image = this.createIconStyle(options);
86
- }
87
- return new Style(style);
88
- }
89
- /**
90
- * 配置图层属性
91
- * @private
92
- * @param layer 图层
93
- * @param options 选项
94
- */
95
- configureLayer(layer, options) {
96
- layer.setVisible(options.visible === undefined ? true : options.visible);
97
- this.map.addLayer(layer);
98
- }
99
- /**
100
- *
101
- * @param pointData
102
- * @param type
103
- * @param options {
104
- * textKey: String 数据中的文本的key
105
- * img: String 图标
106
- * }
107
- */
108
- addPoint(pointData, options) {
109
- if (!ValidationUtils.validatePointData(pointData)) {
110
- return null;
111
- }
112
- const pointFeatureList = [];
113
- pointData.forEach((item) => {
114
- if (!ValidationUtils.validateCoordinates(item)) {
115
- return;
116
- }
117
- const pointFeature = new Feature({
118
- rawData: item,
119
- type: options.layerName,
120
- geometry: new olPoint([item.lgtd, item.lttd])
121
- });
122
- pointFeature.setStyle(this.createPointStyle(options, item));
123
- pointFeatureList.push(pointFeature);
124
- });
125
- const PointVectorLayer = new VectorLayer({
126
- layerName: options.layerName,
127
- source: new VectorSource({
128
- features: pointFeatureList
129
- }),
130
- zIndex: options.zIndex || 21,
131
- });
132
- this.configureLayer(PointVectorLayer, options);
133
- return PointVectorLayer;
134
- }
135
- addClusterPoint(pointData, options) {
136
- if (!ValidationUtils.validatePointData(pointData)) {
137
- return null;
138
- }
139
- const pointFeatureList = [];
140
- pointData.forEach(item => {
141
- if (!ValidationUtils.validateCoordinates(item)) {
142
- return;
143
- }
144
- const pointFeature = new Feature({
145
- geometry: new olPoint([item.lgtd, item.lttd]),
146
- name: options.textKey ? item[options.textKey] : '',
147
- });
148
- pointFeatureList.push(pointFeature);
149
- });
150
- const source = new VectorSource({
151
- features: pointFeatureList,
152
- });
153
- const clusterSource = new Cluster({
154
- distance: options.distance || 40,
155
- minDistance: options.minDistance || 0,
156
- source: source,
157
- });
158
- const clusterLayer = new VectorLayer({
159
- layerName: options.layerName,
160
- source: clusterSource,
161
- style: (feature) => {
162
- const name = feature.get('features')[0].get(options.textKey);
163
- return this.createClusterStyle(options, name);
164
- },
165
- zIndex: options.zIndex || 21,
166
- });
167
- this.configureLayer(clusterLayer, options);
168
- return clusterLayer;
169
- }
170
- // 在流域中心添加闪烁点位
171
- addTwinkleLayerFromPolygon(twinkleList, className, key, json) {
172
- new MapTools(this.map).removeLayer('twinklePoint');
173
- // 计算多边形的中心点坐标
174
- const calculatePolygonCenter = (polygonCoordinates) => {
175
- const polygon = turf.polygon(polygonCoordinates[0]);
176
- const centroid = turf.centroid(polygon);
177
- return centroid.geometry.coordinates;
178
- };
179
- const features = json.features;
180
- const vectorSource = new VectorSource({
181
- format: new GeoJSON(),
182
- });
183
- twinkleList.forEach(item => {
184
- const feature = features.find((ele) => {
185
- return ele.properties.BASIN === item.idx;
186
- });
187
- if (!feature)
188
- return;
189
- feature.properties.level = item.lev;
190
- const geojson = new GeoJSON();
191
- const olFeature = geojson.readFeature(feature);
192
- if (Array.isArray(olFeature)) {
193
- vectorSource.addFeatures(olFeature);
194
- }
195
- else {
196
- vectorSource.addFeature(olFeature);
197
- }
198
- if (feature) {
199
- const polygonCenter = calculatePolygonCenter(feature.geometry.coordinates);
200
- item.lgtd = polygonCenter[0];
201
- item.lttd = polygonCenter[1];
202
- }
203
- });
204
- const basinLayer = new VectorLayer({
205
- name: 'twinklePoint',
206
- layerName: 'twinklePoint',
207
- source: vectorSource,
208
- style: function (feature) {
209
- return new Style({
210
- stroke: new Stroke({
211
- color: 'rgb(139,188,245)',
212
- width: 3
213
- }),
214
- fill: new Fill({ color: 'rgba(255, 255, 255, 0)' }),
215
- text: new Text({
216
- text: feature.values_['BASIN'] || "",
217
- font: '14px Calibri,sans-serif',
218
- fill: new Fill({ color: '#FFF' }),
219
- stroke: new Stroke({
220
- color: '#409EFF', width: 2
221
- }),
222
- })
223
- });
224
- },
225
- zIndex: 21
226
- });
227
- this.map.addLayer(basinLayer);
228
- this.addTwinkleLayer(twinkleList, className, key, (twinkleItem) => {
229
- });
230
- }
231
- /**
232
- * 添加闪烁点
233
- * @param twinkleList 闪烁点数据 - 二维数组 [[],[]]
234
- * @param className 闪烁点样式,需要和id保持一致
235
- * @param key 闪烁点索引
236
- * @param callback
237
- */
238
- addTwinkleLayer(twinkleList, className = 'marker_warning', key, callback) {
239
- // 查找class是warn-points的dom,并删除
240
- const arr = document.getElementsByClassName(className);
241
- const l = arr.length;
242
- for (let i = l - 1; i >= 0; i--) {
243
- if (arr[i] !== null) {
244
- arr[i].parentNode?.removeChild(arr[i]);
245
- }
246
- }
247
- const el = document.getElementById(className);
248
- for (let i = 0; i < twinkleList.length; i++) {
249
- const twinkleItem = twinkleList[i];
250
- // 定义图标Dom
251
- const el2 = document.createElement('div');
252
- el2.id = className + i;
253
- el2.className = className + twinkleItem[key];
254
- el2.onclick = () => {
255
- callback && callback(twinkleItem);
256
- // bus.emit('twinkleClick', twinkleItem)
257
- };
258
- // 插入图标
259
- if (el)
260
- el.insertAdjacentElement('afterend', el2);
261
- // 创建一个覆盖物
262
- const anchor = new Overlay({
263
- element: document.getElementById(className + i) || undefined,
264
- positioning: 'center-center',
265
- className: className
266
- });
267
- // 关键的一点,需要设置附加到地图上的位置
268
- anchor.setPosition([twinkleItem.lgtd, twinkleItem.lttd]);
269
- // 然后添加到map上
270
- this.map.addOverlay(anchor);
271
- }
272
- }
273
- /**
274
- * 地图定位
275
- * @param lgtd 经度
276
- * @param lttd 纬度
277
- * @param zoom 缩放级别
278
- * @param duration 动画时长
279
- */
280
- locationAction(lgtd, lttd, zoom = 20, duration = 3000) {
281
- if (!ValidationUtils.validateLngLat(lgtd, lttd)) {
282
- return false;
283
- }
284
- try {
285
- this.map.getView().animate({ center: [lgtd, lttd], zoom, duration });
286
- return true;
287
- }
288
- catch (error) {
289
- console.error('[地图定位]', '定位失败:', error);
290
- return false;
291
- }
292
- }
293
- /**
294
- * 设置dom元素为点位
295
- */
296
- addDomPoint(id, lgtd, lttd) {
297
- if (!id) {
298
- console.error('Element ID is required');
299
- return false;
300
- }
301
- if (!ValidationUtils.validateLngLat(lgtd, lttd)) {
302
- return false;
303
- }
304
- const el = document.getElementById(id);
305
- if (!el) {
306
- console.error(`Element with id '${id}' not found`);
307
- return false;
308
- }
309
- try {
310
- const anchor = new Overlay({
311
- id: id,
312
- element: el,
313
- positioning: 'center-center',
314
- stopEvent: false
315
- });
316
- anchor.setPosition([lgtd, lttd]);
317
- this.map.addOverlay(anchor);
318
- return true;
319
- }
320
- catch (error) {
321
- console.error('Failed to set DOM point:', error);
322
- return false;
323
- }
324
- }
325
- /**
326
- * 添加vue组件为点位
327
- * @param pointDataList 点位信息列表
328
- * @param template vue组件模板
329
- * @param Vue Vue实例
330
- * @returns 返回控制对象,包含显示、隐藏、移除方法
331
- * @throws 当参数无效时抛出错误
332
- */
333
- addVueTemplatePoint(pointDataList, template, options) {
334
- if (!pointDataList || !Array.isArray(pointDataList) || pointDataList.length === 0) {
335
- throw new Error('Valid point info list is required');
336
- }
337
- if (!template) {
338
- throw new Error('Vue template is required');
339
- }
340
- try {
341
- const vueTemplatePoint = new VueTemplatePoint(this.map);
342
- return vueTemplatePoint.addVueTemplatePoint(pointDataList, template, options);
343
- }
344
- catch (error) {
345
- throw new Error(`Failed to create Vue template points: ${error}`);
346
- }
347
- }
348
- }
1
+ "use strict";
2
+ import Overlay from 'ol/Overlay';
3
+ import Feature from "ol/Feature";
4
+ import { Point as olPoint } from "ol/geom";
5
+ import { Text, Style, Fill, Stroke, Icon } from "ol/style";
6
+ import VectorLayer from "ol/layer/Vector";
7
+ import VectorSource from "ol/source/Vector";
8
+ import { Cluster } from 'ol/source';
9
+ import * as turf from '@turf/turf';
10
+ import GeoJSON from "ol/format/GeoJSON";
11
+ import VueTemplatePoint from './VueTemplatePoint';
12
+ import MapTools from "./MapTools";
13
+ import { ValidationUtils } from '../utils/ValidationUtils';
14
+ export default class Point {
15
+ constructor(map) {
16
+ this.map = map;
17
+ }
18
+ /**
19
+ * 创建文本样式
20
+ * @private
21
+ * @param options 选项
22
+ * @param text 文本内容
23
+ * @returns 文本样式
24
+ */
25
+ createTextStyle(options, text) {
26
+ return new Text({
27
+ text: text,
28
+ font: options.textFont || '12px Calibri,sans-serif',
29
+ fill: new Fill({
30
+ color: options.textFillColor || '#FFF'
31
+ }),
32
+ stroke: new Stroke({
33
+ color: options.textStrokeColor || '#000',
34
+ width: options.textStrokeWidth || 3
35
+ }),
36
+ offsetY: options.textOffsetY || 20,
37
+ });
38
+ }
39
+ /**
40
+ * 创建图标样式
41
+ * @private
42
+ * @param options 选项
43
+ * @returns 图标样式
44
+ */
45
+ createIconStyle(options) {
46
+ const iconOptions = {
47
+ src: options.img,
48
+ scale: options.scale ?? 1,
49
+ };
50
+ if (options.iconColor) {
51
+ iconOptions.color = options.iconColor;
52
+ }
53
+ return new Icon(iconOptions);
54
+ }
55
+ /**
56
+ * 创建点样式
57
+ * @private
58
+ * @param options 选项
59
+ * @param item 数据项
60
+ * @returns 样式对象
61
+ */
62
+ createPointStyle(options, item) {
63
+ const style = {};
64
+ if (options.textKey && item) {
65
+ style.text = this.createTextStyle(options, item[options.textKey]);
66
+ }
67
+ if (options.img) {
68
+ style.image = this.createIconStyle(options);
69
+ }
70
+ return new Style(style);
71
+ }
72
+ /**
73
+ * 创建集群样式
74
+ * @private
75
+ * @param options 选项
76
+ * @param name 名称
77
+ * @returns 样式对象
78
+ */
79
+ createClusterStyle(options, name) {
80
+ const style = {};
81
+ if (options.textKey) {
82
+ style.text = this.createTextStyle(options, name);
83
+ }
84
+ if (options.img) {
85
+ style.image = this.createIconStyle(options);
86
+ }
87
+ return new Style(style);
88
+ }
89
+ /**
90
+ * 配置图层属性
91
+ * @private
92
+ * @param layer 图层
93
+ * @param options 选项
94
+ */
95
+ configureLayer(layer, options) {
96
+ layer.setVisible(options.visible === undefined ? true : options.visible);
97
+ this.map.addLayer(layer);
98
+ }
99
+ /**
100
+ *
101
+ * @param pointData
102
+ * @param type
103
+ * @param options {
104
+ * textKey: String 数据中的文本的key
105
+ * img: String 图标
106
+ * }
107
+ */
108
+ addPoint(pointData, options) {
109
+ if (!ValidationUtils.validatePointData(pointData)) {
110
+ return null;
111
+ }
112
+ const pointFeatureList = [];
113
+ pointData.forEach((item) => {
114
+ if (!ValidationUtils.validateCoordinates(item)) {
115
+ return;
116
+ }
117
+ const pointFeature = new Feature({
118
+ rawData: item,
119
+ type: options.layerName,
120
+ geometry: new olPoint([item.lgtd, item.lttd])
121
+ });
122
+ pointFeature.setStyle(this.createPointStyle(options, item));
123
+ pointFeatureList.push(pointFeature);
124
+ });
125
+ const PointVectorLayer = new VectorLayer({
126
+ layerName: options.layerName,
127
+ source: new VectorSource({
128
+ features: pointFeatureList
129
+ }),
130
+ zIndex: options.zIndex || 21,
131
+ });
132
+ this.configureLayer(PointVectorLayer, options);
133
+ return PointVectorLayer;
134
+ }
135
+ addClusterPoint(pointData, options) {
136
+ if (!ValidationUtils.validatePointData(pointData)) {
137
+ return null;
138
+ }
139
+ const pointFeatureList = [];
140
+ pointData.forEach(item => {
141
+ if (!ValidationUtils.validateCoordinates(item)) {
142
+ return;
143
+ }
144
+ const pointFeature = new Feature({
145
+ geometry: new olPoint([item.lgtd, item.lttd]),
146
+ name: options.textKey ? item[options.textKey] : '',
147
+ });
148
+ pointFeatureList.push(pointFeature);
149
+ });
150
+ const source = new VectorSource({
151
+ features: pointFeatureList,
152
+ });
153
+ const clusterSource = new Cluster({
154
+ distance: options.distance || 40, // The distance for clustering in pixels
155
+ minDistance: options.minDistance || 0,
156
+ source: source,
157
+ });
158
+ const clusterLayer = new VectorLayer({
159
+ layerName: options.layerName,
160
+ source: clusterSource,
161
+ style: (feature) => {
162
+ const name = feature.get('features')[0].get(options.textKey);
163
+ return this.createClusterStyle(options, name);
164
+ },
165
+ zIndex: options.zIndex || 21,
166
+ });
167
+ this.configureLayer(clusterLayer, options);
168
+ return clusterLayer;
169
+ }
170
+ // 在流域中心添加闪烁点位
171
+ addTwinkleLayerFromPolygon(twinkleList, className, key, json) {
172
+ new MapTools(this.map).removeLayer('twinklePoint');
173
+ // 计算多边形的中心点坐标
174
+ const calculatePolygonCenter = (polygonCoordinates) => {
175
+ const polygon = turf.polygon(polygonCoordinates[0]);
176
+ const centroid = turf.centroid(polygon);
177
+ return centroid.geometry.coordinates;
178
+ };
179
+ const features = json.features;
180
+ const vectorSource = new VectorSource({
181
+ format: new GeoJSON(),
182
+ });
183
+ twinkleList.forEach(item => {
184
+ const feature = features.find((ele) => {
185
+ return ele.properties.BASIN === item.idx;
186
+ });
187
+ if (!feature)
188
+ return;
189
+ feature.properties.level = item.lev;
190
+ const geojson = new GeoJSON();
191
+ const olFeature = geojson.readFeature(feature);
192
+ if (Array.isArray(olFeature)) {
193
+ vectorSource.addFeatures(olFeature);
194
+ }
195
+ else {
196
+ vectorSource.addFeature(olFeature);
197
+ }
198
+ if (feature) {
199
+ const polygonCenter = calculatePolygonCenter(feature.geometry.coordinates);
200
+ item.lgtd = polygonCenter[0];
201
+ item.lttd = polygonCenter[1];
202
+ }
203
+ });
204
+ const basinLayer = new VectorLayer({
205
+ name: 'twinklePoint',
206
+ layerName: 'twinklePoint',
207
+ source: vectorSource,
208
+ style: function (feature) {
209
+ return new Style({
210
+ stroke: new Stroke({
211
+ color: 'rgb(139,188,245)',
212
+ width: 3
213
+ }),
214
+ fill: new Fill({ color: 'rgba(255, 255, 255, 0)' }),
215
+ text: new Text({
216
+ text: feature.values_['BASIN'] || "",
217
+ font: '14px Calibri,sans-serif',
218
+ fill: new Fill({ color: '#FFF' }),
219
+ stroke: new Stroke({
220
+ color: '#409EFF', width: 2
221
+ }),
222
+ })
223
+ });
224
+ },
225
+ zIndex: 21
226
+ });
227
+ this.map.addLayer(basinLayer);
228
+ this.addTwinkleLayer(twinkleList, className, key, (twinkleItem) => {
229
+ });
230
+ }
231
+ /**
232
+ * 添加闪烁点
233
+ * @param twinkleList 闪烁点数据 - 二维数组 [[],[]]
234
+ * @param className 闪烁点样式,需要和id保持一致
235
+ * @param key 闪烁点索引
236
+ * @param callback
237
+ */
238
+ addTwinkleLayer(twinkleList, className = 'marker_warning', key, callback) {
239
+ // 查找class是warn-points的dom,并删除
240
+ const arr = document.getElementsByClassName(className);
241
+ const l = arr.length;
242
+ for (let i = l - 1; i >= 0; i--) {
243
+ if (arr[i] !== null) {
244
+ arr[i].parentNode?.removeChild(arr[i]);
245
+ }
246
+ }
247
+ const el = document.getElementById(className);
248
+ for (let i = 0; i < twinkleList.length; i++) {
249
+ const twinkleItem = twinkleList[i];
250
+ // 定义图标Dom
251
+ const el2 = document.createElement('div');
252
+ el2.id = className + i;
253
+ el2.className = className + twinkleItem[key];
254
+ el2.onclick = () => {
255
+ callback && callback(twinkleItem);
256
+ // bus.emit('twinkleClick', twinkleItem)
257
+ };
258
+ // 插入图标
259
+ if (el)
260
+ el.insertAdjacentElement('afterend', el2);
261
+ // 创建一个覆盖物
262
+ const anchor = new Overlay({
263
+ element: document.getElementById(className + i) || undefined,
264
+ positioning: 'center-center',
265
+ className: className
266
+ });
267
+ // 关键的一点,需要设置附加到地图上的位置
268
+ anchor.setPosition([twinkleItem.lgtd, twinkleItem.lttd]);
269
+ // 然后添加到map上
270
+ this.map.addOverlay(anchor);
271
+ }
272
+ }
273
+ /**
274
+ * 地图定位
275
+ * @param lgtd 经度
276
+ * @param lttd 纬度
277
+ * @param zoom 缩放级别
278
+ * @param duration 动画时长
279
+ */
280
+ locationAction(lgtd, lttd, zoom = 20, duration = 3000) {
281
+ if (!ValidationUtils.validateLngLat(lgtd, lttd)) {
282
+ return false;
283
+ }
284
+ try {
285
+ this.map.getView().animate({ center: [lgtd, lttd], zoom, duration });
286
+ return true;
287
+ }
288
+ catch (error) {
289
+ console.error('[地图定位]', '定位失败:', error);
290
+ return false;
291
+ }
292
+ }
293
+ /**
294
+ * 设置dom元素为点位
295
+ */
296
+ addDomPoint(id, lgtd, lttd) {
297
+ if (!id) {
298
+ console.error('Element ID is required');
299
+ return false;
300
+ }
301
+ if (!ValidationUtils.validateLngLat(lgtd, lttd)) {
302
+ return false;
303
+ }
304
+ const el = document.getElementById(id);
305
+ if (!el) {
306
+ console.error(`Element with id '${id}' not found`);
307
+ return false;
308
+ }
309
+ try {
310
+ const anchor = new Overlay({
311
+ id: id,
312
+ element: el,
313
+ positioning: 'center-center',
314
+ stopEvent: false
315
+ });
316
+ anchor.setPosition([lgtd, lttd]);
317
+ this.map.addOverlay(anchor);
318
+ return true;
319
+ }
320
+ catch (error) {
321
+ console.error('Failed to set DOM point:', error);
322
+ return false;
323
+ }
324
+ }
325
+ /**
326
+ * 添加vue组件为点位
327
+ * @param pointDataList 点位信息列表
328
+ * @param template vue组件模板
329
+ * @param Vue Vue实例
330
+ * @returns 返回控制对象,包含显示、隐藏、移除方法
331
+ * @throws 当参数无效时抛出错误
332
+ */
333
+ addVueTemplatePoint(pointDataList, template, options) {
334
+ if (!pointDataList || !Array.isArray(pointDataList) || pointDataList.length === 0) {
335
+ throw new Error('Valid point info list is required');
336
+ }
337
+ if (!template) {
338
+ throw new Error('Vue template is required');
339
+ }
340
+ try {
341
+ const vueTemplatePoint = new VueTemplatePoint(this.map);
342
+ return vueTemplatePoint.addVueTemplatePoint(pointDataList, template, options);
343
+ }
344
+ catch (error) {
345
+ throw new Error(`Failed to create Vue template points: ${error}`);
346
+ }
347
+ }
348
+ }