【GIS交互:在线编辑】openlayers交互编辑图层,进行增删改查并实时入库

已被阅读 2864 次 | 文章分类:OpenLayers | 2021-07-14 00:29

用geoserve将postgis数据库的数据发布为wfs服务,然后可以用openlayers 在线进行编辑并实时入库的;如果在webgis开发中,有相关在线矢量化的编辑需求,就可以采用的;

1 前期准备

(1) 首先将postgis数据库数据发布为geoserve的服务 可参考http://xiaobaigis.com/GiSarticles/GiSArticle?ID=53

(2) openlayers调用geoserver服务,参考http://xiaobaigis.com/GiSarticles/GiSArticle?ID=53

通过上面两步了解如何用geoserver将postgis数据发布为要素服务,如何利用openlayers操作图层要素,会对本节代码有更深入的理解;当然有基础直接看就可以喽,后面会附上完整代码(但是代码其实事很早之前用过的,目前没有geoserver发布的服务,所以没有运行效果,大家可以换成自己服务地址运行即可)

2 openlayes实现原理

2.1 首先创建增删改查的交互事件

2.2 然后在事件交互结束后,获取操作要素的空间信息,也就是几何坐标嘛

2.3 之后再组织数据格式,根据提供的规范提交接口,执行改变数据库数据操作

3 删除要素步骤详解

3.1 首先创建一个图层并在地图显示

                                        
var map = new ol.Map({
        target: "map",
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        view: new ol.View({
          center: [116, 37],
          zoom: 9,
          projection: "EPSG:4326"
        })
      });
      var url1="http://localhost:8090/geoserver/HT/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=HT%3Acrud_zhen&maxFeatures=50&outputFormat=application%2Fjson"
      var pointSource = new ol.source.Vector({
        url:url1,
        format: new ol.format.GeoJSON({
          geometryName: "geom" // postgis的空间存储字段名
        })
      });
      var pointLayer = new ol.layer.Vector({
        source: pointSource
      });
      map.addLayer(pointLayer);
                                        
                                    

3.2  选择要素后就执行删除操作

这里没有写多余的业务代码,选择要素后即可执行删除操作

                                        
var select = new ol.interaction.Select();
      map.addInteraction(select);
      // 选中要素后执行删除操作
      select.on("select", function(e) {
        if (select.getFeatures().getLength() == 0) {
          console.log("null");
        } else {
          let featureId = e.target
            .getFeatures()
            .getArray()[0]
            .getId();
          var feature;
          feature = pointSource.getFeatureById(featureId);
          // 从地图删除
          pointSource.removeFeature(feature);
          e.target.getFeatures().clear();
          // 从数据库删除
          transact(feature, "crud_zhen");
        }
      });
                                        
                                    

从地图删除,调取相关api即可,但是从数据库删除,需要组织一下数据,transact函数定义:

                                        
// feat为要增删改的要素
      // layerName为要进行操作的目标图层名称
      function transact(feature, layerName) {
        if (layerName == "") {
          return;
        }
        // 将选中的要素序列化为字符串格式
        var formatWFS = new ol.format.WFS();
        var formatGML = new ol.format.GML({
          featureNS: "http://localhost:8090/HT",
          featurePrefix: "HT",
          featureType: layerName,
          gmlOptions: { srsName: "EPSG:4326" }
        });
        var node = formatWFS.writeTransaction(null, null, [feature], formatGML);
        var s = new XMLSerializer();
        str = s.serializeToString(node);
        //  执行接口进行删除操作
        $.ajax("http://localhost:8090/geoserver/wfs", {
          type: "POST",
          contentType: "text/xml",
          data: str,
          success: function(res) {
            console.log(new XMLSerializer().serializeToString(res));
          }
        });
      }
                                        
                                    

上面代码,就两部分内容,第一组织数据格式,第二执行post请求接口;formatGML里面的参数,可以从geoserver获取得到;

其中writeTransaction方法,有四个参数,增加,更新,删除的数组,如果执行删除,那么其他就赋值空数组,最后一个是gml对象

小白GIS

