一、创作思路
1、创建一个自定义CustomPrimitive
2、然后根据两个点,生成矩形
3、方便后期绘制矩形
二、实现代码
1、在vue的包中加入turf.
npm install @turf/turf
1、创建一个CustomRectanglePrimitive类,并加入更新的代码
import {
Color,
GeometryInstance,
GroundPolylineGeometry,
GroundPolylinePrimitive,
Material,
PolylineMaterialAppearance,
} from "cesium";
import { getRectanglePositions } from "@/components/MilitaryPlot/utils/PlotUtils";
export default class CustomRectanglePrimitive {
constructor(options) {
this._props = options;
/**
* 渲染列表
* @type {*[]}
* @private
*/
this._primitiveCollection = [];
this._dynamicPrimitive = undefined;
}
updateProperty(options) {
}
/**
* 更新
* @param frameState
*/
update(frameState) {
this._primitiveCollection.forEach((primitive) => {
primitive && !primitive.isDestroyed() && primitive.update(frameState);
});
if (this._dynamicPrimitive) {
this._dynamicPrimitive.update(frameState);
}
}
destroy() {
this._primitiveCollection.forEach((primitive) => {
primitive && !primitive.isDestroyed() && primitive.destroy();
});
this._primitiveCollection = undefined;
if (this._dynamicPrimitive) {
this._dynamicPrimitive.destroy();
}
this._dynamicPrimitive = undefined;
}
}
2、编写更新代码
updateProperty(options) {
this._props = {
...this._props,
...options,
};
let positions = this._props.positions;
let complete = this._props.complete;
if (positions.length > 1) {
let dynamicPrimitive = this._dynamicPrimitive;
if (dynamicPrimitive) {
dynamicPrimitive.destroy();
dynamicPrimitive = null;
this._dynamicPrimitive = null;
}
let primitive = this.initRectanglePrimitive(positions);
if (complete) {
this._primitiveCollection.push(primitive);
} else {
this._dynamicPrimitive = primitive;
}
}
}
3、编写绘制矩形的代码
initRectanglePrimitive(positions) {
let rectanglePositions = getRectanglePositions(positions);
let instance = new GeometryInstance({
geometry: new GroundPolylineGeometry({
positions: rectanglePositions,
width: 4,
}),
});
return new GroundPolylinePrimitive({
geometryInstances: instance,
appearance: new PolylineMaterialAppearance({
material: new Material({
fabric: {
type: "Color",
uniforms: {
color: Color.fromCssColorString("#ff0000"),
},
},
}),
}),
asynchronous: false,
});
}
4、 额外的算法代码
const ellipsoid = Ellipsoid.WGS84;
/**
* 将世界坐标系转换为球面坐标系
* @param {Cartesian3} position
* @return {{alt: number, lon: number, lat: number}}
*/
export const Cartesian3ToWgs84 = (position) => {
let cartographic = ellipsoid.cartesianToCartographic(position);
let lon = CesiumMath.toDegrees(cartographic.longitude);
let lat = CesiumMath.toDegrees(cartographic.latitude);
let alt = cartographic.height;
return {
lon,
lat,
alt,
};
};
/**
* 将世界坐标系转换为球面坐标系
* @param {Cartesian3[]} positions
* @return {{alt: number, lon: number, lat: number}[]}
*/
export const Cartesian3ListToWgs84 = (positions) => {
return positions.map((position) => Cartesian3ToWgs84(position));
};
export const getRectanglePositions = (positions) => {
let position84List = Cartesian3ListToWgs84(positions);
let featureList = featureCollection(
position84List.map((item) => point([item.lon, item.lat]))
);
let enveloped = envelope(featureList);
return enveloped.geometry.coordinates[0].map((item) => {
return Cartesian3.fromDegrees(item[0], item[1]);
});
};
5、测试代码
let primitive = new CustomRectanglePrimitive();
viewer.scene.primitives.add(primitive);
let lon = 106;
let count = 0;
let lat = 26;
let centerP = Cartesian3.fromDegrees(lon, lat);
let interval = setInterval(() => {
count++;
let lonTemp = lon + count * 0.00002;
let latTemp = lat + count * 0.00001;
let nextP = Cartesian3.fromDegrees(lonTemp, latTemp);
primitive.updateProperty({
positions: [centerP, nextP],
complete: count === 11,
});
if (count > 10) {
primitive.updateProperty({
positions: [centerP, nextP],
complete: true,
});
clearInterval(interval);
} else {
primitive.updateProperty({
positions: [centerP, nextP],
complete: false,
});
}
}, 1000);
三、展示效果
四、全部代码
import {
Color,
GeometryInstance,
GroundPolylineGeometry,
GroundPolylinePrimitive,
Material,
PolylineMaterialAppearance,
} from "cesium";
import { getRectanglePositions } from "@/components/MilitaryPlot/utils/PlotUtils";
export default class CustomRectanglePrimitive {
constructor(options) {
this._props = options;
/**
* 渲染列表
* @type {*[]}
* @private
*/
this._primitiveCollection = [];
this._dynamicPrimitive = undefined;
}
updateProperty(options) {
this._props = {
...this._props,
...options,
};
let positions = this._props.positions;
let complete = this._props.complete;
if (positions.length > 1) {
let dynamicPrimitive = this._dynamicPrimitive;
if (dynamicPrimitive) {
dynamicPrimitive.destroy();
dynamicPrimitive = null;
this._dynamicPrimitive = null;
}
let primitive = this.initRectanglePrimitive(positions);
if (complete) {
this._primitiveCollection.push(primitive);
} else {
this._dynamicPrimitive = primitive;
}
}
}
initRectanglePrimitive(positions) {
let rectanglePositions = getRectanglePositions(positions);
let instance = new GeometryInstance({
geometry: new GroundPolylineGeometry({
positions: rectanglePositions,
width: 4,
}),
});
return new GroundPolylinePrimitive({
geometryInstances: instance,
appearance: new PolylineMaterialAppearance({
material: new Material({
fabric: {
type: "Color",
uniforms: {
color: Color.fromCssColorString("#ff0000"),
},
},
}),
}),
asynchronous: false,
});
}
/**
* 更新
* @param frameState
*/
update(frameState) {
this._primitiveCollection.forEach((primitive) => {
primitive && !primitive.isDestroyed() && primitive.update(frameState);
});
if (this._dynamicPrimitive) {
this._dynamicPrimitive.update(frameState);
}
}
destroy() {
this._primitiveCollection.forEach((primitive) => {
primitive && !primitive.isDestroyed() && primitive.destroy();
});
this._primitiveCollection = undefined;
if (this._dynamicPrimitive) {
this._dynamicPrimitive.destroy();
}
this._dynamicPrimitive = undefined;
}
}