CZML中leadTime和trailTime浅析

缘起

参见之前的一篇文章‘STK的CZML Exporter插件’。

链接:STK的CZML Exporter插件_wangyulj的博客-CSDN博客

在STK场景中插入一个圆轨道,轨道高度550km,则轨道周期约为95.6分钟(5736s)。仿真时间设置为210分钟(3个半小时,卫星围绕地球约运行两周多),通过czml exporter插件输出czml文件,导入到Cesium场景,运行流畅,卫星沿轨道(轨迹)运行。

根据仿真时间,卫星的轨迹数据约为2个多轨道周期。作为初学者,习惯性的要问个问题(知其所以然):Cesium是如何实现卫星轨迹的绘制(保持有序不乱的)呢?

查看输出的czml文件,相关内容部分如下,关键信息标红:

[

  {

    "id":"document",

    "name":"testScen",

    "version":"1.0",

    "clock":{

      "interval":"2022-07-23T04:00:00Z/2022-07-23T07:30:00Z",  // 仿真时间

      "currentTime":"2022-07-23T04:00:00Z",

      "multiplier":100,    // 此参数决定Cesium启动场景后的仿真倍速

      "range":"LOOP_STOP",  // 此参数确定到达仿真结束时间后从头再开始重复

      "step":"SYSTEM_CLOCK_MULTIPLIER"

    }

  },

  {

    "id":"Satellite/Satellite1",  // 卫星id

    "availability":"2022-07-23T04:00:00Z/2022-07-23T07:30:00Z",  // 仿真时间

    "name":"Satellite1",

    "billboard":{

……

      },

    },

    "label":{

……

    },

    "path":{  // 此子packet(属性)决定了卫星的轨迹,包括如何绘制和轨迹数据(由position提供)

      "show":[

        {

          "interval":"2022-07-23T04:00:00Z/2022-07-23T07:30:00Z",

          "boolean":true

        }

      ],

      "width":1,

      "material":{

        "solidColor":{

          "color":{

            "rgba":[

              127,255,0,255

            ]

          }

        }

      },

      "resolution":120,  // 此参数决定如何在两点之间插值

      "leadTime":[

        {

          "interval":"2022-07-23T04:00:00Z/2022-07-23T05:35:35.4577096720022Z",

          "epoch":"2022-07-23T04:00:00Z",

          "number":[

            0,5735.457709672002,

            5735.457709672002,0

          ]

        },

        {

          "interval":"2022-07-23T05:35:35.4577096720022Z/2022-07-23T05:54:24.5422903279978Z",

          "epoch":"2022-07-23T05:35:35.4577096720022Z",

          "number":[

            0,5735.457709672002,

            5735.457709672002,0

          ]

        },

        {

          "interval":"2022-07-23T05:54:24.5422903279978Z/2022-07-23T07:30:00Z",

          "epoch":"2022-07-23T05:54:24.5422903279978Z",

          "number":[

            0,5735.457709672002,

            5735.457709672002,0

          ]

        }

      ],

      "trailTime":[

        {

          "interval":"2022-07-23T04:00:00Z/2022-07-23T05:35:35.4577096720022Z",

          "epoch":"2022-07-23T04:00:00Z",

          "number":[

            0,0,

            5735.457709672002,5735.457709672002

          ]

        },

        {

          "interval":"2022-07-23T05:35:35.4577096720022Z/2022-07-23T05:54:24.5422903279978Z",

          "epoch":"2022-07-23T05:35:35.4577096720022Z",

          "number":[

            0,0,

            5735.457709672002,5735.457709672002

          ]

        },

        {

          "interval":"2022-07-23T05:54:24.5422903279978Z/2022-07-23T07:30:00Z",

          "epoch":"2022-07-23T05:54:24.5422903279978Z",

          "number":[

            0,0,

            5735.457709672002,5735.457709672002

          ]

        }

      ]

    },

    "model":{

……

    },

    "position":{

      "interpolationAlgorithm":"LAGRANGE",

      "interpolationDegree":5,

      "referenceFrame":"INERTIAL",

      "epoch":"2022-07-23T04:00:00Z",

      "cartesian":[

        0,-3434067.16966553,6017159.753007312,7312.440334839022,

        60,-3663394.0650235787,5868629.095296768,371239.48733340215,

        120,-3876916.8218236733,5694776.836956464,733563.2383742067,

// 60s为间隔生成卫星的位置数据(笛卡尔坐标系)

……

        12540,-4655634.893307433,490479.88086475834,5107208.192100117,

        12600,-4534775.655193217,71490.03735354387,5237344.863802221

      ]

    },

    "orientation":{

      "interpolationAlgorithm":"LINEAR",

      "interpolationDegree":1,

      "epoch":"2022-07-23T04:00:00Z",

      "unitQuaternion":[

        0,-0.5331649781766161,-0.46447293359885755,0.14627769499813806,-0.6918112719131075,

        60,-0.538760829685413,-0.4857622799970333,0.1301767360316464,-0.6758888911092685,

// 60s为间隔生成的卫星本体指向(旋转)数据,会影响三维模型的显示,以及与本体坐标有关的计算。注:如果不关注卫星模型以及其他与卫星本体坐标有关的计算,可以删除orientation数据,可以大大减小czml文件的尺寸。

……

        12600,-0.8137069547208582,-0.4638392089777909,-0.0377177180973595,-0.3482980818139725

      ]

    }

  }

]