全部代码如下

                                        
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>delete</title>
    <link rel="stylesheet" type="text/css" href="../../data/ol.css" />
    <style type="text/css">
      body,
      #map {
        border: 0px;
        margin: 0px;
        padding: 0px;
        width: 100%;
        height: 100%;
        font-size: 13px;
      }
    </style>
    <script type="text/javascript" src="../../data/jquery.js"></script>
    <script type="text/javascript" src="../../data/ol.js"></script>
  </head>
  <body>
    <div id="map"></div>
    <script type="text/javascript">
      var map = new ol.Map({
        target: "map",
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        view: new ol.View({
          center: [116, 37],
          zoom: 9,
          projection: "EPSG:4326"
        })
      });
      var url1="http://localhost:8090/geoserver/HT/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=HT%3Acrud_zhen&maxFeatures=50&outputFormat=application%2Fjson"
      var pointSource = new ol.source.Vector({
        url:url1,
        format: new ol.format.GeoJSON({
          geometryName: "geom" // postgis的空间存储字段名
        })
      });
      var pointLayer = new ol.layer.Vector({
        source: pointSource
      });
      map.addLayer(pointLayer);

      var select = new ol.interaction.Select();
      map.addInteraction(select);
      // 选中要素后执行删除操作
      select.on("select", function(e) {
        if (select.getFeatures().getLength() == 0) {
          console.log("null");
        } else {
          let featureId = e.target
            .getFeatures()
            .getArray()[0]
            .getId();
          var feature;
          feature = pointSource.getFeatureById(featureId);
          // 从地图删除
          pointSource.removeFeature(feature);
          e.target.getFeatures().clear();
          // 从数据库删除
          transact(feature, "crud_zhen");
        }
      });

      // feat为要增删改的要素
      // layerName为要进行操作的目标图层名称
      function transact(feature, layerName) {
        if (layerName == "") {
          return;
        }
        // 将选中的要素序列化为字符串格式
        var formatWFS = new ol.format.WFS();
        var formatGML = new ol.format.GML({
          featureNS: "http://localhost:8090/HT",
          featurePrefix: "HT",
          featureType: layerName,
          gmlOptions: { srsName: "EPSG:4326" }
        });
        var node = formatWFS.writeTransaction(null, null, [feature], formatGML);
        var s = new XMLSerializer();
        str = s.serializeToString(node);

        //  执行接口进行删除操作
        $.ajax("http://localhost:8090/geoserver/wfs", {
          type: "POST",
          contentType: "text/xml",
          data: str,
          success: function(res) {
            console.log(new XMLSerializer().serializeToString(res));
          }
        });
      }
    </script>
  </body>
</html>
                                        
                                    

4 在线编辑要素

原理跟删除元素一样,只是需要再注册一个modify事件,在修改元素后执行调接口操作;全部代码如下

                                        
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>modify</title>
    <link rel="stylesheet" type="text/css" href="../../data/ol.css" />
    <style type="text/css">
      body,
      #map {
        border: 0px;
        margin: 0px;
        padding: 0px;
        width: 100%;
        height: 100%;
        font-size: 13px;
      }
    </style>
    <script type="text/javascript" src="../../data/jquery.js"></script>
    <script type="text/javascript" src="../../data/ol.js"></script>
  </head>
  <body>
    <div id="map"></div>
    <script type="text/javascript">
      var map = new ol.Map({
        target: "map",
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        view: new ol.View({
          center: [116, 37],
          zoom: 9,
          minZoom: 0,
          maxZoom: 18,
          projection: "EPSG:4326"
        })
      });
      var pointSource = new ol.source.Vector({
        url:
          "http://localhost:8090/geoserver/wfs?" +
          "service=WFS&" +
          "version=1.1.0&" +
          "request=GetFeature&" +
          "typeNames=	HT:crud_railway&" +
          "outputFormat=json&" +
          "srsname=EPSG:4326",
        format: new ol.format.GeoJSON({
          geometryName: "geom"    //postgis的空间存储字段名
        })
      });
      var pointLayer = new ol.layer.Vector({
        source: pointSource
      });
      map.addLayer(pointLayer);
      var select = new ol.interaction.Select();
      var modify = new ol.interaction.Modify({
        features: select.getFeatures()
      });
      map.addInteraction(select);
      map.addInteraction(modify);

      modify.on("modifyend", function(e) {
        var layerName = "";
        var feature = e.features.item(0).clone();
        feature.setId(e.features.item(0).getId());
        var geomType = feature.getGeometry().getType().toLowerCase(); //openlayers绘制类型
          debugger;
        if (geomType == "multilinestring") {
          layerName = "crud_railway";
        } else if (geomType == "polygon") {
          layerName = "sishui";
        } else if (geomType == "point") {
          layerName = "crud_zhen";
        }
        // 调换经纬度坐标,以符合wfs协议中经纬度的位置
        feature
          .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;
            }
          });
        transact("update", feature, layerName);
      });

      // transType为增删改类型
      // feat为要增删改的要素
      // layerName为要进行操作的目标图层名称
      function transact(transType, feat, layerName) {
        if (layerName == "") {
          return;
        }
        var formatWFS = new ol.format.WFS();
        var formatGML = new ol.format.GML({
          featureNS: "http://localhost:8090/HT", // Your namespace
          featurePrefix: "HT",
          featureType: layerName,
          gmlOptions: { srsName: "EPSG:4326" }
        });
        switch (transType) {
          case "insert":
            node = formatWFS.writeTransaction([feat], null, null, formatGML);
            break;
          case "update":
            node = formatWFS.writeTransaction(null, [feat], null, formatGML);
            break;
          case "delete":
            node = formatWFS.writeTransaction(null, null, [feat], formatGML);
            break;
        }

        s = new XMLSerializer();

        str = s.serializeToString(node);

        $.ajax("http://localhost:8090/geoserver/wfs", {
          type: "POST",
          // dataType: 'xml',
          // processData: false,
          contentType: "text/xml",
          data: str,
          success: function(res) {
            console.log(new XMLSerializer().serializeToString(res));
          }
        });
      }
    </script>
  </body>
</html>

                                        
                                    

QQ:3410192267 | 技术支持 微信:popstarqqsmall

Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号