Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make distance display condition property dynamic. #4403

Merged
merged 2 commits into from
Oct 7, 2016

Conversation

bagnell
Copy link
Contributor

@bagnell bagnell commented Oct 4, 2016

Make geometry distance display conditions able to be dynamic. Also fixed an issue with billboard and label when toggling clustering.

@mramato Are there any tests for dynamic geometry attributes?

@mramato
Copy link
Contributor

mramato commented Oct 5, 2016

@mramato Are there any tests for dynamic geometry attributes?

Unfortunately not, this is one of the least covered areas of the code (and something I'd really like to clean up when time allows).

@mramato
Copy link
Contributor

mramato commented Oct 5, 2016

@bagnell do you have the Sandcastle example you were using when you originally found this issue? Thanks.

@bagnell
Copy link
Contributor Author

bagnell commented Oct 5, 2016

Here is the Sandcastle example I was using for testing. Toggling the enable flag was causing the crash in EntityCluster. Switching the labels to billboards caused another.

    var viewer = new Cesium.Viewer('cesiumContainer');

    var dataSource = new Cesium.GeoJsonDataSource();
    dataSource.clustering.enabled = true;

    function getDistance(entity, boundingSphere) {
        var ellipsoid = Cesium.Ellipsoid.WGS84;

        var center = boundingSphere.center;
        var radius = boundingSphere.radius;
        var eastNorthUp = Cesium.Transforms.eastNorthUpToFixedFrame(center, ellipsoid);
        var eastNorthUpRotation = Cesium.Matrix4.getRotation(eastNorthUp, new Cesium.Matrix3());
        var localX = Cesium.Matrix3.getColumn(eastNorthUpRotation, 0, new Cesium.Cartesian3());
        var localY = Cesium.Matrix3.getColumn(eastNorthUpRotation, 1, new Cesium.Cartesian3());
        var scaledX = Cesium.Cartesian3.multiplyByScalar(localX, radius, localX);
        var scaledY = Cesium.Cartesian3.multiplyByScalar(localY, radius, localY);

        var cartesianArray = new Array(4);
        cartesianArray[0] = Cesium.Cartesian3.add(center, scaledX, new Cesium.Cartesian3());
        cartesianArray[1] = Cesium.Cartesian3.add(center, Cesium.Cartesian3.negate(scaledX, scaledX), new Cesium.Cartesian3());
        cartesianArray[2] = Cesium.Cartesian3.add(center, scaledY, new Cesium.Cartesian3());
        cartesianArray[3] = Cesium.Cartesian3.add(center, Cesium.Cartesian3.negate(scaledY, scaledY), new Cesium.Cartesian3());

        var rectangle = Cesium.Rectangle.fromCartesianArray(cartesianArray, ellipsoid);
        var approxCameraPosition = viewer.scene.camera.getRectangleCameraCoordinates(rectangle);
        return Cesium.Cartesian3.magnitude(approxCameraPosition) - ellipsoid.maximumRadius;
    }

    dataSource.entities.collectionChanged.addEventListener(function(collection, added, removed, changed) {
        var deffereds = [];
        var promises = [];

        var entities = added;
        var length = entities.length;
        for (var i = 0; i < length; ++i) {
            var entity = entities[i];
            var deffered = Cesium.when.defer();

            deffereds.push({deffered : deffered, entity : entity});
            promises.push(deffered.promise);
        }

        var removeEventListener = viewer.scene.postRender.addEventListener(function() {
            var length = deffereds.length;
            var defferedsToRemove = [];

            for (var i = 0; i < length; ++i) {
                var deffered = deffereds[i].deffered;
                var entity = deffereds[i].entity;

                var result = new Cesium.BoundingSphere();
                var status = viewer.dataSourceDisplay.getBoundingSphere(entity, true, result);
                if (status === Cesium.BoundingSphereState.DONE) {
                    deffered.resolve({entity : entity, boundingSphere : result});
                } else if (status === Cesium.BoundingSphereState.FAILED) {
                    deffered.reject();
                }

                if (status !== Cesium.BoundingSphereState.PENDING) {
                    defferedsToRemove.push(deffereds[i]);
                }
            }

            for (var j = 0; j < defferedsToRemove.length; ++j) {
                deffereds.splice(deffereds.indexOf(defferedsToRemove[j]), 1);
            }
        });

        Cesium.when.all(promises).then(function(values) {
            var length = values.length;
            for (var i = 0; i < length; ++i) {
                var entity = values[i].entity;
                var boundingSphere = values[i].boundingSphere;

                entity.position = boundingSphere.center;
                entity.label = {
                    show : new Cesium.CallbackProperty(function(time, result) {
                        return dataSource.clustering.enabled;
                    }, false),
                    text : entity.properties.name,
                    distanceDisplayCondition : new Cesium.CallbackProperty(function(time, result) {
                        if (!Cesium.defined(result)) {
                            result = new Cesium.DistanceDisplayCondition();
                        }
                        result.near = getDistance(entity, boundingSphere);
                        return result;
                    }, false)
                };
                entity.polygon.distanceDisplayCondition = new Cesium.CallbackProperty(function(time, result) {
                    if (!Cesium.defined(result)) {
                        result = new Cesium.DistanceDisplayCondition();
                    }
                    if (dataSource.clustering.enabled) {
                        result.far = getDistance(entity, boundingSphere);
                    } else {
                        result.far = Number.MAX_VALUE;
                    }
                    return result;
                }, false);
            }

            removeEventListener();
        });
    });

    var url = '../../SampleData/ne_10m_us_states.topojson';
    dataSource.load(url, { clampToGround : false });
    viewer.dataSources.add(dataSource);

    var viewModel = {
        enabled : dataSource.clustering.enabled
    };
    Cesium.knockout.track(viewModel);

    var toolbar = document.getElementById('toolbar');
    Cesium.knockout.applyBindings(viewModel, toolbar);

    Cesium.knockout.getObservable(viewModel, 'enabled').subscribe(
        function(newValue) {
            dataSource.clustering.enabled = newValue;
        }
    );

@mramato
Copy link
Contributor

mramato commented Oct 7, 2016

Looks good, thanks @bagnell.

@mramato mramato merged commit e00c689 into master Oct 7, 2016
@mramato mramato deleted the dynamic-display-condition branch October 7, 2016 14:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants