Cesium使用Entity无法表达多面、多线、多点为单个实体,多面、多线、多点被解析成多个entity,可以使用CustomDatasource来存储解析后的entity。
this.highLightEntityDs = new Cesium.CustomDataSource('attributeHighLightEntities');
this.map.dataSources.add(this.highLightEntityDs)
对于arcgis server rest api 的几何体,为了构建一个较为通用的解析方法,我们将几何体转为GeoJson格式。
直接上代码了。
(1)首先实体转为GeoJson,引入第三方公开库terraformer-arcgis-parser.js可转换
var geometry = feature.geometry;
var featureJson = Terraformer.ArcGIS.toGeoJSON(geometry)
(2)GeoJson转为Entity,可实现多面、多线、多点、带孔洞面的解析
let geoJsonType = featureJson.type;
if (geoJsonType == "Polygon" || geoJsonType == "MultiPolygon") {
let featureJsonArr = [{
geometry: {
type: featureJson.type,
coordinates: featureJson.coordinates
}
}]
let polygonCesium = this.CreateCesiumPositionsByGeoJson(featureJsonArr)
for (var i = 0; i < polygonCesium.length; i++) {
const polygonGraphic = new Cesium.PolygonGraphics({
hierarchy: {
positions: Cesium.Cartesian3.fromDegreesArray(polygonCesium[i].positions),
holes: that.addHoles(polygonCesium[i].holes)
},
asynchronous: false,
material: new Cesium.ColorMaterialProperty(Cesium.Color.fromBytes(0, 255, 0, 125)),
})
entity = new Cesium.Entity({
name: "attributeHighLightEntity",
show: true,
polygon: polygonGraphic
})
that.highLightEntityDs.entities.add(entity)
}
} else if (geoJsonType == "LineString" || geoJsonType == "MultiLineString") {
if (geoJsonType == "LineString") {
featureJson.coordinates = [featureJson.coordinates];
}
// 三层[]
let entities = [],
position = []
// featureJson.coordinates.length大于1代表含多线
for (var i = 0; i < featureJson.coordinates.length; i++) {
for (var j = 0; j < featureJson.coordinates[i].length; j++) {
position.push(featureJson.coordinates[i][j][0], featureJson.coordinates[i][j][1]);
}
entity = new Cesium.Entity({
name: "attributeHighLightEntity",
show: true,
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray(position),
width: 10,
material: Cesium.Color.fromBytes(0, 255, 0, 125),
clampToGround: true,
},
})
entities.push(entity);
}
entities.forEach(e => that.highLightEntityDs.entities.add(e))
} else if (geoJsonType == "Point" || geoJsonType == "MultiPoint") {
if (geoJsonType == "Point") {
featureJson.coordinates = [featureJson.coordinates];
}
// 三层[]
let entities = [],
position = []
// featureJson.coordinates.length大于1代表含多点
for (var i = 0; i < featureJson.coordinates.length; i++) {
for (var j = 0; j < featureJson.coordinates[i].length; j++) {
position.push(featureJson.coordinates[i][j]);
}
entity = new Cesium.Entity({
name: "attributeHighLightEntity",
position: Cesium.Cartesian3.fromDegrees(position[0], position[1]),
show: true,
point: new Cesium.PointGraphics({
color: new Cesium.Color.fromBytes(255, 0, 0).withAlpha(0.5),
pixelSize: 20,
disableDepthTestDistance: Number.POSITIVE_INFINITY, //不进行深度检测
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
})
})
entities.push(entity);
}
entities.forEach(e => that.highLightEntityDs.entities.add(e))
}
解析多边形(带孔洞)
//可实现带孔洞的解析
CreateCesiumPositionsByGeoJson: function (features) {
const instances = [];
//要素个数
let geometys = []
if (features)
for (let i = 0; i < features.length; i++) {
if (features[i].geometry.type == "MultiPolygon") {
//大于1为多面MultiPolygon,多面的每个面单独作为一个几何体存储
for (let m = 0; m < features[i].geometry.coordinates.length; m++) {
let positions = []
let holes = []
let geometry = {
positions: [],
holes: [],
name: features[i].name
}
var multi = features[i].geometry.coordinates[m];
//大于1则说明存在内环,否则只有外环,外环序号始终为第一个,有内环时将构成孔洞
for (let r = 0; r < multi.length; r++) {
//获取外环,只有一个
if (r == 0) {
let polygonArr = multi[0].toString().split(',');
polygonArr = polygonArr.map(Number);
positions = polygonArr
geometry.positions = positions;
}
//获取内环,可能有多个
else {
let polygonArr = multi[r].toString().split(',');
polygonArr = polygonArr.map(Number);
//应该holes不会再有数值,如果发现再更改
geometry.holes.push({
positions: polygonArr,
holes: []
})
}
}
geometys.push(geometry)
}
} else if (features[i].geometry.type == "Polygon") {
let geometry = {
positions: [],
holes: [],
name: features[i].name
}
// length值为1
for (let m = 0; m < features[i].geometry.coordinates.length; m++) {
let coords = features[i].geometry.coordinates;
let positions = []
let holes = []
if (m == 0) {
let polygonArr = coords[0].toString().split(',');
polygonArr = polygonArr.map(Number);
positions = polygonArr
geometry.positions = positions;
} else {
let polygonArr = coords[m].toString().split(',');
polygonArr = polygonArr.map(Number);
//应该holes不会再有数值,如果发现再更改
geometry.holes.push({
positions: polygonArr,
holes: []
})
}
}
geometys.push(geometry)
}
}
console.log(geometys)
return geometys
},
addHoles: function (holes) {
var holesArr = []
for (var h in holes) {
holesArr.push(new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromDegreesArray(holes[h].positions)
))
}
return holesArr
},