uniapp使用openlayers加载地图服务
<!-- 地图组件 -->
<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', // 行政区idxzqIdYns: 'xzqYns', // 行政区id(省)xzqHighlightId: 'xzqHighlight', // 选择后高亮行政区idprojection: {},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)',},},// 影像生产-落图框图层iddrop05ProduceId: 'drop05_p',drop1ProduceId: 'drop1_p',drop2ProduceId: 'drop2_p',// 影像分发-落图框图层iddrop05DistributeId: '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.drop1ProduceIdthis.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
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依赖放到跟目录