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

Pick/Drillpick Imagery Layer #9651

Merged
merged 32 commits into from
Jul 26, 2021
Merged

Pick/Drillpick Imagery Layer #9651

merged 32 commits into from
Jul 26, 2021

Conversation

srothst1
Copy link
Contributor

@srothst1 srothst1 commented Jun 30, 2021

Fixes #8692

Based on the discussion from this post, there is clearly demand for functionality allowing users to select an imagery layer (or imagery layers) from our viewer. Currently, in demos like this one, if a user selects an imagery layer and not a feature they are presented with the message "No features found." The final goal of this pull request is to give users easy access to imagery layer data.

I have spent the last few days looking through ImageryLayer.js, ImageryLayerCollection.js and Viewer.js. I believe that this functionality should be added to a new method pickImageryLayer in ImageryLayerCollection.js and eventually integrated into either viewer.pickEntity or viewer.pickImageryLayerFeature.

Here is a sandcastle demo that showcases how this functionality currently works. When selecting a position on the globe, we see that pickImageryLayers returns an ImageryLayer and pickImageryLayerFeatures returns nothing since there are no features. I think this is a step in the right direction.

While I am looking for overall feedback and clarification, I do have some more specific questions:

  • Should ImageryLayerCollection.prototype.pickImageryLayers return a ImageryLayerCollection or a promise to ImageryLayerFeatureInfo?
  • How should ImageryLayerCollection.prototype.pickImageryLayers be integrated into ImageryLayer.js and Scene.js?

When I get a better understanding of what needs to be done, I will update ImageryLayerCollectionSpec.js and CHANGES.md. I do not expect this to be part of Thursday's release.

@lilleyse
@ebogo1

@cesium-concierge
Copy link

Thanks for the pull request @srothst1!

  • ✔️ Signed CLA found.
  • CHANGES.md was not updated.
    • If this change updates the public API in any way, please add a bullet point to CHANGES.md.
  • ❔ Unit tests were not updated.
    • Make sure you've updated tests to reflect your changes, added tests for any new code, and ran the code coverage tool.

Reviewers, don't forget to make sure that:

  • Cesium Viewer works.
  • Works in 2D/CV.
  • Works (or fails gracefully) in IE11.

Copy link
Contributor

@lilleyse lilleyse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not too many comments on the code itself which looks pretty good. The major limitation of this approach is that it isn't pixel perfect. Still I think it's would be valuable until someone implements the pixel perfect approach. I wrote some starter notes on that here: #8692 (comment).

Probably not worth tackling now unless you are up for it.

Source/Scene/ImageryLayerCollection.js Outdated Show resolved Hide resolved
Source/Scene/ImageryLayerCollection.js Outdated Show resolved Hide resolved
Source/Scene/ImageryLayerCollection.js Outdated Show resolved Hide resolved
@srothst1
Copy link
Contributor Author

srothst1 commented Jul 7, 2021

@lilleyse Thank you for the feedback. I am happy to hear that the code looked mostly good. I implemented some of your suggestions:

  1. pickImageryLayers returns an array of ImageryLayer objects instead of an ImageryLayerCollection. Following the precedent set by drillPick and pickImageryLayerFeatures.
  2. Created a helper function (pickImageryLayersHelper) for pickImageryLayers and pickImageryLayerFeatures, removing a lot of duplicated code.
  3. Updated the documentation to include information about the caveats of the rectangle-based approach currently implemented.

Before I consider implementing a pixel-perfect version of pickImageryLayers, I want to ensure that the code I currently have is correct.

A few questions:

  1. On my local machine, all specs pass. Why are some checks not successful on GitHub? How should I debug when this occurs?
  2. How do I generate the documentation to make sure everything is generated properly?
  3. Should I create a spec for pickImageryLayersHelper or pickImageryLayers?

Sandcastle Demos:
#1 #2

@lilleyse
Copy link
Contributor

