vue+openlayers图形交互,实现多边形绘制、编辑和保存

知识点:
1.绘制多边形,实例化ol.interaction.Draw对象
draw_inter = new ol.interaction.Draw({
source: source_draw,//矢量地图源
type: "Polygon",//绘图类型
});
//将交互绘图对象添加到地图中
map.addInteraction(draw_inter)
1
2
3
4
5
6
2.图形交互编辑,实例化ol.interaction.Select对象和ol.interaction.Modify对象

let select_f=new ol.interaction.Select({
multi:false //取消多选
})
map.addInteraction(select_f);
let modify_f = new ol.interaction.Modify({
features: select_f.getFeatures()//将选中的要素添加修改功能
})
map.addInteraction(modify_f)
1
2
3
4
5
6
7
8
绘制多边形编辑并保存---- js核心代码
/**
* map 地图对象
* source_draw 用于绘制形状的矢量地图源
* vectorLayer 矢量绘制层
* draw_inter 绘制形状的交互对象
* sketch 当前绘制对象(feature)
* popup_overlay 弹窗overlay,绘制完成后展示编号
* layer_poly 用于展示多边形的layer层
*/
var map,source_draw,vectorLayer,draw_inter,popup_overlay,sketch,layer_poly

var app = new Vue({
el: '#app',
data: {
value_draw:'',
//画笔选择器
options_draw:[
{
value: 'Polygon',
label: '标面'
},
{
value: 'None',
label: '清除画笔'
},
],
popup_ol1:false,//弹窗,用来提示编号的
/**
* 表单
* dk_id 多边形id
* type_dk 多边形类型
* coor 多边形坐标点
* area 多边形面积
*/
formp: {
dk_id:'',
type_dk: '',
coor:'',
area:''
},
//表单规则
formrules:{
dk_id: [
{ required: true, message: '请选择一个多边形', trigger: 'blur' },
],
type_dk: [
{ required: true, message: '请选择用地类型', trigger: 'change' }
],
area:[
{ required: true, message: '请选择一个多边形', trigger: 'blur' },
],
coor: [
{ required: true, message: '请选择一个多边形', trigger: 'blur' },
],
},
active_panel: ['1','2']//地图折叠面板显示
},
mounted() {
//dom挂载完成,加载地图
this.mapLoad();
},
methods: {
mapLoad(){
let 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=天地图秘钥"
})
})
//实例化一个矢量图层Vector作为绘制层
source_draw = new ol.source.Vector()
vectorLayer = new ol.layer.Vector({
source:source_draw,
style: new ol.style.Style({
fill: new ol.style.Fill({ //填充样式
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new ol.style.Stroke({ //线样式
color: '#ffcc33',
2
}),
image: new ol.style.Circle({ //点样式
radius: 7,
fill: new ol.style.Fill({
color: '#2d98da'
})
}),
text: new ol.style.Text({
font: '16px Calibri,sans-serif',
text: "未保存地块",
fill: new ol.style.Fill({
color: "#c0392b"
}),
backgroundFill: new ol.style.Fill({ // 填充背景
color: 'rgba(0,0,0,1)',
}),
})
})
});
//地图容器
map = new ol.Map({
layers: [tdt_image ,tdt_text ,vectorLayer],
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([107.77746092130616, 22.52862563840752]),//ol.proj.fromLonLat后面如果不填要转换的坐标系,默认为3857。// 数据格式4326转为3857
zoom: 17,
minZoom: 2
}),
})
//加载数据已绘制的数据
this.load_data()
//添加交互
this.selectModify()
},
//请求数据
load_data(){
var that_=this
that_.loading=true
$.ajax({
url : 'http://127.0.0.1:8000/lzfy/f/luokuo/getDongyaParcel',
type : 'get',
jsonp: 'jsonpCallback',
dataType: 'jsonp',
success: function(returnData) {
that_.dkOutline(returnData)
},
error : function() {
that_.$message.error('坐标点数据加载失败');
console.log('坐标点数据加载失败')
},
})
},
//select选项改变时
handleChange(){
if(draw_inter){
map.removeInteraction(draw_inter) //绘制之前先清空上一次交互画笔
}
//绘制类型
let draw_type =this.value_draw //获取绘画的类型
if (draw_type !== 'None'){
if(draw_type=='LineString'||draw_type=='Polygon'){
//绘画交互
this.addInteraction()
}
}
},
//绘画交互图形
addInteraction(){
let that_=this
let draw_type =this.value_draw //获取绘画的类型
draw_inter = new ol.interaction.Draw({
source: source_draw,
type: draw_type,
});
//将交互绘图对象添加到地图中
map.addInteraction(draw_inter)
//绘画开始时
// draw_inter.on('drawstart', function (evt) {
// // set sketch
// sketch = evt.feature;
// })
//监听绘制结束事件
draw_inter.on('drawend', function (evt) {
sketch=evt.feature
//为sketch生成唯一编号
let date = new Date()
let dk_id= date.getFullYear().toString() + (date.getMonth()+ 1).toString() +
date.getDate().toString() + date.getHours().toString() + date.getMinutes().toString()
+ date.getSeconds().toString()
//画完之后给sketch添加属性
sketch.setProperties({
attribute: {dk_id:dk_id,state:1},
})
// 添加overlay的内容及表单赋值
that_.addOverlay1()
})
},
//选中修改几何图形
selectModify(){
let that_=this
let select_f=new ol.interaction.Select({
multi:false //取消多选
})
map.addInteraction(select_f);
let modify_f = new ol.interaction.Modify({
features: select_f.getFeatures()//将选中的要素添加修改功能
})
map.addInteraction(modify_f)
select_f.on("select",function (evt) {
if(that_.value_draw !="Polygon"){
//点击空白清除,清除弹窗,清空表单内容
if(evt.selected.length<=0) {
that_.popup_ol1 = false
popup_overlay.setPosition(undefined)
if (that_.$refs['formp']!==undefined) {
that_.$refs['formp'].resetFields();
}
return
}
//选中一个要素时
if(evt.selected.length==1) {
// console.log(evt.selected[0].getProperties())
sketch=evt.selected[0]
// 添加overlay的内容,及给表单赋值
that_.addOverlay1()
}
}
})
//监听要素修改时
modify_f.on("modifyend",function (evt) {
let new_feature = evt.features.item(0)
if(new_feature){
sketch=new_feature
// 添加overlay的内容,及给表单赋值
that_.addOverlay1()
}
})
},
//点击弹窗的
popup_click(){
this.popup_ol1=false
popup_overlay.setPosition(undefined)
},
//表单提交
submitForm(formName){
let that_=this
that_.$refs[formName].validate((valid) => {
if (valid) {
let formData = JSON.stringify(that_.formp); // that_指向这个VUE实例 data默认绑定在实例下的。所以直接that_.student就是要提交的数据
$.ajax({
url : 'http://127.0.0.1:8080/lzfy/f/luokuo/testaaa',
type : 'post',
data : that_.formp,
// jsonp: 'jsonpCallback',
// dataType: 'jsonp',
success: function(returnData) {
that_.$message({
message: '保存成功!!!',
type: 'success'
})
//删除绘制图形层的feature,向展示图形层添加feature
let state=sketch.getProperties().attribute["state"]
if(state){
vectorLayer.getSource().removeFeature(sketch)
sketch.setProperties({
attribute: {
dk_id:that_.formp.dk_id,
type_dk:that_.formp.type_dk,
state:0
}
})
layer_poly.getSource().addFeature(sketch)
}else{
sketch.setProperties({
attribute: {
dk_id:that_.formp.dk_id,
type_dk:that_.formp.type_dk,
state:0
}
})
}
},
error : function() {
that_.$message.error('提交失败')
},
})
} else {
that_.$message.error('提交失败')
console.log("失败")
}
});
},
//重置表单,删除要素
resetForm(formName){
// source_draw
let that_=this
that_.popup_ol1=false
popup_overlay.setPosition(undefined)
let state=sketch.getProperties().attribute["state"]
if(!state){
layer_poly.getSource().removeFeature(sketch)
let dk_id=sketch.getProperties().attribute["dk_id"]
$.ajax({
url : 'http://127.0.0.1:8080/lzfy/f/luokuo/delWithDkid?dk_id='+String(dk_id),
type : 'get',
// data : {dk_id:dk_id},
success: function(returnData) {
console.log(returnData)
that_.$message({
message: '删除成功!!!',
type: 'success'
})
},
error : function() {
that_.$message.error('删除失败')
},
})

}else{
vectorLayer.getSource().removeFeature(sketch)
that_.$message({
message: '删除成功!!!',
type: 'success'
})
}
sketch=null
that_.$nextTick(() => {
if (this.$refs[formName]!==undefined) {
this.$refs[formName].resetFields();
}
})
},
addOverlay1(new_geo){
//添加弹窗
let that_= this
let elPopup = that_.$refs.popup_ol1
popup_overlay = new ol.Overlay({
element: elPopup,
offset:[0,0], //popup的偏移量
positioning: 'center-center',
autoPan: true, // 定义弹出窗口在边缘点击时候可能不完整 设置自动平移效果
autoPanAnimation: {
duration: 250 //当Popup超出地图边界时,为了Popup全部可见,地图移动的速度. 单位为毫秒(ms)
}
})
map.addOverlay(popup_overlay)
that_.popup_ol1 = true
//声明一下变量
let tooltipCoord
let gem1=sketch.getGeometry()
let type_geo=gem1.getType()
let coor=gem1.getCoordinates()
//以下是为表单添加数据
//timeid数据
that_.formp.dk_id=sketch.getProperties().attribute["dk_id"]
//面积数据
if (type_geo=="Polygon"){
//获取多变形内部点的坐标
tooltipCoord = gem1.getInteriorPoint().getCoordinates()
let area = ol.sphere.getArea(gem1)
let num1=(Math.round(area * 100) / 100)*0.0015
let output = num1.toFixed(2) + '亩'
that_.formp.area=output
}else if(type_geo=="LineString"){
tooltipCoord = gem1.getLastCoordinate()
var length = ol.sphere.getLength(gem1)
let output
if (length > 100) {
output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
} else {
output = Math.round(length * 100) / 100 + ' ' + 'm';
}
that_.formp.area=output
}
setTimeout(() => {
popup_overlay.setPosition(tooltipCoord)
// console.log(tooltipCoord)
}, 0)
//地块类型数据和id
let state=sketch.getProperties().attribute["state"]
if(!state){
that_.formp.type_dk=sketch.getProperties().attribute["type_dk"]
}
//坐标点数据
that_.formp.coor=String(coor)
},
//对获取后台数据进行展示到地图中
dkOutline(coor_datas){
let that_ =this
//多边形要素数组
let poly_Features=[]
// console.log(coor_datas)
for (var i = 0; i < coor_datas.length; i++){
// console.log(coor_datas[i].type_dk)
var attr1={
dk_id:coor_datas[i].dk_id,
type_dk:coor_datas[i].type_dk,
state:0
}
// console.log(coor_datas[i].coordinates)
poly_Features.push(new ol.Feature({
geometry: new ol.geom.Polygon([coor_datas[i].coordinates]),
attribute: attr1
}))
}
//实例化一个矢量图层Vector作为绘制层
let source_poly = new ol.source.Vector({
features: poly_Features
})
layer_poly = new ol.layer.Vector({
// visible: false,
source: source_poly,
style: function (feature) {
let type_dk=feature.values_.attribute.type_dk//获取feature的属性的自定义信息
let color_define="#e74c3c"
let text ="旱改水地块"
if (type_dk=="A"){
color_define="#e74c3c"
text ="旱改水地块"
}else if (type_dk=="B"){
color_define="#e67e22"
text ="施肥地块"
}else if (type_dk=="C"){
color_define="#3498db"
text ="缓释肥实验地块"
}
else if (type_dk=="D"){
color_define="#2ecc71"
text ="康泽公司地块"
}else if (type_dk=="E"){
color_define="#9b59b6"
text ="石埠奶场征地"
}
return new ol.style.Style({
fill: new ol.style.Fill({ //填充样式
color: 'rgba(0, 0, 0, 0.5'
}),
stroke: new ol.style.Stroke({ //线样式
color: color_define,
2
}),
text: new ol.style.Text({
text: text,
font: '16px Calibri,sans-serif',
fill: new ol.style.Fill({
color: '#fff'
}),
backgroundFill: new ol.style.Fill({ // 填充背景
color: 'rgba(0,0,0,0.4)',
}),
}),
})
}
})
//将绘制层添加到地图容器中
map.addLayer(layer_poly)
},
}
})
————————————————
版权声明:本文为CSDN博主「小黑猪hhh」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46074818/article/details/117807715

原文地址:https://www.cnblogs.com/javalinux/p/15330820.html