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

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

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)
  • 绘制多边形编辑并保存---- 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)
		},
	}
})

你可能感兴趣的:(openlayers)