铯:"扇出"重叠折线?

时间:2017-02-14 22:00:23

标签: javascript cesium

我正在使用Cesium,我希望在视觉上代表同一两个实体之间的多条折线。例如,从实体A到实体B的绿色折线,以及从实体A到实体B的蓝色折线。我希望它们不重叠或混合,所以我想象一个扇形,因为绘制了更多的线条,所以每条线及其代表的内容都可以看到。我已经包含了一个粗略的图画,说明了我试图用扇出来解释而不是重叠。

enter image description here

我有一个功能数据结构,跟踪我想要表示的行,以及它们已经以编程方式绘制的Cesium映射。我想在这一点上,我正在寻找关于如何以编程方式弯曲地图上的折线的技术解释,以及任何有关折线管理的建议,以便识别重叠线,以便我可以应用弯曲。

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

这是一种方法。此示例代码将仅沿经度“扩展”线,因此最好在北/南线上而不是在东/西线上。但我认为它应该传达正确的想法,你只需要找出一种更通用的方式将中点“移动”到一个视觉上令人愉悦的位置。

我在这里使用基于时间的路径,以获得对Cesium插值逻辑的访问。但是我在过去选择了一个参考时间,而我只是在观察者上显示完成的路径。因此,用户在这里扮演任何角色都不是明智之举。

var viewer = new Cesium.Viewer('cesiumContainer', {
    navigationInstructionsInitiallyVisible: false,
    animation: false,
    timeline: false,
    // These next 5 lines are just to avoid the Bing Key error message.
    imageryProvider : Cesium.createTileMapServiceImageryProvider({
        url : Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII')
    }),
    baseLayerPicker : false,
    geocoder : false,
    // This next line fixes another Stack Snippet error, you may omit
    // this setting from production code as well.
    infoBox : false
});

var numberOfArcs = 5;
var startLon = -105;
var startLat = 39.7;

var stopLon = -98.4;
var stopLat = 29.4;
var spread = 5;

var referenceTime = Cesium.JulianDate.fromIso8601('2001-01-01T00:00:00Z');
var midTime = Cesium.JulianDate.addSeconds(referenceTime, 43200, new Cesium.JulianDate());
var stopTime = Cesium.JulianDate.addSeconds(referenceTime, 86400, new Cesium.JulianDate());

for (var i = 0; i < numberOfArcs; ++i) {
    var color = Cesium.Color.fromRandom({
        alpha : 1.0
    });

    // Create a straight-line path.
    var property = new Cesium.SampledPositionProperty();
    var startPosition = Cesium.Cartesian3.fromDegrees(startLon, startLat, 0);
    property.addSample(referenceTime, startPosition);
    var stopPosition = Cesium.Cartesian3.fromDegrees(stopLon, stopLat, 0);
    property.addSample(stopTime, stopPosition);

    // Find the midpoint of the straight path, and move it.
    var spreadAmount = (spread / (numberOfArcs - 1)) * i - (spread / 2);
    var midPoint = Cesium.Cartographic.fromCartesian(property.getValue(midTime));
    midPoint.longitude += Cesium.Math.toRadians(spreadAmount);
    var midPosition = viewer.scene.globe.ellipsoid.cartographicToCartesian(
        midPoint, new Cesium.Cartesian3());

    // Redo the path to be the new arc.
    property = new Cesium.SampledPositionProperty();
    property.addSample(referenceTime, startPosition);
    property.addSample(midTime, midPosition);
    property.addSample(stopTime, stopPosition);

    // Create an Entity to show the arc.
    var arcEntity = viewer.entities.add({
        position : property,
        // This path shows the arc as a polyline.
        path : {
            resolution : 1200,
            material : new Cesium.PolylineGlowMaterialProperty({
                glowPower : 0.16,
                color : color
            }),
            width : 10,
            leadTime: 1e11,
            trailTime: 1e11
        }
    });

    // This is where it becomes a smooth path.
    arcEntity.position.setInterpolationOptions({
        interpolationDegree : 5,
        interpolationAlgorithm : Cesium.LagrangePolynomialApproximation
    });
}

// Optionally, add start and stop points, mostly for easy zoomTo().
viewer.entities.add({
    position : Cesium.Cartesian3.fromDegrees(startLon, startLat),
    point : {
        pixelSize : 8,
        color : Cesium.Color.WHITE
    }
});
viewer.entities.add({
    position : Cesium.Cartesian3.fromDegrees(stopLon, stopLat),
    point : {
        pixelSize : 8,
        color : Cesium.Color.WHITE
    }
});

viewer.zoomTo(viewer.entities);
html, body, #cesiumContainer {
  width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
  font-family: sans-serif;
}
<link href="http://cesiumjs.org/releases/1.30/Build/Cesium/Widgets/widgets.css" 
      rel="stylesheet"/>
<script src="http://cesiumjs.org/releases/1.30/Build/Cesium/Cesium.js">
</script>
<div id="cesiumContainer"></div>