• 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

  • 相关阅读:
    cef加载flash的办法
    一个高性能的对象属性复制类,支持不同类型对象间复制,支持Nullable<T>类型属性
    php检测php.ini是否配制正确
    openwrt的路由器重置root密码
    windows 7 + vs2010 sp1编译 x64位版qt4
    解决SourceGrid在某些系统上无法用鼠标滚轮滚动的问题
    判断一个点是否在多边形内部,射线法思路,C#实现
    [转载]使用HttpWebRequest进行请求时发生错误:基础连接已关闭,发送时发生错误处理
    让Dapper+SqlCE支持ntext数据类型和超过4000字符的存储
    通过WMI
  • 原文地址:https://www.cnblogs.com/javalinux/p/15330820.html
Copyright © 2020-2023  润新知