利用Geoerver+Mysql+openlayers实现gis空间数据线段、多边形的存储、编辑、平移等功能


Geoerver+Mysql+openlayers实现gis空间数据线段、多边形的存储、编辑、平移

本人新手一枚,本篇文章是对自己遇到的问题进行简单梳理,错误的地方还望不吝赐教,本篇实现内容主要参考‘扯淡大叔’写的文章,因不同的环境,实现效果需自己调整,大叔的链接:http://weilin.me/ol3-primer/ch12/12-01-05.html。

首先,原来我用的是Geoerver+postgis+mysql,后来为了使用方便,索性将空间数据和业务数据统一保存到mysql,实现方法如下:https://blog.csdn.net/GISuuser/article/details/80728267
因为涉及到空间数据的编辑保存,所以在做保存操作的时候会接触到基础性问题先理一下:
1、‘readonly’只读。保存数据的时提示无法保存,提示只读,这是需要在geoserver的data内设置一下权限,具体操作可查看(测试可行):
https://blog.csdn.net/shaxiaozilove/article/details/61619388
2、跨域问题。跨域问题经常会碰到,访问被拒,解决办法:
https://www.cnblogs.com/ytwy/p/6823955.html
https://blog.csdn.net/mengdong_zy/article/details/51784781
Mysql数据库–数据类型一致:保存几何数据的字段‘SHAPE’(实际情况名称可能略有不同),其数据类型最好设置成geomtry类型,这样可以在同一个表内保存任意类型的数据,包括多段线,多边形,点,圆等,如果设置的数据类型是Polygon或者其他的指定单一类型,就无法保存其他数据类型Line,Circle的数据。


前端代码

   <button type="submit " class="btn btn-primary">图形新增</button>
   <input id="addLayer" type="checkbox" value="add" />新增
   <input id="saveNew" type="button" value="保存" onclick="onSaveNew();" />
   <input type="button" value="刷新" onclick="queryWfs();" />
   <button type="submit " class="btn btn-primary">图形删除</button>
   <input id="selectDelete" type="checkbox" value="select" />选择
   <input id="delete" type="button" value="删除选中Feature" onclick="onDeleteFeature();" />
   <button type="submit " class="btn btn-primary">图形编辑</button>
   <input id="select" type="checkbox" value="select" />选择
   <input id="modify" type="checkbox" value="modify" />编辑
   <input id="save" type="button" value="保存" onclick="onSave();" />
   <input id="moveInteraction" type="checkbox" value="moveInteraction"/>平移
   <input id="addLayer1" type="checkbox" value="add" />新增多边形
   <input id="saveNew1" type="button" value="保存" onclick="onSaveNew1();" />

新增要素

var onSaveNew;//保存函数
var queryWfs;
var modifiedFeatures = null;
var onDeleteFeature;
var onSave;
var onSaveNew1;//多边形测试
var onSaveNew2;//圆测试

    //因为要进行编辑修改,因为选用wfs类型图层
    var vectorLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
            format: new ol.format.GeoJSON({
                geometryName: 'SHAPE' // 因为数据源里面字段'SHAPE'存储的是几何图形数据,所以需要指定
            }),
            url: 'http://locahost:7777/geoserver/degao_mysql/ows?service=WFS&version=1.0.0&request=GetFeature&outputFormat=application/json&typeName=degao_mysql:zhuguanduan_line&srsname=EPSG:4326'
        }),
            style: function(feature, resolution) {//两个参数暂时没用的上
            return new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: 'blue',
                    width: 2
                })
            });
        }
    });


    // 底图这里我选用的是天地图
    var layers = [new ol.layer.Tile(
        {
            title: "tianditu",
            source: new ol.source.XYZ(
                {
                    url: "http://t1.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}"
                })
        })
        ]
    ;

    //图层主入口
    var map = new ol.Map({
        layers: layers,
        target: 'editData',
        view: new ol.View({
            projection: 'EPSG:4326',
            //center: [13172306.74073, 4074323.92117],  //4326的视角入口
            center: [118.34589, 34.34524],    //3857的视角入口
            zoom: 14
        })
    });
    map.addLayer(vectorLayer);

    //天地图文字标注
    var tian_di_tu_annotation = new ol.layer.Tile(
        {
            title: "天地图文字标注",
            source: new ol.source.XYZ(
                {
                    url: 'http://t3.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}'
                })
        });
    map.addLayer(tian_di_tu_annotation);


