cd-mapgis 1.0.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/package.json +17 -0
- package/src/LayerUtil.js +187 -0
- package/src/OM.js +106 -0
- package/src/index.d.ts +4 -0
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cd-mapgis",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "./src/index.js",
|
|
5
|
+
"types": "./src/index.d.ts",
|
|
6
|
+
"private": false,
|
|
7
|
+
"scripts": {
|
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [],
|
|
11
|
+
"author": "cdzd",
|
|
12
|
+
"license": "ISC",
|
|
13
|
+
"description": "",
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"ol": "^8.1.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/LayerUtil.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import XYZ from 'ol/source/XYZ';
|
|
2
|
+
import Tile from 'ol/layer/Tile';
|
|
3
|
+
import Image from 'ol/layer/Image';
|
|
4
|
+
import ImageWMS from 'ol/source/ImageWMS';
|
|
5
|
+
import WMTS from 'ol/source/WMTS';
|
|
6
|
+
import TilegridWMTS from 'ol/tilegrid/WMTS';
|
|
7
|
+
import { get as getProjection } from 'ol/proj';
|
|
8
|
+
import { getWidth } from 'ol/extent';
|
|
9
|
+
import WMTSCapabilities from 'ol/format/WMTSCapabilities';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 图层工具
|
|
13
|
+
*/
|
|
14
|
+
export default class LayerUtil {
|
|
15
|
+
static _tdt_map = {
|
|
16
|
+
img_w: '卫星影像图层',
|
|
17
|
+
cia_w: '卫星影像注记图层',
|
|
18
|
+
vec_w: '矢量图层',
|
|
19
|
+
cva_w: '矢量注记图层',
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* 获取通用Tile-XYZ图层
|
|
23
|
+
* wrapX:设置为 true(默认):适用于全球地图、需要无缝水平滚动的场景;
|
|
24
|
+
* 设置为 false:适用于局部区域地图、不需要全球连续显示的场景
|
|
25
|
+
* @param {*} p {name,url,projection?}
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
static xyz(p) {
|
|
29
|
+
let param = {
|
|
30
|
+
title: p.name,
|
|
31
|
+
source: new XYZ({
|
|
32
|
+
url: p.url,
|
|
33
|
+
wrapX: false
|
|
34
|
+
})
|
|
35
|
+
};
|
|
36
|
+
return new Tile(param);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* nginx中发布的xyz目录瓦片(不能设置projection,设置后地图消失)
|
|
40
|
+
* var url = 'http://172.20.2.9:30016/{z}/{x}/{y}.png';
|
|
41
|
+
* @param {*} p
|
|
42
|
+
*/
|
|
43
|
+
static ngXyz(p) {
|
|
44
|
+
let name = p.name ? p.name : 'ngXyz';
|
|
45
|
+
let url = p.url + '/{z}/{x}/{y}.png';
|
|
46
|
+
return LayerUtil.xyz({ name: name, url: url });
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 获取在线天地图
|
|
50
|
+
* @param {*} p {type,tk}
|
|
51
|
+
* @returns
|
|
52
|
+
*/
|
|
53
|
+
static onLineTianditu(p) {
|
|
54
|
+
let name = LayerUtil._tdt_map[p.type];
|
|
55
|
+
let url = 'http://t0.tianditu.com/DataServer?T=' + p.type + '_w&x={x}&y={y}&l={z}&tk=' + p.tk;
|
|
56
|
+
return LayerUtil.xyz({ name: name, url: url });
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 获取geoserver图层
|
|
60
|
+
* @param {*} p {workspace,name,url,mv{cql}?}
|
|
61
|
+
* @returns
|
|
62
|
+
*/
|
|
63
|
+
static geoServerWmsLayer(p) {
|
|
64
|
+
let params = {
|
|
65
|
+
LAYERS: p.workspace + ":" + p.name,
|
|
66
|
+
EXCEPTIONS: 'application/vnd.ogc.se_inimage',
|
|
67
|
+
FORMAT: 'image/png',
|
|
68
|
+
VERSION: '1.1.1'
|
|
69
|
+
};
|
|
70
|
+
//条件过滤显示图层
|
|
71
|
+
if (p.mv && p.mv.cql) {
|
|
72
|
+
params['CQL_FILTER'] = node.mv.cql;
|
|
73
|
+
}
|
|
74
|
+
return new Image({
|
|
75
|
+
source: new ImageWMS({
|
|
76
|
+
ratio: 1,
|
|
77
|
+
url: p.url,
|
|
78
|
+
params: params
|
|
79
|
+
})
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 获取标准的wmts图层
|
|
84
|
+
* @param {*} p
|
|
85
|
+
* @returns
|
|
86
|
+
*/
|
|
87
|
+
static async getWmtsLayer(p) {
|
|
88
|
+
try {
|
|
89
|
+
let wmtsUrl = p.url;
|
|
90
|
+
// 构造 GetCapabilities 请求地址
|
|
91
|
+
const capabilitiesUrl = wmtsUrl.includes('?')
|
|
92
|
+
? `${wmtsUrl}&service=WMTS&request=GetCapabilities`
|
|
93
|
+
: `${wmtsUrl}?service=WMTS&request=GetCapabilities`;
|
|
94
|
+
// 获取服务元数据
|
|
95
|
+
const response = await fetch(capabilitiesUrl);
|
|
96
|
+
const capabilitiesText = await response.text();
|
|
97
|
+
// 使用 OpenLayers 的 WMTS 能力文档解析器
|
|
98
|
+
const wmtsFormat = new WMTSCapabilities();
|
|
99
|
+
const capabilities = wmtsFormat.read(capabilitiesText);
|
|
100
|
+
// 提取关键参数
|
|
101
|
+
const contents = capabilities.Contents;
|
|
102
|
+
const layers = contents.Layer;
|
|
103
|
+
const tileMatrixSets = contents.TileMatrixSet;
|
|
104
|
+
// 获取第一个图层
|
|
105
|
+
const layer = layers[0];
|
|
106
|
+
const layerName = layer.Identifier;
|
|
107
|
+
// 获取图层关联的瓦片矩阵集链接
|
|
108
|
+
const tileMatrixSetLink = layer.TileMatrixSetLink[0];
|
|
109
|
+
const matrixSetName = tileMatrixSetLink.TileMatrixSet;
|
|
110
|
+
// 在 TileMatrixSet 中查找对应的矩阵集以获取 CRS
|
|
111
|
+
const tileMatrixSet = tileMatrixSets.find(set => set.Identifier === matrixSetName);
|
|
112
|
+
const supportedCRS = tileMatrixSet.SupportedCRS;
|
|
113
|
+
const projectionCode = supportedCRS.includes('4490') ? 'EPSG:4326' :
|
|
114
|
+
supportedCRS.replace('urn:ogc:def:crs:', '').replace('::', ':');
|
|
115
|
+
// 创建投影对象
|
|
116
|
+
const proj = getProjection(projectionCode) || getProjection('EPSG:4326');
|
|
117
|
+
const projExtent = proj.getExtent();
|
|
118
|
+
// 获取支持的格式
|
|
119
|
+
const format = layer.Format && layer.Format.length > 0 ? layer.Format[0] : 'tiles';
|
|
120
|
+
// 获取样式
|
|
121
|
+
const style = layer.Style && layer.Style.length > 0 ? layer.Style[0].Identifier : 'default';
|
|
122
|
+
// 构造瓦片网格参数
|
|
123
|
+
const matrixIds = [];
|
|
124
|
+
const resolutions = [];
|
|
125
|
+
const origin = [];
|
|
126
|
+
// 判断是否为经纬度坐标系
|
|
127
|
+
const isGeographic = projectionCode.includes('4326') || projectionCode.includes('4490');
|
|
128
|
+
// 从瓦片矩阵集中提取信息
|
|
129
|
+
if (tileMatrixSet && tileMatrixSet.TileMatrix) {
|
|
130
|
+
// 按照矩阵ID排序(确保顺序正确)
|
|
131
|
+
const sortedMatrices = tileMatrixSet.TileMatrix.sort((a, b) => {
|
|
132
|
+
return parseInt(a.Identifier) - parseInt(b.Identifier);
|
|
133
|
+
});
|
|
134
|
+
const size = getWidth(projExtent) / 256;
|
|
135
|
+
sortedMatrices.forEach(matrix => {
|
|
136
|
+
matrixIds.push(matrix.Identifier);
|
|
137
|
+
// 根据坐标系类型自动选择分辨率计算方式
|
|
138
|
+
if (isGeographic) {
|
|
139
|
+
// 经纬度坐标系:使用度为单位的分辨率计算
|
|
140
|
+
const zoomLevel = parseInt(matrix.Identifier);
|
|
141
|
+
// 基于经纬度的分辨率计算(1.40625 度/像素作为起始分辨率)
|
|
142
|
+
const resolution = size / Math.pow(2, zoomLevel);
|
|
143
|
+
resolutions.push(resolution);
|
|
144
|
+
} else {
|
|
145
|
+
// 米制坐标系:使用标准 WMTS 分辨率计算
|
|
146
|
+
resolutions.push(matrix.ScaleDenominator * 0.00028);
|
|
147
|
+
}
|
|
148
|
+
if (origin.length === 0 && matrix.TopLeftCorner) {
|
|
149
|
+
// 处原点坐标
|
|
150
|
+
if (isGeographic) {
|
|
151
|
+
// 经纬度坐标系的原点处理
|
|
152
|
+
origin.push(matrix.TopLeftCorner[1]); // 经度
|
|
153
|
+
origin.push(matrix.TopLeftCorner[0]); // 纬度
|
|
154
|
+
} else {
|
|
155
|
+
// 米制坐标系的原点处理
|
|
156
|
+
origin.push(matrix.TopLeftCorner[0]);
|
|
157
|
+
origin.push(matrix.TopLeftCorner[1]);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// 创建瓦片网格配置
|
|
163
|
+
const tileGridConfig = new TilegridWMTS({
|
|
164
|
+
origin: origin.length > 0 ? origin : (isGeographic ? [-180, 90] : [-20037508.342789244, 20037508.342789244]),
|
|
165
|
+
resolutions: resolutions,
|
|
166
|
+
matrixIds: matrixIds
|
|
167
|
+
});
|
|
168
|
+
// 创建 WMTS 图层
|
|
169
|
+
const wmtsLayer = new Tile({
|
|
170
|
+
source: new WMTS({
|
|
171
|
+
url: wmtsUrl,
|
|
172
|
+
layer: layerName,
|
|
173
|
+
matrixSet: matrixSetName,
|
|
174
|
+
format: format,
|
|
175
|
+
projection: proj,
|
|
176
|
+
tileGrid: tileGridConfig,
|
|
177
|
+
style: style,
|
|
178
|
+
wrapX: true
|
|
179
|
+
})
|
|
180
|
+
});
|
|
181
|
+
return wmtsLayer;
|
|
182
|
+
} catch (e) {
|
|
183
|
+
console.error("加载wmts图层失败:" + JSON.stringify(node), e);
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
}
|
package/src/OM.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import GeoJSON from 'ol/format/GeoJSON';
|
|
2
|
+
import Feature from 'ol/Feature';
|
|
3
|
+
import VectorSource from 'ol/source/Vector';
|
|
4
|
+
import Style from 'ol/style/Style';
|
|
5
|
+
import Stroke from 'ol/style/Stroke';
|
|
6
|
+
import Fill from 'ol/style/Fill';
|
|
7
|
+
import VectorLayer from 'ol/layer/Vector';
|
|
8
|
+
import View from 'ol/View';
|
|
9
|
+
import Map from 'ol/Map';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* OM
|
|
13
|
+
*/
|
|
14
|
+
export default class OM {
|
|
15
|
+
static map = null;//openlayer map对象
|
|
16
|
+
static view = null;
|
|
17
|
+
/**
|
|
18
|
+
* 初始化
|
|
19
|
+
*/
|
|
20
|
+
static initMap(p) {
|
|
21
|
+
let target = p.target ? p.target : 'map';//地图div的id
|
|
22
|
+
let center = p.center ? p.center : [104.0633664, 30.6598344];//地图初始中心点(默认天府广场)
|
|
23
|
+
let zoom = p.zoom ? p.zoom : 16; //地图初始显示级数
|
|
24
|
+
let projection = p.projection ? p.projection : 'EPSG:4326';
|
|
25
|
+
let layers = p.layers ? p.layers : [];
|
|
26
|
+
OM.view = new View({
|
|
27
|
+
center: center,
|
|
28
|
+
zoom: zoom,
|
|
29
|
+
projection: projection
|
|
30
|
+
});
|
|
31
|
+
OM.map = new Map({
|
|
32
|
+
target: target,
|
|
33
|
+
controls: [],
|
|
34
|
+
layers: layers,
|
|
35
|
+
view: view,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 高亮显示图斑
|
|
40
|
+
* @param {*} p
|
|
41
|
+
*/
|
|
42
|
+
static viewOnTemplayer(p) {
|
|
43
|
+
let geometry = new GeoJSON().readGeometry(p.data);
|
|
44
|
+
let feature = new Feature({
|
|
45
|
+
geometry: geometry
|
|
46
|
+
});
|
|
47
|
+
let vectorSource = new VectorSource({
|
|
48
|
+
features: [feature]
|
|
49
|
+
});
|
|
50
|
+
let style = new Style({
|
|
51
|
+
stroke: new Stroke({
|
|
52
|
+
color: '#0af5e6', // 默认选择色
|
|
53
|
+
width: 2 // 线宽
|
|
54
|
+
}),
|
|
55
|
+
fill: new Fill({
|
|
56
|
+
color: 'rgba(0, 0, 0, 0)' // 透明填充
|
|
57
|
+
})
|
|
58
|
+
});
|
|
59
|
+
//移除之前的显示
|
|
60
|
+
if (window._view_templayer) {
|
|
61
|
+
window._view_templayer.getSource().clear();//清空图层
|
|
62
|
+
this.map.removeLayer(window._view_templayer);//移除图层
|
|
63
|
+
}
|
|
64
|
+
//重建图层,避免在其他地方全部移除图层后,templayer不为空,但是已经不在地图中的情况
|
|
65
|
+
window._view_templayer = new VectorLayer({
|
|
66
|
+
source: vectorSource,
|
|
67
|
+
style: style
|
|
68
|
+
});
|
|
69
|
+
// 添加到地图
|
|
70
|
+
this.map.addLayer(window._view_templayer);
|
|
71
|
+
// fit方法 - 自动适应范围
|
|
72
|
+
let extent = geometry.getExtent();
|
|
73
|
+
let extent2 = OM.expandExtent(extent);
|
|
74
|
+
this.map.getView().fit(extent2, {
|
|
75
|
+
size: this.map.getSize()
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* 扩大一倍extent
|
|
80
|
+
* @param {*} extent
|
|
81
|
+
*/
|
|
82
|
+
static expandExtent(extent) {
|
|
83
|
+
if (!extent || extent.length !== 4) {
|
|
84
|
+
return extent;
|
|
85
|
+
}
|
|
86
|
+
var minX = extent[0];
|
|
87
|
+
var minY = extent[1];
|
|
88
|
+
var maxX = extent[2];
|
|
89
|
+
var maxY = extent[3];
|
|
90
|
+
// 计算中心点
|
|
91
|
+
var centerX = (minX + maxX) / 2;
|
|
92
|
+
var centerY = (minY + maxY) / 2;
|
|
93
|
+
// 计算原始宽度和高度
|
|
94
|
+
var width = maxX - minX;
|
|
95
|
+
var height = maxY - minY;
|
|
96
|
+
// 扩大一倍(乘以2)
|
|
97
|
+
var newWidth = width * 2;
|
|
98
|
+
var newHeight = height * 2;
|
|
99
|
+
// 计算新的边界
|
|
100
|
+
var newMinX = centerX - newWidth / 2;
|
|
101
|
+
var newMinY = centerY - newHeight / 2;
|
|
102
|
+
var newMaxX = centerX + newWidth / 2;
|
|
103
|
+
var newMaxY = centerY + newHeight / 2;
|
|
104
|
+
return [newMinX, newMinY, newMaxX, newMaxY];
|
|
105
|
+
}
|
|
106
|
+
}
|
package/src/index.d.ts
ADDED