利用Geoerver+Mysql+openlayers实现gis空间数据线段、多边形的存储、编辑、平移等功能
程序员文章站
2022-06-11 17:09:27
...
Geoerver+Mysql+openlayers实现gis空间数据线段、多边形的存储、编辑、平移
本人新手一枚,本篇文章是对自己遇到的问题进行简单梳理,错误的地方还望不吝赐教,本篇实现内容主要参考‘扯淡大叔’写的文章,因不同的环境,实现效果需自己调整,大叔的链接:http://weilin.me/ol3-primer/ch12/12-01-05.html。
首先,原来我用的是Geoerver+postgis+mysql,后来为了使用方便,索性将空间数据和业务数据统一保存到mysql,实现方法如下:https://blog.csdn.net/GISuuser/article/details/80728267
因为涉及到空间数据的编辑保存,所以在做保存操作的时候会接触到基础性问题先理一下:
1、‘readonly’只读。保存数据的时提示无法保存,提示只读,这是需要在geoserver的data内设置一下权限,具体操作可查看(测试可行):
https://blog.csdn.net/shaxiaozilove/article/details/61619388
2、跨域问题。跨域问题经常会碰到,访问被拒,解决办法:
https://www.cnblogs.com/ytwy/p/6823955.html
https://blog.csdn.net/mengdong_zy/article/details/51784781
Mysql数据库–数据类型一致:保存几何数据的字段‘SHAPE’(实际情况名称可能略有不同),其数据类型最好设置成geomtry类型,这样可以在同一个表内保存任意类型的数据,包括多段线,多边形,点,圆等,如果设置的数据类型是Polygon或者其他的指定单一类型,就无法保存其他数据类型Line,Circle的数据。
前端代码
<button type="submit " class="btn btn-primary">图形新增</button>
<input id="addLayer" type="checkbox" value="add" />新增
<input id="saveNew" type="button" value="保存" onclick="onSaveNew();" />
<input type="button" value="刷新" onclick="queryWfs();" />
<button type="submit " class="btn btn-primary">图形删除</button>
<input id="selectDelete" type="checkbox" value="select" />选择
<input id="delete" type="button" value="删除选中Feature" onclick="onDeleteFeature();" />
<button type="submit " class="btn btn-primary">图形编辑</button>
<input id="select" type="checkbox" value="select" />选择
<input id="modify" type="checkbox" value="modify" />编辑
<input id="save" type="button" value="保存" onclick="onSave();" />
<input id="moveInteraction" type="checkbox" value="moveInteraction"/>平移
<input id="addLayer1" type="checkbox" value="add" />新增多边形
<input id="saveNew1" type="button" value="保存" onclick="onSaveNew1();" />
新增要素
var onSaveNew;//保存函数
var queryWfs;
var modifiedFeatures = null;
var onDeleteFeature;
var onSave;
var onSaveNew1;//多边形测试
var onSaveNew2;//圆测试
//因为要进行编辑修改,因为选用wfs类型图层
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
format: new ol.format.GeoJSON({
geometryName: 'SHAPE' // 因为数据源里面字段'SHAPE'存储的是几何图形数据,所以需要指定
}),
url: 'http://locahost:7777/geoserver/degao_mysql/ows?service=WFS&version=1.0.0&request=GetFeature&outputFormat=application/json&typeName=degao_mysql:zhuguanduan_line&srsname=EPSG:4326'
}),
style: function(feature, resolution) {//两个参数暂时没用的上
return new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'blue',
width: 2
})
});
}
});
// 底图这里我选用的是天地图
var layers = [new ol.layer.Tile(
{
title: "tianditu",
source: new ol.source.XYZ(
{
url: "http://t1.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}"
})
})
]
;
//图层主入口
var map = new ol.Map({
layers: layers,
target: 'editData',
view: new ol.View({
projection: 'EPSG:4326',
//center: [13172306.74073, 4074323.92117], //4326的视角入口
center: [118.34589, 34.34524], //3857的视角入口
zoom: 14
})
});
map.addLayer(vectorLayer);
//天地图文字标注
var tian_di_tu_annotation = new ol.layer.Tile(
{
title: "天地图文字标注",
source: new ol.source.XYZ(
{
url: 'http://t3.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}'
})
});
map.addLayer(tian_di_tu_annotation);
// 创建用于新绘制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
})
})
});
map.addLayer(drawLayer);
// 添加绘制新图形的interaction,用于添加新的线条
var newId = 1;
var drawedFeature = null;
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;
});
/* drawInteraction.on('drawstart', function(e) {
//清除先前未保存的图形
if (drawedFeature) {
drawLayer.getSource().removeFeature(drawedFeature);
}
drawedFeature = null;
});*/
$('#addLayer').change(function() {
if (this.checked) {
document.getElementById('selectDelete').checked=false;
document.getElementById('select').checked=false;
document.getElementById('modify').checked=false;
// 勾选新增复选框时,添加绘制的Interaction
map.removeInteraction(drawInteraction);
map.addInteraction(drawInteraction);
} else {
// 取消勾选新增复选框时,移出绘制的Interaction,删除已经绘制的feature
map.removeInteraction(drawInteraction);
if (drawedFeature) {
drawLayer.getSource().removeFeature(drawedFeature);
}
drawedFeature = null;
}
});
queryWfs=function() {
window.location.reload();
}
// 保存新绘制的feature
onSaveNew = function() {
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.setGeometryName('SHAPE');
newFeature.set('SHAPE', null);
newFeature.setGeometry(new ol.geom.LineString(geometry.getCoordinates()));//获取几何图形的坐标数组
addWfs([newFeature]);
// 3秒后,自动刷新页面上的feature
setTimeout(function() {
drawLayer.getSource().clear();
// queryWfs();
}, 1000);
}
// 添加到服务器端
function addWfs(features) {
var WFSTSerializer = new ol.format.WFS();
var featObject = WFSTSerializer.writeTransaction(features,
null, null, {
featureType: 'degao_mysql:zhuguanduan_line',
featureNS: 'http://locahost/geoserver/degao_mysql',
srsName: 'EPSG:4326'
});
var serializer = new XMLSerializer();
var featString = serializer.serializeToString(featObject);
var request = new XMLHttpRequest();
request.open('POST', 'http://locahost:7777/geoserver/wfs?service=wfs');
request.setRequestHeader('Content-Type', 'text/xml');
request.send(featString);
}
修改和平移对象
// 新建openlayers选择器
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: 'red',
width: 5
})
}),
features: selectInteraction.getFeatures()
});
modifyInteraction.on('modifyend', function(e) {
// 把修改完成的feature暂存起来
modifiedFeatures = e.features;
});
$('#select').change(function() {
if (this.checked) {
//控制其他编辑功能,防止冲突
document.getElementById('addLayer').checked=false;
document.getElementById('selectDelete').checked=false;
// 勾选选择复选框时,添加选择器到地图
map.removeInteraction(selectInteraction);
map.addInteraction(selectInteraction);
} else {
// 不勾选选择复选框的情况下,移出选择器和修改器
map.removeInteraction(selectInteraction);
document.getElementById('modify').checked = false;
map.removeInteraction(modifyInteraction);
}
});
$('#modify').change(function() {
if (this.checked) {
document.getElementById('addLayer').checked=false;
document.getElementById('selectDelete').checked=false;
// 勾选修改复选框时,添加选择器和修改器到地图
document.getElementById('select').checked = true;
map.removeInteraction(modifyInteraction);
map.addInteraction(modifyInteraction);
map.removeInteraction(selectInteraction);
map.addInteraction(selectInteraction);
} else {
// 不勾选修改复选框时,移出修改器
map.removeInteraction(modifyInteraction);
modifiedFeatures = null;
}
});
//平移功能
var translate = new ol.interaction.Translate({
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 2
})
})
});
$('#moveInteraction').change(function() {
if(this.checked){
map.removeInteraction(translate);
document.getElementById('select').checked = true;
map.addInteraction(translate);
}else{
map.removeInteraction(translate);
}
});
translate.on('translateend', function(e) {
// 把修改完成的feature暂存起来
modifiedFeatures = e.features;
});
// 保存已经编辑的要素
onSave = function() {
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: 'zhuguanduan_line',
featureNS: 'http://locahost/geoserver/degao_mysql',
srsName: 'EPSG:4326'
});
var serializer = new XMLSerializer();
var featString = serializer.serializeToString(featObject);
var request = new XMLHttpRequest();
request.open('POST', 'http://locahost:7777/geoserver/wfs?service=wfs');
request.setRequestHeader('Content-Type', 'text/xml');
request.send(featString);
}
删除要素
// 选择器
var selectInteractionDel = new ol.interaction.Select({
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 2
})
})
});
$('#selectDelete').change(function() {
if (this.checked) {
document.getElementById('addLayer').checked=false;
document.getElementById('select').checked=false;
document.getElementById('modify').checked=false;
// 勾选选择复选框时,添加选择器到地图
map.removeInteraction(selectInteractionDel);
map.addInteraction(selectInteractionDel);
} else {
// 不勾选选择复选框的情况下,移出选择器和修改器
map.removeInteraction(selectInteractionDel);
}
});
onDeleteFeature =function() {
// 删选择器选中的feature
if (selectInteractionDel.getFeatures().getLength() > 0) {
deleteWfs([selectInteractionDel.getFeatures().item(0)]);
// 3秒后自动更新features
setTimeout(function() {
selectInteractionDel.getFeatures().clear();
queryWfs();
}, 1000);
}
}
// 添加到服务器端
function deleteWfs(features) {
var WFSTSerializer = new ol.format.WFS();
var featObject = WFSTSerializer.writeTransaction(null,
null, features, {
featureType: 'zhuguanduan_line',
featureNS: 'http://locahost/geoserver/degao_mysql',
srsName: 'EPSG:4326'
});
var serializer = new XMLSerializer();
var featString = serializer.serializeToString(featObject);
var request = new XMLHttpRequest();
request.open('POST', 'http://locahost:7777/geoserver/wfs?service=wfs');
request.setRequestHeader('Content-Type', 'text/xml');
request.send(featString);
}
多边形新增
var drawLayer1 = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'blue',
width: 5
})
})
});
map.addLayer(drawLayer1);
// 添加绘制新图形的interaction,用于添加新的线条
var newId1 = 1;
var drawFeature1 = null;
var drawInteraction1 = new ol.interaction.Draw({
type: 'Polygon', // 设定为线条
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 10
})
}),
source: drawLayer1.getSource()
});
drawInteraction1.on('drawend', function(e) {
// 绘制结束时暂存绘制的feature
drawFeature1 = e.feature;
vectorLayer.getSource().addFeature(drawFeature1);
});
$('#addLayer1').change(function() {
if (this.checked) {
// 勾选新增复选框时,添加绘制的Interaction
map.removeInteraction(drawInteraction1);
map.addInteraction(drawInteraction1);
} else {
// 取消勾选新增复选框时,移出绘制的Interaction,删除已经绘制的feature
map.removeInteraction(drawInteraction1);
if (drawedFeature) {
drawLayer1.getSource().removeFeature(drawFeature1);
}
drawFeature1 = null;
}
});
queryWfs=function() {
window.location.reload();
}
// 保存新绘制的feature
onSaveNew1 = function() {
var geometry = drawFeature1.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.setGeometryName('SHAPE');
newFeature.set('SHAPE', null);
newFeature.set('gid', 1);
newFeature.setGeometry(new ol.geom.Polygon(geometry.getCoordinates()));//注Polygon和MultiPolygon是有区别的
addWfs1([newFeature]);
}
// 添加到服务器端
function addWfs1(features) {
var WFSTSerializer = new ol.format.WFS();
var featObject = WFSTSerializer.writeTransaction(features,
null, null, {
featureType: 'zhuguanduan_line',
featureNS: 'http://locahost/geoserver/degao_mysql',
srsName: 'EPSG:4326'
});
var serializer = new XMLSerializer();
var featString = serializer.serializeToString(featObject);
var request = new XMLHttpRequest();
request.open('POST', 'http://locahost:7777/geoserver/wfs?service=wfs');
request.setRequestHeader('Content-Type', 'text/xml');
request.send(featString);
}