// 创建用于新绘制feature的layer
    var drawLayer = new ol.layer.Vector({
        source: new ol.source.Vector(),
        style: new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'blue',
                width: 5
            })
        })
    });
    map.addLayer(drawLayer);

// 添加绘制新图形的interaction,用于添加新的线条
    var newId = 1;
    var drawedFeature = null;
    var drawInteraction = new ol.interaction.Draw({
        type: 'LineString', // 设定为线条
        style: new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'red',
                width: 10
            })
        }),
        source: drawLayer.getSource()
    });

    drawInteraction.on('drawend', function(e) {
        // 绘制结束时暂存绘制的feature
        drawedFeature = e.feature;
    });

  /*  drawInteraction.on('drawstart', function(e) {
        //清除先前未保存的图形
        if (drawedFeature) {
            drawLayer.getSource().removeFeature(drawedFeature);
        }
        drawedFeature = null;
    });*/

    $('#addLayer').change(function() {
        if (this.checked) {
            document.getElementById('selectDelete').checked=false;
            document.getElementById('select').checked=false;
            document.getElementById('modify').checked=false;
            // 勾选新增复选框时,添加绘制的Interaction
            map.removeInteraction(drawInteraction);
            map.addInteraction(drawInteraction);
        } else {
            // 取消勾选新增复选框时,移出绘制的Interaction,删除已经绘制的feature
            map.removeInteraction(drawInteraction);
            if (drawedFeature) {
                drawLayer.getSource().removeFeature(drawedFeature);
            }
            drawedFeature = null;
        }
    });

    queryWfs=function() {
        window.location.reload();
    }

    // 保存新绘制的feature
     onSaveNew = function() {
        var geometry = drawedFeature.getGeometry().clone();
         /*geometry.applyTransform(function(flatCoordinates, flatCoordinates2, stride) {
             for (var j = 0; j < flatCoordinates.length; j += stride) {
                 var y = flatCoordinates[j];
                 var x = flatCoordinates[j + 1];
                 flatCoordinates[j] = x;
                 flatCoordinates[j + 1] = y;
             }
         });*/

        // 设置feature对应的属性,这些属性是根据数据源的字段来设置的
        var newFeature = new ol.Feature();
        newFeature.setGeometryName('SHAPE');
        newFeature.set('SHAPE', null);
        newFeature.setGeometry(new ol.geom.LineString(geometry.getCoordinates()));//获取几何图形的坐标数组
        addWfs([newFeature]);
        // 3秒后,自动刷新页面上的feature
       setTimeout(function() {
            drawLayer.getSource().clear();
          // queryWfs();
        }, 1000);
    }


    // 添加到服务器端
    function addWfs(features) {
        var WFSTSerializer = new ol.format.WFS();
        var featObject = WFSTSerializer.writeTransaction(features,
            null, null, {
                featureType: 'degao_mysql:zhuguanduan_line',
                featureNS: 'http://locahost/geoserver/degao_mysql',
                srsName: 'EPSG:4326'
            });
        var serializer = new XMLSerializer();
        var featString = serializer.serializeToString(featObject);
        var request = new XMLHttpRequest();
        request.open('POST', 'http://locahost:7777/geoserver/wfs?service=wfs');
        request.setRequestHeader('Content-Type', 'text/xml');
        request.send(featString);
    }

