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

研究与专注 8970

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

常用的数据结构以及常用的算法

常用的数据结构以及常用的算法 常用数据结构 数据结构是计算机存储、组织数据的方式。 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。 数据结构往往同高效的检索算法和索引技术有关。 一、线性表 线性结构: 最常用、最简单的一种数据结构。 线性表: 典型的线性结构。基本特点是线性表中的 数据元素有序且有限。结构中: ① 存在一个唯一的被称为“第一个”的数据元素; ② 存在一个唯一的被称为“最后一个”的数据元素; ③ 除第一个元素外,每

qq_47605698的博客 1450

openlayers6 第一篇绘制点线面

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

m0_65607651的博客 1598

【HAL库-STM】智能温控按键小风扇【胎教级教学】

硬件设备:DHT11,0.96寸oled屏,二/三/四线风扇(不挑),面包板 、f10的精英板等等。当人在的风扇面前时可以自行控制风扇,不在面前时又想开风扇就让他温控自行开启,(在这里有一个想法就是加上蓝牙和wifi控制的功能能够远程遥控,这个如果做的再全一点就要自主研发是一个多功能app,这里没有做。针对这个dht11,我一开始是卡在了这个check函数里面,一直是我给完dht11低电平和高电平后,dht11不回复我低电平和高电平,这个不是我的问题,当时代码是没毛病的,这个点一直卡着我。吐血五天实现小成品

weixin_52451652的博客 1740

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

扫地机器人全场景测试实战:从实验室到真实家庭的可靠性验证

本文深入探讨了扫地机器人从实验室到真实家庭的全场景测试方法,揭示了软硬件测试中的关键挑战。通过分析场景化测试的重要性,文章详细介绍了硬件耐久性、软件稳定性和环境适应性三大测试维度,并提供了真实家庭测试的实用方法论。消费者可重点关注清洁率、覆盖率等核心指标,同时了解测试工程师的私房建议,帮助选择更可靠的扫地机器人产品。

hhh00的博客 1077

torchsparse安装

torchsparse安装以及安装失败原因分析和解决

AI_BING_的博客 1万+

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

免费测试国外大模型Claude 3.7 Sonnet API:无需api key(秘钥)

Claude 3.7 Sonnet是Anthropic公司推出的第三代Claude系列AI模型中的中规模版本(2024年发布),在性能与效率间实现平衡。该模型基于改进的Transformer架构,支持128K上下文窗口,擅长复杂推理、数学计算和创意写作,在GSM8K数学基准测试中准确率达92%。其采用"宪法AI"伦理框架,通过多轮对抗训练减少有害输出,同时新增多模态理解能力(可解析图片/图表内容)。Claude 3.7 Sonnet是Anthropic推出的高效轻量级大模型,主打快速响应与成本优化。

Explinks的博客 1497

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

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

MagicMHD的博客 2775

BP神经网络回归预测+SHAP可解释分析+新数据预测(MATLAB完整源码)

BP神经网络回归预测+SHAP可解释分析+新数据预测(MATLAB完整源码)

机器学习之心的博客,关注并私信文章链接,获取对应文章源码和数据。 391

Vue3 - 实现用户上传本地视频文件到服务器+上传进度条+暂停续传+中断取消上传等,视频上传后可在线播放预览已上传的视频,视频文件上传视频回显示例代码(支持Element、Antd等upload组件

实现视频上传和视频预览,vue3实现视频上传功能,上传视频回显,视频流上传播放功能,vue与axios上传视频并显示上传进度,upload组件实现视频文件上传视频回显,upload组件实现视频上传及进度条展示,视频上传及实时进度条显示,视频上传过程中如何中断上传,VUE3+element 上传视频,大文件分片上传+断点续传,axios大文件切片上传,Vue3上传视频后如何播放预览,上传本地视频到后端服务器及在线预览播放视频+移除视频+进度条上传,将已选视频上传服务端并可预览视频,详细实现选择视频并上传到服务

🏆 前端领域优质创作者 3114

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

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

MagicMHD的博客 3205

YOLO26训练教程,训练自己的数据集教学,从源码下载,配置虚拟环境,准备数据集、训练、验证、推理测试 。实现0到1的完整教学过程。快速入门必看

本文详细介绍了YOLO26目标检测模型的配置与使用流程:1)下载YOLOv11源码并创建Python3.10虚拟环境;2)安装PyTorch2.5.1及相关依赖库;3)准备数据集并修改配置文件;4)编写训练脚本设置参数(640x640分辨率、500轮次);5)验证模型效果;6)使用训练好的模型进行推理测试;7)生成可视化热力图。整个过程涵盖了从环境搭建到模型应用的全流程,并提供了清华镜像源加速下载。

Ai缝合怪、助力小伙伴高效发论文 5285

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

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

gitblog_00374的博客 1243

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

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

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

@必意玲 8008

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

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

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

gitblog_00817的博客 1205

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

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博客 1805

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、付费专栏及课程。

余额充值