使用するシーン
WebGLを使用してサーフェス データ サービスにクエリを実行すると、完全なサーフェス データをクエリでき、フロント エンドを正常に描画できることがわかりますが、次の図に示すアイランド ホール ポリゴンのサーフェス データなどの特殊なサーフェス オブジェクトに遭遇すると、異常な状況が発生します。
理由
iServerのデータサービスでクエリされる点オブジェクトであり、ガイドホールのポリゴン境界ノードデータや内島ホールのノードデータに加え、通常のサーフェスオブジェクトのように直接構築することはできません。
1. データサービスを見る
まず、データ サービスのガイド ホール ポリゴンによって返される構造を理解しましょう。
図 1 は通常のサーフェス オブジェクト、図 2 は島穴ポリゴンです。
ここで、返された構造フィーチャには、ポイント ノード配列に加えて、partTopo および Parts 属性も存在することがわかります。
partTopo: オブジェクトのトポロジを表します。1 はアイランドを表し、-1 はホールを表します。
Parts: t は、対応するサブオブジェクトに含まれるノードの数です。
上記のパラメーターの分析を通じて、 partTopo によってアイランド ホールを特定した後、パーツ内のデータを使用して点をグループ化できます。上図を例にとると、partTopo およびpart パラメータを通じて、最初の 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. 次に、オブジェクトエディタの[スクリーンカット]機能を使用して、前手順で描画した面の中央に穴を掘り、完了したら、中央の面オブジェクトを削除します。