项目中需要添加行政区划,并在区域中心添加label标注,而使用cesium计算的中心点是最小外接圆圆心。
//cesium方法计算多边形中心
// 得到每块多边形的坐标集合
var polyPositions = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()).positions;
// 根据坐标集合构造BoundingSphere获取中心点坐标
var polyCenter = Cesium.BoundingSphere.fromPoints(polyPositions).center;
// 将中心点拉回到地球表面
polyCenter = Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter);
在面对凹多边形的时候,中心点往往在图形外,因此需要计算多边形重心来设置label位置。可以利用turf.js提供的空间分析方法进行计算:
turf.js在计算重心时是在二维平面上计算,而在加载geojson数据到cesium时,得到的是三维笛卡尔坐标系,因此需要将x,y坐标数据提取出来后再运用turf.js进行计算。cesium添加geojson是通过entity方法,因此先要获取多边形的坐标集合,并将x,y数据信息存储在数组中。而通过entity添加label时是通过Cartesian3坐标系进行定位,因此还需要将高度信息z值提取出来。最后再通过 Cesium.Cartesian3.fromArray(array, startingIndex, result)
方法将重心数组转换为Cartesian3坐标。
var value = [];
var center = [];
var a = 0;
var b = 0;
for(var j = 0 ; j <= entity.polygon._hierarchy._value.positions.length-1 ; j++){
value[j] = [entity.polygon._hierarchy._value.positions[j].x,entity.polygon._hierarchy._value.positions[j].y];
a = entity.polygon._hierarchy._value.positions[j].z;
b = b+a;
};
var polygon = turf.polygon([value]);
var centroid = turf.centroid(polygon);
center = [centroid.geometry.coordinates[0],centroid.geometry.coordinates[1],b/entity.polygon._hierarchy._value.positions.length+2000];
var labelpostion = Cesium.Cartesian3.fromArray(center);