关于leadTime和trailTime的number属性在Cesium场景中作用机制,一时半会儿理解不了,靠猜是不行的。搜索!网上有两个相关的问答,仔细阅读多遍,迷迷糊糊有所领会,但仍没有彻底理解。

关于czml中卫星轨迹绘制描述中leadTime和trailTime问答的两个资源:

https://groups.google.com/g/cesium-dev/c/8epkYvAsjX0

What the "number":[0,3000.546684141998,3000.546684141998,0] mean in the sample.czml in the SampleData · Issue #141 · AnalyticalGraphicsInc/czml-writer · GitHub

最好的办法是上例子!

vehicle实例分析

打开Cesium的实例网站:Cesium Sandcastle

定位到页面下方Gallery -> DataSources中的CZML实例:Cesium Sandcastle

场景加载后页面左上角有两个按钮:‘Satellite’和‘Vehicle’,点击‘Vehicle’,界面如下:

 我们以本实例来研究leadTime和trailTime在Cesium场景中的意义。

下载Vehicle实例代码到本地调试运行,需要下载定制项目中的vehicle.czml文件,该文件代码如下:

[

  {

    "id":"document",

    "version":"1.0"

  },

  {

    "id":"Vehicle",

    "availability":"2012-08-04T16:00:00Z/2012-08-04T17:04:54.9962195740191Z",

    "billboard":{

……

    },

    "label":{

……

    },

    "path":{  // 小车的轨迹定义,包括如何绘制以及位置(position)数据

      "material":{

          "solidColor":{

            "color":{

                "interval":"2012-08-04T16:00:00Z/2012-08-04T18:00:00Z",

                "rgba":[

                  255,255,0,255

                ]

              }

            }

      },

      "width":[

        {

          "interval":"2012-08-04T16:00:00Z/2012-08-04T18:00:00Z",

          "number":5.0

        }

      ],

      "show":[

        {

          "interval":"2012-08-04T16:00:00Z/2012-08-04T18:00:00Z",

          "boolean":true

        }

      ]

    },

    "position":{  // 小车位置数据

      "interpolationAlgorithm":"LAGRANGE",

      "interpolationDegree":1,

      "epoch":"2012-08-04T16:00:00Z",

      "cartesian":[

        0.0,-2379754.6637012,-4665332.88013588,3628133.68924173,

        10.0,-2379510.08905552,-4665419.64840452,3628182.20006795,

        20.0,-2379568.4769522,-4665555.3441867,3627970.83323261,

        30.0,-2379638.93786855,-4665691.63561896,3627750.82085873,

……

        3890.0,-2291370.1520906,-4682428.91355119,3662609.11403735,

        3894.996219574019,-2291336.52323822,-4682359.21232197,3662718.52171165

      ]

    }

  }

]

