my-openlayer 1.0.0 → 1.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.
@@ -11,6 +11,7 @@ import WMTSTileGrid from "ol/tilegrid/WMTS";
11
11
  import XYZ from "ol/source/XYZ";
12
12
  import MapTools from "./MapTools";
13
13
  import { ErrorHandler, ErrorType } from "../utils/ErrorHandler";
14
+ import { ValidationUtils } from "../utils/ValidationUtils";
14
15
  /**
15
16
  * 天地图服务器配置
16
17
  */
@@ -53,10 +54,8 @@ export default class MapBaseLayers {
53
54
  * @private
54
55
  */
55
56
  validateConstructorParams(map, options) {
56
- ErrorHandler.validateMap(map);
57
- if (!options || typeof options !== 'object') {
58
- throw new Error('Valid options object is required');
59
- }
57
+ ValidationUtils.validateMap(map);
58
+ ValidationUtils.validateOptions(options);
60
59
  }
61
60
  /**
62
61
  * 合并默认配置选项
@@ -291,12 +290,8 @@ export default class MapBaseLayers {
291
290
  */
292
291
  addGeoServerLayer(url, layerName, options = {}) {
293
292
  try {
294
- if (!url || typeof url !== 'string') {
295
- throw new Error('Valid URL is required for GeoServer layer');
296
- }
297
- if (!layerName || typeof layerName !== 'string') {
298
- throw new Error('Valid layer name is required for GeoServer layer');
299
- }
293
+ ValidationUtils.validateNonEmptyString(url, 'Valid URL is required for GeoServer layer');
294
+ ValidationUtils.validateNonEmptyString(layerName, 'Valid layer name is required for GeoServer layer');
300
295
  const wmsLayer = new TileLayer({
301
296
  source: new TileWMS({
302
297
  url: url,
@@ -410,9 +405,7 @@ export default class MapBaseLayers {
410
405
  */
411
406
  static getTileGrid(length) {
412
407
  try {
413
- if (!length || length <= 0) {
414
- throw new Error('Valid length is required for tile grid');
415
- }
408
+ ValidationUtils.validatePositiveNumber(length, 'Valid length is required for tile grid');
416
409
  const projection = getProjection('EPSG:4326');
417
410
  if (!projection) {
418
411
  throw new Error('Failed to get EPSG:4326 projection');
@@ -6,6 +6,7 @@ import { Fill, Style } from "ol/style";
6
6
  import { getVectorContext } from "ol/render";
7
7
  import { EventManager } from "./EventManager";
8
8
  import { ErrorHandler, ErrorType } from "../utils/ErrorHandler";
9
+ import { ValidationUtils } from "../utils/ValidationUtils";
9
10
  /**
10
11
  * 地图工具类
11
12
  * 提供地图的基础操作功能
@@ -14,7 +15,7 @@ class MapTools {
14
15
  constructor(map) {
15
16
  this.errorHandler = ErrorHandler.getInstance();
16
17
  try {
17
- ErrorHandler.validateMap(map);
18
+ ValidationUtils.validateMap(map);
18
19
  this.map = map;
19
20
  this.eventManager = new EventManager(map);
20
21
  }
@@ -43,12 +44,8 @@ class MapTools {
43
44
  * @throws 当参数无效时抛出错误
44
45
  */
45
46
  static getLayerByLayerName(map, layerName) {
46
- if (!map) {
47
- throw new Error('Map instance is required');
48
- }
49
- if (!layerName || (typeof layerName !== 'string' && !Array.isArray(layerName))) {
50
- throw new Error('Valid layer name is required');
51
- }
47
+ ValidationUtils.validateMap(map);
48
+ ValidationUtils.validateLayerNameParam(layerName);
52
49
  const targetLayer = [];
53
50
  try {
54
51
  const layers = map.getLayers().getArray();
@@ -6,6 +6,7 @@ import { Vector as VectorSource } from 'ol/source.js';
6
6
  import { Vector as VectorLayer } from 'ol/layer.js';
7
7
  import { getArea, getLength } from 'ol/sphere.js';
8
8
  import { unByKey } from 'ol/Observable.js';
9
+ import { ValidationUtils } from '../utils/ValidationUtils';
9
10
  /**
10
11
  * 测量工具处理类
11
12
  * 提供距离和面积测量功能
@@ -18,9 +19,7 @@ export default class MeasureHandler {
18
19
  */
19
20
  constructor(map) {
20
21
  this._draw = null;
21
- if (!map) {
22
- throw new Error('Map instance is required');
23
- }
22
+ ValidationUtils.validateMap(map);
24
23
  this._map = map;
25
24
  this.source = new VectorSource();
26
25
  this.vector = new VectorLayer({
@@ -162,12 +161,8 @@ export default class MeasureHandler {
162
161
  * @throws 当测量类型无效时抛出错误
163
162
  */
164
163
  start(type) {
165
- if (!type || (type !== 'LineString' && type !== 'Polygon')) {
166
- throw new Error('Invalid measure type. Must be "LineString" or "Polygon"');
167
- }
168
- if (!this._map) {
169
- throw new Error("MeasureHandler has not been register to the map");
170
- }
164
+ ValidationUtils.validateMeasureType(type);
165
+ ValidationUtils.validateMap(this._map);
171
166
  try {
172
167
  this.createMeasureTooltip();
173
168
  this.createHelpTooltip();
@@ -5,6 +5,44 @@ import { MapJSONData, PointOptions, ClusterOptions, PointData } from '../types';
5
5
  export default class Point {
6
6
  private map;
7
7
  constructor(map: Map);
8
+ /**
9
+ * 创建文本样式
10
+ * @private
11
+ * @param options 选项
12
+ * @param text 文本内容
13
+ * @returns 文本样式
14
+ */
15
+ private createTextStyle;
16
+ /**
17
+ * 创建图标样式
18
+ * @private
19
+ * @param options 选项
20
+ * @returns 图标样式
21
+ */
22
+ private createIconStyle;
23
+ /**
24
+ * 创建点样式
25
+ * @private
26
+ * @param options 选项
27
+ * @param item 数据项
28
+ * @returns 样式对象
29
+ */
30
+ private createPointStyle;
31
+ /**
32
+ * 创建集群样式
33
+ * @private
34
+ * @param options 选项
35
+ * @param name 名称
36
+ * @returns 样式对象
37
+ */
38
+ private createClusterStyle;
39
+ /**
40
+ * 配置图层属性
41
+ * @private
42
+ * @param layer 图层
43
+ * @param options 选项
44
+ */
45
+ private configureLayer;
8
46
  /**
9
47
  *
10
48
  * @param pointData
@@ -10,10 +10,92 @@ import * as turf from '@turf/turf';
10
10
  import GeoJSON from "ol/format/GeoJSON";
11
11
  import DomPoint from './DomPoint';
12
12
  import MapTools from "./MapTools";
13
+ import { ValidationUtils } from '../utils/ValidationUtils';
13
14
  export default class Point {
14
15
  constructor(map) {
15
16
  this.map = map;
16
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.nameKey && item) {
65
+ style.text = this.createTextStyle(options, item[options.nameKey]);
66
+ }
67
+ if (options.hasImg || options.hasImg === undefined) {
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.nameKey) {
82
+ style.text = this.createTextStyle(options, name);
83
+ }
84
+ if (options.hasImg || options.hasImg === undefined) {
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
+ }
17
99
  /**
18
100
  *
19
101
  * @param pointData
@@ -25,14 +107,12 @@ export default class Point {
25
107
  * }
26
108
  */
27
109
  addPoint(pointData, options) {
28
- if (!pointData || pointData.length === 0) {
29
- console.warn('Point data is empty or undefined');
110
+ if (!ValidationUtils.validatePointData(pointData)) {
30
111
  return null;
31
112
  }
32
113
  const pointFeatureList = [];
33
114
  pointData.forEach((item) => {
34
- if (!item.lgtd || !item.lttd) {
35
- console.warn('Invalid coordinates for point:', item);
115
+ if (!ValidationUtils.validateCoordinates(item)) {
36
116
  return;
37
117
  }
38
118
  const pointFeature = new Feature({
@@ -40,32 +120,7 @@ export default class Point {
40
120
  type: options.layerName,
41
121
  geometry: new olPoint([item.lgtd, item.lttd])
42
122
  });
43
- const style = {};
44
- if (options.nameKey) {
45
- style.text = new Text({
46
- text: item[options.nameKey],
47
- font: options.textFont || '12px Calibri,sans-serif',
48
- fill: new Fill({
49
- color: options.textFillColor || '#FFF'
50
- }),
51
- stroke: new Stroke({
52
- color: options.textStrokeColor || '#000',
53
- width: options.textStrokeWidth || 3
54
- }),
55
- offsetY: options.textOffsetY || 20,
56
- });
57
- }
58
- if (options.hasImg || options.hasImg === undefined) {
59
- const iconOptions = {
60
- src: options.img,
61
- scale: options.scale ?? 1,
62
- };
63
- if (options.iconColor) {
64
- iconOptions.color = options.iconColor;
65
- }
66
- style.image = new Icon(iconOptions);
67
- }
68
- pointFeature.setStyle(new Style(style));
123
+ pointFeature.setStyle(this.createPointStyle(options, item));
69
124
  pointFeatureList.push(pointFeature);
70
125
  });
71
126
  const PointVectorLayer = new VectorLayer({
@@ -75,19 +130,16 @@ export default class Point {
75
130
  }),
76
131
  zIndex: options.zIndex || 21,
77
132
  });
78
- PointVectorLayer.setVisible(options.visible === undefined ? true : options.visible);
79
- this.map.addLayer(PointVectorLayer);
133
+ this.configureLayer(PointVectorLayer, options);
80
134
  return PointVectorLayer;
81
135
  }
82
136
  addClusterPoint(pointData, options) {
83
- if (!pointData || pointData.length === 0) {
84
- console.warn('Point data is empty or undefined');
137
+ if (!ValidationUtils.validatePointData(pointData)) {
85
138
  return null;
86
139
  }
87
140
  const pointFeatureList = [];
88
141
  pointData.forEach(item => {
89
- if (!item.lgtd || !item.lttd) {
90
- console.warn('Invalid coordinates for cluster point:', item);
142
+ if (!ValidationUtils.validateCoordinates(item)) {
91
143
  return;
92
144
  }
93
145
  const pointFeature = new Feature({
@@ -100,45 +152,20 @@ export default class Point {
100
152
  features: pointFeatureList,
101
153
  });
102
154
  const clusterSource = new Cluster({
103
- distance: 40, // The distance for clustering in pixels
155
+ distance: options.distance || 40, // The distance for clustering in pixels
156
+ minDistance: options.minDistance || 0,
104
157
  source: source,
105
158
  });
106
159
  const clusterLayer = new VectorLayer({
107
160
  layerName: options.layerName,
108
161
  source: clusterSource,
109
- style: function (feature) {
162
+ style: (feature) => {
110
163
  const name = feature.get('features')[0].get(options.nameKey);
111
- const style = {};
112
- if (options.nameKey) {
113
- style.text = new Text({
114
- text: name,
115
- font: options.textFont || '12px Calibri,sans-serif',
116
- fill: new Fill({
117
- color: options.textFillColor || '#FFF'
118
- }),
119
- stroke: new Stroke({
120
- color: options.textStrokeColor || '#000',
121
- width: options.textStrokeWidth || 3
122
- }),
123
- offsetY: options.textOffsetY || 20,
124
- });
125
- }
126
- if (options.hasImg || options.hasImg === undefined) {
127
- const iconOptions = {
128
- src: options.img,
129
- scale: options.scale ?? 1,
130
- };
131
- if (options.iconColor) {
132
- iconOptions.color = options.iconColor;
133
- }
134
- style.image = new Icon(iconOptions);
135
- }
136
- return new Style(style);
164
+ return this.createClusterStyle(options, name);
137
165
  },
138
166
  zIndex: options.zIndex || 21,
139
167
  });
140
- clusterLayer.setVisible(options.visible === undefined ? true : options.visible);
141
- this.map.addLayer(clusterLayer);
168
+ this.configureLayer(clusterLayer, options);
142
169
  return clusterLayer;
143
170
  }
144
171
  // 在流域中心添加闪烁点位
@@ -247,8 +274,7 @@ export default class Point {
247
274
  * @param duration 动画时长
248
275
  */
249
276
  locationAction(lgtd, lttd, zoom = 20, duration = 3000) {
250
- if (!lgtd || !lttd || isNaN(lgtd) || isNaN(lttd)) {
251
- console.error('[地图定位]', '经纬度不能为空或无效');
277
+ if (!ValidationUtils.validateLngLat(lgtd, lttd)) {
252
278
  return false;
253
279
  }
254
280
  try {
@@ -264,8 +290,11 @@ export default class Point {
264
290
  * 设置dom元素为点位
265
291
  */
266
292
  setDomPoint(id, lgtd, lttd) {
267
- if (!id || !lgtd || !lttd || isNaN(lgtd) || isNaN(lttd)) {
268
- console.error('Invalid parameters for setDomPoint');
293
+ if (!id) {
294
+ console.error('Element ID is required');
295
+ return false;
296
+ }
297
+ if (!ValidationUtils.validateLngLat(lgtd, lttd)) {
269
298
  return false;
270
299
  }
271
300
  const el = document.getElementById(id);
@@ -309,7 +338,7 @@ export default class Point {
309
338
  }
310
339
  try {
311
340
  const layer = pointInfoList.map((pointInfo) => {
312
- if (!pointInfo.lgtd || !pointInfo.lttd || isNaN(pointInfo.lgtd) || isNaN(pointInfo.lttd)) {
341
+ if (!ValidationUtils.validateLngLat(pointInfo.lgtd, pointInfo.lttd)) {
313
342
  throw new Error('Valid longitude and latitude are required for each point');
314
343
  }
315
344
  return new DomPoint(this.map, {
@@ -9,6 +9,7 @@ import { fromExtent } from "ol/geom/Polygon";
9
9
  import Feature from "ol/Feature";
10
10
  import ImageStatic from "ol/source/ImageStatic";
11
11
  import MapTools from "./MapTools";
12
+ import { ValidationUtils } from '../utils/ValidationUtils';
12
13
  /**
13
14
  * Polygon 类用于处理地图上的面要素操作
14
15
  * 包括添加多边形、边框、图片图层、热力图等功能
@@ -47,9 +48,7 @@ export default class Polygon {
47
48
  * @throws 当数据格式无效时抛出错误
48
49
  */
49
50
  addBorderPolygon(data, options) {
50
- if (!data || !data.features || !Array.isArray(data.features)) {
51
- throw new Error('Invalid GeoJSON data: features array is required');
52
- }
51
+ ValidationUtils.validateGeoJSONData(data);
53
52
  const mergedOptions = {
54
53
  layerName: 'border',
55
54
  fillColor: 'rgba(255, 255, 255, 0)',
@@ -69,9 +68,7 @@ export default class Polygon {
69
68
  * @throws 当数据格式无效时抛出错误
70
69
  */
71
70
  addPolygon(dataJSON, options) {
72
- if (!dataJSON || !dataJSON.features || !Array.isArray(dataJSON.features)) {
73
- throw new Error('Invalid GeoJSON data: features array is required');
74
- }
71
+ ValidationUtils.validateGeoJSONData(dataJSON);
75
72
  const mergedOptions = {
76
73
  zIndex: 11,
77
74
  visible: true,
@@ -185,9 +182,7 @@ export default class Polygon {
185
182
  * @throws 当图层不存在时抛出错误
186
183
  */
187
184
  updateFeatureColor(layerName, colorObj, options) {
188
- if (!layerName) {
189
- throw new Error('Layer name is required');
190
- }
185
+ ValidationUtils.validateLayerName(layerName);
191
186
  const layers = MapTools.getLayerByLayerName(this.map, layerName);
192
187
  if (layers.length === 0) {
193
188
  throw new Error(`Layer with name '${layerName}' not found`);
@@ -346,12 +341,7 @@ export default class Polygon {
346
341
  * @throws 当数据格式无效时抛出错误
347
342
  */
348
343
  addImageLayer(imageData, options) {
349
- if (!imageData || !imageData.img || !imageData.extent) {
350
- throw new Error('Invalid image data: img and extent are required');
351
- }
352
- if (!Array.isArray(imageData.extent) || imageData.extent.length !== 4) {
353
- throw new Error('Invalid extent: must be an array of 4 numbers [minX, minY, maxX, maxY]');
354
- }
344
+ ValidationUtils.validateImageData(imageData);
355
345
  const mergedOptions = {
356
346
  opacity: 1,
357
347
  visible: true,
@@ -427,9 +417,7 @@ export default class Polygon {
427
417
  * @throws 当数据格式无效时抛出错误
428
418
  */
429
419
  addMaskLayer(data, options) {
430
- if (!data) {
431
- throw new Error('Mask data is required');
432
- }
420
+ ValidationUtils.validateMaskData(data);
433
421
  const mergedOptions = {
434
422
  fillColor: 'rgba(0, 0, 0, 0.5)',
435
423
  opacity: 1,
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ export { ConfigManager } from './core/ConfigManager';
11
11
  export { EventManager } from './core/EventManager';
12
12
  export type { MapEventType, EventCallback, MapEventData } from './core/EventManager';
13
13
  export { ErrorHandler, MyOpenLayersError, ErrorType } from './utils/ErrorHandler';
14
+ export { ValidationUtils } from './utils/ValidationUtils';
14
15
  export type { BaseOptions, StyleOptions, TextOptions } from './types';
15
16
  export type { PointOptions, LineOptions, PolygonOptions } from './types';
16
17
  export type { OptionsType } from './types';
package/dist/index.js CHANGED
@@ -13,3 +13,5 @@ export { ConfigManager } from './core/ConfigManager';
13
13
  export { EventManager } from './core/EventManager';
14
14
  // 错误处理
15
15
  export { ErrorHandler, MyOpenLayersError, ErrorType } from './utils/ErrorHandler';
16
+ // 验证工具
17
+ export { ValidationUtils } from './utils/ValidationUtils';