Openlayers在线编辑

在BS端可能有这样的需求——对发布的地图进行修改(例如行政边界变化、路网变化、建筑物的变化)。样就必须对发布的地图数据进行重新修改,重新发布。这样太麻烦且不方便。

Openlayers提供对WFS数据进行修改的方法

在Openlayers中提供了ol.interaction方法对矢量瓦片进行修改。对于矢量服务,主要用于feature选中(点击、鼠标悬浮等),做出相应的操作,例如高亮显示什么的,改变渲染样式。看一下其中的方法:

(节选翻译)Interaction for selecting vector features. By default, selected features are styled differently, so this interaction can be used for visual highlighting, as well as selecting features for other actions, such as modification or output. There are three ways of controlling which features are selected: using the browser event as defined by the condition and optionally the toggle, add/remove, and multi options; a layers filter; and a further feature filter using the filter option.
交互操作是为了选择适量要素。默认情况下,被选择要素的样式显示会不同,所以这种交互操作可以用于可视化高亮显示,以及为其他操作(如修改或输出)选择特性。这里有三种方法控制选择哪些要素:使用浏览器事件作为条件以及可选的切换、添加/删除和多个选项。选择更多的要素去操作。

  • ol.interaction.Modify
    interaction.Modify方法

    ol.interaction.Modify提供对矢量要素的修改方法。

实现思路

(一)因为是实现在线编辑,不是用GeoJSON数据。在PostGIS将自己的数据进行发布。发布的格式是WFS的矢量格式的地图服务;
(二)记录发布的工作区的URL地址和名称(这个两个参数尤为重要,保证了数据修改提交是否成功):


工作区的地址和名称

(三)编写代码进行修改和编辑。

代码思路

(一)使用Openlayers方法进行加载发布的矢量图层;
(二)使用interaction方法选择、修改矢量要素;

//选择要素
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: 'black',
                width: 2
            })
        }),
        features: selectInteraction.getFeatures()
    });

(三)对修改的要素提交到GeoServer进行保存,相当于重新发布(实质是通过XML进行数据的重新提交)

 function queryWfs() {
        // 支持重新查询
        if (wfsVectorLayer) {
            map.removeLayer(wfsVectorLayer);
        }

        // 创建新的图层来加载wfs的要素
        wfsVectorLayer = new ol.layer.Vector({
            source: new ol.source.Vector({
                format: new ol.format.GeoJSON({
                    geometryName: 'geom' // 将shp格式矢量文件导入PostgreGIS数据库中,对应的表中增加了一个字段名为geom的字段,所有这里的名称就是数据库表中增加的那个字段名称
                }),                                                                                              //PostgreGIS:xian_polygon为工作空间:图层名
         
                url:''//图层地址
          }),
            style: function(feature, resolution) {
                return new ol.style.Style({
                    stroke: new ol.style.Stroke({
                        color: 'blue',
                        width:2
                    })
                });
            }
        });
        map.addLayer(wfsVectorLayer);
    }

// 保存已经编辑的要素
    function onSave() {
        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: '',  //图层名
                featureNS: '',  // 注意这个值必须为创建工作区时的命名空间URI
                srsName: 'EPSG:4326'
            });
        // 转换为xml内容发送到服务器端
        var serializer = new XMLSerializer();
        var featString = serializer.serializeToString(featObject);
        var request = new XMLHttpRequest();
        request.open('POST', '');//URL地址
        // 指定内容为xml类型
        request.setRequestHeader('Content-Type', 'text/xml');
        request.send(featString);
    }
// 在服务器端删除feature
    function deleteWfs(features) {
      var WFSTSerializer = new ol.format.WFS();
      var featObject = WFSTSerializer.writeTransaction(null,
        null, features, {
          featureType: '',  //图层名
                featureNS: '',  // 注意这个值必须为创建工作区时的命名空间URI
                srsName: 'EPSG:4326'
        });
      var serializer = new XMLSerializer();
      var featString = serializer.serializeToString(featObject);
      var request = new XMLHttpRequest();
      request.open('POST', '');
      request.setRequestHeader('Content-Type', 'text/xml');
      request.send(featString);
    }

最后即可完成在BS端完成矢量要素的在线编辑操作。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Samples 通过EPSG.io搜索进行二次投影 视图(View)动画 使用动态 ArcGIS REST Map...
    changhr2013阅读 15,424评论 0 8
  • OGC——Open Geospatial Consortium——开放地理信息联盟,是一个非盈利的志愿的国际标准化...
    fangxu622阅读 2,362评论 0 3
  • source 是 Layer 的重要组成部分,表示图层的来源,也就是服务地址。除了在构造函数中指定外,还可以使用 ...
    changhr2013阅读 10,521评论 1 1
  • 乐活的状态 乍之一听,好似一种优酸乳,其实我们一直所要寻找的生活态度也无非如此。 不知不觉已到了而立之年,然而在他...
    最忆韭菜盒子阅读 126评论 0 0
  • 连翘12g浙贝母10g胖大海二枚,罗汉果20g甘草5g芦根25g制何首乌12g韭菜子10g一剂 连翘12g浙贝母1...
    KG5阅读 152评论 0 0