Openlayers结合Geoserver实现修改元素

标签: Geoserver / Openlayers 分类: Gis 创建时间:2019-10-23 02:57:57 更新时间:2025-01-17 10:39:22

先来点铺垫,主要查询下有哪些东西,什么是WFS-T服务。

参考文章:
1.WFS reference:https://docs.geoserver.org/latest/en/user/services/wfs/reference.html
2.Modifying Feature Types:https://geoserver.geo-solutions.it/edu/en/vector_data/wfst.html
3.Getting Transaction Support enabled in WFS on GeoServer (Boundless OpenGeoSuite)?:https://gis.stackexchange.com/questions/141031/getting-transaction-support-enabled-in-wfs-on-geoserver-boundless-opengeosuite
4.通过wfs修改要素:http://weilin.me/ol3-primer/ch12/12-01-04.html (扯淡大叔,这个步骤讲到的非常的全面)
5.最近在学习OpenLayer教程,通过OpenLayer加载geoserver中图层,其中遇到的问题并解决在此做下记录:https://blog.csdn.net/wo_buzhidao/article/details/79268902

直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<!DOCTYPE html>
<html>
<head>
<title>WFS-T</title>
<meta charset="utf-8"/>
<link rel="stylesheet" href="../lib/ol/ol.css" type="text/css">
<script src="../lib/ol/ol.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<style>
body,html{
width:100%;
margin:0;
padding:0;
height: 100%;
position:absolute;
}
.map{
width:100%;
height:100%;
position:absolute;
}
.save{
position: absolute;
left: 200px;
z-index: 10;
}
</style>
</head>
<body>
<button class="save">保存</button>
<div class="map" id="map"></div>
<script src="../lib/lodash.min.js"></script>
<script src="../js/TMap.js"></script>
<script>
var tmap=new TMap('map',[120.349,30.34],18);

//添加矢量数据
var url="http://localhost:8088/geoserver/proheng/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=proheng%3Apipeline&maxFeatures=50&outputFormat=application%2Fjson";
$.ajax({
url:url,
success:function(data){
var geojsonFormat=new ol.format.GeoJSON();
var features=geojsonFormat.readFeatures(data);

//绘制图层
var vectorSource = new ol.source.Vector({
format: new ol.format.GeoJSON(),
});
vectorSource.addFeatures(features);
var vector = new ol.layer.Vector({
name:"pipeline",
source: vectorSource,
zIndex:11,
minResolution:tmap.getResolution(20),
maxResolution:tmap.getResolution(12),
style:new ol.style.Style({
stroke: new ol.style.Stroke({
lineCap:"square",
width:4,
color:"#000"
})
})
});
tmap.addLayer(vector);
},
error:function(err){
console.log(err);
}
});
// 添加选择
var selectInteraction=new ol.interaction.Select({
style:new ol.style.Style({
stroke:new ol.style.Stroke({
color: 'red',
width: 2
})
})
});
tmap.addInteraction(selectInteraction);
//添加修改交互
var modifyInteraction = new ol.interaction.Modify({
style:new ol.style.Style({
stroke:new ol.style.Stroke({
color: 'black',
width: 2
})
}),
features: selectInteraction.getFeatures()
});
var modifiedFeatures=null;
tmap.addInteraction(modifyInteraction);
modifyInteraction.on('modifyend',function (p1) {
modifiedFeatures = p1.features;
});
// 把修改提交到服务器端
function modifyWfs(features) {
var WFSTSerializer = new ol.format.WFS();
var featObject = WFSTSerializer.writeTransaction(null,
features, null, {
featureType: 'pipeline', //图层名
featureNS: 'proheng', // 注意这个值必须为创建工作区时的命名空间URI
srsName: 'EPSG:4326'
});
// 转换为xml内容发送到服务器端
var serializer = new XMLSerializer();
var featString = serializer.serializeToString(featObject);
var request = new XMLHttpRequest();
console.log(featString);
featString=featString.replace("<Name>geometry</Name>","<Name>the_geom</Name>");

request.open('POST', 'http://localhost:8088/geoserver/wfs?service=wfs');
// 指定内容为xml类型
request.setRequestHeader('Content-Type', 'text/xml');
request.send(featString);
}

