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

Support imagery in alternate map projections #7438

Closed
wants to merge 17 commits into from

Conversation

likangning93
Copy link
Contributor

Take 2. See discussion in attempt 1 here.

This PR adds support for imagery in alternate projections, for example, the kind of TMS you would get from throwing a geotiff of LIMA through GDAL2Tiles using the raster profile. There's also some of this stuff hosted online, like in the new Sandcastle:

cassini_poles

Reprojection is once again accomplished with a fixed-resolution vertex warp grid that is much less sophisticated than what OpenLayers advertises and might need further discussion.

However, instead of projecting each image into a geographic tile that overlaps its neighbors, we're generating non-overlapping geographic tiles that may draw from 0 or more projected imagery tiles.
This seems to have gotten around most of the craziness in the first attempt.

@cesium-concierge
Copy link

Thanks for the pull request @likangning93!

  • ✔️ Signed CLA found.

Reviewers, don't forget to make sure that:

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

I am a bot who helps you make Cesium awesome! Contributions to my configuration are welcome.

🌍 🌎 🌏

@@ -15,7 +15,8 @@ define([
READY : 4,
FAILED : 5,
INVALID : 6,
PLACEHOLDER : 7
PLACEHOLDER : 7,
EMPTY : 8

Choose a reason for hiding this comment

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

lol

@mramato
Copy link
Contributor

mramato commented Jan 2, 2019

@likangning93 would automatically handling imagery servers that support different projections be possible/easy once this is done? See #7435 which shows that ArcGisMapServerImageryProvider should be able to detect other projections and act accordingly, right? (Not for projections MVP, but something we should probably support eventually)

@likangning93
Copy link
Contributor Author

@likangning93 would automatically handling imagery servers that support different projections be possible/easy once this is done? See #7435 which shows that ArcGisMapServerImageryProvider should be able to detect other projections and act accordingly, right? (Not for projections MVP, but something we should probably support eventually)

I think so? It might be tricky if ArcGisMapServerImageryProvider can't get at a WKT for the projection though, right now everything with projections is assuming WKT is available.

@likangning93
Copy link
Contributor Author

@bagnell this is ready for a look.

@likangning93
Copy link
Contributor Author

@bagnell bump

projectedRectangle : new Cesium.Rectangle(-4194304, -4194304, 4194304, 4194304),
numberOfLevelZeroTilesX : 2,
numberOfLevelZeroTilesY : 2,
imageResolution : new Cesium.Cartesian2(512, 512)
Copy link
Contributor

Choose a reason for hiding this comment

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

imageResolution isn't an option.

*/
ProjectedImageryTilingScheme.prototype.getProjectedTilesForNativeTile = function(x, y, level) {
var tileRectangle = this.tileXYToRectangle(x, y, level, new Rectangle());
var tileProjectedRectangle = Rectangle.approximateProjectedExtents(tileRectangle, this._projection, new Rectangle());
Copy link
Contributor

Choose a reason for hiding this comment

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

Use scratch variables.


var tilingScheme = this.imageryLayer.imageryProvider.tilingScheme;
var singleSource = !(tilingScheme instanceof ProjectedImageryTilingScheme);
var imageryLayer = this.imageryLayer;
Copy link
Contributor

Choose a reason for hiding this comment

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

Move this to the top of the function and replace the other this.imageryLayers.

var index = i * 2;
var x = projectedIndices[index];
var y = projectedIndices[index + 1];
this.projectedRectangles[i] = tilingScheme.getProjectedTileProjectedRectangle(x, y, level);
Copy link
Contributor

Choose a reason for hiding this comment

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

Pass this.projectedRectangles[i] as the result parameter. This way it doesn't always create new Rectangles.

}

// Mark discarded imagery tiles invalid. Parent imagery will be used instead.
if (discardPolicy.shouldDiscardImage(projectedImages[0])) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this have a mix of images that should be discarded and some that should not? If so, you should discard the ones that need to be and, if all are discarded, set the state to invalid.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

discard the ones that need to be

If only some of the images are discarded do we need to fill in the missing areas using the parent image? Is it too heavy-handed to mark the entire tile as invalid if one of its images is discarded?

If we're filling in, maybe we could grab the parent's reprojected image and copy over select areas. We can use the computed texcoords like a mask but read out of the parent texture using the fragment coordinates and another uniform or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

grab the parent's reprojected image

There might be complications with this too, if the parent isn't available would we want to go for the nearest ancestor instead? If so, would we want to regenerate the tile when the parent becomes available?

-___-

Copy link
Contributor

Choose a reason for hiding this comment

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

Those are good questions. Maybe open an issue? What do you think @lilleyse?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Had a discussion offline, we'll just discard the entire "target" tile for now when any of the source images are invalidated. I'll document the behavior.

Source/Scene/ImageryLayer.js Show resolved Hide resolved
when,
Imagery,
ImagerySplitDirection,
ImageryState,
TileImagery) {
'use strict';

var ARBITRARY_PROJECTION_VERTICES_WIDTH = 128;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should these be configurable?

Source/Scene/ImageryLayer.js Show resolved Hide resolved
}

if (projectedTilesLength === 0) {
this.state = ImageryState.EMPTY;
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be marked as invalid instead?

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 think if it was INVALID an ancestor would be rendered, but the rendered portion would be entirely transparent so we might as well just not render anything:

img_20190116_145731914

Copy link
Contributor

Choose a reason for hiding this comment

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

What if imagery was requested past the zoom level of the imagery? It should render the ancestor there. Is there a way to tell the difference between this and the case you posted?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussed offline, this happens when users don't set a max level and the terrain tile might need an INVALID imagery to upsample correctly. Just looping the state machine when the imagery isn't actually "ready" might cause problems, so I'll replace with INVALID.


void main()
{
bool inBounds = 0.0 < v_textureCoordinates.x && v_textureCoordinates.x < 1.0 && 0.0 < v_textureCoordinates.y && v_textureCoordinates.y < 1.0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this include 0.0 and 1.0?

@likangning93
Copy link
Contributor Author

@bagnell this is up-to-date!

@mramato
Copy link
Contributor

mramato commented Jan 23, 2019

It might be better to hold off on merging this until we get the main projection branch into master (since these PRs are related but build on each other as separate features, it would be easier to review projections as-is first.

@hpinkos
Copy link
Contributor

hpinkos commented Sep 18, 2019

@likangning93 what's the plan for this PR?

@likangning93
Copy link
Contributor Author

what's the plan for this PR?

@mramato?

It wouldn't be ideal, but if nobody has time to review this I can make my peace with closing this unmerged.

@hpinkos
Copy link
Contributor

hpinkos commented Sep 18, 2019

Spoke with @mramato offline, and we're going to leave these open for now and will hopefully be able to finish them up soon

@ebogo1
Copy link
Contributor

ebogo1 commented Sep 23, 2021

At this point the branches are out of date and it'd be a lot of effort to get this PR ready. I'll leave the branch around if we want to look at this again in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

7 participants