OpenLayers学习笔记高级篇(四、地图开发实战之地图要素的增删改查)

OpenLayers基础教程——点要素图层的聚合显示 1、前言 在很多情况下,点要素图层中的要素数量可能会成百上千,这时候如果不做任何处理直接加载到地图上不仅会使用户视觉体验下降,而且也会造成地图界面的卡顿。下面这段代码创建了1000个随机点进行显示: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta charset="utf-8" 阅读详情

一切都准备好了,现在终于可以通过ol3加载配置好的数据了。上一节中最后的预览结果,大家已经看到了,此处我们自己通过ol来实现这个预览页面,直接上代码如下:

1、加载Geoserver发布的wfs地图服务,直接上代码如下:


<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="http://localhost:8080/geoserver/openlayers3/ol.css" type="text/css">
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
   

     <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
     <script type="text/javascript" src="js/jquery.js" charset="utf-8"></script>
    <title>加载wfs地图服务</title>
  </head>

s
  <body>
 <div id="map" style="width:100%;height:100%;"></div>

  <script>
    var vector = new ol.layer.Vector({
      source: new ol.source.Vector({
        format: new ol.format.GeoJSON(),
        url: 'http://localhost:8080/geoserver/wfs?service=wfs&version=1.1.0&request=GetFeature&typeNames=nyc_roads:nyc_roads&outputFormat=application/json&srsname=EPSG:4326'
      }),
      style: function(feature, resolution) {
        return new ol.style.Style({
          stroke: new ol.style.Stroke({
            color: 'blue',
            width: 1
          })
        });
      }
    });

    var map = new ol.Map({
      layers: [new ol.layer.Tile({
        source: new ol.source.OSM()
      }), vector],
      target: 'map',
      view: new ol.View({
        center: [-73.99710639567148, 40.742270050255556],
        maxZoom: 19,
        zoom: 14,
        projection: 'EPSG:4326'
      })
    });
  </script>

  </body>
</html>

下面运行代码看一下效果:

加载wfs服务成功!这里我们其实是加载的GeoJSON数据。

这里我们来看一下代码,和一般的矢量地图加载没什么两样,对于wfs而言,需要弄明白的是ol.source.Vector的url参数: 

http://localhost:8080/geoserver/wfs?service=wfs&version=1.1.0&request=GetFeature&typeNames=nyc_roads:nyc_roads&outputFormat=application/json&srsname=EPSG:4326

http://localhost:8080/geoserver/wfs?这一个不用多说,说明的是我们请求的是wfs地图服务;

service=wfs&version=1.1.0说明我们请求的服务是wfs服务,版本号是1.1.0;

request=GetFeature说明我们请求的是获取这个图层所有的要素;

typeNames=nyc_roads是因为我们之前配置的图层命名是这个;

outputFormat=application/json是说明我们的地图输出格式是json数据;

srsname=EPSG:4326这个是指定我们的地图输出坐标系为4326

这样我们就把url的所有参数解释了一遍!下面我们再思考一下,上面是全部查询,我们知道wfs也支持filter,所以我们可以在url里面设置filter,从而实现更细粒度的查询,比如这样:

http://localhost:8080/geoserver/wfs?service=wfs&version=1.1.0&request=GetFeature&typeNames=nyc_roads:nyc_roads&outputFormat=application/json&srsname=EPSG:4326&cql_filter=in ('nyc_roads.1162')

我们先在网页上输入上面的url看一下:

可以看到返回的是一串json字符串,我们格式化一个这个json数据如下图:

可以看到这是我们之前发布的wfs地图服务中一个id为1162的地图Feature!

这样我们就做到了过滤wfs图层中的数据的功能。大家可以使用这个url做一下测试!

2、通过wfs修改要素

在查询的基础上,我们更进一步对界面上呈现的要素进行修改,然后通过wfs协议保存到服务器端。直接上代码如下:


<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="http://localhost:8080/geoserver/openlayers3/ol.css" type="text/css">
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
   
     <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
     <script type="text/javascript" src="js/jquery.js" charset="utf-8"></script>
    <title>修改wfs地图要素</title>
  </head>
  <body>
  <input type="button" value="查询" onclick="queryWfs();" />
  <input id="select" type="checkbox" value="select" />选择
  <input id="modify" type="checkbox" value="modify" />编辑
  <input id="save" type="button" value="保存" onclick="onSave();" />

  <div id="map" style="width:100%;height:100%;"></div>

  <script>
  	//wfs地图服务图层,暂时设置为空
    var wfsVectorLayer = null;
    //修改的地图feature,暂时设置为空
    var modifiedFeatures = null;

    // 地图选取feature的交互类
    var selectInteraction = new ol.interaction.Select({
      style: new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: 'red',
          width: 2
        })
      })
    });

    // 地图选取feature修改器
    var modifyInteraction = new ol.interaction.Modify({
      style: new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: 'red',
          width: 5
        })
      }),
      //这个要修改的feature是我们之前通过ol.interaction.Select选中的feature
      features: selectInteraction.getFeatures()
    });
    //监听地图feature修改
    modifyInteraction.on('modifyend', function(e) {
      // 把修改完成的feature暂存起来
      modifiedFeatures = e.features;
    });

    var map = new ol.Map({
      layers: [new ol.layer.Tile({
        source: new ol.source.OSM()
      })],
      target: 'map',
      view: new ol.View({
        center: [-73.99710639567148, 40.742270050255556],
        maxZoom: 19,
        zoom: 13,
        projection: 'EPSG:4326'
      })
    });

    // 通过wfs查询所有的要素方法
    function queryWfs() {
      // 支持重新查询,即如果已经查询过了wfs图层,那我们就移除这个图层,然后重新查询添加
      if (wfsVectorLayer) {
        map.removeLayer(wfsVectorLayer);
      }

      // 创建新的图层来加载wfs的要素,即重新加载wfs矢量图层
      wfsVectorLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
          format: new ol.format.GeoJSON({
            geometryName: 'the_geom' // 因为数据源里面字段the_geom存储的是geometry,所以需要指定
          }),
          url: 'http://localhost:8080/geoserver/wfs?service=wfs&version=1.1.0&request=GetFeature&typeNames=nyc_roads:nyc_roads&outputFormat=application/json&srsname=EPSG:4326'
        }),
        //使用style+feature的方式修改添加的矢量图层的feature样式
        style: function(feature, resolution) {
          return new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: 'blue',
              width: 5
            })
          });
        }
      });
      map.addLayer(wfsVectorLayer);
    }

    //选择地图要素时执行的方法
    $('#select').change(function() {
      if (this.checked) {
        // 勾选选择复选框时,添加选择器到地图。先移除后添加
        map.removeInteraction(selectInteraction);
        map.addInteraction(selectInteraction);
      } else {
        // 不勾选选择复选框的情况下,移出选择器和修改器
        //移除选择器
        map.removeInteraction(selectInteraction);
        //把修改的checkbox置为false
        document.getElementById('modify').checked = false;
        //移除修改选择器
        map.removeInteraction(modifyInteraction);
        //把修改features置为空
        modifiedFeatures = null;
      }
    });

	//修改地图要素时执行的方法
    $('#modify').change(function() {
      if (this.checked) {
        // 勾选修改复选框时,添加选择器和修改器到地图
        //首先把选择地图要素的checkbox置为true
        document.getElementById('select').checked = true;
        //先移除修改器
        map.removeInteraction(modifyInteraction);
        //再添加修改器
        map.addInteraction(modifyInteraction);
        //先移除选择器
        map.removeInteraction(selectInteraction);
        //再添加选择器
        map.addInteraction(selectInteraction);
      } else {
        // 不勾选修改复选框时,移出修改器
        map.removeInteraction(modifyInteraction);
        modifiedFeatures = null;
      }
    });

    // 保存已经编辑的要素
    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: 'nyc_roads',    
          featureNS: 'http://geoserver.org/nyc_roads',  // 注意这个值必须为创建工作区时的命名空间URI
          srsName: 'EPSG:4326'      //参考坐标系
        });
      // 转换为xml内容发送到服务器端
      var serializer = new XMLSerializer();
      var featString = serializer.serializeToString(featObject);
      var request = new XMLHttpRequest();
      request.open('POST', 'http://localhost:8080/geoserver/wfs?service=wfs');
      // 指定内容为xml类型
      request.setRequestHeader('Content-Type', 'text/xml');
      request.send(featString);
    }
  </script>

</body>
</html>

运行一下看一下效果:

然后我们点击查询:

 

我们的wfs地图服务就加载上了,然后点击选择:

我们选择的feature样式会改变,然后再点击编辑:

我们就可以修改feature样式了,然后点击保存,这里我们打开开发者工具看一下网络交互!

可以看到发起了一个wfs的http请求到geoserver服务器,请求的url为:http://localhost:8080/geoserver/wfs?service=wfs,

发送的内容大致为:

<Transaction xmlns="http://www.opengis.net/wfs" service="WFS" version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
  <Update typeName="feature:nyc_roads" xmlns:feature="http://geoserver.org/nyc_roads">
    <Property>
      <Name>the_geom</Name>
      <Value>
        <MultiLineString xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
          <lineStringMember>
            <LineString srsName="EPSG:4326">
              <posList>-73.98528635501862 40.768332481384284 -73.98608637 40.76719342 -73.98449242115021 40.767849683761604 -73.98447096347809 40.76647639274598 -73.98299038410187 40.767334699630744 -73.98336657 40.76604531</posList>
            </LineString>
          </lineStringMember>
        </MultiLineString>
      </Value>
    </Property>
    <Property>
      <Name>modified</Name>
      <Value>5/28/2001</Value>
    </Property>
    <Property>
      <Name>name</Name>
      <Value>W 56 ST</Value>
    </Property>
    <Property>
      <Name>vsam</Name>
      <Value>15060</Value>
    </Property>
    <Property>
      <Name>sourcedate</Name>
      <Value>3/31/1996</Value>
    </Property>
    <Property>
      <Name>sourcetype</Name>
      <Value>Photogrammetric</Value>
    </Property>
    <Property>
      <Name>source_id</Name>
      <Value>96083</Value>
    </Property>
    <Property>
      <Name>borough</Name>
      <Value>Manhattan</Value>
    </Property>
    <Property>
      <Name>feat_code</Name>
      <Value>2900</Value>
    </Property>
    <Property>
      <Name>feat_desc</Name>
      <Value>Paved Road</Value>
    </Property>
    <Property>
      <Name>exported</Name>
      <Value>05/19/2004</Value>
    </Property>
    <Property>
      <Name>feat_type</Name>
      <Value>0</Value>
    </Property>
    <Filter xmlns="http://www.opengis.net/ogc">
      <FeatureId fid="nyc_roads.882" />
    </Filter>
  </Update>
</Transaction>

如果保存成功,则response的内容大致如下:

<?xml version="1.0" encoding="UTF-8"?>
<wfs:TransactionResponse 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:sf="http://www.openplans.org/spearfish" 
  xmlns:wfs="http://www.opengis.net/wfs" 
  xmlns:gml="http://www.opengis.net/gml" 
  xmlns:nyc_roads="http://geoserver.org/nyc_roads" 
  xmlns:ogc="http://www.opengis.net/ogc" 
  xmlns:ows="http://www.opengis.net/ows" 
  xmlns:tiger="http://www.census.gov" 
  xmlns:topp="http://www.openplans.org/topp" 
  xmlns:xlink="http://www.w3.org/1999/xlink" x
  mlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  version="1.1.0" 
  xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8080/geoserver/schemas/wfs/1.1.0/wfs.xsd">

  <wfs:TransactionSummary>
    <wfs:totalInserted>0</wfs:totalInserted>
    <wfs:totalUpdated>1</wfs:totalUpdated>
    <wfs:totalDeleted>0</wfs:totalDeleted>
  </wfs:TransactionSummary>
  <wfs:TransactionResults/>
  <wfs:InsertResults>
    <wfs:Feature><ogc:FeatureId fid="none"/></wfs:Feature>
  </wfs:InsertResults>
</wfs:TransactionResponse>

有的同学可能保存没有成功,那么就会response就会返回下面的信息:

