一、参考文件:
1.学习的教程为‘扯淡大叔’的OpenLayer教程,非常好,非常详细,在学习过程中遇到不懂的也请教过作者的帮助,很适合初学者学习,地址为:通过wfs修改要素
2.在遇到修改的图层提交后,network显示200,Context length:0,is read-only,这些问题,是在解决方法在这里
二、具体步骤
1.将shp格式文件加载到postgresGIS数据库,使用Geoserver中postGIS发布图层的方法发布加载的图层,具体可参考我之前的博客;
2.在通过扯淡大叔的教程编写代码,即可加载和显示发布的图层;
3.具体代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>更新WFS要素</title>
<link href="../css/ol.css">
<script src="../js/ol,js.js"></script>
<script src="../js/jquery-1.3.1.js"></script>
</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="height: 70%;">
</div>
</body>
<script>
var modifiedFeatures=null;
var wfsVectorLayer = null;
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()
});
var map=new ol.Map({
view:new ol.View({
projection:'EPSG:4326',
center:[129.631215,44.590727],
maxZoom: 19,
zoom: 13,
}),
target:'map',
layers:[new ol.layer.Tile({
source:new ol.source.OSM()
})]
})
modifyInteraction.on('modifyend',function (p1) {
modifiedFeatures = p1.features;
})
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: 'http://localhost:8087/geoserver/wfs?service=wfs&version=1.1.0&request=GetFeature&typeNames=PostgreGIS:xian_polygon&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);
document.getElementById('modify').checked = false;
map.removeInteraction(modifyInteraction);
modifiedFeatures = null;
}
});
$('#modify').change(function() {
if (this.checked) {
// 勾选修改复选框时,添加选择器和修改器到地图
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: 'xian_polygon', //图层名
featureNS: 'http://PostgreGIS.com', // 注意这个值必须为创建工作区时的命名空间URI
srsName: 'EPSG:4326'
});
// 转换为xml内容发送到服务器端
var serializer = new XMLSerializer();
var featString = serializer.serializeToString(featObject);
var request = new XMLHttpRequest();
request.open('POST', 'http://localhost:8087/geoserver/wfs?service=wfs');
// 指定内容为xml类型
request.setRequestHeader('Content-Type', 'text/xml');
request.send(featString);
}
</script>
</html>
三、发现问题
1.加载地图可以出现,查询要素可以出现,可以选择和编辑,点击保存后,network传输正确没有任何报错,但是返回值为空,显示提示为”/ows:ExceptionText>{http://PostgreGIS.com}xian_polygon is read-only“”,猜测应该是权限问题,百度后,在参考资料第二个链接中找到方法;
四、解决步骤
1.打开geoserver管理界面,点击左侧的“”Security“”中的“”Data“”栏,点击“Rule path”中的“..w”,勾选“Grant access to any role”下面的单选框,点击保存,清理缓存,再是修改后点击提交,保存成功。