$(".save").on("click",function(e){
console.log(modifiedFeatures);
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]);
}
});

</script>
</body>
</html>

其中添加天地图的代码就不在这里写了,主要思路就是添加底图,添加select,添加modifyInteraction,然后监听modifyend函数,最后在保存的时候,将修改的图形使用writeTransaction序列化为xml。示例xml如下:

1
<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:pipeline" xmlns:feature="proheng"><Property><Name>geometry</Name><Value><MultiLineString xmlns="http://www.opengis.net/gml" srsName="EPSG:4326"><lineStringMember><LineString srsName="EPSG:4326"><posList srsDimension="2">120.34757794 30.33886672 120.34854859113693 30.339445173740387 120.34748333 30.34026191</posList></LineString></lineStringMember></MultiLineString></Value></Property><Property><Name>FID_</Name><Value>0</Value></Property><Property><Name>LineNumber</Name><Value>1</Value></Property><Property><Name>EndLat</Name><Value>120.347483332</Value></Property><Property><Name>EndLon</Name><Value>30.3402619111</Value></Property><Property><Name>StartLon</Name><Value>30.3388667219</Value></Property><Property><Name>StartLat</Name><Value>120.347577944</Value></Property><Filter xmlns="http://www.opengis.net/ogc"><FeatureId fid="pipeline.18"/></Filter></Update></Transaction>

最后更新成功,返回的内容:

图形修改成功:

问题

(1) Feature type ‘pipeline’ is not available

主要是因为在写featureNS时写错了

1
2
3
4
5
6
var featObject = WFSTSerializer.writeTransaction(null,
features, null, {
featureType: 'pipeline', //图层名
featureNS: 'proheng', // 注意这个值必须为创建工作区时的命名空间URI
srsName: 'EPSG:4326'
});

其中的featureNS是工作空间的URI

其中的featureType,是图层的名字,不带工作空间

参考文章:
1.Geoserver WFS-T “Feature type ‘Workspace:Layer’ is not available” Error on update / delete:https://gis.stackexchange.com/questions/172112/geoserver-wfs-t-feature-type-workspacelayer-is-not-available-error-on-updat

(2) No such property: geometry

尝试解决方式是将xml中的feature:myLayer,改为myNameSpace:myLayer

1
2
var str=new XMLSerializer().serializeToString(node);
var data=str.replace("feature:myLayer","myNameSpace:myLayer");

这中方式是不对的。
实际上,查看这个xml,其中的图形属性是geometry

但是实际上图形属性的名称是the_geom而不是geometry

应该将其中的xml中的gemtory改为the_geom

如果是使用postgis发布的底图,那么这个图形属性的名称可能为geom,根据具体情况进行调整

参考文章:
1.No such property: geometry when updating feature in openlayers 3 - Geoserver:https://stackoverflow.com/questions/37250892/no-such-property-geometry-when-updating-feature-in-openlayers-3-geoserver

(3) {proheng}pipeline is read-only(这里的proheng和pipeline不需要知道具体含义,就是工作空间和图层的名字))

解决方式主要是打开geoserver的控制面板,左侧的Security->Data

然后点击“*.*.w”,这一栏,然后选择:Grant access to any role

重启geoserver

参考文章:
1.geoserver wfs-t is read-only exception:https://stackoverflow.com/questions/41972613/geoserver-wfs-t-is-read-only-exception
2.最近在学习OpenLayer教程,通过OpenLayer加载geoserver中图层,其中遇到的问题并解决在此做下记录:https://blog.csdn.net/wo_buzhidao/article/details/79268902
文章目录
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。