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',
width: 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,
width: 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM