一、主要方法
1、加载geojson数据:
// 添加geoson 数据
const addGeoJsonLayer = (map) =>{
removeGeoJsonLayer(map);
// 数据源
const geoJsonSource = new VectorSource({
format:new GeoJSON(),
// 长春在线json数据
url:"https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=220100_full"
});
// 图层
geoJsonLayer.value = new VectorLayer({
name:"geojson图层",
source:geoJsonSource,
fill: new Fill({
color: 'rgba(255, 0, 0, 1)'
}),
// 样式-边框
stroke: new Stroke({
color: '#0099ff',
width: 3
}),
zIndex: 20,
});
map.addLayer(geoJsonLayer.value);
}
2、选中geojson数据
// 选中要素图层
const selectGeoJsonLayer = (map) =>{
// 清除弹窗html
if (container.value) {
container.value.remove();
}
// 创建popup
popupOverlay.value = new Overlay({
element:container.value,
autoPan:true,// 定义弹出窗口在边缘点击时候可能不完整,设置自动平移效果
positioning:"bottom-center",
stopEvent:true,// 地图的事件传播是否停止,默认是 true;单击OverlayPopup可以查看效果
autoPanAnimation:{
duration:250// 动画
}
});
// 添加popup到地图容器
map.addOverlay(popupOverlay.value);
map.on('click', ev => {
const pixel = ev.pixel // 鼠标点击的位置,这个应该是像素
const mousePoint = ev.coordinate // 鼠标点击的坐标位置
const feature = map.forEachFeatureAtPixel(pixel, (feature) => {
return feature // 查找出点击的哪个要素
});
if (feature) { // 如果是点击了坐标点
// 样式显示dom
container.value.classList.remove('overlay-popup-hidden');
// 区域名称
const placeName = feature.getProperties().name;
// 添加数据
container.value.innerHTML = `<span>行政区:${placeName}</span>`;
// 弹出popup
popupOverlay.value.setPosition(mousePoint);
} else {
// 清除弹窗html
if (container.value) {
//container.value.remove();
// 隐藏弹窗-方法1
//that.popupOverlay.setPosition(undefined)
// 样式隐藏dom-隐藏弹窗-方法2
container.value.classList.add('overlay-popup-hidden');
}
console.log("没有要素数据");
}
})
// 选中获取geojson数据
/* if(geoJsonLayer.value != null){
const featureLayer = toRaw(geoJsonLayer.value);
// 创建选择交互
const selectInteraction = new Select({
layers:[featureLayer],
});
map.addInteraction(selectInteraction);
// 监听选中要素的变化
selectInteraction.on('select',(event) =>{
// 获取被选中的要素
const selectedFeatures = event.target.getFeatures();
selectedFeatures.forEach(element => {
//获取到选中要素的属性
console.log("element",element.getProperties());
});
});
}else{
alert("没有要素图层!")
}*/
}
3、清除geojson数据
// 清除geojson图层
const removeGeoJsonLayer = (map) =>{
// 清空geoJsonLayer图层
if(geoJsonLayer.value != null){
map.removeLayer(geoJsonLayer.value);
geoJsonLayer.value = null;
}
}
二、全部代码
geojson.vue:
<template>
<div ref="container" id="overlay-popup" class="overlay-popup"></div>
</template>
<script setup>
import {ref} from 'vue';
import { Vector as VectorLayer } from 'ol/layer.js';
import { Vector as VectorSource } from 'ol/source.js';
import { Style, Fill, Stroke, Circle as CircleStyle } from 'ol/style';
import Feature from 'ol/Feature.js';
import GeoJSON from 'ol/format/GeoJSON.js';
import Select from 'ol/interaction/Select.js';
import Overlay from 'ol/Overlay';
const geoJsonLayer = ref(null);// geojson图层
const popupOverlay = ref(null);
const container = ref(null);// 创建dom弹窗视图
// 添加geoson 数据
const addGeoJsonLayer = (map) =>{
removeGeoJsonLayer(map);
// 数据源
const geoJsonSource = new VectorSource({
format:new GeoJSON(),
// 长春在线json数据
url:"https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=220100_full"
});
// 图层
geoJsonLayer.value = new VectorLayer({
name:"geojson图层",
source:geoJsonSource,
fill: new Fill({
color: 'rgba(255, 0, 0, 1)'
}),
// 样式-边框
stroke: new Stroke({
color: '#0099ff',
width: 3
}),
zIndex: 20,
});
map.addLayer(geoJsonLayer.value);
}
// 选中要素图层
const selectGeoJsonLayer = (map) =>{
// 清除弹窗html
if (container.value) {
container.value.remove();
}
// 创建popup
popupOverlay.value = new Overlay({
element:container.value,
autoPan:true,// 定义弹出窗口在边缘点击时候可能不完整,设置自动平移效果
positioning:"bottom-center",
stopEvent:true,// 地图的事件传播是否停止,默认是 true;单击OverlayPopup可以查看效果
autoPanAnimation:{
duration:250// 动画
}
});
// 添加popup到地图容器
map.addOverlay(popupOverlay.value);
map.on('click', ev => {
const pixel = ev.pixel // 鼠标点击的位置,这个应该是像素
const mousePoint = ev.coordinate // 鼠标点击的坐标位置
const feature = map.forEachFeatureAtPixel(pixel, (feature) => {
return feature // 查找出点击的哪个要素
});
if (feature) { // 如果是点击了坐标点
// 样式显示dom
container.value.classList.remove('overlay-popup-hidden');
// 区域名称
const placeName = feature.getProperties().name;
// 添加数据
container.value.innerHTML = `<span>行政区:${placeName}</span>`;
// 弹出popup
popupOverlay.value.setPosition(mousePoint);
} else {
// 清除弹窗html
if (container.value) {
//container.value.remove();
// 隐藏弹窗-方法1
//that.popupOverlay.setPosition(undefined)
// 样式隐藏dom-隐藏弹窗-方法2
container.value.classList.add('overlay-popup-hidden');
}
console.log("没有要素数据");
}
})
// 选中获取geojson数据
/* if(geoJsonLayer.value != null){
const featureLayer = toRaw(geoJsonLayer.value);
// 创建选择交互
const selectInteraction = new Select({
layers:[featureLayer],
});
map.addInteraction(selectInteraction);
// 监听选中要素的变化
selectInteraction.on('select',(event) =>{
// 获取被选中的要素
const selectedFeatures = event.target.getFeatures();
selectedFeatures.forEach(element => {
//获取到选中要素的属性
console.log("element",element.getProperties());
});
});
}else{
alert("没有要素图层!")
}*/
}
// 清除geojson图层
const removeGeoJsonLayer = (map) =>{
// 清空geoJsonLayer图层
if(geoJsonLayer.value != null){
map.removeLayer(geoJsonLayer.value);
geoJsonLayer.value = null;
}
}
// 暴漏方法
defineExpose({
addGeoJsonLayer,
selectGeoJsonLayer,
removeGeoJsonLayer
})
</script>
<style scoped lang="scss">
// 点选弹窗样式
.overlay-popup{
position: absolute;
background-color: white;
font-size: 14px;
-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;
text-align: center;// 内容居中
left: -75px;// 整体位置往左偏移60px(根据实际情况调整)
width: 140px;
}
.overlay-popup:before {// 弹出框底部的三角
position: absolute;
top: 100%;
border: 10px solid transparent;
border-top-color: #ffffff;
content: "";
left: 70px;// 根据上面的宽度进行三角号的调整
}
.overlay-popup-hidden{// 隐藏样式
display: none
}
.overlay-popup-show{// 显示样式-暂时用不上
display: block
}
</style>
三、使用方法
<template>
****
<GeoJSONVue ref="geojsonRef" @addGeoJson="addGeoJson" @selectGeoJson="selectPoint" @removeGeoJson="clear"></GeoJSONVue>
</template>
<script>
***
// 引用
import GeoJSONVue from "../vue/geojson.vue";
// 子组件承接父组件对象
const props = defineProps({
map: Map,
mapCenter: [],
mapZoom: Number
});
// 定义与 ref 同名变量
const geojsonRef = ref(null)
// 调用方法
// 添加geojson
const addGeoJson = () =>{
geojsonRef.value.addGeoJsonLayer(props.map);
}
// 点选geojson事件
const selectPoint = () =>{
//alert("点选");
geojsonRef.value.selectGeoJsonLayer(props.map);
}
const clear = () => {
//alert("清除");
geojsonRef.value.removeGeoJsonLayer(props.map);
}
</script>
<style scoped lang="scss">
</style>