【问题标题】:Cesium: "fan out" overlapping polylines?铯:“扇出”重叠折线?
【发布时间】:2017-02-14 22:00:23
【问题描述】:

我正在使用 Cesium,并希望直观地表示相同两个实体之间的多条折线。例如,从实体 A 到实体 B 的绿色多段线,以及从实体 A 到实体 B 的蓝色多段线。我希望它们不重叠或混合,所以我想象绘制更多线时呈扇形散开,这样每条线及其代表的内容都可以可视化。我已经包含了我试图用扇形而不是重叠来解释的粗略图。

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

感谢您的帮助!

【问题讨论】:

    标签: javascript cesium


    【解决方案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>

    【讨论】:

    • 完美!再次感谢您的帮助。我使用和理解 sampledPositionProperty 和插值算法的应用越多,我就越有能力在我的应用程序的上下文中解决这个问题。再一次,这个例子是正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多