<?xml version="1.0" encoding="UTF-8"?><ows:ExceptionReport xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ows="http://www.opengis.net/ows" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/ows http://localhost:8080/geoserver/schemas/ows/1.0.0/owsExceptionReport.xsd">
<ows:Exception exceptionCode="NoApplicableCode">
<ows:ExceptionText>{http://geoserver.org/nyc_roads}nyc_roads is read-only</ows:ExceptionText>
</ows:Exception>
</ows:ExceptionReport>

这是因为我们在的nyc_roads图层设置了只读服务,即我们不能在服务器上修改这个feature!但是我们是可以在本地修改保存的!

3、我们前面写完了查询、修改feature,下面我们再来写一个增加要素的功能,现在我们该介绍一下如何在前端绘制一个新的要素,并且保存到服务器端,直接上代码如下:


<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="http://localhost:8080/geoserver/openlayers3/ol.css" type="text/css">
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
   
     <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
     <script type="text/javascript" src="js/jquery.js" charset="utf-8"></script>
    <title>增加wfs地图要素</title>
  </head>
 <body>
  <input type="button" value="查询" onclick="queryWfs();" />
  <input id="add" type="checkbox" value="add" />新增
  <input id="saveNew" type="button" value="保存" onclick="onSaveNew();" />

  <div id="map" style="width:100%;height:100%;"></div>

  <script>
    var newId = 1;
    var wfsVectorLayer = null;
    //绘制feature,暂时设置为空
    var drawedFeature = null;

    // 创建用于新绘制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
        })
      })
    });

    // 添加绘制新图形的interaction,用于添加新的线条
    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;
    });

    var map = new ol.Map({
      layers: [new ol.layer.Tile({
        source: new ol.source.OSM()
      }), drawLayer],
      target: 'map',
      view: new ol.View({
        center: [-73.99710639567148, 40.742270050255556],
        maxZoom: 19,
        zoom: 13,
        projection: 'EPSG:4326'
      })
    });

    function queryWfs() {
      if (wfsVectorLayer) {
        map.removeLayer(wfsVectorLayer);
      }

      wfsVectorLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
          format: new ol.format.GeoJSON({
            geometryName: 'the_geom'
          }),
          url: 'http://localhost:8080/geoserver/wfs?service=wfs&version=1.1.0&request=GetFeature&typeNames=nyc_roads:nyc_roads&outputFormat=application/json&srsname=EPSG:4326'
        }),
        style: function(feature, resolution) {
          return new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: 'blue',
              width: 5
            })
          });
        }
      });
      map.addLayer(wfsVectorLayer);
    }


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

    // 保存新绘制的feature
    function onSaveNew() {
      // 转换坐标
      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.setId('nyc_roads.new.' + newId);
      newFeature.setGeometryName('the_geom');
      newFeature.set('the_geom', null);
      newFeature.set('name', newFeature.getId());
      newFeature.set('modified', newFeature.getId());
      newFeature.set('vsam', 0);
      newFeature.set('sourcedate', '');
      newFeature.set('sourcetype', '');
      newFeature.set('source_id', newId);
      newFeature.set('borough', '');
      newFeature.set('feat_code', 0);
      newFeature.set('feat_desc', '11');
      newFeature.set('feat_type', 0);
      newFeature.set('exported', 'true');
      newFeature.setGeometry(new ol.geom.MultiLineString([geometry.getCoordinates()]));

      addWfs([newFeature]);
      // 更新id
      newId = newId + 1;
      // 3秒后,自动刷新页面上的feature
      setTimeout(function() {
        drawLayer.getSource().clear();
        queryWfs();
      }, 3000);
    }

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

</body>
</html>

运行代码看一下效果:

点击查询:

点击新增:

可以自己绘制一个图形,然后点击保存,我们还是打开开发者工具查看网络传输情况:

在开发者工具界面可以看到http请求:

请求头文件为:

请求内容为:

<Transaction xmlns="http://www.opengis.net/wfs" service="WFS" version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
  <Insert>
    <nyc_roads xmlns="http://geoserver.org/nyc_roads" fid="nyc_roads.new.1">
      <the_geom>
        <MultiLineString xmlns="http://www.opengis.net/gml" srsName="EPSG:4326">
          <lineStringMember>
            <LineString srsName="EPSG:4326">
              <posList>-73.99970054626465 40.732669830322266 -73.98974418640137 40.71481704711914 -73.98545265197754 40.730438232421875 -73.98064613342285 40.71636199951172 -73.97360801696777 40.73284149169922</posList>
            </LineString>
          </lineStringMember>
        </MultiLineString>
      </the_geom>
      <name>nyc_roads.new.1</name>
      <modified>nyc_roads.new.1</modified>
      <vsam>0</vsam>
      <sourcedate></sourcedate>
      <sourcetype></sourcetype>
      <source_id>1</source_id>
      <borough></borough>
      <feat_code>0</feat_code>
      <feat_desc>11</feat_desc>
      <feat_type>0</feat_type>
      <exported>true</exported>
    </nyc_roads>
  </Insert>
</Transaction>

服务器端response的内容为:

<?xml version="1.0" encoding="UTF-8"?>
  <wfs:TransactionResponse xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sf="http://www.openplans.org/spearfish" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:nyc_roads="http://geoserver.org/nyc_roads" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:tiger="http://www.census.gov" xmlns:topp="http://www.openplans.org/topp" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8080/geoserver/schemas/wfs/1.1.0/wfs.xsd">
    <wfs:TransactionSummary>
      <wfs:totalInserted>1</wfs:totalInserted>
      <wfs:totalUpdated>0</wfs:totalUpdated>
      <wfs:totalDeleted>0</wfs:totalDeleted>
    </wfs:TransactionSummary>
    <wfs:TransactionResults/>
    <wfs:InsertResults>
      <wfs:Feature>
        <ogc:FeatureId fid="new0" />
      </wfs:Feature>
    </wfs:InsertResults>
  </wfs:TransactionResponse>

如果图层设置了只读的限制,那么在上传到服务端时response为:

<?xml version="1.0" encoding="UTF-8"?><ows:ExceptionReport xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ows="http://www.opengis.net/ows" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/ows http://localhost:8080/geoserver/schemas/ows/1.0.0/owsExceptionReport.xsd">
<ows:Exception exceptionCode="NoApplicableCode">
<ows:ExceptionText>{http://geoserver.org/nyc_roads}nyc_roads is read-only</ows:ExceptionText>
</ows:Exception>
</ows:ExceptionReport>

4、最后我们再来一个增删改查中的删除功能!直接上代码如下:


<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="http://localhost:8080/geoserver/openlayers3/ol.css" type="text/css">
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
   
     <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
     <script type="text/javascript" src="js/jquery.js" charset="utf-8"></script>
    <title>增加wfs地图要素</title>
  </head>
<body>
  <input type="button" value="查询" onclick="queryWfs();" />
  <input id="select" type="checkbox" value="select" />选择
  <input id="delete" type="button" value="删除选中Feature" onclick="onDeleteFeature();" />

  <div id="map" style="width:100%;height:100%;"></div>

  <script>
    var wfsVectorLayer = null;

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

    var map = new ol.Map({
      layers: [new ol.layer.Tile({
        source: new ol.source.OSM()
      })],
      target: 'map',
      view: new ol.View({
        center: [-73.99710639567148, 40.742270050255556],
        maxZoom: 19,
        zoom: 13,
        projection: 'EPSG:4326'
      })
    });

    function queryWfs() {
      if (wfsVectorLayer) {
        map.removeLayer(wfsVectorLayer);
      }

      wfsVectorLayer = new ol.layer.Vector({
        source: new ol.source.Vector({
          format: new ol.format.GeoJSON({
            geometryName: 'the_geom'
          }),
          url: 'http://localhost:8080/geoserver/wfs?service=wfs&version=1.1.0&request=GetFeature&typeNames=nyc_roads:nyc_roads&outputFormat=application/json&srsname=EPSG:4326'
        }),
        style: function(feature, resolution) {
          return new ol.style.Style({
            stroke: new ol.style.Stroke({
              color: 'blue',
              width: 5
            })
          });
        }
      });
      map.addLayer(wfsVectorLayer);
    }

    $('#select').change(function() {
      if (this.checked) {
        map.removeInteraction(selectInteraction);
        map.addInteraction(selectInteraction);
      } else {
        map.removeInteraction(selectInteraction);
      }
    });

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

    // 在服务器端删除feature
    function deleteWfs(features) {
      var WFSTSerializer = new ol.format.WFS();
      var featObject = WFSTSerializer.writeTransaction(null,
        null, features, {
          featureType: 'nyc_roads',
          featureNS: 'http://geoserver.org/nyc_roads',
          srsName: 'EPSG:4326'
        });
      var serializer = new XMLSerializer();
      var featString = serializer.serializeToString(featObject);
      var request = new XMLHttpRequest();
      request.open('POST', 'http://localhost:8080/geoserver/wfs?service=wfs');
      request.setRequestHeader('Content-Type', 'text/xml');
      request.send(featString);
    }
  </script>

</body>

</html>


运行代码看一下效果:

请大家自己测试删除feature的工作!

到此,我们就完成二零地图开发实战的所有增删改查工作!

我们关于OpenLayers的所有入门开发教程也将告一段落,以后有时间的话我会把一些项目中常用的功能集中到一个项目中,开发一个完全满足上线要求的系统!请大家把我们之前学过的一些功能多写几遍,最后达到融会贯通,然后再进行实际项目的开发锻炼!大家加油!

Openlayers之编辑要素 1、新建一个html页面,引入ol.js文件,然后在body中创建两个div标签和一个label标签; 2、代码实现 window.onload = function () { //初始化点要素 var pointFeature = new ol.Feature(new ol.geom.Poi 阅读详情

相关推荐

OpenLayers 3 之加载地图

摘要          一个加载地图的小例子,分析原理,并解析源码! 正文 例程如下: .map { height: 400px; width: 100%; } OpenLayers 3 example My Map

研究与专注 8968

4. Openlayers 点、线、面基本样式渲染(结合Vue 详细教程)

在本篇博客中,我们将学习如何在 OpenLayers 中使用样式系统,并在 Vue 项目中绘制点、线、面的基本样式。首先,我们将学习 OpenLayers 的样式系统,然后使用 Vue 创建一个地图组件,并在地图组件中添加点、线、面要素并为其设置样式。

全栈三维GIS开发工程师,擅长Cesium、OpenLayers、Three.js、WebGL、Vue、Django、GDAL和QGIS技术。在这个博客里,我将分享我的开发经验、技术心得和项目案例,希望能为GIS爱好者和开发者提供有价值的参考。 5849

Geoserver+openlayer+postGis要素增删改查

此代码主要是编写了通过geoServer发布数据服务,postGis作为空间数据的数据库,通过openlayer完成几个数据的增加,修改,删除,查询,包括属性查询,并且提供元数据测试。

在地图上基于OpenLayers实现点/线/面静态的绘制显示

在做GIS相关的工作过程中,是离不开矢量的数据的。矢量作为最基础的数据形式,一般通用在各个项目中。在导航软件开发或者应用中,点/线/面的标记,标绘,显示等都是不可缺少的。本文主要是来介绍在地图上基于OpenLayers实现点/线/面静态的绘制显示方法。

nanke_yh的博客 5012

GeoServer学习——发布shp格式的地图

NULL 博文链接:https://wallimn.iteye.com/blog/2279574

Unity跨平台存储避坑指南:persistentDataPath权限真相

Application.persistentDataPath是Unity中用于持久化数据的核心路径,表面提供跨平台抽象,实则底层访问机制因操作系统而异。其原理并非简单路径映射,而是受Android Scoped Storage、iOS Data Protection、Windows组策略及macOS隐私权限等多层安全模型动态约束。技术价值在于保障用户数据长期可靠存储,但若忽略平台差异,极易引发‘本地正常、真机崩溃’‘iOS可存、Android报错’等线上事故。典型应用场景包括游戏存档、离线缓存、自定义资源包

weixin_32073537的博客 351

openlayers6 第一篇绘制点线面

openlayers6 绘制点线面 并实现编辑效果

m0_65607651的博客 1598

IMU660RA姿态解算实战:从传感器滤波到欧拉角输出的完整实现

本文详细介绍了IMU660RA姿态解算的完整实现过程,从传感器滤波到欧拉角输出。通过实战案例和代码示例,展示了如何有效处理陀螺仪和加速度计的噪声问题,并选择合适的算法进行数据融合和姿态解算。特别强调了欧拉角输出中的坐标系对齐和动态补偿技巧,帮助工程师快速掌握IMU660RA的应用。

weixin_42524762的博客 386

openlayers学习笔记:

使用overlay <!DOCTYPE html> <html> <head> <title>学习overlay</title> <script src="..\bin\ol.js"></script> <link href="..\bin\ol.css"> <script src="https://cdn.staticfile.org/jquery/1.10.2/jq

Handsome2013的博客 2795

AVL-Excite新手必看:5步搞定发动机阀系系统建模(附B站视频教程)

本文为AVL-Excite新手提供发动机阀系系统建模的5步详细指南,涵盖软件环境搭建、基本结构建立、关键参数设置、仿真分析及常见问题排查。通过清晰的步骤说明和实用技巧,帮助工程师快速掌握建模方法,并附有精选B站视频教程链接,便于实践学习。

weixin_29305313的博客 508

H3C防火墙旁路部署实战:网关迁移到防火墙后,如何配置DHCP和VLAN间隔离策略?

本文详细介绍了H3C防火墙旁路部署实战,重点讲解网关迁移到防火墙后的DHCP配置和VLAN间隔离策略。通过实际案例和配置示例,帮助网络工程师解决传统核心交换机架构的性能瓶颈和安全管控问题,实现精细化访问控制。

weixin_42549451的博客 416

openlayers+vue实现在地图上删除text文本

openlayers+vue实现在地图上删除text文本标注 //根据图层名称移出图层 removeLayerByName(layerName) { let layerArr = this.map.getLayers().array_; for (let i = 0; i < layerArr.length; i++) { let ln = layerArr[i].values_.name; if (ln == layerName) {

weixin_46262744的博客 1106

Keras神经网络可视化模块keras.utils.visualize_util的安装配置方法

本文介绍了如何安装和配置keras.utils.visualize_util模块,并提供了一个简单的示例演示如何使用该模块来可视化神经网络的结构。在上述代码中,我们首先定义了一个简单的神经网络模型,该模型具有一个输入层、一个隐藏层和一个输出层,其中隐藏层具有512个神经元,输出层具有10个神经元。运行上述代码后,我们将在当前工作目录下找到一个名为model.png的文件,它显示了神经网络的结构图。这种方式有效地展示了整个过程,让我们能够更好地理解神经网络的结构,方便对其进行改进和调试。

. 892

OpenLayers学习笔记高级篇(四、地图开发实战之Geoserver配置与发布地图服务)

本节将讲解ol使用wfs同后台geoserver进行交互,从而实现要素的增删改查。由于geoserver需要服务器端,所以我们将从环境搭建开始讲解,使用公开的数据源,进行查询,修改,添加,删除操作的演示,使得大家最终学会。 1、Geoserver环境配置 由于wfs协议涉及到跨域的问题,在配置过程中,我们也将把跨域的环境配置好。虽然跨域的解决方式有很多,但此处选择一个稍微简单的方式,详见下面的...

MagicMHD的博客 2775

PreScan快速入门到精通第三十九讲基于车道线识别传感器的车道保持辅助算法Demo讲解

车道保持辅助系统使用一个前置的摄像头,一般安装在车内后视镜附近,用来检测车辆前方的车道线,并监测车辆在其车道上的位置。在有电动助力转向EPS的车辆中,它轻轻地,但明显地反转向,以保持车辆在车道上。在简单车辆动力学的Simulink模型中,一个25%的油门开度常数被设定为输入,作为车辆行驶的纵向动力。首先是近似的角度α,它是传感器航向(=车辆航向)与右侧车道车道线的切线的近似角。一个配备了车道线传感器和简单动力学模型的车辆(MAZDA),将在没有任何规定轨迹的情况下跟随道路车道线行驶。3D浏览器中的多视图。

小明师兄的博客 1842

【BlueZ】编译产物详解:可执行文件/库文件/工具的生成路径与用途

BlueZ二次开发编译产物机制解析 摘要:在BlueZ蓝牙协议栈二次开发中,90%的报错源于对编译产物类型和路径的混淆。本文系统剖析BlueZ的三阶段编译机制:1)配置阶段生成Makefile;2)编译阶段在.libs目录下产生临时库和可执行文件(不可直接运行);3)安装阶段将产物部署到系统标准路径。重点解析守护进程、命令行工具、动态库的核心路径差异,并针对五大高频问题(如临时库运行崩溃、动态库不匹配、系统覆盖等)给出解决方案。

byte轻骑兵的技术小窝 1万+

OpenLayers学习笔记初级篇(一、地图加载)

开源的地图包做的比较优秀比较好的就是OpenLayers了,下面我将用我的学习笔记带领一些没接触过OpenLayers的同学进行学习,目前初步将学习笔记分为初级基础篇,中级进阶篇和高级应用篇,我将通过一个个小的demo进行学习,比较有助于大家加深记忆和动手编码能力,下面我们进行初级基础的学习! 1、OpenLayers 3简介 OpenLayers 3简称ol3,它是一个开源的Web GIS引...

MagicMHD的博客 3205

jsqlparser 版本不兼容:net.sf.jsqlparser.statement.select.SelectItem 以及 select.SelectBody 解决方法

看Bug直接定位到最后面的错误提示,一开始以为是UnabletostartembeddedTomcat的基本错误,后续发现排查方向错误!问题比较复杂,不过这类问题可看:出现WebServerException:UnabletostartembeddedTomcat解决方法(全)

码农研究僧的博客 2673

OpenLayers 地图要素拖拽编辑功能:5个高级实现技巧与最佳实践

OpenLayers 是一个功能强大的开源地图库,提供了丰富的地图要素交互功能。本文将重点介绍如何使用 OpenLayers 实现专业级的地图要素拖拽编辑功能,帮助开发者提升 WebGIS 应用的用户体验。 ## 🗺️ 核心交互功能概述 OpenLayers 提供了多种交互式工具来操作地图要素,其中最核心的是 `Modify` 交互。通过 `ol/interaction/Modify` 模块

gitblog_00374的博客 1243

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

openlayers6【十三】地图矢量图层 Vector 详解

文章目录1. 认识什么是矢量地图2. 矢量图层的构成3. 矢量图层的常用参数4. 初始化一个矢量图层5. 总结 1. 认识什么是矢量地图 在 GIS 中,地图一般分为两大类:栅格地图和矢量地图 栅格地图:它们有一个共同特征,就是它们都是由很多个像素组成,像素大小是一致的,行高和列宽是一致的,从这个角度看,一幅遥感影像就像栅格。我们可以把一幅栅格图像考虑为一个矩阵,矩阵中的任一元素对应于图像中的一个点,而相应的值对应于该点的灰度级,数字矩阵中的元素叫做像素。 矢量地图:矢量图使用直线和曲线来描述图形,这些图形

@必意玲 8008

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

OpenLayers 地图要素选择交互高级技巧:框选、圈选、多边形选

在地理信息系统(GIS)应用中,高效选择地图要素是用户最核心的需求之一。你是否遇到过在密密麻麻的地图上逐一点击选择要素的繁琐?是否需要快速圈定一片区域内的所有目标?本文将系统介绍 OpenLayers 中三种高级选择交互技巧——框选、圈选和多边形选,帮助你摆脱低效操作,实现"一指掌控地图要素"的流畅体验。 ## 框选:矩形区域的精准选择 框选(Box Selection)是处理规则区域选择的高...

