赞
踩
由于最近项目中用到了地图,所以今天有时间把代码摘出来,自己写个地图的小demo标记下
话不多说,先看效果:
map1
1、安装ol
npm i ol@6.14.1
这是我的目录结构
2、下面是OpenlayerMap/index.vue(地图)的代码,记得申请地图得key,记得填到下方的代码中
<template> <div class="openlayersMap"> <div id="map"></div> <!-- 鼠标经纬度指示 --> <div id="mouse-position" :style="assignMouseIndicatePosition" v-if="needMouseIndicate" ></div> <!-- 图层上展示的弹窗 --> <div id="popup-box"> <!-- <span id="popup-closer">✖</span> --> <div id="popup-content"> <slot :value="sol"></slot> </div> </div> <div id="popup-box-right" :style="{top:'-90px',left:'5px'}"> <hr :style="{border: '2px solid #2af0e1',borderRadius: '40px',width:'2vw',marginTop:'80px'}"/> <div id="popup-content"> <slot name="right" :value="sol"> </slot> </div> </div> </div> </template> <script lang="ts" setup> import { ref, reactive, onMounted, nextTick } from "vue"; import { getTopLeft, getWidth } from "ol/extent"; import { getArea, getLength } from "ol/sphere"; import { Map, View, Feature, Overlay } from "ol"; import { Draw, Modify, Snap } from "ol/interaction"; import { Circle as CircleGeo } from "ol/geom"; import { Circle, Fill, Stroke, Style, Text, Icon } from "ol/style"; import { Tile, Vector as VectorLayer } from "ol/layer"; import { defaults, MousePosition } from "ol/control"; import { get, fromLonLat } from "ol/proj"; import WMTSTileGrid from "ol/tilegrid/WMTS"; import { createStringXY } from "ol/coordinate"; import { WMTS, Vector as VectorSource } from "ol/source"; import { LineString, Point, Polygon } from "ol/geom"; import { createBox, createRegularPolygon } from "ol/interaction/Draw"; import CircleStyle from "ol/style/Circle"; import { unByKey } from "ol/Observable"; const startImg: any = require("@/image/startPoint.png"); //轨迹起点图标 const endImg: any = require("@/image/endPoint.png"); //轨迹终点图标 // 是否显示地图的经纬度指示 const props = withDefaults(defineProps<{ needMouseIndicate: boolean }>(), { needMouseIndicate: true }); const modelMange: String=''; let sol: any = ref(null); // 插槽回填数据 let assignMouseIndicatePosition: IMosueIndicatePosition; let drawSource: VectorSource; let drawVector: any = null; let exportDrawVector: any = ref(null); let map: Map | undefined = undefined; const exportMap =ref<any>(null) let saveVectorLayer: any | null = null; let mousePositionControl: MousePosition; const layerObj: any=ref(null); const isActivePopup:any=ref(false); const singleLayer:any=ref(null); const saveGroupLayer:any=ref(null); //图形Layer const draw:any=ref(null); //画笔 const drawList:any=ref([]); // const snap:any=ref(null); // const state=reactive<any>({ shapeType:'', layerIndex:0, drawCache:[], helpTooltip:'', continueLineMsg:'', helpTooltipElement:null, measureTooltipElement:null, measureTooltip:null, sketch:null, listener:null, //路径相关 routeMap:[], }) /** * 在地图上绘制图层 */ //#region const initDrawSource = () => { drawSource = new VectorSource(); drawVector = new VectorLayer({ source: drawSource, style: new Style({ fill: new Fill({ color: "rgba(255, 255, 255, 0.2)", }), stroke: new Stroke({ color: "#ffcc33", width: 2, }), image: new Circle({ radius: 7, fill: new Fill({ color: "#ffcc33", }), }), }), }); exportDrawVector.value=drawVector const modify = new Modify({ source: drawSource }); // exportMap.value.addInteraction(modify) return modify; }; // 得到初始化地图控制器 function getIninialControl(mouseInfoTargetId: string = "mouse-position") { if (props.needMouseIndicate) { mousePositionControl = new MousePosition({ coordinateFormat: createStringXY(5), projection: "EPSG:4326", className: "custom-mouse-position", target: document.getElementById(mouseInfoTargetId) || undefined, undefinedHTML: " ", }); return defaults({ zoom: false, rotate: false }).extend([ mousePositionControl, // 全屏插件 // new FullScreen(), ]); } else { return defaults({ zoom: false, rotate: false }); } } // 地图初始化 const initMap=()=>{ try { let projection: any = get("EPSG:4326"); let projectionExtent = projection!.getExtent(); let size = getWidth(projectionExtent) / 256; let resolutions = new Array(18); let matrixIds = new Array(18); const modify = initDrawSource(); for (let i = 1; i <= 18; i++) { resolutions[i] = size / Math.pow(2, i); matrixIds[i] = i; } map = new Map({ controls: getIninialControl(), layers: [ // 卫星图层数据 new Tile({ source: new WMTS({ url: "http://t{0-7}.tianditu.gov.cn/img_c/wmts?tk=你的KEY",//这里是你申请的key layer: "img", style: "default", matrixSet: "c", projection: projection, format: "tiles", tileGrid: new WMTSTileGrid({ origin: getTopLeft(projectionExtent), resolutions: resolutions, matrixIds: matrixIds, }), wrapX: true, }), }), // 卫星行政数据 new Tile({ source: new WMTS({ url: "http://t{0-7}.tianditu.gov.cn/cia_c/wmts?tk=你的KEY",//这里是你申请的key layer: "cia", //vec/cva img/cia matrixSet: "c", format: "tiles", style: "default", projection: projection, tileGrid: new WMTSTileGrid({ origin: getTopLeft(projectionExtent), resolutions: resolutions, matrixIds: matrixIds, }), wrapX: true, }), }), drawVector, ], target: "map", view: new View({ center: [108.8821,34.2227], // 初始化中心点 西安软件园 maxZoom: 18, minZoom: 8, zoom: 15,//地图层级 projection: "EPSG:4326", }), }); exportMap.value=map map.addInteraction(modify); } catch (err) { console.log(err); } } // 在页面上展示点 const lastShowPoints= (dataList: any[], imgStr: string,scale: number=1,fn?: any,)=>{ if (dataList.length === 0) return; try { let features: any[] = []; // 定义坐标s imgStr =require(`../../image/${imgStr}`); let vectorLayer = new VectorLayer({ renderBuffer: 200, source: new VectorSource(), style: (feature) => [ new Style({ image: new Icon({ src: imgStr, scale: scale, // imgSize: [50, 50], }), }), ], }); // console.log('points',dataList); dataList.forEach((item) => { item.sol = fn(JSON.parse(JSON.stringify(item))); if ((item.lng || item.longitude) && (item.lat || item.latitude)) { let newObj = Object.assign({}, item); const wz=[+item.lng?item.lng:item.longitude, +item.lat?item.lat:item.latitude]; // console.log('wz',wz); newObj.geometry = new Point(wz); features.push(new Feature(newObj)); if(item.sol.circle){ let circleFeature = new Feature({ //添加面 geometry: new CircleGeo([wz[0]*1,wz[1]*1], 0.005) }); circleFeature.setStyle(new Style({ // 设置样式 fill: new Fill({ color: 'rgba(255, 255, 255, 0.1)' }), stroke: new Stroke({ color: 'rgba(217, 11, 53, 0.4)', lineDash: [20, 10] }) })); features.push(circleFeature); } } }); vectorLayer.getSource()!.addFeatures(features); map!.addLayer(vectorLayer); saveVectorLayer=vectorLayer return saveVectorLayer } catch (error) { console.log(error); } } //点数组绘图 const groupPlot=(data:any,color?:string,borderColor?:string)=>{ console.log(color); color=color || "rgba(252, 51, 40, 0.2700)" let source = new VectorSource(); let style = new Style({ text: new Text({ // font: '15px Microsoft YaHei', // text:'xxxx', fill: new Fill({ color: '#fff' }) }), fill: new Fill({ color }), stroke: new Stroke({ color: borderColor || 'rgba(252, 51, 40, 1)', width: 2 }), image: new Circle({ radius: 10, fill: new Fill({ color: '#ffcc33' }) }) }); //矢量图层 let vectorLayer = new VectorLayer({ source: source, style: style, }); let features: any[] = []; //多边形要素类 data.map((n:any)=>{ //声明一个新的数组 let coordinatesPolygon = new Array(); //循环遍历将经纬度转到"EPSG:4326"投影坐标系下 for (let i = 0; i < n.pointList.length; i++) { let pointTransform = fromLonLat([n.pointList[i][0], n.pointList[i][1]], "EPSG:4326"); coordinatesPolygon.push(pointTransform); } let feature = new Feature({ ...n, geometry: new Polygon([coordinatesPolygon]),//多边形此处注意一定要是[坐标数组] }); features.push(feature) }) source.addFeatures(features); map!.addLayer(vectorLayer); saveGroupLayer.value=vectorLayer; return vectorLayer } // 点击地图后的交互(主要是图标) const mapClick=()=>{ map!.on("click", (event) => { console.log(784,event) removeModel(); let bool=true; let pixel =map!.getEventPixel(event.originalEvent); map?.forEachFeatureAtPixel(pixel, (feature: any,a) => { try { let myfeature; if(feature.values_.features){//聚合点击 myfeature=feature.values_.features[0]; }else{ myfeature=feature; } // console.log('myfeature',myfeature); if(!myfeature.values_.sol) return sol.value=myfeature.values_.sol; console.log('sol',sol.value) // console.log('sol',sol.value || myfeature.values_); let x = myfeature.get("longitude") || myfeature.get("lng"), y = myfeature.get("latitude") || myfeature.get("lat"); let coordinate = [x, y]; //来控制弹框样式 let popupClass="popup-box"; //popup-box-right if(sol.value.popupClass) popupClass=sol.value.popupClass //来控制弹框边距样式 // this.modelMangebottom=this.sol.bottom || '0'; // this.modelMangeleft=this.sol.left || '0'; let overlay = new Overlay({ element: document.getElementById(popupClass) || undefined, }); map!.addOverlay(overlay); overlay.setPosition(coordinate); layerObj.value = overlay; bool=false isActivePopup.value=true; } catch (error) { console.log(error); } }); // if((this.$parent as any).isPopup && (this.$parent as any).isPopup.length>0) (this.$parent as any).isPopup=[]; if(bool) map!.removeLayer(singleLayer.value); }); } //清除已打开的弹框 const removeModel=()=>{ if(isActivePopup.value){ layerObj.value.setPosition(undefined); sol.value = {}; layerObj.value=null; isActivePopup.value=false } } // 移动到指定中心点位 const moveToPoint=async (x: number, y: number)=>{ // console.log(x,y); map!.getView().animate({ center: [x, y], }); } //画线 const drawLine=(bool:boolean)=>{ draw.value && map!.removeInteraction(draw.value); draw.value = new Draw({ source:drawVector.getSource(), type: "LineString", freehand: bool, stopClick: true, }); exportMap.value.addInteraction(draw.value); draw.value && draw.value.on('drawend',() =>drawList.value.push(draw.value)) // console.log('drawVector',drawVector); return draw.value; } // 多边形 const drawPolygon=()=>{ draw.value && map!.removeInteraction(draw.value); draw.value = new Draw({ source: drawVector.getSource(), type: "Polygon", stopClick: true, }); exportMap.value.addInteraction(draw.value); draw.value && draw.value.on('drawend',() =>drawList.value.push(draw.value)) } // 画圆 const drawCircle=(type:string)=>{ draw.value && map!.removeInteraction(draw.value); if (type == "triangle") { //正三角 draw.value = new Draw({ source: drawVector.getSource(), type: "Circle", geometryFunction: createRegularPolygon(3), stopClick: true, }); } else if (type == "circle") { draw.value = new Draw({ //正圆 source: drawVector.getSource(), type: "Circle", stopClick: true, }); } else if (type == "square") { draw.value = new Draw({ //正方形 source: drawVector.getSource(), type: "Circle", geometryFunction: createRegularPolygon(4), stopClick: true, }); } else if (type == "rectangle") { draw.value = new Draw({ //长方形 source: drawVector.getSource(), type: "Circle", geometryFunction: createBox(), stopClick: true, }); } snap.value = new Snap({source: drawSource }); exportMap.value.addInteraction(snap.value); //鼠标捕捉 exportMap.value.addInteraction(draw.value); draw.value && draw.value.on('drawend',() =>drawList.value.push(draw.value)) } /** 测距、测面*/ const measure=(type:string)=>{ draw.value && exportMap.value.removeInteraction(draw.value); state.shapeType = type; state.layerIndex++; state.drawCache[state.layerIndex] = { feature: null, measureTooltip: null, }; if (draw.value) { exportMap.value.removeInteraction(draw.value); } // 添加map事件 addMapEvent(); } const addMapEvent=()=>{ exportMap.value.on("pointermove", (evt:any) => { draw.value? pointerMoveHandler(evt): exportMap.value.removeOverlay(state.helpTooltip); }); exportMap.value.getViewport().addEventListener("mouseout", () => { state.helpTooltipElement && state.helpTooltipElement.classList.add("hidden"); }); addInteraction(); } const addInteraction=()=> { draw.value = new Draw({ source: drawVector.getSource(), type: state.shapeType, style: new Style({ fill: new Fill({ color: "rgba(255, 255, 255, 0.2)" }), stroke: new Stroke({ color: "rgba(255, 255, 255, 1)", lineDash: [10, 10], width: 2, }), image: new CircleStyle({ radius: 5, stroke: new Stroke({ color: "rgba(255, 255, 255, 0.8)" }), fill: new Fill({ color: "rgba(255, 255, 255, 0.2)" }), }), }), }); exportMap.value.addInteraction(draw.value); createMeasureTooltip(); createHelpTooltip(); drawHandler(); } const createMeasureTooltip=()=>{ if(state.measureTooltipElement) { state.measureTooltipElement.parentNode.removeChild( state.measureTooltipElement ); } state.measureTooltipElement = document.createElement("div"); state.measureTooltipElement.className = "ol-tooltip ol-tooltip-measure"; state.measureTooltip = new Overlay({ element: state.measureTooltipElement, offset: [0, -15], positioning: "bottom-center", }); exportMap.value.addOverlay(state.measureTooltip); } const createHelpTooltip=()=>{ if (state.helpTooltipElement) { state.helpTooltipElement.parentNode.removeChild(state.helpTooltipElement); } state.helpTooltipElement = document.createElement("div"); state.helpTooltipElement.className = "ol-tooltip hidden"; state.helpTooltip = new Overlay({ element: state.helpTooltipElement, offset: [15, 0], positioning: "center-left", }); exportMap.value.addOverlay(state.helpTooltip); } const drawHandler=()=>{ draw.value.on("drawstart", (evt:any) => { state.sketch = evt.feature; let tooltipCoord = evt.coordinate; state.listener = state.sketch.getGeometry().on("change", (evt:any) => { let output; const geom = evt.target; if (geom instanceof LineString) { output = formatLength(geom); tooltipCoord = geom.getLastCoordinate(); } else if (geom instanceof Polygon) { output = formatArea(geom); tooltipCoord = geom.getInteriorPoint().getCoordinates(); } let closeBtn = "<i class='tooltip-close-btn tooltip-close-btn_" + state.layerIndex + "' data-index='" + state.layerIndex + "'></i>"; state.measureTooltipElement.innerHTML = output + closeBtn; state.measureTooltip.setPosition(tooltipCoord); state.drawCache[state.layerIndex].measureTooltip = state.measureTooltip; }); }); draw.value.on("drawend", (evt:any) => { // console.log('hhhh'); // (this.$parent as any).toolsindex =''; state.drawCache[state.layerIndex].feature = evt.feature; state.measureTooltipElement.className = "ol-tooltip ol-tooltip-static"; state.measureTooltip.setOffset([0, -7]); state.sketch = null; state.measureTooltipElement = null; createMeasureTooltip(); unByKey(state.listener); exportMap.value.removeInteraction(draw.value); draw.value = null; // 删除图层 const self = this; document?.querySelector(".tooltip-close-btn_" + state.layerIndex).addEventListener("click", function (e:any) { // console.log('dataset',e); // state.drawVector // .getSource() // .removeFeature(state.drawCache[state.dataset.index].feature); // state.map.removeOverlay( // state.drawCache[state.dataset.index].measureTooltip // ); // delete state.drawCache[state.dataset.index]; }); }); } const formatLength=(line:any)=>{ const sourceProj = exportMap.value.getView().getProjection(); //获取投影坐标系 var length = getLength(line, { projection: sourceProj }); var output; if (length > 100) { output = Math.round((length / 1000) * 100) / 100 + " " + "km"; } else { output = Math.round(length * 100) / 100 + " " + "m"; } return output; } const formatArea=(polygon:any)=>{ const sourceProj = exportMap.value.getView().getProjection(); //获取投影坐标系 const geom = polygon.clone().transform(sourceProj, "EPSG:3857"); const area = getArea(geom); let output; if (area > 10000) { output = Math.round((area / 1000000) * 100) / 100 + " " + "km<sup>2</sup>"; } else { output = Math.round(area * 100) / 100 + " " + "m<sup>2</sup>"; } return output; } const pointerMoveHandler=(evt:any)=>{ if (evt.dragging) { return; } /** @type {string} */ var helpMsg = "测量"; if (state.sketch) { var geom = state.sketch.getGeometry(); if (geom instanceof LineString) { helpMsg = state.continueLineMsg; } } state.helpTooltipElement.innerHTML = helpMsg; state.helpTooltip.setPosition(evt.coordinate); state.helpTooltipElement.classList.remove("hidden"); } // ************** //路径相关 // 开始显示一条轨迹 const showWay=async(_routeInfo: IRouteInfo)=>{ if (state.routeMap.some((route:any) => route.id === _routeInfo.id)) { // 已经有了路径,直接移动视野到该点 moveToPoint(_routeInfo.gis[0][0], _routeInfo.gis[0][1]); return; } // 根据一系列点设置地图视野中点 const point = _routeInfo.gis[0]; // 将地图设置到最大缩放度 const view = map!.getView(); const MaxZoom = view.getMaxZoom(); const MinZoom = view.getMinZoom(); const zoom = Math.ceil((MaxZoom + MinZoom) / 2); view.setZoom(zoom); await moveToPoint(point[0], point[1]); showRouterMap(_routeInfo); } // 路径显示 const showRouterMap=(_routeInfo: any)=>{ let pointsList = _routeInfo.gis; // pointsList.map(n=>{ // n=[1*n[0],1*n[1]] // }) let roadLine = new LineString(pointsList); let output=formatLength(roadLine) console.log('output',pointsList,output); let roadLineSource = new VectorSource({ features: [new Feature(roadLine)], }); const roadLineLayer = new VectorLayer({ source: roadLineSource, style: new Style({ stroke: new Stroke({ color: "#38A0FF", width: 4, }), }), }); map!.addLayer(roadLineLayer); let pointLayer1 = addVectorLabel({ pointsList: pointsList[0], txt: "起", }); let pointLayer2 = addVectorLabel({ pointsList: pointsList[pointsList.length - 1], txt: "终", }); let label = addVectorLabel({ pointsList: [pointsList[0][0], pointsList[0][1]], txt: _routeInfo.name + ",全程" + output, fill: "#111111", stroke: "#ffffff", }); // 保存实例 state.routeMap.push({ id: _routeInfo.id as string, routeLayerExample: roadLineLayer, vectorLabels: [label], points: [pointLayer1, pointLayer2], }); } // 添加矢量标签(例如路径的起终点、描述) const addVectorLabel=(opt: any)=>{ let vectorSource = new VectorSource(); //矢量标注的数据源 const layer = new VectorLayer({ source: vectorSource, }); //矢量标注图层 map!.addLayer(layer); if (opt.txt == "起" || opt.txt == "终") { // 添加起点以及终点的layer let newFeature = new Feature({ geometry: new Point(opt.pointsList || []), }); newFeature.setStyle( new Style({ image: new Icon({ src: opt.txt == "起" ? startImg : endImg, offset: [0, -26], offsetOrigin: "bottom-right", size: [32, 60], }), fill: new Fill({ color: "#ffffff" }), zIndex: 1, }) ); // 将新要素添加到数据源中 vectorSource.addFeature(newFeature); return layer; } let overlayerElement = document.createElement("div"); overlayerElement.className = "ol-tooltip-draw-route"; overlayerElement.innerHTML = opt.txt; const overlayObj = new Overlay({ element: overlayerElement, offset: [0, -30], positioning: "bottom-center", }); overlayObj.setPosition(opt.pointsList); map!.addOverlay(overlayObj); return overlayObj; } // 清除部分路径 const clearRoute=(_routeId: number|string | Array<number|string>)=>{ if (Array.isArray(_routeId)) { for (let routeId of _routeId) { let routeWayIndex = state.routeMap.findIndex((it:any)=>it.id == routeId) let routeItem = state.routeMap[routeWayIndex] // console.log('routeItem',routeItem,state.routeMap,routeId); exportMap.value.removeLayer(routeItem.routeLayerExample); routeItem.points?.forEach((it:any) => exportMap.value.removeLayer(it)); routeItem.vectorLabels.forEach((it:any) => exportMap.value.removeOverlay(it)); state.routeMap.splice(routeWayIndex, 1); } } else { if (!_routeId) return; let routeWayIndex = state.routeMap.findIndex((it:any)=>it.id == _routeId) let routeItem = state.routeMap[routeWayIndex] exportMap.value.removeLayer(routeItem.routeLayerExample); routeItem.points?.forEach((it:any) => exportMap.value.removeLayer(it)); routeItem.vectorLabels.forEach((it:any) => exportMap.value.removeOverlay(it)); state.routeMap.splice(routeWayIndex, 1); } } nextTick(()=>{ }) defineExpose({measure,removeModel,lastShowPoints,groupPlot,moveToPoint,exportMap,drawLine,drawPolygon,drawCircle,draw,exportDrawVector,state,showWay,clearRoute}) onMounted(() => { initMap(); mapClick() }); </script> <style lang="scss" scoped> .openlayersMap { width: 100%; height: 100%; #map { height: 100%; } #mouse-position { position: absolute; top: 10px; right: 20px; color: #fff; font-weight: bold; font-size: 18px; } #popup-box{ bottom: 25px; left: 0px; background-color: rgba(0, 0, 1, 0.5); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); } #popup-box ,#popup-box-right{ position: absolute; z-index: -1; box-sizing: border-box; padding: 4px 6px; border-radius: 4px; border: 2px solid #84f199; min-width: 280px; position: absolute; // bottom: 20px; // left: -50px; #popup-closer { font-size: 14px; height: 20px; line-height: 20px; text-align: right; position: absolute; right: 0; top: 0; margin-right: 4px; user-select: none; cursor: pointer; color: #fff; } #popup-content { // margin-top: 24px; display: flex; max-height: 600px; // overflow-y: scroll; position: relative; } &:after, &:before { top: 100%; border: solid transparent; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } &:after { border-top-color: white; border-width: 10px; left: 48px; margin-left: -10px; } &:before { border-top-color: #cccccc; border-width: 11px; left: 48px; margin-left: -11px; } } #popup-box-right{ // bottom: -24vh; // left: 2vh; border: none; display: flex; &:after, &:before {content:none;} > #popup-content{ background: url("~@/image/chart.png") no-repeat; background-size: 100% 100%; } } } </style>
3、下面是OpenlayerMap/index.ts的代码
import OpenLayerMap from "./index.vue"
export {
OpenLayerMap
}
4、这是我地图中用到的三张图片,chart.png是地图上弹窗的背景图。icon.png是个标点的小图标,剩下两个是地图画轨迹时一个起点和终点的图标,如果你粘贴我的代码,没这几张图片会报错
把几张图片分别给大家贴出来吧:
chart.png
endPoint.png
startPoint.png
icon.png
5、全局引入
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
//引入地图
import components from "@/components/index";
let app=createApp(App)
Object.values(components).forEach((com) => {
app.use(com);
});
app.use(store).use(router).use(Antd).mount('#app')
6、页面代码
<template> <div class="Box"> <div class="homeBox"> <div class="leftBox"> <a-button type="primary" @click="showIcon">在地图上显示点</a-button ><br /><br /> <a-button type="primary" @click="moveXiAn([108.9423, 34.261])" >移动到西安钟楼</a-button ><br /><br /> <a-button type="primary" @click="moveXiAn([108.8821, 34.2227])" >移动到初始点</a-button ><br /><br /> <a-button type="primary" @click="trajectory">显示一段轨迹</a-button ><br /><br /> <a-button type="primary" @click="clearTrajectory" >清除上面的轨迹</a-button ><br /><br /> <a-button type="primary" @click="range">显示范围</a-button><br /><br /> </div> <!-- 地图 --> <section class="map-wrap"> <OpenlayerMap ref="mapRef" :assignMouseIndicatePosition="{ zIndex: 1, right: '83px', top: '14px', fontSize: '16px', fontWeight: '400', color: '#fff', }" > <!-- 地图弹框 --> <template #right="sol"> <div :style="{ width: '0vh' }"></div> <div> <div class="map_right" v-if="sol.value?.showLength"> <div v-for="(item, l) in sol.value.show" :key="l"> <span v-for="(n, i) in item" :key="i">{{ n }}</span> </div> <button v-if="sol.value.button"> {{ sol.value.buttonText ? sol.value.buttonText : "查看" }} </button> </div> <div class="map_right" v-else> <span v-for="(n, i) in sol.value?.show" :key="i">{{ n }}</span> <button v-if="sol.value?.button"> {{ sol.value.buttonText ? sol.value.buttonText : "查看" }} </button> </div> </div> </template> </OpenlayerMap> <!-- 工具箱 --> <div class="work-box"> <div class="tool"> <div v-for="(n, i) in toolData" :key="i"> <span>{{ n.title }}</span> <div> <span :style="{ color: toolsindex == `${i}${l}` ? '#409EFF' : '' }" v-for="(e, l) in n.data" :key="l" @click="clickTool(e, i, l)" >{{ e.title }}</span > </div> </div> </div> </div> </section> </div> </div> </template> <script lang="ts" setup> import { defineComponent, reactive, ref, onMounted, nextTick } from "vue"; const mapRef = ref<null | HTMLElement>(null); const data = ref<any>([ { id: 14, name: "张三", longitude: "108.8821", latitude: "34.2227", pointList: [ [108.8646, 34.2136], [108.8695, 34.2134], [108.8647, 34.2187], ], }, { id: 14, name: "李四", longitude: "108.8867", latitude: "34.2283", pointList: [ [108.8943, 34.2149], [108.8951, 34.2127], [108.8909, 34.2135], [108.8973, 34.2122], ], }, ]); const toolData = ref<any>([ { title: "基础", key: 0, data: [ { title: "测量距离" }, { title: "测量面积" }, { title: "清除测量" }, ], }, { title: "消防", key: 1, data: [ { title: "画笔" }, { title: "隔离带" }, { title: "线选" }, { title: "框选" }, { title: "多边形选" }, { title: "圈选" }, { title: "清除" }, ], }, ]); const toolsindex = ref<string>(""); //地图跳转 function moveXiAn(coordinate: any) { (mapRef.value as any).moveToPoint(...coordinate); } //显示轨迹 function trajectory() { let gis = [ [108.9423, 34.261], [108.9424, 34.2568], [108.9478, 34.2566], [108.9538, 34.2496], ]; (mapRef.value as any).showWay({ id: 11, //id gis: gis, name: "轨迹", // }); } function clearTrajectory() { (mapRef.value as any).clearRoute(11); } //地图上显示图标 function showIcon() { data.value.forEach((item: any) => { nextTick(() => { (mapRef.value as any).lastShowPoints( data.value, "icon.png", 1, (item: any) => { return { show: [ `${item.name}`, `纬度:${item.latitude},经度:${item.longitude}`, ], data: item, popupClass: "popup-box-right", bottom: "-13vh", left: "15px", button: true, //地图弹窗是否显示按钮 buttonText: "点击", //地图弹窗按钮文字 circle: true, //是否展示范围 }; } ); }); }); } //地图上显示范围 function range() { nextTick(() => { (mapRef.value as any).groupPlot(data.value); }); } //点击工具 function clickTool(n:any,i:number,l:number){ if(toolsindex.value=='') toolsindex.value=`${i}${l}`; else { toolsindex.value=''; nextTick(()=>{ (mapRef.value as any).exportMap.removeInteraction((mapRef.value as any).draw); (mapRef.value as any).draw = null; }); } switch (`${i}${l}`) { case '00': //测量距离 if(toolsindex.value==`00`) (mapRef.value as any).measure("LineString"); break; case '01': //测量面积 if(toolsindex.value==`01`) (mapRef.value as any).measure("Polygon"); break; case '02': //清除测量 if(toolsindex.value==`02`) { for (const key in (mapRef.value as any).state.drawCache) { (mapRef.value as any).exportMap.removeOverlay( (mapRef.value as any).state.drawCache[key].measureTooltip ); } (mapRef.value as any).exportDrawVector.getSource().clear(); toolsindex.value ='' } break; case "01": //测量距离 if (toolsindex.value == `01`) (mapRef.value as any).measure("LineString"); break; case "02": //测量面积 if (toolsindex.value == `02`) (mapRef.value as any).measure("Polygon"); break; case "03": //清除测量 if (toolsindex.value == `03`) { for (const key in (mapRef.value as any).drawCache) { (mapRef.value as any).map.removeOverlay( (mapRef.value as any).drawCache[key].measureTooltip ); } (mapRef.value as any).drawVector.getSource().clear(); toolsindex.value = ""; } break; case "10": //点 if (toolsindex.value == `10`) (mapRef.value as any).drawLine(true); break; case "11": //正三角 隔离带 if (toolsindex.value == `11`) (mapRef.value as any).drawCircle("triangle"); break; case "12": //线 if (toolsindex.value == `12`) (mapRef.value as any).drawLine(false); break; case "13": //正方形 if (toolsindex.value == `13`) (mapRef.value as any).drawCircle("square"); break; case "14": //多边形 if (toolsindex.value == `14`) (mapRef.value as any).drawPolygon(); break; case "15": //圆形 if (toolsindex.value == `15`) (mapRef.value as any).drawCircle("circle"); break; case '16': //清除 if(toolsindex.value==`16`){ (mapRef.value as any).exportDrawVector.getSource().clear(); toolsindex.value ='' } break; default: break; } (mapRef.value as any).draw && (mapRef.value as any).draw.on("drawend", () => { (mapRef.value as any).exportMap.removeInteraction((mapRef.value as any).draw); (mapRef.value as any).draw = null; toolsindex.value = ''; }); } </script> <style lang="scss" scoped> .Box { width: 100%; height: 100vh; position: relative; .homeBox { width: 100%; height: 100%; border: 1px solid gray; display: flex; justify-content: space-between; align-items: flex-start; .leftBox { width: 20%; } .map-wrap { flex: 1; height: 100%; position: relative; } } } //地图弹窗样式 .map_right { color: #fff; font-size: 14px; padding: 15px 20px; display: flex; flex-direction: column; span:nth-child(n) { display: flex; flex-direction: column; margin-bottom: 10px; white-space: nowrap; } span:nth-child(1) { font-size: 16px; font-weight: 500; margin-top: 10px; } > button { // color: #409EFF; background: #409eff; text-align: center !important; padding: 6px 0; border: none; margin: 10px 16px 20px 16px; cursor: pointer; } } .work-box { display: flex; align-items: center; color: #fff; position: absolute; bottom: 60px; left: 30px; .tool { position: absolute; // bottom: 100%; display: flex; flex-direction: column; justify-content: center; border: 1px solid; margin: 0 20px; background: gray; border-radius: 5px; > * { padding: 0 10px; display: flex; width: 510px; align-items: center; > span { font-size: 16px; font-weight: 700; } > div:first-child { border-bottom: 1px solid; } > div { margin: 3px 10px; display: flex; flex: 1; justify-content: space-around; span { display: inline-block; padding: 8px; border: 1px solid; cursor: pointer; margin: 3px 5px; font-size: 14px; border-radius: 5px; } } } } } </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。