修改和平移对象

    // 新建openlayers选择器
    var selectInteraction = new ol.interaction.Select({
        style: new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'red',
                width: 2
            })
        })
    });

    // 修改器
    var modifyInteraction = new ol.interaction.Modify({
        style: new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'red',
                width: 5
            })
        }),
        features: selectInteraction.getFeatures()
    });
    modifyInteraction.on('modifyend', function(e) {
        // 把修改完成的feature暂存起来
        modifiedFeatures = e.features;
    });


    $('#select').change(function() {
        if (this.checked) {
            //控制其他编辑功能,防止冲突
            document.getElementById('addLayer').checked=false;
            document.getElementById('selectDelete').checked=false;
            // 勾选选择复选框时,添加选择器到地图
            map.removeInteraction(selectInteraction);
            map.addInteraction(selectInteraction);
        } else {
            // 不勾选选择复选框的情况下,移出选择器和修改器
            map.removeInteraction(selectInteraction);
            document.getElementById('modify').checked = false;
            map.removeInteraction(modifyInteraction);
        }
    });

    $('#modify').change(function() {
        if (this.checked) {
            document.getElementById('addLayer').checked=false;
            document.getElementById('selectDelete').checked=false;
            // 勾选修改复选框时,添加选择器和修改器到地图
            document.getElementById('select').checked = true;
            map.removeInteraction(modifyInteraction);
            map.addInteraction(modifyInteraction);
            map.removeInteraction(selectInteraction);
            map.addInteraction(selectInteraction);
        } else {
            // 不勾选修改复选框时,移出修改器
            map.removeInteraction(modifyInteraction);
            modifiedFeatures = null;
        }
    });

   //平移功能
    var translate = new ol.interaction.Translate({
        style: new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'red',
                width: 2
            })
        })
    });

    $('#moveInteraction').change(function() {
        if(this.checked){
            map.removeInteraction(translate);
            document.getElementById('select').checked = true;
            map.addInteraction(translate);
        }else{
            map.removeInteraction(translate);
        }

    });

    translate.on('translateend', function(e) {
        // 把修改完成的feature暂存起来
        modifiedFeatures = e.features;
    });

    // 保存已经编辑的要素
    onSave = function() {
        if (modifiedFeatures && modifiedFeatures.getLength() > 0) {

            // 转换坐标
            var modifiedFeature = modifiedFeatures.item(0).clone();
            // 注意ID是必须,通过ID才能找到对应修改的feature
            modifiedFeature.setId(modifiedFeatures.item(0).getId());
            // 调换经纬度坐标,以符合wfs协议中经纬度的位置
            modifiedFeature.getGeometry().applyTransform(function(flatCoordinates, flatCoordinates2, stride) {
                for (var j = 0; j < flatCoordinates.length; j += stride) {
                    var y = flatCoordinates[j];
                    var x = flatCoordinates[j + 1];
                    flatCoordinates[j] = x;
                    flatCoordinates[j + 1] = y;
                }
            });
            modifyWfs([modifiedFeature]);
        }
    }

    // 添加到服务器端
    function modifyWfs(features) {
        var WFSTSerializer = new ol.format.WFS();
        var featObject = WFSTSerializer.writeTransaction(null,
            features, null, {
                featureType: 'zhuguanduan_line',
                featureNS: 'http://locahost/geoserver/degao_mysql',
                srsName: 'EPSG:4326'
            });
        var serializer = new XMLSerializer();
        var featString = serializer.serializeToString(featObject);
        var request = new XMLHttpRequest();
        request.open('POST', 'http://locahost:7777/geoserver/wfs?service=wfs');
        request.setRequestHeader('Content-Type', 'text/xml');
        request.send(featString);
    }

删除要素

// 选择器
    var selectInteractionDel = new ol.interaction.Select({
        style: new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'red',
                width: 2
            })
        })
    });

    $('#selectDelete').change(function() {
        if (this.checked) {
            document.getElementById('addLayer').checked=false;
            document.getElementById('select').checked=false;
            document.getElementById('modify').checked=false;
            // 勾选选择复选框时,添加选择器到地图
            map.removeInteraction(selectInteractionDel);
            map.addInteraction(selectInteractionDel);
        } else {
            // 不勾选选择复选框的情况下,移出选择器和修改器
            map.removeInteraction(selectInteractionDel);
        }
    });

    onDeleteFeature =function() {
        // 删选择器选中的feature
        if (selectInteractionDel.getFeatures().getLength() > 0) {
            deleteWfs([selectInteractionDel.getFeatures().item(0)]);
            // 3秒后自动更新features
            setTimeout(function() {
                selectInteractionDel.getFeatures().clear();
                queryWfs();
            }, 1000);
        }
    }

