需求
需要保证加载效率,传geojson进去就能进行加载,然后能飞能定位,能贴地
Geojson数据处理代码
javascript
_geojsonTransformation(featureCollection, targetType) {
const features = [];
if (targetType === 'point') {
featureCollection.features.forEach(feature => {
const points = turf.explode(feature).features;
features.push(...points);
});
} else if (targetType === 'line') {
// 遍历GeoJSON中的每个feature
featureCollection.features.forEach(feature => {
const geometry = feature.geometry;
const coordinates = geometry.coordinates;
// 初始化最小和最大经纬度
let minLon = Number.POSITIVE_INFINITY,
maxLon = Number.NEGATIVE_INFINITY;
let minLat = Number.POSITIVE_INFINITY,
maxLat = Number.NEGATIVE_INFINITY;
// 计算边界范围的函数
function updateBounds(lon, lat) {
minLon = Math.min(minLon, lon);
maxLon = Math.max(maxLon, lon);
minLat = Math.min(minLat, lat);
maxLat = Math.max(maxLat, lat);
}
// 处理LineString
if (geometry.type === 'LineString') {
const positions = coordinates.flatMap(coord => {
updateBounds(coord[0], coord[1]); // 更新边界
return [coord[0], coord[1]];
});
features.push({
type: 'LineString',
positions: Cesium.Cartesian3.fromDegreesArray(positions),
bounds: { minLon, maxLon, minLat, maxLat },
});
}
// 处理MultiLineString
else if (geometry.type === 'MultiLineString') {
coordinates.forEach(line => {
const positions = line.flatMap(coord => {
updateBounds(coord[0], coord[1]); // 更新边界
return [coord[0], coord[1]];
});
features.push({
type: 'MultiLineString',
positions: Cesium.Cartesian3.fromDegreesArray(positions),
bounds: { minLon, maxLon, minLat, maxLat },
});
});
}
});
} else if (targetType === 'polygon') {
// 遍历GeoJSON中的每个feature
featureCollection.features.forEach(feature => {
const geometry = feature.geometry;
const coordinates = geometry.coordinates;
// 初始化最小和最大经纬度
let minLon = Number.POSITIVE_INFINITY,
maxLon = Number.NEGATIVE_INFINITY;
let minLat = Number.POSITIVE_INFINITY,
maxLat = Number.NEGATIVE_INFINITY;
// 计算边界范围的函数
function updateBounds(lon, lat) {
minLon = Math.min(minLon, lon);
maxLon = Math.max(maxLon, lon);
minLat = Math.min(minLat, lat);
maxLat = Math.max(maxLat, lat);
}
// 处理Polygon
if (geometry.type === 'Polygon') {
let positions = coordinates[0].flatMap(coord => {
updateBounds(coord[0], coord[1]); // 更新边界
return [coord[0], coord[1]];
});
// 判断头和尾的坐标是否一致
if (
positions[0] !== positions[positions.length - 2] ||
positions[1] !== positions[positions.length - 1]
) {
positions.push(positions[0], positions[1]);
}
features.push({
type: 'Polygon',
positions: Cesium.Cartesian3.fromDegreesArray(positions),
bounds: { minLon, maxLon, minLat, maxLat },
});
}
// 处理MultiPolygon
else if (geometry.type === 'MultiPolygon') {
coordinates.forEach(polygon => {
let positions = polygon[0].flatMap(coord => {
updateBounds(coord[0], coord[1]); // 更新边界
return [coord[0], coord[1]];
});
// 判断头和尾的坐标是否一致
if (
positions[0] !== positions[positions.length - 2] ||
positions[1] !== positions[positions.length - 1]
) {
positions.push(positions[0], positions[1]);
}
features.push({
type: 'MultiPolygon',
positions: Cesium.Cartesian3.fromDegreesArray(positions),
bounds: { minLon, maxLon, minLat, maxLat },
});
});
}
});
}
return features;
}
点primitive数据加载
测试示例
javascript
const testParams = { data: { type: "FeatureCollection", features: [ { type: "Feature", geometry: { type: "Point", coordinates: [120.0, 30.0, 100.0] }, properties: {} }, { type: "Feature", geometry: { type: "Point", coordinates: [121.0, 31.0, 200.0] }, properties: {} } ] }, loadOptions: { color: "#FF0000", // 红色 opacity: 1.0, // 透明度 radius: 20 // 半径 }, needFly: true, // 是否飞到点的位置 clampToGround: true // 是否贴地 }; addPointGeojsonEffect(testParams.data,testParams.loadOptions,testParams.needFly,testParams.clampToGround)
加载代码
javascript
_addPointGeojsonEffect(data, loadOptions, needFly, clampToGround) {
const { color, opacity, radius } = loadOptions;
const viewer = window.viewer;
// const pointCollection = viewer.scene.primitives.add(new Cesium.PrimitiveCollection());
const pointCollection = viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection());
const features = this._geojsonTransformation(data, 'point');
const pointArray = [];
features.forEach(async feature => {
const { geometry } = feature;
const { coordinates } = geometry;
const position = Cesium.Cartesian3.fromDegrees(
coordinates[0],
coordinates[1],
coordinates[2] || 0
);
pointArray.push(position);
if (clampToGround) {
try {
const cartographicPosition = Cesium.Cartographic.fromCartesian(position);
const updatedPositions = await Cesium.sampleTerrainMostDetailed(
map3d_viewer.viewer.scene.terrainProvider,
[cartographicPosition],
true
);
pointCollection.add({
position: Cesium.Cartographic.toCartesian(updatedPositions[0]),
color: Cesium.Color.fromCssColorString(color).withAlpha(opacity),
pixelSize: radius,
});
} catch (error) {
// A tile request error occurred.
console.error(error);
// 正常加载
pointCollection.add({
position: position,
color: Cesium.Color.fromCssColorString(color).withAlpha(opacity),
pixelSize: radius,
});
}
} else {
pointCollection.add({
position: position,
color: Cesium.Color.fromCssColorString(color).withAlpha(opacity),
pixelSize: radius,
});
}
});
if (needFly) {
const rectangle = Cesium.Rectangle.fromCartesianArray(pointArray);
const expandedRectangle = Cesium.Rectangle.expand(rectangle, 0.1); // 增加矩形的高度
// 飞到点的位置
map3d_viewer.viewer.camera.flyTo({
destination: expandedRectangle,
duration: 2.0, // 设置飞行时间
});
}
return [pointCollection];
}
线primitive数据加载
测试示例
javascript
const testParams = { data: { "type": "FeatureCollection", "features": [ { "type": "Feature", "id": 8843, "properties": { "_draw_type": "line" }, "geometry": { "type": "LineString", "coordinates": [ [ 114.11329217, 22.57045667 ], [ 114.15516134, 22.59674445 ], [ 114.21545293, 22.59751754 ], [ 114.23471297, 22.62495966 ], [ 114.22717668, 22.64621393 ] ] }, "bbox": [ 114.11329217, 22.57045667, 114.23471297, 22.64621393 ] } ] }, loadOptions: { color: "#FF0000", // 红色 opacity: 1.0, // 透明度 width: 2 }, needFly: true, // 是否飞到点的位置 clampToGround: true// 是否贴地 }; addLineGeojsonEffect(testParams.data,testParams.loadOptions,testParams.needFly,testParams.clampToGround)
加载代码
javascript
_addLineGeojsonEffect(data, loadOptions, needFly, clampToGround) {
const { color, opacity, width } = loadOptions;
const viewer = window.viewer;
const polylineCollection = viewer.scene.primitives.add(new Cesium.PrimitiveCollection());
const transformedFeatures = this._geojsonTransformation(data, 'line');
transformedFeatures.forEach(feature => {
let polyline;
const polylineAppearance = new Cesium.PolylineMaterialAppearance({
material: Cesium.Material.fromType('Color', {
color: Cesium.Color.fromCssColorString(color).withAlpha(opacity), // 点的颜色
}),
});
if (clampToGround) {
polyline = new Cesium.GeometryInstance({
geometry: new Cesium.GroundPolylineGeometry({
positions: feature.positions,
width: width,
}),
});
polylineCollection.add(
new Cesium.GroundPolylinePrimitive({
geometryInstances: polyline,
appearance: polylineAppearance,
})
);
} else {
polyline = new Cesium.GeometryInstance({
geometry: new Cesium.PolylineGeometry({
positions: feature.positions,
width: width,
}),
});
polylineCollection.add(
new Cesium.Primitive({
geometryInstances: polyline,
appearance: polylineAppearance,
asynchronous: false, // 同步渲染
})
);
}
const rectangle = Cesium.Rectangle.fromDegrees(
feature.bounds.minLon,
feature.bounds.minLat,
feature.bounds.maxLon,
feature.bounds.maxLat
);
if (needFly) {
// 飞到线条位置
viewer.camera.flyTo({
destination: rectangle,
duration: 2.0, // 设置飞行时间
});
}
});
return [polylineCollection];
}
面数据加载
测试示例
javascript
const testParams = { data: { type: 'FeatureCollection', features: [ { type: 'Feature', id: 4385, properties: { _draw_type: 'fill' }, geometry: { type: 'Polygon', coordinates: [ [ [114.06953141, 22.60794206], [114.03559538, 22.56155188], [114.08407557, 22.54282868], [114.19425786, 22.58474811], [114.06953141, 22.60794206], ], ], }, bbox: [114.03559538, 22.54282868, 114.19425786, 22.60794206], }, ], }, loadOptions: { fillColor: '#FF0000', // 红色 lineColor: '#ff0000', opacity: 0.6, // 透明度 lineWidth: 2, }, needFly: true, // 是否飞到点的位置 clampToGround: true, // 是否贴地 }; addPolygonGeojsonEffect(testParams.data, testParams.loadOptions, testParams.needFly, testParams.clampToGround);
加载代码
javascript
addPolygonGeojsonEffect(data, loadOptions, needFly, clampToGround) {
const { fillColor, opacity, lineColor, lineWidth } = loadOptions;
const viewer = window.viewer;
const polygonCollection = viewer.scene.primitives.add(new Cesium.PrimitiveCollection());
const transformedFeatures = this._geojsonTransformation(data, 'polygon');
transformedFeatures.forEach(feature => {
let polygon;
let polyline;
const polygonAppearance = new Cesium.MaterialAppearance({
material: Cesium.Material.fromType('Color', {
color: Cesium.Color.fromCssColorString(fillColor).withAlpha(opacity),
}),
});
const polylineAppearance = new Cesium.PolylineMaterialAppearance({
material: Cesium.Material.fromType('Color', {
color: Cesium.Color.fromCssColorString(lineColor).withAlpha(opacity), // 点的颜色
}),
});
if (clampToGround) {
polygon = new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(feature.positions),
}),
});
polyline = new Cesium.GeometryInstance({
geometry: new Cesium.GroundPolylineGeometry({
positions: feature.positions,
width: lineWidth,
}),
});
polygonCollection.add(
new Cesium.GroundPrimitive({
geometryInstances: polygon,
appearance: polygonAppearance,
})
);
polygonCollection.add(
new Cesium.GroundPolylinePrimitive({
geometryInstances: polyline,
appearance: polylineAppearance,
})
);
} else {
polygon = new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(feature.positions),
}),
});
polyline = new Cesium.GeometryInstance({
geometry: new Cesium.PolylineGeometry({
positions: feature.positions,
width: lineWidth,
}),
});
polygonCollection.add(
new Cesium.Primitive({
geometryInstances: polygon,
appearance: polygonAppearance,
asynchronous: false, // 同步渲染
})
);
polygonCollection.add(
new Cesium.Primitive({
geometryInstances: polyline,
appearance: polylineAppearance,
asynchronous: false, // 同步渲染
})
);
}
const rectangle = Cesium.Rectangle.fromDegrees(
feature.bounds.minLon,
feature.bounds.minLat,
feature.bounds.maxLon,
feature.bounds.maxLat
);
if (needFly) {
// 飞到线条位置
viewer.camera.flyTo({
destination: rectangle,
duration: 2.0, // 设置飞行时间
});
}
});
return [polygonCollection];
}