<template>
<div class="selectLocation">
<div
class="project_map"
id="project_map"
ref="container"
style="width: 100%; height: 100%; z-index: 1"
></div>
<div class="layerControl">
<el-radio-group v-model="radio">
<el-radio
size="large"
v-for="(item, index) in MapList.groundList"
:label="index"
@change="fly"
>
{{ item.name }}{{ index }}
</el-radio>
</el-radio-group>
</div>
<div
id="popup"
class="ol-popup"
style="background-color: bisque"
v-if="popshow"
>
<div class="pophead" style="width: 100%; height: 20px">
<div
id="popup-title"
style="
font: bold 15px sans-serif;
align: left;
position: absolute;
top: 5px;
left: 8px;
color: #000000;
height: 100px;
border-radius: 10px;
display: flex;
justify-content: space-between;
"
>
<div>信息</div>
<div id="popup-closer">关闭</div>
</div>
<a id="popup-closer" class="ol-popup-closer" style="color: #8e908c"></a>
</div>
<div
id="popup-content"
style="padding: 10px; width: 500px; height: 100px"
></div>
</div>
</div>
</template>
script
<script setup>
import { onMounted, ref } from "vue";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import Feature from "ol/Feature";
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import Point from "ol/geom/Point";
import Overlay from "ol/Overlay.js";
import { Circle, Geometry, LineString, Polygon } from "ol/geom";
import {
Icon,
Style,
Stroke,
Circle as CircleStyle,
Fill,
Text,
} from "ol/style";
import { useRvo } from "@/hook/useRvo";
import { useStore } from "vuex";
import API from "@/network/api";
import { Cluster, OSM } from "ol/source.js";
import { altKeyOnly, click, pointerMove } from "ol/events/condition";
import { boundingExtent } from "ol/extent";
let choseLocation = ref("");
let choseCoordinates = ref("");
const radio = ref("");
//地图容器
let map;
//矢量地图
let baseMapLayer;
//中文标记
let annotateMapLayer;
//加载资源类
let vectorSource;
//加载的资源图层
let polygonsource;
let polygonterLayer;
let vectorLayer;
let chosePositionSource;
let chosePositionLayer;
const store = useStore();
//弹窗
let popshow = ref("false");
let container = document.getElementById("popup");
let content = document.getElementById("popup-content");
const fly = (e) => {
let features = [];
for (let item in polygonsource.featuresRtree_.items_) {
features.push(polygonsource.featuresRtree_.items_[item]);
}
let a = features[e];
Views.setCenter([(a.minX + a.maxX) / 2, (a.minY + a.maxY) / 2]);
Views.setZoom(18);
};
let overlay1 = new Overlay({
//设置弹出框的容器
element: container,
//是否自动平移,即假如标记在屏幕边缘,弹出时自动平移地图使弹出框完全可见
autoPan: true,
autoPanAnimation: {
duration: 250,
//当Popup超出地图边界时,为了Popup全部可见,地图移动的速度.
},
});
const emit = defineEmits(["choseLocation"]);
// 提交位置信息
const confirmLocation = () => {
emit(
"choseLocation",
choseLocation.value,
projectArea,
choseCoordinates.value
);
};
let clusters = ref("");
let MapList = ref("");
const Views = new View({
projection: "EPSG:4326", //使用这个坐标系
center: [114.280485, 30.280073],
zoom: 5,
maxZoom: 23,
minZoom: 1,
// //1.设置缩放级别为整数
// constrainResolution: false,
// //2.关闭无级缩放地图
// smoothResolutionConstraint: false,
});
onMounted(async () => {
//获取访问者IP
overlay1.setPosition(undefined);
let IP = localStorage.getItem("Ip");
map = new Map({
target: "project_map",
view: Views,
});
// // 天地图 标注
let url = "http://t{0-5}.tianditu.com/DataServer?x={x}&y={y}&l={z}";
url = `${url}&T=vec_c&tk={{自己的token}}`
const source = new XYZ({
url: url,
projection: "EPSG:4326",
});
baseMapLayer = new TileLayer({
source: source,
});
url = "http://t{0-5}.tianditu.com/DataServer?x={x}&y={y}&l={z}";
url = `${url}&T=cva_c&tk={{自己的token}}`;
const sourceCVA = new XYZ({
url: url,
projection: "EPSG:4326",
});
annotateMapLayer = new TileLayer({
source: sourceCVA,
});
//添加底图
map.addLayer(baseMapLayer);
let idRvo = useRvo().idRvo;
map.addLayer(annotateMapLayer);
// 请求数据
const getmaplist = async () => {
MapList.value = res.data;
createPoint(MapList.value);
createPolygon(MapList.value);
};
getmaplist();
// 加 聚合点
const createPoint = (list) => {
const features = new Array(list.holeList.length);
//遍历点,EPSG4326
for (let i = 0; i < list.holeList.length; ++i) {
let lan = list.holeList[i].geom
.slice(6, list.holeList[i].geom.length - 1)
.split(/\s+/)[0];
let lon = list.holeList[i].geom
.slice(6, list.holeList[i].geom.length - 1)
.split(/\s+/)[1];
let lanNum = Number(lan);
let lonNum = Number(lon);
const coordinates = [lanNum, lonNum];
features[i] = new Feature({
geometry: new Point(coordinates),
zkCode: list.holeList[i].zkCode,
warning: list.holeList[i].ewDrillholeInfos ? false : true,
});
features[i].setProperties(list.holeList[i].ewDrillholeInfos);
}
// 添加feature到source//添加点
const pointsource = new VectorSource({
features: features,
});
// 添加feature到source//添加到cluster
const clusterSource = new Cluster({
distance: 20,
minDistance: 5,
source: pointsource,
});
///添加到适量层
const pointerLayer = new VectorLayer({
source: pointsource,
});
///添加到clusters层
clusters = new VectorLayer({
source: clusterSource,
style: stylefunction,
});
//添加点到map
// map.addLayer(pointerLayer);
//添加点到clusters
map.addLayer(clusters);
// 设置图层高度
pointerLayer.setZIndex(100);
};
// 加面
const createPolygon = (list) => {
const features = new Array(list.groundList.length);
for (let i = 0; i < list.groundList.length; ++i) {
let onePolygon = [];
let polygoninfo = list.groundList[i]?.geo
.slice(9, list.groundList[i].geo.length - 2)
.split(",");
for (let index = 0; index < polygoninfo.length; index++) {
let lon = Number(polygoninfo[index].split(/\s+/)[0]);
let lan = Number(polygoninfo[index].split(/\s+/)[1]);
let point = [lon, lan];
onePolygon.push(point);
}
let finalArr = [];
finalArr.push(onePolygon);
features[i] = new Feature({
geometry: new Polygon(finalArr),
});
}
polygonsource = new VectorSource({
features: features,
});
polygonterLayer = new VectorLayer({
source: polygonsource,
// style: polugonstyles,
});
map.addLayer(polygonterLayer);
polygonterLayer.setZIndex(200);
};
//设置点样式
const stylefunction = (feature) => {
const styleCache = {};
const size = feature.get("features").length;
let style = styleCache[size];
if (!style) {
if (size == 1) {
if (feature.values_.features[0].values_.warning) {
style = new Style({
image: new Icon({
src: "src/assets/image/gisIco/icon_hover.png",
scale: map.getView().getZoom() / 14,
}),
text: new Text({
//对齐方式
textAlign: "center",
//文本基线
textBaseline: "middle",
//字体样式
font: "normal 10px 微软雅黑",
//文本内容
text: feature.values_.features[0].values_.zkCode,
//填充样式
fill: new Fill({
color: "#aa3300",
}),
offsetY: (20 * map.getView().getZoom()) / 7,
//笔触
stroke: new Stroke({
color: "#ffcc33",
width: 2,
}),
scale: map.getView().getZoom() / 7,
}),
});
} else {
style = new Style({
image: new Icon({
src: "src/assets/image/gisIco/icon.png",
scale: map.getView().getZoom() / 14,
}),
text: new Text({
//对齐方式
textAlign: "center",
//文本基线
textBaseline: "middle",
//字体样式
font: "normal 10px 微软雅黑",
//文本内容
text: feature.values_.features[0].values_.zkCode,
//填充样式
fill: new Fill({
color: "#aa3300",
}),
offsetY: (20 * map.getView().getZoom()) / 7,
//笔触
stroke: new Stroke({
color: "#ffcc33",
width: 2,
}),
scale: map.getView().getZoom() / 7,
}),
});
}
} else {
style = new Style({
image: new CircleStyle({
radius: 10,
stroke: new Stroke({
color: "#fff",
}),
fill: new Fill({
color: "#3399CC",
}),
}),
text: new Text({
text: size.toString(),
fill: new Fill({
color: "#fff",
}),
}),
});
styleCache[size] = style;
}
}
return style;
};
map.on("click", (e) => {
//cluster要到外部申明
clusters.getFeatures(e.pixel).then((clickedFeatures) => {
if (clickedFeatures.length) {
const features = clickedFeatures[0].get("features");
if (features.length > 1) {
const extent = boundingExtent(
features.map((r) => r.getGeometry().getCoordinates())
);
map
.getView()
.fit(extent, { duration: 1000, padding: [50, 50, 50, 50] });
} else {
let attr = features[0].values_[0];
let keyID = features[0].values_.zkCode;
let coodinate = e.coordinate;
let container = document.getElementById("popup");
let content = document.getElementById("popup-content");
let popupCloser = document.getElementById("popup-closer");
let overlay1 = new Overlay({
//设置弹出框的容器
element: container,
//是否自动平移,即假如标记在屏幕边缘,弹出时自动平移地图使弹出框完全可见
autoPan: true,
autoPanAnimation: {
duration: 250,
//当Popup超出地图边界时,为了Popup全部可见,地图移动的速度.
},
});
if (features[0].values_[0]) {
content.innerHTML =
"<ul>" +
"<li>设备id: " +
keyID +
"</li>" +
"<li>设备描述:" +
attr.info +
"</li>" +
"<li>设备类型: " +
attr.type +
"</li>" +
"</ul>";
} else {
content.innerHTML =
"<ul>" + "<li>" + "警告" + "</li>" + "</ul>";
}
overlay1.setPosition(coodinate);
map.addOverlay(overlay1);
//关闭隐藏
popupCloser.addEventListener("click", function () {
overlay1.setPosition(undefined);
});
}
}
});
});
});
</script>
<style scoped lang="scss">
.selectLocation {
width: 100%;
height: 100%;
position: relative;
// float: right;
}
.layerControl {
overflow: auto;
width: 200px;
height: 300px;
background-color: rgb(255, 249, 249);
z-index: 100;
position: absolute;
top: 10px;
left: 50px;
}
.popup {
// width: 200px;
// height: 100px;
}
#popup-closer {
border-radius: 5px;
text-align: center;
width: 40px;
margin: 5px;
left: 380px;
height: 20px;
background-color: rgb(230, 114, 20);
}
.ol-popup {
position: absolute;
background-color: #eeeeee;
-webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: 50px;
min-width: 280px;
}
.ol-popup:after,
.ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
</style>
效果图
本文转载自: https://blog.csdn.net/weixin_46527645/article/details/129026526
版权归原作者 三好学生69号 所有, 如有侵权,请联系我们删除。
版权归原作者 三好学生69号 所有, 如有侵权,请联系我们删除。