经常有客户咨询,说SuperMap iClient只有对点数据集的修改 & 添加,对于面数据的操作不清楚改如何去做,下面我就以iClient for MapboxGL 和其Draw控件来实现面数据加载与编辑的功能。
效果截图
实现面数据加载与编辑思路:
1. 数据查询;
2. Draw控件添加查询面数据;
3. 修改面对象数据并保存;
4. 要素更新。
1. 数据查询
本次通过iServer的几何查询获取该几何面对象所相交数据集的面对象,可以参考官网代码( https://iclient.supermap.io/examples/mapboxgl/editor.html#02_getFeatureByGeometry )再此就不做多余介绍,如果需要使用其他的查询方案可以iClent 官网范例代码实现。
2. Draw控件添加查询面数据
mapbox-gl-draw控件的使用可以参考其官方API文档: https://github.com/mapbox/mapbox-gl-draw/blob/main/docs/API.md ,将上一步查询查询的结果添加到Draw控件中需要使用到其add()接口,其详细介绍如下图:
实现代码如下:
<!-- 引入Draw控件包 -->
<link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.3.0/mapbox-gl-draw.css' type='text/css' />
<script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.3.0/mapbox-gl-draw.js'></script>
// mapbox 绘制要素图形控件
var Draw = new MapboxDraw();
map.addControl(Draw,'top-left');
// 遍历添加第一步查询结果的面数据
for (var i=0; i< serviceResult.result.features.features.length; i++){
Draw.add(serviceResult.result.features.features[i]);
}
3. 修改面对象数据并保存
通过draw控件的“draw.selectionchange”去监听选中的对象,Draw.getSelected()获取选中的面对象数据,创建table表显示属性值,监听input的change事件去修改properties。
实现代码如下:
var fea,propertiesList = [];
map.on("draw.selectionchange",function(e){
fea = Draw.getSelected()
if (fea && fea.features && fea.features[0]) {
var properties = fea.features[0].properties
// 判断系统属性字段SM开头除了SMID & SMUSERID不显示
var reg = new RegExp("^(?=SM)")
for (var iable in properties) {
if (!reg.test(iable) || iable == "SMID" || iable == "SMUSERID"){
propertiesList.push(iable)
}
}
// 判断是否已经创建了table表
if (document.getElementById("propertiesTable")){
document.getElementById("propertiesTable").parentNode.removeChild(document.getElementById("propertiesTable"));
}
// 创建页面table表
var tabl = document.createElement("table");
tabl.setAttribute("id", "propertiesTable");
var tablebody = document.createElement("tbody");
var tablehead = document.createElement("thead");
var tr,tdP,tdV,tdtext;
var trHead = document.createElement("tr");
var tdHeadP = document.createElement("td");
var tdHeadV = document.createElement("td");
var tdHeadPTX = document.createTextNode("PROPERTY");
var tdHeadVTX = document.createTextNode("VALUE");
tdHeadP.appendChild(tdHeadPTX)
tdHeadV.appendChild(tdHeadVTX)
trHead.appendChild(tdHeadP)
trHead.appendChild(tdHeadV)
tablehead.appendChild(trHead)
tabl.appendChild(tablehead)
for (var i=0; i < propertiesList.length; i++) {
tr = document.createElement("tr");
tdP = document.createElement("td")
tdV = document.createElement("td")
tdtext = document.createTextNode(propertiesList[i]);
tdP.appendChild(tdtext)
tr.appendChild(tdP)
if (propertiesList[i] == "SMID") {
tdtext = document.createTextNode(properties[propertiesList[i]]);
tdV.appendChild(tdtext)
} else {
var inp = document.createElement("input");
inp.value = properties[propertiesList[i]]
inp.setAttribute("onChange", "inputChange("+ i +")")
inp.setAttribute("id", "input"+i)
tdV.appendChild(inp)
}
tr.appendChild(tdV)
tablebody.appendChild(tr)
}
tabl.appendChild(tablebody)
document.getElementsByTagName("body")[0].appendChild(tabl)
}
})
// 修改更新properties
function inputChange(id){
var inValue = document.getElementById("input" + id).value;
var ids = Draw.getSelectedIds();
Draw.delete(Draw.getSelectedIds())
if (fea){
fea.features[0].properties[propertiesList[id]] = inValue
}
Draw.add(fea)
4. 要素更新
使用iClient的要素数据集类(FeatureService)的地物编辑方法(editFeatures)去更新数据集数据,其传参EditFeaturesParameters详细介绍如下
实现代码如下:
function submit(){
var drs = Draw.getAll();
var addFeatureParams = new SuperMap.EditFeaturesParameters({
features: drs.features,
dataSourceName: "World",
dataSetName: "Countries",
editType: "update",
returnContent: true
});
var featureService = new mapboxgl.supermap.FeatureService(dataUrl);
featureService.editFeatures(addFeatureParams, function (serviceResult) {
if (serviceResult.result.succeed) {
fea,propertiesList = []
Draw.deleteAll()
if (document.getElementById("propertiesTable")){
document.getElementById("propertiesTable").parentNode.removeChild(document.getElementById("propertiesTable"));
}
query()
}
});
}
以上就是实现加载编辑数据的完整流程,本文只是提供解决加载更新数据集,需要注意的是针对实际项目中应该是将修改后的对象提交更新操作,而不是把Draw里面所有的features均提交更新。