lilleyse commented Jul 9, 2021

  1. It could be a fluke. I restarted the build and CI passed. If you see similar issues open an issue. (EDIT: still running actually)
  2. Run npm run generateDocumentation. If you're curious about the various build commands see the Build Guide
  3. Add tests for pickImageryLayers. It's fine not to test pickImageryLayersHelper. On the topic of tooling, you can check how well the unit tests cover the the code by running npm run coverage and seeing the coverage results. If you're only concerned with a single suite of tests you can change describe to fdescribe and it will only run those tests.

Source/Scene/ImageryLayerCollection.js Outdated Show resolved Hide resolved
Source/Scene/ImageryLayerCollection.js Outdated Show resolved Hide resolved
Source/Scene/ImageryLayerCollection.js Outdated Show resolved Hide resolved
@lilleyse
Copy link
Contributor

lilleyse commented Jul 9, 2021

The new approach is better but there's still a lot of code duplication. One idea is to pass a callback function to the helper so that once overlapping imagery is found it can let the callback do the rest of the work. This lets pickImageryLayers and pickImageryLayerFeatures define their own custom behavior with little code duplication.

It was a bit hard to annotate the idea on github so I mocked something up: callback.txt. I haven't actually tested it so double check that there aren't any mistakes. What do you think?

@lilleyse
Copy link
Contributor

lilleyse commented Jul 9, 2021

On my local machine, all specs pass. Why are some checks not successful on GitHub? How should I debug when this occurs?

I submitted an issue for this #9672

@srothst1
Copy link
Contributor Author

srothst1 commented Jul 13, 2021

@lilleyse Thanks for the feedback! I added a series of commits. Here is a quick summary:

  1. Added specs for pickImageryLayers. I modeled these specs after the tests for pickImageryLayerFeatures. Let me know if the specs that I added are comprehensive enough.
  2. Updated the documentation for pickImageryLayers according to your specifications.
  3. Removed an unnecessary if statement from pickImageryLayers.
  4. Updated the helper function pickImageryHelper, removing it from the ImageryLayerCollection class.
  5. Implemented your suggestion of using a callback function to minimize code duplication. Upon further consideration, I agree with this approach. I think it makes the code is a lot more intuitive and ImageryLayerCollection.js now matches the rest of our codebase more closely.

@srothst1 srothst1 assigned srothst1 and unassigned srothst1 Jul 13, 2021
Copy link
Contributor