// 添加到服务器端
    function deleteWfs(features) {
        var WFSTSerializer = new ol.format.WFS();
        var featObject = WFSTSerializer.writeTransaction(null,
            null, features, {
                featureType: 'zhuguanduan_line',
                featureNS: 'http://locahost/geoserver/degao_mysql',
                srsName: 'EPSG:4326'
            });
        var serializer = new XMLSerializer();
        var featString = serializer.serializeToString(featObject);
        var request = new XMLHttpRequest();
        request.open('POST', 'http://locahost:7777/geoserver/wfs?service=wfs');
        request.setRequestHeader('Content-Type', 'text/xml');
        request.send(featString);
    }

多边形新增

    var drawLayer1 = new ol.layer.Vector({
        source: new ol.source.Vector(),
        style: new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'blue',
                width: 5
            })
        })
    });
    map.addLayer(drawLayer1);

// 添加绘制新图形的interaction,用于添加新的线条
    var newId1 = 1;
    var drawFeature1 = null;
    var drawInteraction1 = new ol.interaction.Draw({
        type: 'Polygon', // 设定为线条
        style: new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'red',
                width: 10
            })
        }),
        source: drawLayer1.getSource()
    });

    drawInteraction1.on('drawend', function(e) {

        // 绘制结束时暂存绘制的feature
        drawFeature1 = e.feature;
        vectorLayer.getSource().addFeature(drawFeature1);
    });


    $('#addLayer1').change(function() {
        if (this.checked) {

            // 勾选新增复选框时,添加绘制的Interaction
            map.removeInteraction(drawInteraction1);
            map.addInteraction(drawInteraction1);
        } else {
            // 取消勾选新增复选框时,移出绘制的Interaction,删除已经绘制的feature
            map.removeInteraction(drawInteraction1);
            if (drawedFeature) {
                drawLayer1.getSource().removeFeature(drawFeature1);
            }
            drawFeature1 = null;
        }
    });

    queryWfs=function() {
        window.location.reload();
    }

    // 保存新绘制的feature
    onSaveNew1 = function() {
        var geometry = drawFeature1.getGeometry().clone();
         geometry.applyTransform(function(flatCoordinates, flatCoordinates2, stride) {
             for (var j = 0; j < flatCoordinates.length; j += stride) {
                 var y = flatCoordinates[j];
                 var x = flatCoordinates[j + 1];
                 flatCoordinates[j] = x;
                 flatCoordinates[j + 1] = y;
             }
         });

        // 设置feature对应的属性,这些属性是根据数据源的字段来设置的
        var newFeature = new ol.Feature();
        newFeature.setGeometryName('SHAPE');
        newFeature.set('SHAPE', null);
        newFeature.set('gid', 1);
        newFeature.setGeometry(new ol.geom.Polygon(geometry.getCoordinates()));//注Polygon和MultiPolygon是有区别的
        addWfs1([newFeature]);
    }


    // 添加到服务器端
    function addWfs1(features) {
        var WFSTSerializer = new ol.format.WFS();
        var featObject = WFSTSerializer.writeTransaction(features,
            null, null, {
                featureType: 'zhuguanduan_line',
                featureNS: 'http://locahost/geoserver/degao_mysql',
                srsName: 'EPSG:4326'
            });
        var serializer = new XMLSerializer();
        var featString = serializer.serializeToString(featObject);
        var request = new XMLHttpRequest();
        request.open('POST', 'http://locahost:7777/geoserver/wfs?service=wfs');
        request.setRequestHeader('Content-Type', 'text/xml');
        request.send(featString);
    }

转载自:https://blog.csdn.net/qq190781319/article/details/81583599

You may also like...