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
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端完成矢量要素的在线编辑操作。