使用场景
当我们使用WebGL对面数据服务进行查询的时候,会发现,完整的面数据可以进行查询以及前端能够正常绘制,但是遇到一些特殊的面对象,如下图的岛洞多边形的面数据,就会出现异常的情况。
原因
是iServer的数据服务中查询到的点对象中除了导洞多边形边界节点数据还有里面岛洞的节点数据,我们不能像普通的面对象一样直接构建。
1、 查看数据服务
我们先来了解一下数据服务中导洞多边形返回的结构:
图一为普通的面对象;图2为岛洞多边形。
这里,我们会发现,在返回的结构feature中,除了points节点数组外,还有一个partTopo和parts属性。
partTopo:表示的是对象的拓扑结构,1代表岛,-1代表洞;
parts:t即相应的子对象所包含的节点个数。
通过以上参数的解析,我们可以通过partTopo识别岛洞之后,利用parts中的数据对points进行分组。以上图为例,通过partTopo和part参数,可确定points中前7点对象是岛的节点,7至7+9为洞对象的节点。
通过对数据结构的分析,我们就可以在WebGL中去构建导洞对象了。具体实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>矢量面</title>
<link href="../../Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<link href="./css/bootstrap.min.css" rel="stylesheet">
<link href="./css/pretty.css" rel="stylesheet">
<script src="./js/jquery.min.js"></script>
<script src="./js/bootstrap.min.js"></script>
<script src="./js/bootstrap-select.min.js"></script>
<script src="./js/config.js"></script>
<script type="text/javascript" src="../../Build/Cesium/Cesium.js"></script>
</head>
<body>
<div id="cesiumContainer"></div>
<div id='loadingbar' class="spinner">
<div class="spinner-container container1">
<div class="circle1"></div>
<div class="circle2"></div>
<div class="circle3"></div>
<div class="circle4"></div>
</div>
<div class="spinner-container container2">
<div class="circle1"></div>
<div class="circle2"></div>
<div class="circle3"></div>
<div class="circle4"></div>
</div>
<div class="spinner-container container3">
<div class="circle1"></div>
<div class="circle2"></div>
<div class="circle3"></div>
<div class="circle4"></div>
</div>
</div>
<script>
function onload(Cesium) {
var viewer = new Cesium.Viewer('cesiumContainer', {
infoBox: false
});
//查询成功后,对节点进行重新弄分组,然后构建对象,添加到entity;
function onQueryComplete(features) {
console.log("features", features);
var feature = features[0];
var point3ds = [];
var pointholes = [];
var partTopoInfor = [];
var partTopo = feature.geometry.partTopo;
var parts = feature.geometry.parts
console.log("feature.geometry", feature.geometry);
if (partTopo.length > 0) {
for (var i = 0; i < partTopo.length; i++) {
partTopoInfor.push({
partTopoValue: partTopo[i],
partsValue: parts[i]
});
}
}
var j = 0;
console.log("partTopoInfor", partTopoInfor);
for (var i = 0; i < partTopoInfor.length; i++) {
console.log("partTopoValue", partTopoInfor[i].partTopoValue)
if (partTopoInfor[i].partTopoValue === 1) {
for (j; j < partTopoInfor[i].partsValue; j++) {
point3ds.push(feature.geometry.points[j].x, feature.geometry.points[j].y);
}
} else {
var holes = j;
console.log("j", j);
console.log("holescount", holes + partTopoInfor[i].partsValue);
for (j; j < holes + partTopoInfor[i].partsValue; j++) {
pointholes.push(feature.geometry.points[j].x, feature.geometry.points[j].y);
}
}
}
console.log("point3ds", point3ds);
console.log("pointholes", pointholes);
if (partTopo.length > 1) {
console.log("partTopo>1");
viewer.entities.add({
polygon: {
hierarchy: {
positions: Cesium.Cartesian3.fromDegreesArray(point3ds),
holes: [{
positions: Cesium.Cartesian3.fromDegreesArray(pointholes),
}],
},
material: new Cesium.Color(255 / 255, 0 / 255, 255 / 255, 0.6)
},
// clampToGround: true
});
} else {
console.log("partTopo<1");
viewer.entities.add({
polygon: {
hierarchy: {
positions: Cesium.Cartesian3.fromDegreesArray(point3ds)
},
material: new Cesium.Color(255 / 255, 0 / 255, 255 / 255, 0.6)
},
// clampToGround: true
});
}
}
//根据数据服务去查询获取到对应的对象;
//smid = 4为导洞多边形,smid为2的时候为普通的面对象;
// doSqlQuery("smid = 4");
doSqlQuery("smid = 2");
function doSqlQuery(sqlStr) {
var sqlParameter = {
"datasetNames": ["导洞多边形:New_Region"],
getFeatureMode: "SQL",
queryParameter: {
attributeFilter: sqlStr
}
};
var url =
"http://localhost:8090/iserver/services/data-Data/rest/data/featureResults.rjson?returnContent=true";
var queryData = JSON.stringify(sqlParameter);
$.ajax({
type: "post",
url: url,
data: queryData,
success: function(result) {
var resultObj = JSON.parse(result);
console.log("resultObj", resultObj);
if (resultObj.featureCount > 0) {
onQueryComplete(resultObj.features);
}
},
error: function(msg) {
console.log(msg);
},
})
}
$('#loadingbar').remove();
}
if (typeof Cesium !== 'undefined') {
window.startupCalled = true;
onload(Cesium);
}
</script>
</body>
</html>
其中的数据服务http://localhost:8090/iserver/services/data-Data/rest/data/featureResults.rjson?returnContent=true是自己发布的数据服务,这里可以通过桌面去提前制作好数据。
iDesktop忠构建岛洞多边形的方法:
1、 新建面数据集、双击添加到地图;
2、 图层设置位可编辑,然后绘制一个普通的多边形面对象(外面的岛对象),
3、 然后使用对象编辑忠的【画面切割】功能,对上一步绘制的面进行中间挖洞即可,完成后,将中间的那个面对象删除即可。