vue+openlayers根据坐标点绘制多边形
需求:根据多边形轮廓点及中心点在天地图上绘制形状;不同类型的多边形轮廓以颜色区分功能:1.中心点坐标实现聚合2.根据地图的缩放级别显示或者隐藏多边形3.鼠标移入多边形或者中心点实现高亮并显示弹框,移除恢复原来的效果js代码var map,layer_poly_A,layer_poly_B,layer_poly_C,layer_poi_A,layer_poi_B,layer_poi_Cconst o
·
需求:根据多边形轮廓点及中心点在天地图上绘制形状;不同类型的多边形轮廓以颜色区分
功能:
1.中心点坐标实现聚合
2.根据地图的缩放级别显示或者隐藏多边形
3.鼠标移入多边形或者中心点实现高亮并显示弹框,移除恢复原来的效果
js代码
var map,layer_poly_A,layer_poly_B,layer_poly_C,layer_poi_A,layer_poi_B,layer_poi_C
const overlapOptions = ['A类', 'B类', 'C类'];
var app = new Vue({
el: '#app',
data: {
loading:false,//加载标识
arrow_show:true,//地图页的第一个箭头
checkedA:false,//A类复选框
checkedB:false,//B类复选框
isLoadB:false,//控制B类数据加载的div
checkedC:false,//C类复选框
dkPopup1:false,//弹窗1,用于地块详情数据展示
dkPopup2:false,//弹窗2,用于提示
isPolygon:false,//弹窗1中,控制面积字段的显示
//地图页地块提示语
dk_detail:{
lclass:"加载中……", pepeatCnt:"加载中……", belong :"加载中……", tbmj:"加载中……",clmj:"加载中……",
},
},
mounted() {
this.mapLoad();
},
methods: {
mapLoad(){
var that_=this
//官方天地图
var tdt_image =new ol.layer.Tile({
source:new ol.source.XYZ({
title: "天地图卫星影像图",
url:"http://t0.tianditu.gov.cn/img_w/wmts?" +
"SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" +
"&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=天地图秘钥"
})
})
var tdt_text =new ol.layer.Tile({
source:new ol.source.XYZ({
title: "天地图卫星影像文字标注",
url: "http://t0.tianditu.gov.cn/cia_w/wmts?" +
"SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" +
"&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}" +
"&tk=天地图秘钥"
})
})
//地图容器
map = new ol.Map({
layers: [tdt_image ,tdt_text ],
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([106.79274503710936, 22.517548223446013]),//ol.proj.fromLonLat后面如果不填要转换的坐标系,默认为3857。// 数据格式4326转为3857
zoom: 13,
minZoom: 2
}),
// interactions:ol.interaction.defaults({
// doubleClickZoom: false,// 取消双击放大功能交互
// mouseWheelZoom: false, // 取消滚动鼠标中间的滑轮交互
// shiftDragZoom: false, // 取消shift+wheel左键拖动交互
// })
});
//地图移动事件(包括放大或者缩小的移动)
this.map_moveend()
// 加载数据A类
this.load_data("A")
//先加入地图动作,鼠标移入动作
this.map_pmove()
this.map_secect()
//加载数据B类
this.load_data("B")
},
//构造集合对象
dkOutline(dk_data,dk_class){
var that_ =this
//多边形要素数组
var poly_Features=[]
var poi_Features=[]
for (var i = 0; i < dk_data.length; i++){
for (var j = 0; j <dk_data[i].parcels.length; j++){
var attr1={
jd:dk_data[i].jd,
wed:dk_data[i].wed,
lclass:dk_data[i].lclass,
pepeatCnt:dk_data[i].pepeatCnt,
parcels:dk_data[i].parcels,
cur_fea:j
}
var polygon = new ol.geom.Polygon([dk_data[i].parcels[j].coordinates])
//坐标转换
polygon.applyTransform(ol.proj.getTransform('EPSG:4326', 'EPSG:3857'));
//附加信息
var poly_Feature = new ol.Feature({
geometry: polygon,
attribute: attr1,//添加特征
})
poly_Features.push(poly_Feature)
poi_Features.push(new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([dk_data[i].jd,dk_data[i].wed])),
attribute: attr1
})
)
}
}
//实例化一个矢量图层Vector作为绘制层
var source_poly = new ol.source.Vector({
features: poly_Features
});
//实例化一个矢量图层Vector作为绘制层
var source_point = new ol.source.Vector({
features: poi_Features
});
//聚合标注数据源
var clusterSource = new ol.source.Cluster({
distance: 20, //聚合的距离参数,即当标注间距离小于此值时进行聚合,单位是像素
source: source_point //聚合的数据源,即矢量要素数据源对象
});
//判断A类还是B类,然后以A类还是B类控制聚合点的颜色
if(dk_class=="A"){
//layer矢量层
layer_poly_A = new ol.layer.Vector({
visible: false,
source: source_poly,
style: function (feature) {
// var type=feature.values_.attribute.type//获取feature的属性的自定义信息
return new ol.style.Style({
fill: new ol.style.Fill({ //填充样式
color: 'rgba(0, 0, 0, 0.5'
}),
stroke: new ol.style.Stroke({ //线样式
color: "red",
width: 2
}),
})
}
});
layer_poi_A = new ol.layer.Vector({
source: clusterSource,
style: function (feature) {
var size = feature.get('features').length;
// var type=feature.values_.attribute.type//获取feature的属性的自定义信息
return new ol.style.Style({
image: new ol.style.Circle({
radius: 12,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: "red"
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
}),
})
}
});
//将绘制层添加到地图容器中
map.addLayer(layer_poly_A)
map.addLayer(layer_poi_A)
// 勾选A类
that_.checkedA=true
}else if(dk_class=="B"){
//layer矢量层
layer_poly_B = new ol.layer.Vector({
visible: false,
source: source_poly,
style: function (feature) {
// var type=feature.values_.attribute.type//获取feature的属性的自定义信息
return new ol.style.Style({
fill: new ol.style.Fill({ //填充样式
color: 'rgba(0, 0, 0, 0.5'
}),
stroke: new ol.style.Stroke({ //线样式
color: "#9b59b6",
width: 2
}),
})
}
});
layer_poi_B = new ol.layer.Vector({
// visible: false,
source: clusterSource,
style: function (feature) {
var size = feature.get('features').length;
// var type=feature.values_.attribute.type//获取feature的属性的自定义信息
return new ol.style.Style({
image: new ol.style.Circle({
radius: 12,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: "#9b59b6",
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
}),
})
}
});
//将绘制层添加到地图容器中
map.addLayer(layer_poly_B)
map.addLayer(layer_poi_B)
// 勾选B类
that_.checkedB=true
that_.isLoadB=true
}
this.$message({
message: dk_class+'类地块轮廓渲染完成!',
type: 'success'
});
},
//请求后端坐标点数据
load_data(dk_class){
//请求坐标点
var that_=this
that_.loading=true
$.ajax({
url : 'http://39.105.12.242:18080/lzfy/f/luokuo/getjsonstr?lclass='+dk_class,
type : 'get',
jsonp: 'jsonpCallback',
dataType: 'jsonp',
success: function(returnData) {
that_.dkOutline(returnData,dk_class)
that_.loading=false
},
error : function() {
that_.$message.error('坐标点数据加载失败');
// console.log(err.status)
that_.loading=false
console.log('坐标点数据加载失败')
},
})
},
//地图移入动作
map_pmove(){
var that_=this
// 利用js浅拷贝原理实现要素高亮
map.on("pointermove",function(evt){
let elPopup1 = that_.$refs.popup1;
//多边形的的弹窗
var popup_overlay1 = new ol.Overlay({
element: elPopup1,
positioning: "bottom-center",
stopEvent: false,
offset: [-6, -40],
});
map.addOverlay(popup_overlay1);
//判断当前单击处是否有要素,捕获到要素时弹出popup
let feature = map.forEachFeatureAtPixel(
evt.pixel,
function(feature){
feature.dispatchEvent({type: 'mouseout', event: event})
return feature
}
);
if (feature){ //捕捉到要素
fea_type=feature.getGeometry().getType() //要素类型
var belong_Arr=[],clmj,tbmj,center_poly
if (fea_type=="Polygon"){
var attr1=feature.get('attribute')
that_.isPolygon=true
// console.log(feature.getGeometry().getCoordinates())
if(attr1.lclass=="A"){
for (i in attr1.parcels){
var belong_str=attr1.parcels[i].znm+"-"+attr1.parcels[i].znName+"-"+attr1.parcels[i].parcelId
belong_Arr.push(belong_str)
tbmj=attr1.parcels[0].tbmj
clmj=attr1.parcels[0].clmj
}
center_poly=[attr1.parcels[0].jd,attr1.parcels[0].wed]
}
if(attr1.lclass=="B"){
fea_num=attr1.cur_fea
var belong_str=attr1.parcels[fea_num].znm+"-"+attr1.parcels[fea_num].znName+"-"+attr1.parcels[fea_num].parcelId
belong_Arr.push(belong_str)
tbmj=attr1.parcels[fea_num].tbmj
clmj=attr1.parcels[fea_num].clmj
center_poly=[attr1.parcels[fea_num].jd,attr1.parcels[fea_num].wed]
}
that_.dk_detail={
lclass:attr1.lclass, pepeatCnt:attr1.pepeatCnt, belong:belong_Arr, tbmj:tbmj,clmj:clmj,
}
// //设置中心点
// map.getView().setCenter(ol.proj.transform([attr1.parcels[0].jd,attr1.parcels[0].wed], 'EPSG:4326', 'EPSG:3857'));
that_.dkPopup1=true
// 将弹窗显示坐标点上
setTimeout(() => {
popup_overlay1.setPosition(ol.proj.fromLonLat(center_poly));
}, 0);
}
if (fea_type=="Point"){
var curzoom = map.getView().getZoom(); //获取当前地图的缩放级别
that_.isPolygon=false
// 将弹窗显示坐标点上
var attr2=feature.getProperties().features[0].values_.attribute
let ceter_point = feature.getGeometry().getCoordinates();
// console.log(feature.getGeometry().getCoordinates())
if (curzoom>15){
that_.dkPopup2=false
that_.isPolygon=false
for (i in attr2.parcels){
var belong_str=attr2.parcels[i].znm+"-"+attr2.parcels[i].znName+"-"+attr2.parcels[i].parcelId
belong_Arr.push(belong_str)
tbmj=attr2.parcels[0].tbmj
clmj=attr2.parcels[0].clmj
}
that_.dk_detail={
lclass:attr2.lclass, pepeatCnt:attr2.pepeatCnt, belong:belong_Arr, tbmj:tbmj,clmj:clmj,
}
// map.getView().setCenter(ol.proj.transform([attr2.parcels[0].jd,attr2.parcels[0].wed], 'EPSG:4326', 'EPSG:3857'));
that_.dkPopup1=true
setTimeout(() => {
popup_overlay1.setPosition(ceter_point);
}, 0);
}else{
let elPopup2 = that_.$refs.popup2;
var popup_overlay2 = new ol.Overlay({
element: elPopup2,
positioning: "bottom-center",
stopEvent: false,
offset: [-6, -15],
});
map.addOverlay(popup_overlay2);
that_.dkPopup2 = true;
setTimeout(() => {
popup_overlay2.setPosition(ceter_point);
}, 0);
}
}
}else{
that_.dkPopup1=false
that_.dkPopup2=false
}
})
},
map_secect(){
//交互时高亮
var select_move=new ol.interaction.Select({
condition:ol.events.condition.pointerMove,
style:new ol.style.Style({
fill: new ol.style.Fill({ //填充样式
color: 'rgba(255, 255, 255, 0.5'
}),
stroke: new ol.style.Stroke({ //线样式
color: '#ffcc33',
width: 5
}),
image: new ol.style.Circle({ //点样式
radius: 10,
fill: new ol.style.Fill({
color: '#e67e22'
})
})
})
});
map.addInteraction(select_move)
},
//地图移动事件;地图扩大或者缩小到某个级别后需要隐藏图层
map_moveend(){
var that_=this
//地图移动事件;地图扩大或者缩小到某个级别后需要隐藏图层
map.on("moveend",function(evt){
var curzoom = map.getView().getZoom(); //获取当前地图的缩放级别
if(that_.checkedA){
layer_poi_A.setVisible(true); //显示瓦片
if(curzoom > 15){
layer_poly_A.setVisible(true)//显示瓦片
}else{
layer_poly_A.setVisible(false)
}
}
else{
if(layer_poly_A){
layer_poly_A.setVisible(false)
}
if(layer_poi_A){
layer_poi_A.setVisible(false);
}
}
if(that_.checkedB){
layer_poi_B.setVisible(true) //显示瓦片
if(curzoom > 15){
layer_poly_B.setVisible(true) //显示瓦片
}else{
layer_poly_B.setVisible(false)
}
}
else{
if(layer_poly_B){
layer_poly_B.setVisible(false)
}
if(layer_poi_B){
layer_poi_B.setVisible(false)
}
}
})
},
//地图页中panel_box箭头切换时
showArrow(){
if (this.arrow_show){
this.arrow_show=!this.arrow_show
$("#panel_option").slideUp();
// $("#form_show").css("display","block");
}
else if(!this.arrow_show) {
this.arrow_show=!this.arrow_show
$("#panel_option").slideDown();
// $("#form_show").css("display","none");
}
},
//地图页的复选框
checkedChangeA(val){
var curzoom = map.getView().getZoom(); //获取当前地图的缩放级别
if(val){
layer_poi_A.setVisible(true); //显示瓦片
if(curzoom > 15){
layer_poly_A.setVisible(true)
}else{
layer_poly_A.setVisible(false)
}
}
else{
if(layer_poly_A){
layer_poly_A.setVisible(false)
}
if(layer_poi_A){
layer_poi_A.setVisible(false); //显示瓦片
}
}
},
checkedChangeB(val){
var curzoom = map.getView().getZoom(); //获取当前地图的缩放级别
if(val){
layer_poi_B.setVisible(true); //显示瓦片
if(curzoom > 15){
layer_poly_B.setVisible(true)
}else{
layer_poly_B.setVisible(false)
}
}
else{
if(layer_poly_B){
layer_poly_B.setVisible(false)
}
if(layer_poi_B){
layer_poi_B.setVisible(false); //显示瓦片
}
}
},
}
})
html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="Access-Control-Allow-Origin" content="*" />
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="js/v6.5.0-dist/v6.5.0-dist/ol.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="js/v6.5.0-dist/v6.5.0-dist/ol.css"/>
<link rel="stylesheet" type="text/css" href="css/index.css"/>
<script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="app">
<div id="map">
<div class="panel_box">
<div class="panel_title flex_between_center">
<el-badge is-dot class="item">地块重叠类型</el-badge>
<span class="panel_p"><i @click="showArrow" :class="arrow_show==true?'el-icon-arrow-down':'el-icon-arrow-up'"></i></span>
</div>
<div class="panel_option" id="panel_option">
<el-tooltip class="item" effect="dark" content="重叠率:100%" placement="right">
<div class="flex_between_center panel_option1">
<div><el-checkbox v-model="checkedA" @change="checkedChangeA"></el-checkbox> A类 (重叠率:100%)</div>
<div>231</div>
</div>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="50%<重叠率<100%" placement="right">
<div class="flex_between_center panel_option2">
<div v-show="!isLoadB"><el-checkbox disabled></el-checkbox> B类 (重叠率:>50%)</div>
<div v-show="isLoadB" ><el-checkbox v-model="checkedB" @change="checkedChangeB"></el-checkbox> B类 (重叠率:>50%)</div>
<div>1070</div>
</div>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="0<重叠率<50%" placement="right">
<div class="flex_between_center panel_option3">
<div><el-checkbox v-model="checkedC" disabled></el-checkbox> C类 (重叠率:>0%)</div>
<div>0</div>
</div>
</el-tooltip>
</div>
</div>
<!-- 多边形弹窗 -->
<div ref="popup1" class="popup1" v-show="dkPopup1">
<table>
<caption><i class="el-icon-star-on"></i><i class="el-icon-star-on"></i><i class="el-icon-star-on"></i><i class="el-icon-star-on"></i><i class="el-icon-star-on"></i></caption>
<tr><td class="td1">重叠类型 :</td><td class="td2">{{ dk_detail.lclass }} 类</td></tr>
<tr><td class="td1">重叠次数 :</td><td class="td2">{{ dk_detail.pepeatCnt }} 次</td></tr>
<tr v-show="isPolygon"><td class="td1">填表面积 :</td><td class="td2">{{ dk_detail.tbmj }} 亩</td></tr>
<tr v-show="isPolygon"><td class="td1">测量面积 :</td><td class="td2">{{ dk_detail.tbmj }} 亩</td></tr>
<tr v-for="(item,i) in dk_detail.belong">
<td class="td1">
<span v-show="dk_detail.belong.length==1">地块所属 :</span>
<span v-show="dk_detail.belong.length>1">地块所属{{ i+1 }} :</span>
</td>
<td class="td2">{{ item }}</td>
</tr>
</table>
</div>
<!-- 提示弹窗 -->
<div ref="popup2" v-show="dkPopup2">
<el-button size="mini" type="info">请将地图放大查看详情!</el-button>
</div>
</div>
</div>
</body>
<script src="js/index.js" type="text/javascript" charset="utf-8"></script>
</html>
后端获取的数据格式
效果图:
更多推荐
已为社区贡献2条内容
所有评论(0)