my-openlayer 2.1.6 → 2.1.8
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/MapTools.d.ts +2 -0
- package/core/MapTools.js +48 -22
- package/core/Point.js +1 -0
- package/core/Polygon.js +47 -28
- package/package.json +1 -1
package/core/MapTools.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export default class MapTools {
|
|
|
30
30
|
static getLayerByLayerName(map: Map, layerName: string | string[]): (VectorLayer<VectorSource> | BaseLayer | ImageLayer<ImageSource>)[];
|
|
31
31
|
/**
|
|
32
32
|
* 设置地图裁剪
|
|
33
|
+
* 使用 Canvas clip 实现裁剪,支持多个闭合区域
|
|
34
|
+
* 注意:此方法会修改 baseLayer 的 prerender 和 postrender 事件
|
|
33
35
|
*/
|
|
34
36
|
static setMapClip(baseLayer: any, data: MapJSONData): any;
|
|
35
37
|
/**
|
package/core/MapTools.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
import VectorLayer from "ol/layer/Vector";
|
|
3
|
-
import VectorSource from "ol/source/Vector";
|
|
4
2
|
import GeoJSON from "ol/format/GeoJSON";
|
|
5
|
-
import { Fill, Style } from "ol/style";
|
|
6
|
-
import { getVectorContext } from "ol/render";
|
|
7
3
|
import { ErrorHandler, ErrorType } from "../utils/ErrorHandler";
|
|
8
4
|
import { ValidationUtils } from "../utils/ValidationUtils";
|
|
9
5
|
/**
|
|
@@ -69,26 +65,59 @@ class MapTools {
|
|
|
69
65
|
}
|
|
70
66
|
/**
|
|
71
67
|
* 设置地图裁剪
|
|
68
|
+
* 使用 Canvas clip 实现裁剪,支持多个闭合区域
|
|
69
|
+
* 注意:此方法会修改 baseLayer 的 prerender 和 postrender 事件
|
|
72
70
|
*/
|
|
73
71
|
static setMapClip(baseLayer, data) {
|
|
74
|
-
const
|
|
75
|
-
style: null,
|
|
76
|
-
source: new VectorSource({
|
|
77
|
-
features: new GeoJSON().readFeatures(data)
|
|
78
|
-
})
|
|
79
|
-
});
|
|
80
|
-
const style = new Style({
|
|
81
|
-
fill: new Fill({
|
|
82
|
-
color: 'transparent'
|
|
83
|
-
})
|
|
84
|
-
});
|
|
72
|
+
const features = new GeoJSON().readFeatures(data);
|
|
85
73
|
baseLayer.on("prerender", (event) => {
|
|
86
|
-
const vectorContext = getVectorContext(event);
|
|
87
|
-
event.context.globalCompositeOperation = 'source-over';
|
|
88
74
|
const ctx = event.context;
|
|
75
|
+
// 获取坐标转换矩阵 (pixel = coordinate * transform)
|
|
76
|
+
// 注意:OpenLayers 的 transform 可能包含 pixelRatio,也可能不包含,取决于版本
|
|
77
|
+
// 在现代版本中,event.frameState.coordinateToPixelTransform 通常用于将地理坐标转换为 Canvas 像素坐标
|
|
78
|
+
const transform = event.frameState.coordinateToPixelTransform;
|
|
89
79
|
ctx.save();
|
|
90
|
-
|
|
91
|
-
|
|
80
|
+
ctx.beginPath();
|
|
81
|
+
features.forEach((feature) => {
|
|
82
|
+
const geometry = feature.getGeometry();
|
|
83
|
+
if (!geometry)
|
|
84
|
+
return;
|
|
85
|
+
const type = geometry.getType();
|
|
86
|
+
const coordinates = geometry.getCoordinates();
|
|
87
|
+
// 辅助函数:绘制单个线性环
|
|
88
|
+
const drawRing = (ringCoords) => {
|
|
89
|
+
if (!ringCoords || ringCoords.length === 0)
|
|
90
|
+
return;
|
|
91
|
+
for (let i = 0; i < ringCoords.length; i++) {
|
|
92
|
+
const coord = ringCoords[i];
|
|
93
|
+
// 手动应用变换: pixelX = x * m0 + y * m1 + m4
|
|
94
|
+
// pixelY = x * m2 + y * m3 + m5
|
|
95
|
+
// transform 数组结构: [m0, m1, m2, m3, m4, m5]
|
|
96
|
+
const pixelX = coord[0] * transform[0] + coord[1] * transform[1] + transform[4];
|
|
97
|
+
const pixelY = coord[0] * transform[2] + coord[1] * transform[3] + transform[5];
|
|
98
|
+
if (i === 0) {
|
|
99
|
+
ctx.moveTo(pixelX, pixelY);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
ctx.lineTo(pixelX, pixelY);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
ctx.closePath();
|
|
106
|
+
};
|
|
107
|
+
if (type === 'MultiPolygon') {
|
|
108
|
+
// MultiPolygon: [Polygon, Polygon] -> Polygon: [OuterRing, InnerRing, ...]
|
|
109
|
+
coordinates.forEach((polygonCoords) => {
|
|
110
|
+
polygonCoords.forEach((ringCoords) => {
|
|
111
|
+
drawRing(ringCoords);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else if (type === 'Polygon') {
|
|
116
|
+
// Polygon: [OuterRing, InnerRing, ...]
|
|
117
|
+
coordinates.forEach((ringCoords) => {
|
|
118
|
+
drawRing(ringCoords);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
92
121
|
});
|
|
93
122
|
ctx.clip();
|
|
94
123
|
});
|
|
@@ -96,9 +125,6 @@ class MapTools {
|
|
|
96
125
|
const ctx = event.context;
|
|
97
126
|
ctx.restore();
|
|
98
127
|
});
|
|
99
|
-
clipLayer.getSource()?.on('addfeature', function () {
|
|
100
|
-
baseLayer.setExtent(clipLayer.getSource()?.getExtent());
|
|
101
|
-
});
|
|
102
128
|
return baseLayer;
|
|
103
129
|
}
|
|
104
130
|
/**
|
package/core/Point.js
CHANGED
|
@@ -118,6 +118,7 @@ export default class Point {
|
|
|
118
118
|
const pointFeature = new Feature({
|
|
119
119
|
rawData: item,
|
|
120
120
|
type: options.layerName,
|
|
121
|
+
layerName: options.layerName,
|
|
121
122
|
geometry: new olPoint([item.lgtd, item.lttd])
|
|
122
123
|
});
|
|
123
124
|
pointFeature.setStyle(this.createPointStyle(options, item));
|
package/core/Polygon.js
CHANGED
|
@@ -4,7 +4,7 @@ import VectorSource from "ol/source/Vector";
|
|
|
4
4
|
import GeoJSON from "ol/format/GeoJSON";
|
|
5
5
|
import { Fill, Stroke, Style, Text } from "ol/style";
|
|
6
6
|
import { Image as ImageLayer, Heatmap } from "ol/layer";
|
|
7
|
-
import {
|
|
7
|
+
import { LinearRing, Point } from "ol/geom";
|
|
8
8
|
import { fromExtent } from "ol/geom/Polygon";
|
|
9
9
|
import Feature from "ol/Feature";
|
|
10
10
|
import ImageStatic from "ol/source/ImageStatic";
|
|
@@ -350,34 +350,27 @@ export default class Polygon {
|
|
|
350
350
|
}
|
|
351
351
|
return group;
|
|
352
352
|
}
|
|
353
|
-
/** 擦除操作 **/
|
|
354
|
-
function erase(
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
353
|
+
/** 擦除操作 - 创建遮罩多边形 **/
|
|
354
|
+
function erase(geometries, view) {
|
|
355
|
+
// 收集所有几何图形的坐标环
|
|
356
|
+
let allParts = [];
|
|
357
|
+
geometries.forEach(geom => {
|
|
358
|
+
const parts = getCoordsGroup(geom);
|
|
359
|
+
if (parts && parts.length > 0) {
|
|
360
|
+
allParts = allParts.concat(parts);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
if (allParts.length === 0) {
|
|
364
|
+
return null;
|
|
358
365
|
}
|
|
359
366
|
const extent = view.getProjection().getExtent();
|
|
360
367
|
const polygonRing = fromExtent(extent);
|
|
361
|
-
|
|
368
|
+
allParts.forEach((item) => {
|
|
362
369
|
const linearRing = new LinearRing(item);
|
|
363
370
|
polygonRing.appendLinearRing(linearRing);
|
|
364
371
|
});
|
|
365
372
|
return polygonRing;
|
|
366
373
|
}
|
|
367
|
-
/** 添加遮罩 **/
|
|
368
|
-
function createShade(geom, view) {
|
|
369
|
-
if (geom instanceof Geometry) {
|
|
370
|
-
const source = geom.clone();
|
|
371
|
-
const polygon = erase(source, view);
|
|
372
|
-
const feature = new Feature({
|
|
373
|
-
geometry: polygon
|
|
374
|
-
});
|
|
375
|
-
return {
|
|
376
|
-
feature,
|
|
377
|
-
shade: source
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
374
|
// 遮罩样式
|
|
382
375
|
const shadeStyle = new Style({
|
|
383
376
|
fill: new Fill({
|
|
@@ -398,13 +391,39 @@ export default class Polygon {
|
|
|
398
391
|
});
|
|
399
392
|
this.map.addLayer(vtLayer);
|
|
400
393
|
const features = new GeoJSON().readFeatures(data);
|
|
401
|
-
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
394
|
+
// 收集所有要素的几何图形
|
|
395
|
+
const geometries = [];
|
|
396
|
+
features.forEach(feature => {
|
|
397
|
+
const geometry = feature.getGeometry();
|
|
398
|
+
if (geometry) {
|
|
399
|
+
geometries.push(geometry);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
if (geometries.length > 0) {
|
|
403
|
+
// 创建遮罩
|
|
404
|
+
const polygon = erase(geometries, this.map.getView());
|
|
405
|
+
if (polygon) {
|
|
406
|
+
const feature = new Feature({
|
|
407
|
+
geometry: polygon
|
|
408
|
+
});
|
|
409
|
+
vtSource.addFeature(feature);
|
|
410
|
+
// 如果需要适应视图,计算所有几何图形的合并范围
|
|
411
|
+
if (options?.extent) {
|
|
412
|
+
let totalExtent = geometries[0].getExtent();
|
|
413
|
+
for (let i = 1; i < geometries.length; i++) {
|
|
414
|
+
// 注意:这里需要导入 extend 函数,或者使用简单的 extent 合并逻辑
|
|
415
|
+
// 由于 openlayers 的 extent 是 [minx, miny, maxx, maxy]
|
|
416
|
+
const ext = geometries[i].getExtent();
|
|
417
|
+
totalExtent = [
|
|
418
|
+
Math.min(totalExtent[0], ext[0]),
|
|
419
|
+
Math.min(totalExtent[1], ext[1]),
|
|
420
|
+
Math.max(totalExtent[2], ext[2]),
|
|
421
|
+
Math.max(totalExtent[3], ext[3])
|
|
422
|
+
];
|
|
423
|
+
}
|
|
424
|
+
this.map.getView().fit(totalExtent);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
408
427
|
}
|
|
409
428
|
}
|
|
410
429
|
/**
|