可以看出,文件中没有有关leadTime和trailTime的定义,动画全程都将绘制position数据描述的小车的整个路径。

leadTime、trailTime与当前动画时刻

在vehicle的path对象中配置添加如下的leadTime和trailTime配置,两个参数均为一常数。

    "path":{  // 小车的轨迹定义,包括如何绘制以及位置(position)数据

      "material":{

……

      },

      "width":[

        {

          "interval":"2012-08-04T16:00:00Z/2012-08-04T18:00:00Z",

          "number":5.0

        }

      ],

      "show":[

        {

          "interval":"2012-08-04T16:00:00Z/2012-08-04T18:00:00Z",

          "boolean":true

        }

      ],

      "leadTime": 300,

      "trailTime": 600

    },

    "position":{  // 小车位置数据

……

其中,设置leadTime为300s,trailTime为600s(时间/长度为leadTime的两倍)。运行项目,结果如下图。

 可以看出,小车行进前面绘制的路径只有小车后方路径的一半,根据所设置的参数数值,可以判断leadTime和trailTime与(动画)时间的先后关系,如下图:

leadTime、traiTime与场景动画时间的关系

分析:小车行驶的前方绘制300s,小车行驶的后方绘制600s。在动画开始的时候,前方300s路径有数据(路径数据均由position提供,下面同),后方轨迹随小车行进逐步绘制,小车行驶到600s后,后方的路径保持600s长度。行进过程中绘制的小车轨迹保持900s的长度。在即将到达终点时,例如小于300s,绘制小车行驶前方的路径逐步缩短,直至没有,后方的路径保持600s。随后切换到起点,之前的绘制消失。

结论:leadTime在当前时刻之前,即小车行驶的前方(尚未到达的路径点/时间);trailTime在当前时刻之后,即小车行驶的后方(小车已经经历过的路径点),根据英文字面可理解为尾迹(trail)。

运行轨迹分段

根据插入卫星后的效果,卫星的轨迹绘制应当是分段的,为更直观理解最后的结果,我们将小车的路径也分段,每段时间15分钟。

参考czml文件,小车路径位置(position)的最后一组数为:

       3894.996219574019,-2291336.52323822,-4682359.21232197,3662718.52171165

该数据表示小车在场景中运行的最长路径时间为:3894.996219574019,为约64.91分钟。15分钟一段,则路径分为5段,前4段每段15分钟,最后一段为4.91分钟。

通过向场景中插入‘点(point)’辅助观测,注意插入的point是与小车(id=vehicle)同级的场景(document)对象,插入point的czml代码如下:

[

  {

    "id":"document",

    "version":"1.0"

  },

  {

    "id":"point01",

    "availability":"2012-08-04T16:00:00Z/2012-08-04T17:04:54.9962195740191Z",

    "position": {

      "epoch":"2012-08-04T16:15:00Z",

      "cartesian":[

        -2359636.23211162,-4673992.70319966,3630114.23911177

      ]

    },

    "point":{

      "color":{

        "rgba": [255, 255, 0, 255]

      },

      "outlineColor":{

        "rgba": [255, 0, 0, 255]

      },

      "outlineWidth":2,

      "pixelSize": 10

    }

  },

  {

    "id":"point02",

    "availability":"2012-08-04T16:00:00Z/2012-08-04T17:04:54.9962195740191Z",

    "position": {

      "epoch":"2012-08-04T16:30:00Z",

      "cartesian":[

        -2337565.21855632,-4678665.13993177,3638310.07564116

      ]

    },

    "point":{

      "color":{

        "rgba": [255, 255, 0, 255]

      },

      "outlineColor":{

        "rgba": [255, 0, 0, 255]

      },

      "outlineWidth":2,

      "pixelSize": 10

    }

  },

  {

    "id":"point03",

    "availability":"2012-08-04T16:00:00Z/2012-08-04T17:04:54.9962195740191Z",

    "position": {

      "epoch":"2012-08-04T16:45:00Z",

      "cartesian":[

        -2315886.04323336,-4683337.61973972,3646101.60469867

      ]

    },

    "point":{

      "color":{

        "rgba": [255, 255, 0, 255]

      },

      "outlineColor":{

        "rgba": [255, 0, 0, 255]

      },

      "outlineWidth":2,

      "pixelSize": 10

    }

  },

  {

    "id":"point04",

    "availability":"2012-08-04T16:00:00Z/2012-08-04T17:04:54.9962195740191Z",

    "position": {

      "epoch":"2012-08-04T17:00:00Z",

      "cartesian":[

        -2295922.94060166,-4684231.15580147,3657484.43279599

      ]

    },

    "point":{

      "color":{

        "rgba": [255, 255, 0, 255]

      },

      "outlineColor":{

        "rgba": [255, 0, 0, 255]

      },

      "outlineWidth":2,

      "pixelSize": 10

    }

  },

  {

    "id":"Vehicle",

    "availability":"2012-08-04T16:00:00Z/2012-08-04T17:04:54.9962195740191Z",

"billboard":{

……

提示:在point的配置代码中根据时间点借用了小车position中的数据。

然后,我们将小车的path绘制也对照按15分钟间隔分段,czml代码如下。其中所有interval的leadTime设置为100s,trailTime设置为200s。

……

      "show":[

        {

          "interval":"2012-08-04T16:00:00Z/2012-08-04T18:00:00Z",

          "boolean":true

        }

      ],

      "resolution": 120,

      "leadTime":[

        {

          "interval":"2012-08-04T16:00:00Z/2012-08-04T16:15:00Z",

          "epoch":"2012-08-04T16:00:00Z",

          "number":100

        },

        {

          "interval":"2012-08-04T16:15:00Z/2012-08-04T16:30:00Z",

          "epoch":"2012-08-04T16:15:00Z",

          "number":100

        },

        {

          "interval":"2012-08-04T16:30:00Z/2012-08-04T16:45:00Z",

          "epoch":"2012-08-04T16:30:00Z",

          "number":100

        },

        {

          "interval":"2012-08-04T16:45:00Z/2012-08-04T17:00:00Z",

          "epoch":"2012-08-04T16:45:00Z",

          "number":100

        },

        {

          "interval":"2012-08-04T17:00:00Z/2012-08-04T17:04:54.9962195740191Z",

          "epoch":"2012-08-04T17:00:00Z",

          "number":100

        }

      ],

      "trailTime":[

        {

          "interval":"2012-08-04T16:00:00Z/2012-08-04T16:15:00Z",

          "epoch":"2012-08-04T16:00:00Z",

          "number":200

        },

        {

          "interval":"2012-08-04T16:15:00Z/2012-08-04T16:30:00Z",

          "epoch":"2012-08-04T16:15:00Z",

          "number":200

        },

        {

          "interval":"2012-08-04T16:30:00Z/2012-08-04T16:45:00Z",

          "epoch":"2012-08-04T16:30:00Z",

          "number":200

        },

        {

          "interval":"2012-08-04T16:45:00Z/2012-08-04T17:00:00Z",

          "epoch":"2012-08-04T16:45:00Z",

          "number":200

        },

        {

          "interval":"2012-08-04T17:00:00Z/2012-08-04T17:04:54.9962195740191Z",

          "epoch":"2012-08-04T17:00:00Z",

          "number":200

        }

      ]

    },

    "position":{

      "interpolationAlgorithm":"LAGRANGE",

      "interpolationDegree":1,

……

运行效果如下,可以看出效果与第一个配置相同,绘制的小车路径(轨迹),前面是后面的一半,而且全程如此,在interval的分界处并无不同。

 效果:所绘制的小车轨迹效果与前面第一个配置完全一致。从配置分析也应该是,本例中仅仅是简单的将路径分段,其leadTime和trailTime的配置没有改变(为分段观察,只是数值有变化),设想取消时间段(interval)的分隔,就是一条完整的路径。

分析:在动画绘制的开始,如第一个配置,前方(leadTime)的100s有,后方(trailTime)的路径逐渐出现;在即将到达终点时,绘制效果也与前面第一个配置完全一致。在两个interval的分割点,路径的绘制全程一致,leadTime和trailTime的路径长度不变,其仅受position中的数据的影响,无论interval如何划分,只要在leadTime和trailTime时间范围内有有效的position数据,则绘制

将第二个interval(15~30分钟)设置为不显示

修改小车(id=vehicle)子packet:‘path’的show属性,指定在15~30分钟内不进行显示(绘制),代码如下:

      "show":[

        {

          "interval":"2012-08-04T16:00:00Z/2012-08-04T18:00:00Z",

          "boolean":true

        },

        {

          "interval":"2012-08-04T16:15:00Z/2012-08-04T16:30:00Z",

          "boolean":false

        }

      ],

效果图略……

结果分析:小车在运行到15s后,轨迹消失,到30s后,轨迹重新开始绘制,其他与第一个配置相同。(之前自己想不明白,总在想之前的绘制轨迹上哪儿去了,其实场景每一刻都是重新在绘制,当然具体绘制的周期,及animation的更新周期,应当是Cesium的全局配置,另一个话题。)

模拟卫星轨道的周期性绘制

在小车的轨迹中模拟STK输出的czml文件的配置,将小车的绘制配置修改为如下。

……

      "leadTime":[

        {

          "interval":"2012-08-04T16:00:00Z/2012-08-04T16:15:00Z",

          "epoch":"2012-08-04T16:00:00Z",

          "number":[

            0,900,

            900,0

          ]

        },

        {

          "interval":"2012-08-04T16:15:00Z/2012-08-04T16:30:00Z",

          "epoch":"2012-08-04T16:15:00Z",

          "number":[

            0,900,

            900,0

          ]

        },

        {

          "interval":"2012-08-04T16:30:00Z/2012-08-04T16:45:00Z",

          "epoch":"2012-08-04T16:30:00Z",

          "number":[

            0,900,

            900,0

          ]

        },

        {

          "interval":"2012-08-04T16:45:00Z/2012-08-04T17:00:00Z",

          "epoch":"2012-08-04T16:45:00Z",

          "number":[

            0,900,

            900,0

          ]

        },

        {

          "interval":"2012-08-04T17:00:00Z/2012-08-04T17:04:54.9962195740191Z",

          "epoch":"2012-08-04T17:00:00Z",

          "number":[

            0,900,

            900,0

          ]

        }

      ],

      "trailTime":[

        {

          "interval":"2012-08-04T16:00:00Z/2012-08-04T16:15:00Z",

          "epoch":"2012-08-04T16:00:00Z",

          "number":[

            0,0,

            900,900

          ]

        },

        {

          "interval":"2012-08-04T16:15:00Z/2012-08-04T16:30:00Z",

          "epoch":"2012-08-04T16:15:00Z",

          "number":[

            0,0,

            900,900

          ]

        },

        {

          "interval":"2012-08-04T16:30:00Z/2012-08-04T16:45:00Z",

          "epoch":"2012-08-04T16:30:00Z",

          "number":[

            0,0,

            900,900

          ]

        },

        {

          "interval":"2012-08-04T16:45:00Z/2012-08-04T17:00:00Z",

          "epoch":"2012-08-04T16:45:00Z",

          "number":[

            0,0,

            900,900

          ]

        },

        {

          "interval":"2012-08-04T17:00:00Z/2012-08-04T17:04:54.9962195740191Z",

          "epoch":"2012-08-04T17:00:00Z",

          "number":[

            0,0,

            900,900

          ]

        }

      ]

    },

    "position":{

      "interpolationAlgorithm":"LAGRANGE",

……

先上效果图,再慢慢分析。如下图,小车在每个interval绘制该interval的全程路径。

一点说明(很重要!): 

关于number的描述。在前面的配置中,leadTime和trailTime的number属性均设置为一个值,表示在特定绘制周期内保持一个恒定的值。czml中允许number值的成对出现,此时每对值的第一个值会被解释为时间(时刻,单位均为s(秒)),第二个值是真正的参数值。

例如对于配置(本例中的leadTime配置):

          "number":[

            0,900,

            900,0

          ]

则将被解释为在0时刻(0秒),参数值为900;而在第900秒,参数值为0。中间的时刻Cesium会进行插值,插值的算法可以自行指定,默认的应该是线性等距插值(猜测,未经验证,另外一个话题)。

反之,对于如下配置(本例中的trailTime配置):

          "number":[

            0,0,

            900,900

          ]

则表示在0时刻,参数值为0;而在第900秒,参数值为900。

根据此配置,一个interval(周期为900s)中leadTime的值将随时间递减,而trailTime的值将随时间递增。根据推导(本文中忽略,不复杂),任意时刻二者之和leadTime + trailTime = 900,保持恒定,即一个interval周期。

如下图:

 这下终于明白了,通过将轨迹分段,使得每段绘制的轨迹长度正好为分段时间的长度,即可完美复现(绘制)卫星的轨道!

回到卫星的例子

回到本文开始卫星的例子,观察czml中的leadTime和trailTime的设置。

      "leadTime":[

        {

          "interval":"2022-07-23T04:00:00Z/2022-07-23T05:35:35.4577096720022Z",  // interval为一个轨道周期

          "epoch":"2022-07-23T04:00:00Z",

          "number":[

            0,5735.457709672002,  // 5735.457709672002(秒),即为卫星的轨道周期

            5735.457709672002,0

          ]

        },

        {

          "interval":"2022-07-23T05:35:35.4577096720022Z/2022-07-23T05:54:24.5422903279978Z",  // interval不足一个轨道周期,是其他两个interval划分后的剩余量

          "epoch":"2022-07-23T05:35:35.4577096720022Z",

          "number":[

            0,5735.457709672002,

            5735.457709672002,0

          ]

        },

        {

          "interval":"2022-07-23T05:54:24.5422903279978Z/2022-07-23T07:30:00Z",  // interval为一个轨道周期

          "epoch":"2022-07-23T05:54:24.5422903279978Z",

          "number":[

            0,5735.457709672002,

            5735.457709672002,0

          ]

        }

      ],

      "trailTime":[  // interval的划分与leadTime相同

        {

          "interval":"2022-07-23T04:00:00Z/2022-07-23T05:35:35.4577096720022Z",

          "epoch":"2022-07-23T04:00:00Z",

          "number":[

            0,0,

            5735.457709672002,5735.457709672002

          ]

        },

        {

          "interval":"2022-07-23T05:35:35.4577096720022Z/2022-07-23T05:54:24.5422903279978Z",

          "epoch":"2022-07-23T05:35:35.4577096720022Z",

          "number":[

            0,0,

            5735.457709672002,5735.457709672002

          ]

        },

        {

          "interval":"2022-07-23T05:54:24.5422903279978Z/2022-07-23T07:30:00Z",

          "epoch":"2022-07-23T05:54:24.5422903279978Z",

          "number":[

            0,0,

            5735.457709672002,5735.457709672002

          ]

        }

      ]

    },

leadTime和trailTime中的number的设置中的那个数值,就是卫星的轨道周期!

通过对动画时间根据卫星轨道周期进行划分并如本例中所示的相应设置,即可完美复现卫星运动时的轨迹。

拓展:leadTime和trailTime配合interval的设置能够实现许多神奇的轨迹效果,感兴趣的同学们可以多多的参考学习Cesium网站给出的示例。

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值