@lilleyse lilleyse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @srothst1 - the main code looks good - I have some comments on the tests. Make sure to run code coverage (see #9651 (comment)) - there are some code paths that would be frequently hit that could be better tested. I marked some of those in red.

Untitled

Specs/Scene/ImageryLayerCollectionSpec.js Outdated Show resolved Hide resolved
Specs/Scene/ImageryLayerCollectionSpec.js Outdated Show resolved Hide resolved
Specs/Scene/ImageryLayerCollectionSpec.js Outdated Show resolved Hide resolved
@srothst1
Copy link
Contributor Author

srothst1 commented Jul 14, 2021

@lilleyse a few updates:

  1. We now see that the ImageryLayerCollection spec passes. In addition, the following individual specs in pickImageryLayers now pass:
  1. I created a spec providing coverage for imageryLayers.length === 0 in pickImageryLayers. (see above)

  2. The following paths can be found in pickImageryHelper:

  • line 356 -> undefined pickedTile
  • line 370 -> pickFeatures && !defined(provider.pickFeatures)
  • line 374 -> !Rectangle.contains(imagery.rectangle, pickedLocation)

Should specs covering these paths go in a separate describe, or should they be implemented in "pickImageryLayers" or "pickImageryLayerFeatures"? Do you have any suggestions for how to cover these paths?

  1. I moved the updateUntilDone helper function out of the describe block of "pickImageryLayers" and "pickImageryLayerFeatures". updateUntilDone is now a stand-alone function, making the code cleaner looking.

  2. I removed tests from pickImageryLayers that referenced ImageryProvider.pickFeatures and pickFeatures references from "returns imagery from one layer" and "returns imagery from two layers" in "pickImageryLayers".

@lilleyse
Copy link
Contributor

lilleyse commented Jul 16, 2021

Should specs covering these paths go in a separate describe, or should they be implemented in "pickImageryLayers" or "pickImageryLayerFeatures"? Do you have any suggestions for how to cover these paths?

The specs can be put in the group they're most relevant to. If there's overlap I think pickImageryLayers is fine because it's the more general capability. This is how I would do it:

pickImageryLayers describe block

  • line 356 -> undefined pickedTile
  • line 374 -> !Rectangle.contains(imagery.rectangle, pickedLocation)

pickImageryLayerFeatures describe block

  • line 370 -> pickFeatures && !defined(provider.pickFeatures)

@srothst1
Copy link
Contributor Author

@lilleyse I apologize for the delay - I just added three specs that should address the cases outlined above.

"continues if imagery rectangle does not contain picked location" covers the following code in ImageryLayerCollection.js when run individually (checked using DevTools)

    if (!Rectangle.contains(imagery.rectangle, pickedLocation)) {
      continue;
    }

However, coverage is not shown when running npm run coverage.

image

Any ideas of why we are seeing this behavior?

Copy link
Contributor

@lilleyse lilleyse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"pickImageryHelper returns if undefined tile picked"
"continues if imagery rectangle does not contain picked location"

These descriptions could be improved. They should be describing the behavior, not how the code is written. Maybe instead:

  • pickImageryLayers returns undefined if no tiles are picked
  • pickImageryLayers skips imagery layers that don't overlap the picked location
"pickImageryHelper continues if provider.pickFeatures is undefined"

This ought to already be covered by returns undefined when ImageryProvider does not implement pickFeatures...

"continues if imagery rectangle does not contain picked location" covers the following code in ImageryLayerCollection.js when run individually (checked using DevTools)
...
However, coverage is not shown when running npm run coverage.

This is most likely related to #9651 (comment). You'll need to get to the bottom of why. This could also explain why other tests aren't hitting the right code.

Comment on lines 291 to 306
var customScene;
var customGlobe;
var customCamera;

beforeAll(function () {
scene = createScene();
globe = scene.globe = new Globe();
camera = scene.camera;

scene.frameState.passes.render = true;
//NEW:
customScene = createScene();
customGlobe = customScene.globe = new Globe();
customCamera = customScene.camera;

customScene.frameState.passes.render = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these custom variables used for? Feels like a strange workaround.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally added the set of custom variables because the spec "pickImageryLayers returns undefined if no tiles are picked" modifies globe._surface._tilesToRender and I do not want this change to impact the other specs.

Copy link
Contributor

@lilleyse lilleyse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@srothst1 just one comment and then this PR can be merged.

* Asynchronously determines the imagery layer features that are intersected by a pick ray. The intersected imagery
* layer features are found by invoking {@link ImageryProvider#pickFeatures} for each imagery layer tile intersected
* by the pick ray. To compute a pick ray from a location on the screen, use {@link Camera.getPickRay}.
* Helper function for `pickImageryLayers` and `pickImageryLayerFeatures`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine to remove the documentation above pickImageryHelper since it's a local function.

Also some of the doc is misformatted (I think in @return) which is causing CI to fail, but no need to worry about since the doc will be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lilleyse I just removed the documentation above pickImageryHelper. CI now passes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@lilleyse
Copy link
Contributor

@srothst1 Sorry one last thing - could you add an entry to CHANGES.md?

@srothst1
Copy link
Contributor Author

@lilleyse done!

@lilleyse
Copy link
Contributor

  • Added the ability to select imagery layers. #9651

This could use a little more detail, maybe:

  • Added ImageryLayerCollection.pickImageryLayers which determines the imagery layers that are intersected by a pick ray. #9651

@lilleyse lilleyse merged commit 1cf9d5b into main Jul 26, 2021
@lilleyse lilleyse deleted the drillpick-imagery-layer branch July 26, 2021 18:01
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.

Pick/drillpick imagery layer
3 participants