uniapp使用openlayers加载地图服务
js
<!-- 地图组件 -->
<template>
<view id="myMap" :regionChangeItem="regionChangeItem" :change:regionChangeItem="olRender.selectAdministrativeRegion"
:tagSelectProduce=tagSelectProduce :tagSelectDistribute="tagSelectDistribute"
:change:tagSelectProduce="olRender.tagSelectChangeProduce"
:change:tagSelectDistribute="olRender.tagSelectChangeDistribute" :dropFrameDataProduce="dropFrameDataProduce"
:dropFrameDataDistribute="dropFrameDataDistribute" :change:dropFrameDataProduce="olRender.loadDropFrameProduce"
:change:dropFrameDataDistribute="olRender.loadDropFrameDistribute"
style="width: 100%; height: calc(100vh - 84rpx);"></view>
</template>
<script>
export default {
props: {
// 行政区选择数据
regionChangeItem: {
type: Object,
default: () => ({
geom: null,
})
},
dropFrameDataProduce: {
type: Object,
default: () => ({
imagesGeom05: [],
imagesGeom1: [],
imagesGeom2: [],
xzqdm: 530000,
})
},
dropFrameDataDistribute: {
type: Object,
default: () => ({
imagesGeom05: [],
imagesGeom1: [],
imagesGeom2: [],
xzqdm: 530000,
})
},
tagSelectProduce: {
type: Object,
default: () => ({
tag05: true,
tag1: true,
tag2: true,
})
},
tagSelectDistribute: {
type: Object,
default: () => ({
tag05: true,
tag1: true,
tag2: true,
})
},
},
}
</script>
<script module="olRender" lang="renderjs">
import source, {
Vector as sourceVector
} from 'ol/source';
import ol, {
Map,
Tile,
View,
Feature
} from 'ol';
import {
Polygon
} from 'ol/geom';
import {
Style,
Fill,
Stroke
} from 'ol/style';
import {
fromLonLat,
transform,
Projection
} from 'ol/proj.js';
import {
DragPan,
MouseWheelZoom,
defaults as defaultInteractions
} from 'ol/interaction';
import {
Vector,
} from 'ol/layer';
import VectorImageLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import WKT from 'ol/format/WKT';
import GeoJSON from "ol/format/GeoJSON";
import {
bbox as bboxStrategy
} from 'ol/loadingstrategy';
import {
MapServiceLoader
} from '@/map/MapServiceLoader.js';
import GLOBAL_VARIABLE from '@/public/config/GlobalConfig';
import {
eventBus
} from '@/utils/eventBus.js';
export default {
data() {
return {
mapId: 'myMap',
map: null,
mapServiceLoader: null,
format: new WKT(),
xzqId: 'xzq', // 行政区id
xzqIdYns: 'xzqYns', // 行政区id(省)
xzqHighlightId: 'xzqHighlight', // 选择后高亮行政区id
projection: {},
dropColor: {
imagesGeom05: {
strokeColor: 'rgba(175, 175, 175, 0.5)',
fillColor: 'rgba(147, 250, 194, 0.5)',
},
imagesGeom1: {
strokeColor: 'rgba(175, 175, 175, 0.5)',
fillColor: 'rgba(147, 240, 250, 0.5)',
},
imagesGeom2: {
strokeColor: 'rgba(175, 175, 175, 0.5)',
fillColor: 'rgba(255, 196, 196, 0.5)',
},
},
dropColorDistribute: {
imagesGeom05: {
strokeColor: 'rgba(152, 230, 0, 0.5)',
fillColor: 'rgba(76, 230, 0, 0.5)',
},
imagesGeom1: {
strokeColor: 'rgba(152, 230, 0, 0.5)',
fillColor: 'rgba(152, 230, 0, 0.5)',
},
imagesGeom2: {
strokeColor: 'rgba(230, 230, 0, 0.5)',
fillColor: 'rgba(230, 230, 0, 0.5)',
},
},
// 影像生产-落图框图层id
drop05ProduceId: 'drop05_p',
drop1ProduceId: 'drop1_p',
drop2ProduceId: 'drop2_p',
// 影像分发-落图框图层id
drop05DistributeId: 'drop05_d',
drop1DistributeId: 'drop1_d',
drop2DistributeId: 'drop2_d',
// 影像生产落图框图层
imagesGeom05LayersProduce: null,
imagesGeom1LayersProduce: null,
imagesGeom2LayersProduce: null,
// 影像分发-落图框图层
imagesGeom05LayersDistribute: null,
imagesGeom1LayersDistribute: null,
imagesGeom2LayersDistribute: null,
};
},
methods: {
getRegionLayerDataCounty(cqlFilter = 'level in (2)') {
const workspaceName = GLOBAL_VARIABLE.administrativeConfig.workspaceName;
const layerName = GLOBAL_VARIABLE.administrativeConfig.layerNameCounty;
const accessUrl = GLOBAL_VARIABLE.administrativeConfig.accessUrl;
const optionWms = {
layerName,
matrixSet: 'EPSG:4326',
accessUrl: `${accessUrl}/${workspaceName}/wms`,
id: this.xzqId,
serviceType: 'wms',
otherPara: {
layerName: layerName,
matrixSet: 'EPSG:4326',
format: 'image/png',
VERSION: '1.1.1',
LAYERS: workspaceName + ':' + layerName,
projection: this.projection,
zIndex: 10,
opacity: 1,
exceptions: 'application/vnd.ogc.se_inimage',
CQL_FILTER: cqlFilter,
},
transformationMatrix: '1,2,3 2,4,5 4,6,7',
};
const optionWmTs = {
layerName,
matrixSet: 'EPSG:4326',
accessUrl: `${accessUrl}/${workspaceName}/gwc/service/wmts?request=GetCapabilities`,
id: this.xzqId,
serviceType: 'wmts',
transformationMatrix: '1,2,3 2,4,5 4,6,7',
otherPara: {}
};
return optionWmTs;
},
innitMap() {
const projection = new Projection({
code: 'EPSG:4490',
units: 'degrees',
global: false,
});
this.projection = projection;
const view = new View({
projection,
enableRotation: false, // 禁止地图旋转
})
const map = new Map({
target: this.mapId,
layers: [],
view,
controls: [],
interactions: defaultInteractions({
dragPan: false,
doubleClickZoom: false, // 取消双击放大功能交互
mouseWheelZoom: false, // 取消滚动鼠标中间的滑轮交互
shiftDragZoom: false, // 取消shift+wheel左键拖动交互
})
.extend([
new DragPan({
condition: function(event) {
return event.originalEvent.button === 1;
}
})
]),
});
// 拖拽移动
// const dragPan = new DragPan();
// const mouseWheelZoom = new MouseWheelZoom();
// // 添加DragPan和MouseWheelZoom交互到地图
// map.addInteraction(dragPan);
// map.addInteraction(mouseWheelZoom);
// 禁用地图旋转
view.setRotation(0);
this.map = map;
this.mapServiceLoader = new MapServiceLoader(map);
// 加载行政区
this.mapServiceLoader.loadServices(this.getRegionLayerDataCounty());
// this.xzqLoadLocal();
this.map.on('click', (e) => {
this.handleMapClick(e);
})
// 定位到行政区
this.goToXzqLayer();
},
/**
* 影像生产-落图框显示标签改变
*/
tagSelectChangeProduce(e) {
this.imagesGeom05LayersProduce && this.imagesGeom05LayersProduce.setVisible(e.tag05);
this.imagesGeom1LayersProduce && this.imagesGeom1LayersProduce.setVisible(e.tag1);
this.imagesGeom2LayersProduce && this.imagesGeom2LayersProduce.setVisible(e.tag2);
},
/**
* 影像分发-落图框显示标签改变
*/
tagSelectChangeDistribute(e) {
this.imagesGeom05LayersDistribute && this.imagesGeom05LayersDistribute.setVisible(e.tag05);
this.imagesGeom1LayersDistribute && this.imagesGeom1LayersDistribute.setVisible(e.tag1);
this.imagesGeom2LayersDistribute && this.imagesGeom2LayersDistribute.setVisible(e.tag2);
},
/**
* 影像分发-加载落图框
*/
loadDropFrameDistribute({
imagesGeom05,
imagesGeom1,
imagesGeom2,
xzqdm,
}) {
const wktFormat = this.format;
const that = this;
// 移除之前的高亮图层
if (this.mapServiceLoader) {
this.mapServiceLoader.removeLayerBiyId(this.drop05DistributeId);
this.mapServiceLoader.removeLayerBiyId(this.drop1DistributeId);
this.mapServiceLoader.removeLayerBiyId(this.drop2DistributeId);
}
this.imagesGeom05LayersDistribute = null;
this.imagesGeom1LayersDistribute = null;
this.imagesGeom2LayersDistribute = null;
if (imagesGeom05.length) {
let features = [];
imagesGeom05.forEach((geom) => {
features = [...features, ...wktFormat.readFeatures(geom)];
});
features.forEach((f) => {
f.setProperties({
cLayerStyleType: 'type1',
type: that.drop05DistributeId
});
});
const vectorSource = new VectorSource({
features: [...features],
strategy: bboxStrategy
});
const vectorLayer = new VectorImageLayer({
source: vectorSource,
zIndex: 300,
style(feature) {
let strokeWidth = 1;
return new Style({
fill: new Fill({
color: that.dropColorDistribute.imagesGeom05.fillColor,
}),
stroke: new Stroke({
color: that.dropColorDistribute.imagesGeom05.strokeColor,
width: strokeWidth,
}),
});
},
});
vectorLayer.id = this.drop05DistributeId;
this.imagesGeom05LayersDistribute = vectorLayer;
// vectorLayer.setVisible(false);
this.map.addLayer(vectorLayer);
}
if (imagesGeom1.length) {
let features = [];
imagesGeom1.forEach((geom) => {
features = [...features, ...wktFormat.readFeatures(geom)];
});
features.forEach((f) => {
f.setProperties({
cLayerStyleType: 'type1',
type: that.drop1DistributeId
});
});
const vectorSource = new VectorSource({
features: [...features],
strategy: bboxStrategy
});
const vectorLayer = new VectorImageLayer({
source: vectorSource,
zIndex: 200,
style(feature) {
let strokeWidth = 1;
return new Style({
fill: new Fill({
color: that.dropColorDistribute.imagesGeom1.fillColor,
}),
stroke: new Stroke({
color: that.dropColorDistribute.imagesGeom1.strokeColor,
width: strokeWidth,
}),
});
},
});
vectorLayer.id = this.drop1DistributeId;
this.imagesGeom1LayersDistribute = vectorLayer;
// vectorLayer.setVisible(false);
this.map.addLayer(vectorLayer);
}
if (imagesGeom2.length) {
let features = [];
imagesGeom2.forEach((geom) => {
features = [...features, ...wktFormat.readFeatures(geom)];
});
features.forEach((f) => {
f.setProperties({
cLayerStyleType: 'type1',
type: that.drop2DistributeId
});
});
const vectorSource = new VectorSource({
features: [...features],
strategy: bboxStrategy
});
const vectorLayer = new VectorImageLayer({
source: vectorSource,
zIndex: 100,
style(feature) {
let strokeWidth = 1;
return new Style({
fill: new Fill({
color: that.dropColorDistribute.imagesGeom2.fillColor,
}),
stroke: new Stroke({
color: that.dropColorDistribute.imagesGeom2.strokeColor,
width: strokeWidth,
}),
});
},
});
vectorLayer.id = this.drop2DistributeId;
this.imagesGeom2LayersDistribute = vectorLayer;
// vectorLayer.setVisible(false);
this.map.addLayer(vectorLayer);
}
if (xzqdm == 530000) {
const myset = setTimeout(function() {
that.gotoDropLayers([this.drop05DistributeId, this.drop1DistributeId, this
.drop2DistributeId
]);
clearTimeout(myset)
}, 200);
}
},
/**
* 影像生产-加载图框
*/
loadDropFrameProduce({
imagesGeom05,
imagesGeom1,
imagesGeom2,
xzqdm,
}) {
const wktFormat = this.format;
const that = this;
// 移除之前的高亮图层
if (this.mapServiceLoader) {
this.mapServiceLoader.removeLayerBiyId(this.drop05ProduceId);
this.mapServiceLoader.removeLayerBiyId(this.drop1ProduceId);
this.mapServiceLoader.removeLayerBiyId(this.drop2ProduceId);
}
this.imagesGeom05LayersProduce = null;
this.imagesGeom1LayersProduce = null;
this.imagesGeom2LayersProduce = null;
if (imagesGeom05.length) {
let features = [];
imagesGeom05.forEach((geom) => {
features = [...features, ...wktFormat.readFeatures(geom)];
});
features.forEach((f) => {
f.setProperties({
cLayerStyleType: 'type1',
type: that.drop05ProduceId
});
});
const vectorSource = new VectorSource({
features: [...features],
strategy: bboxStrategy
});
const vectorLayer = new VectorImageLayer({
source: vectorSource,
zIndex: 300,
style(feature) {
let strokeWidth = 1;
return new Style({
fill: new Fill({
color: that.dropColor.imagesGeom05.fillColor,
}),
stroke: new Stroke({
color: that.dropColor.imagesGeom05.strokeColor,
width: strokeWidth,
}),
});
},
});
vectorLayer.id = this.drop05ProduceId;
this.imagesGeom05LayersProduce = vectorLayer;
this.map.addLayer(vectorLayer);
}
if (imagesGeom1.length) {
let features = [];
imagesGeom1.forEach((geom) => {
features = [...features, ...wktFormat.readFeatures(geom)];
});
features.forEach((f) => {
f.setProperties({
cLayerStyleType: 'type1',
type: that.drop1ProduceId
});
});
const vectorSource = new VectorSource({
features: [...features],
strategy: bboxStrategy
});
const vectorLayer = new VectorImageLayer({
source: vectorSource,
zIndex: 200,
style(feature) {
let strokeWidth = 1;
return new Style({
fill: new Fill({
color: that.dropColor.imagesGeom1.fillColor,
}),
stroke: new Stroke({
color: that.dropColor.imagesGeom1.strokeColor,
width: strokeWidth,
}),
});
},
});
vectorLayer.id = this.drop1ProduceId
this.imagesGeom1LayersProduce = vectorLayer;
this.map.addLayer(vectorLayer);
}
if (imagesGeom2.length) {
let features = [];
imagesGeom2.forEach((geom) => {
features = [...features, ...wktFormat.readFeatures(geom)];
});
features.forEach((f) => {
f.setProperties({
cLayerStyleType: 'type1',
type: that.drop2ProduceId
});
});
const vectorSource = new VectorSource({
features: [...features],
strategy: bboxStrategy
});
const vectorLayer = new VectorImageLayer({
source: vectorSource,
zIndex: 100,
style(feature) {
let strokeWidth = 1;
return new Style({
fill: new Fill({
color: that.dropColor.imagesGeom2.fillColor,
}),
stroke: new Stroke({
color: that.dropColor.imagesGeom2.strokeColor,
width: strokeWidth,
}),
});
},
});
vectorLayer.id = this.drop2ProduceId;
this.imagesGeom2LayersProduce = vectorLayer;
this.map.addLayer(vectorLayer);
}
if (xzqdm == 530000) {
const myset = setTimeout(function() {
that.gotoDropLayers([this.drop05ProduceId, this.drop1ProduceId, this.drop2ProduceId]);
clearTimeout(myset)
}, 200);
}
},
/**定位到行政区
*/
goToXzqLayer() {
// console.log('定位到行政区');
const extents = [97.52736740199998, 21.142140719999986, 106.19671131500002, 29.22577058899998];
this.map.getView().fit(extents);
},
/**
* 开关图层显示
*/
setLayerVisible(layerId, visible) {
const layer = this.mapServiceLoader.findLayerById(this.xzqId);
if (layer) {
layer.setVisible(visible);
}
},
/**
* 根据id定位到图层
*/
positioningLayersById(layerId, isVisible = true) {
const that = this;
const layer = this.mapServiceLoader.findLayerById(layerId);
if (layer) {
const extents = layer.getSource().getExtent();
this.map.getView().fit(extents, {
duration: 1000
});
}
const myset = setTimeout(function() {
// 关闭主图
that.setLayerVisible(that.xzqId, isVisible);
clearTimeout(myset)
}, 1000);
},
/**
* 服务-切换地图到选择行政区上
*/
selectAtiveRegion({
geom,
xzqdm,
children,
}) {
const that = this;
// console.log('服务-切换地图到选择行政区上', xzqdm);
const cqlFilter = `xzqdm = '${xzqdm}'`;
// 加载行政区
this.mapServiceLoader.loadServices(this.getRegionLayerDataCounty(cqlFilter));
},
/**
* 定位到落图框
*/
gotoDropLayers(ids = [this.drop05ProduceId, this.drop1ProduceId, this.drop2ProduceId, this.drop05DistributeId,
this.drop1DistributeId, this.drop2DistributeId
]) {
const allLayers = this.map.getLayers().getArray();
let extents = [];
allLayers.forEach((o, i) => {
if (ids.includes(o['id'])) {
extents = [...extents, ...o.getSource().getExtent()]
}
});
if (extents.length) {
this.map.getView().fit(extents, {
duration: 500
});
} else {
// 没有落图框,定位到行政区
this.goToXzqLayer();
}
},
/**
* 行政区地图加载本地json
*/
xzqLoadLocal() {
// 创建 GeoJSON 图层
const geoJSONLayer = new VectorImageLayer({
source: new VectorSource({
url: "../../static/XZQ_2K.json",
format: new GeoJSON()
}),
style: new Style({
stroke: new Stroke({
color: "#ff0000", // 描边红色
width: 2 // 设置描边宽度为 1 像素
}),
fill: new Fill({
color: "#ff000020" // 填充红色透明
})
})
});
console.log('geoJSONLayer', geoJSONLayer.getSource().getFeatures());
geoJSONLayer.id = this.xzqId;
geoJSONLayer.setVisible(false);
this.map.addLayer(geoJSONLayer);
},
/**
* 行政区geom-切换地图到选择行政区上
*/
selectAdministrativeRegion({
geom,
xzqdm,
children,
}) {
const isYns = xzqdm == 530000;
let isYnsTrue = null;
if (this.mapServiceLoader) {
// 省显示地图是否存在
isYnsTrue = this.mapServiceLoader.layersIsTrueById(this.xzqIdYns);
// 移除之前的高亮图层
this.mapServiceLoader.removeLayerBiyId(this.xzqHighlightId);
if (isYnsTrue) {
this.mapServiceLoader.setVisibleById(this.xzqIdYns, isYns);
}
}
if (!isYnsTrue || !isYns) {
if (!geom) {
return;
}
const wktFormat = this.format;
let features = [];
if (children && children.length) {
children.forEach((c) => {
features = [...features, ...wktFormat.readFeatures(c.geom)];
});
} else {
features = wktFormat.readFeatures(geom);
}
features.forEach((f) => {
f.setProperties({
cLayerStyleType: 'type1',
type: 'region'
});
});
const vectorSource = new VectorSource({
features: [...features],
strategy: bboxStrategy
});
const vectorLayer = new VectorImageLayer({
source: vectorSource,
zIndex: 10,
style(feature) {
let strokeWidth = 2;
return new Style({
fill: new Fill({
color: '#E1F0FF',
}),
stroke: new Stroke({
color: '#FFFFFF',
width: strokeWidth,
}),
});
},
});
vectorLayer.id = isYns ? this.xzqIdYns : this.xzqHighlightId;
// this.mapServiceLoader.setVisibleById(this.xzqIdYns, isYns);
this.map.addLayer(vectorLayer);
}
// // 移除之前的高亮图层
// // this.mapServiceLoader && this.mapServiceLoader.removeLayerBiyId(this.xzqHighlightId);
// // this.setLayerVisible(this.xzqId, true);
// // this.goToXzqLayer();
// if (xzqdm === 530000) {
// this.map
// }
// 定位到行政区
this.positioningLayersById(this.xzqHighlightId, false);
},
/**
* 影像点击事件
*
* @param {Object} event
*/
handleMapClick(event) {
console.log('点击:', event, event.coordinate);
},
/**
* 过滤行政区显示
*/
filterRegions() {
console.log('过滤行政区显示')
}
},
mounted() {
this.innitMap();
},
onUnload() {
// 移除地图实例
this.map.dispose();
}
}
</script>
<style lang="scss" scoped>
#myMap {
padding: 0 $padding-base;
margin-top: 30rpx;
}
</style>
MapServiceLoader.js
js
import {
Map
} from 'ol';
import {
Tile as TileLayer,
Vector as VectorLayer
} from 'ol/layer';
import {
OSM,
XYZ,
Vector as VectorSource,
ImageWMS,
TileWMS,
WMTS as sourceWMTS,
} from 'ol/source';
import {
optionsFromCapabilities
} from 'ol/source/WMTS';
import {
WMTS as tilegridWMTS
} from 'ol/tilegrid';
import {
get as getProjection
} from 'ol/proj';
import {
WMTSCapabilities
} from 'ol/format';
export class MapServiceLoader {
map;
wmtsOptionss = [];
constructor(map) {
this.map = map;
}
/**
* 获取当前的地图
*/
getMap() {
return this.map;
}
/**
* 根据id查找图层
*/
findLayerById(id) {
const layers = this.map.getLayers().getArray();
// 使用自定义 id 属性查找图层
return layers.find((layer) => layer.id === id);
}
/**
* 根据id移除图层
*/
removeLayerBiyId(layerId = null) {
if (layerId) {
const layer = this.findLayerById(layerId);
if (layer) {
this.map.removeLayer(layer);
}
}
}
/**
* 根据id显示或隐藏图层
*/
setVisibleById(layerId, isShow = true) {
const layer = this.findLayerById(layerId);
if (layer) {
layer.setVisible(isShow);
}
}
/**
* 根据id判断图层是否存在
*/
layersIsTrueById(layerId) {
let isTrue = false;
const layer = this.findLayerById(layerId);
if (layer) {
isTrue = true;
}
return isTrue;
}
async getWMTSLayerConfig({
layerName,
matrixSet,
accessUrl,
serviceType,
}) {
const response = await fetch(accessUrl);
const text = await response.text();
const parser = new WMTSCapabilities();
let wmtsCapabilities = parser.read(text);
const options = optionsFromCapabilities(wmtsCapabilities, {
layer: layerName,
matrixSet,
});
this.wmtsOptionss.push({
url: accessUrl,
ops: wmtsCapabilities
});
return options;
}
/**
* @param {Object} serviceConfigs
*
*/
async loadServices(serviceConfigs) {
const {
layerName,
matrixSet,
accessUrl,
serviceType,
otherPara,
} = serviceConfigs;
let layer = null;
if (serviceType == 'wmts') {
const options = await this.getWMTSLayerConfig(serviceConfigs);
layer = new TileLayer({
source: new sourceWMTS(options)
})
} else if (serviceType == 'wms') {
console.log('otherPara', otherPara);
const source = new TileWMS({
url: accessUrl,
params: {
...otherPara
},
});
layer = new TileLayer({
source,
});
} else {
console.error('serviceType类型错误')
}
this.removeLayerBiyId(serviceConfigs.id);
console.log('layer', layer);
layer.id = serviceConfigs.id;
this.map.addLayer(layer);
}
}
ol依赖放到跟目录