Get Year from Clock

I am trying to create a dynamic Cesiumjs Scene, I’ve created a small function that loads and styles a GeoJSON and I’ve added a clock with the date range I need. What I’m trying to do now is pass the year from the clock to the layer function so it loads the layer for the year in the clock. I tried viewer.clock.currentTime and that only gave me today’s date not the date from the clock. Ive also tried onTick() and that didnt work for me either. My data is from 1979 to 2013 but theres a gap in data from 1999-2003 so that poses another issue with the timeline. I guess I have two questions:

Does anyone have any idea how to get just the year from the clock? (or the date and how to convert it)

Is there a way to skip a few years in a clock range? (would i be able to set up two clocks? one that runs from 1979 to 1998 and then goes to the next clock that runs 2004 to 2013)

Sample Code:

        var clock = new Cesium.Clock({
            startTime: Cesium.JulianDate.fromIso8601('1979-01-01'),
            stopTime: Cesium.JulianDate.fromIso8601('2014-01-01'),
            clockRange: Cesium.ClockRange.LOOP_STOP,
            clockStep: Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER,
            multiplier: 7889238,
            shouldAnimate: true
        });
        var viewer = new Cesium.Viewer("cesiumContainer", {
            imageryProvider: new Cesium.IonImageryProvider({assetId: 3845}),
            clockViewModel: new Cesium.ClockViewModel(clock),
            shouldAnimate: true
        });
        viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(-56.5, 45.45, 450000.0),
            orientation: {
                pitch: Cesium.Math.toRadians(-50.0)
            }
        });

        var source1 = 'GeoJSON path part 1';
        var source2 = 'GeoJSON path part 2';
        var year_time = viewer.clock.currentTime;
        console.log(year_time);

        getLayer(year_time);

        function getLayer(year) {
            var promise = Cesium.GeoJsonDataSource.load(source1 + year_time + source2);

``

I’m currently more interested in getting the layers to change according to the year, the timeline gap issue is not as pressing.

UPDATE:

I have been able to find a way to get the year as the time changes but for some reason when i try to pass it along to the getLayer function it get an error.

“SyntaxError: Unexpected token < in JSON at position 0”

Here is my updated code sample:

        var clock = new Cesium.Clock({
            startTime: Cesium.JulianDate.fromIso8601('1979-01-01'),
            currentTime: Cesium.JulianDate.fromIso8601('1979-01-01'),
            stopTime: Cesium.JulianDate.fromIso8601('2014-01-01'),
            clockRange: Cesium.ClockRange.LOOP_STOP,
            clockStep: Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER,
            multiplier: 15778476,
            shouldAnimate: true
        });
        var viewer = new Cesium.Viewer("cesiumContainer", {
            imageryProvider: new Cesium.IonImageryProvider({assetId: 3845}),
            clockViewModel: new Cesium.ClockViewModel(clock),
            shouldAnimate: true,
            skyAtmosphere: false,
            skyBox: false
        });
        viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(-56.5, 45.45, 450000.0),
            orientation: {
                pitch: Cesium.Math.toRadians(-50.0)
            }
        });

        var source1 = 'GeoJSON path part 1';
        var source2 = 'GeoJSON path part 2';
        var year_time = '';
        viewer.clock.onTick.addEventListener(function (clock) {
            year_time = Cesium.JulianDate.toIso8601(viewer.clock.currentTime).substr(0, 4);
        });
        console.log(year_time);
        getLayer(year_time);

        function getLayer(year) {
            var promise = Cesium.GeoJsonDataSource.load(source1 + year + source2);

``

I feel like I’m getting pretty close! I just cant figure out whats going on with this to cause the error. Can anyone help me figure this out?

I think you need to put the call to getLayer() into your onTick function which hasn’t been called yet and won’t get called until all of the setup is complete. Otherwise, it seems to work ok.

Scott

Thanks for the reply Scott! I did end up trying that but for some reason it adds the layer hundreds of times because there is a bunch of “ticks” for each year, it also stops the clock from moving forward.
I’m currently trying to add the logic from the first answer on this stack exchange question and it does the same thing.

I think what I need to do now is only call the getLayer function once for every year, instead of for every “tick”. If you have any idea how I can do that, itd be much appreciated!

Thanks so much

-Rory

I have gotten it to work! I had to add an if/else to make it work properly.

Here is my updated code snippet:

        viewer.clock.onTick.addEventListener(function () {
            clockMultiYear = Cesium.JulianDate.toIso8601(viewer.clock.currentTime).substr(0, 4);
            if (clockYear === clockMultiYear)
                return;
            else if (clockYear !== clockMultiYear) {
                clockYear = clockMultiYear;
            }

``

I use clockYear to load my GeoJSON layer and it worked perfectly!

That looks ok but could be simplified.

viewer.clock.onTick.addEventListener(function () {

var tickYear = Cesium.JulianDate.toIso8601(viewer.clock.currentTime).substr(0, 4);

if (clockYear === tickYear)

return;

}

clockYear = tickYear;

``

You might want to consider what should happen if the clock’s direction is reversed. For instance, should entities for a particular year be removed as the corresponding year is passed?

Thanks again Scott! I have solved my issues and am now working on efficiency.

Here is what I ended up doing:

        var tickYear = '';
        var clockYear;
        viewer.clock.onTick.addEventListener(function () {
            tickYear = Cesium.JulianDate.toIso8601(viewer.clock.currentTime).substr(0, 4);
            if (clockYear === tickYear)
                return;
            clockYear = tickYear;

            if (clockYear == 1979) {
                getLayer(1979);
                removeLayer();
            } else if (clockYear == 1980) {
                getLayer(1980);
                removeLayer();
            } else if (clockYear == 1981) {
                getLayer(1981);
                removeLayer();
            } else if (clockYear == 1982) {
                getLayer(1982);
                removeLayer();
            } else {
                viewer.clock.currentTime = Cesium.JulianDate.fromIso8601('2003-12-31');
            }
        });

        function removeLayer() {
            viewer.dataSources.removeAll();
        }
        function getLayer(year) {
            promise = Cesium.GeoJsonDataSource.load('Source part 1' + year + 'Source part 2');

``

The if loop in my full code has ‘else if’ for each year. I’m pretty pleased with it, there’s just a few years that are quite a bit larger than the rest so I’m now trying to get it to load faster. I’ve read a few stack exchange posts that suggest “lazy loading” which I think will work well, just have to figure out how to remove the layer as the years go on.

Thanks

Rory