gitblog_00817的博客 1205

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

openlayers 入门教程(十一):Formats 篇

OpenLayers中的Formats主要用于处理地理空间数据的读写和解析,它包含了多种格式支持,比如WKT(Well-Known Text)、GeoJSON、KML、GML等。这些格式类允许开发者在客户端将地图要素转换为特定格式的字符串或者从字符串反序列化为地图要素。

大剑师兰特的GIS世界 2096

OpenLayers学习笔记中级篇(一、各种地图的加载)

学习了前面的初级篇,相信大家对OplenLayers已经有了一个初步的认识,下面我们再继续深入学习OpenLayers的相关功能! 我们这节主要是加载各种各样的地图,包括在线服务的地图,比如天地图、高德、OSM等,还有一些我们自己使用地图服务器发布的地图,比如使用Geoserver发布的wms地图服务,最后还介绍了常用矢量地图数据的加载,好了,让我们开始吧! 首先我们再来深入学习一下Sourc...

MagicMHD的博客 4590

OpenLayers学习笔记高级篇(三、地图动画)

在OpenLayers 3中,动画是随处可见的,比如平移地图时,地图移动会有惯性,停止移动后,还会继续沿着之前的方向移动一会。 比如下面这个demo地图具有回到原始点的功能,一个是有动画效果的,一个是没有动画效果的。我们先写出来然后做一个直接的视觉对比: 1、地图有无动画的对比: <!doctype html> <html xmlns=http://www.w3.org/1...

MagicMHD的博客 2529

OpenLayers3, 设置地图背景

本文基于OpenLayers3,实现地图加入背景图的功能。以上为基于openlayer3 实现设置地图背景图的简单案例,希望对您有帮助~

我哎GIS博客 1803

openlayers 鼠标浮动要素上弹窗显示要素信息

项目中要求鼠标hover到要素时候,在要素位置弹窗,并在框内显示要素的信息。怎么才能具体弹窗到那个位置呢,原来ol官方有个弹窗实例,跟着new就完事了。 上效果图 map 构造完之后popup添加到map中。 // 这段代码是mounted中执行的,只要是在初始化map 之后执行就行。 map.on('pointermove', this.ShowFeatureInfo); 要素有多种,为了避免和其他的引起冲突,做了很多判断。这里只对点要素进行数据处理。 // An highlighted block

Anonymous996的博客 6119
上一篇: OpenLayers学习笔记高级篇(四、地图开发实战之Geoserver配置与发布地图服务)
下一篇: Arcgis栅格数据的空间分析(一、掩膜分析、密度分析)
MagicMHD
博客等级 码龄9年 503粉丝 78原创
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值