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

Added HereMaps as an additional ImageryProvider #6241

Closed
wants to merge 16 commits into from

Conversation

themikelester
Copy link

This is based on Kevin Ring's initial implementation mentioned in this discussion: https://groups.google.com/forum/#!topic/cesium-dev/-JZK_zVhYNA.

I've cleaned it up, added some user-exposed options and added full support for credits. The HereMaps attribution system is rectangle-based and very similar to BingMaps, so I tried to copy that style as much as possible.

Doarama will be using this for an upcoming event with a client, so I thought it might be useful to submit back upstream. I'll also write some tests similar to BingMaps and update this PR.

@cesium-concierge
Copy link

Please sign the CLA before we review this PR.

Welcome to the Cesium community @themikelester!

Can you please send in a Contributor License Agreement (CLA) so that we can review and merge this pull request?

⚠️ I noticed that CHANGES.md has not been updated. If this change updates the public API in any way, fixes a bug, or makes any non-trivial update, please add a bullet point to CHANGES.md and comment on this pull request so we know it was updated. For more info, see the Pull Request Guidelines.


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

🌍 🌎 🌏

@themikelester
Copy link
Author

Fixed eslint errors, updated CHANGES and CONTRIBUTORS

@themikelester
Copy link
Author

Submitted Contributor License Agreement

@pjcozzi
Copy link
Contributor

pjcozzi commented Feb 21, 2018

Thanks @themikelester, we received your CLA.

We'll find someone to review this. In the meantime, two quick things:

  • Could you please add unit tests? Here is the Testing Guide and you could check out any of the imagery provider tests in the Specs/Scene directory.
  • Please don't leave any TODO comments in the code. Address them or submit an issue to this repo so we can consider it for the future.

Also, if you let us know what else you plan to contribute (post processing, other effects, etc.), we are happy to help point you in the right direction.

BTW, are you going to GDC this year?

@themikelester
Copy link
Author

I'll write some unit tests as soon as I can. Regarding that TODO, I don't fully understand the use of TileDiscardPolicy yet. It sounds like Bing occasionally sends invalid tiles when they temporarily don't have imagery for a specific location. Is that the case? If so I haven't used Here enough to know if they do the same thing.

Unfortunately I won't be able to get to GDC this year, I'm currently in Sydney at Doarama HQ for a few months. I'll start a forum thread for other contributions, I've got some ideas.

@pjcozzi
Copy link
Contributor

pjcozzi commented Feb 21, 2018

All sounds good.

@tfili can advise on TileDiscardPolicy.

@themikelester
Copy link
Author

themikelester commented Feb 22, 2018

I added tests based on those written for the BingMapsImageryProvider, and switched all the url strings to use the new Resource interface.

@shunter
Copy link
Contributor

shunter commented Feb 22, 2018

The TileDiscardPolicy is to detect and reject the placeholder images that Bing returns when they don't have imagery at the requested zoom level.

They return this image for any request, even with an absurd level of detail:

https://ecn.t1.tiles.virtualearth.net/tiles/a030130012123122.jpeg?g=6299
https://ecn.t1.tiles.virtualearth.net/tiles/a030130012123122000000000.jpeg?g=6299

So we need to detect and ignore this image. Other imagery providers may not have this need.

* @constructor
*
* @param {Object} options Object with the following properties:
* @param {String} [options.baseUrl="aerial.maps.api.here.com"] The URL for accessing tiles, without the Load Balancing prefix.
Copy link
Contributor

Choose a reason for hiding this comment

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

This parameter is usually name url on the other providers. It should also be a {Resource|String}. You can use Resource.createIfNeeded method to create or clone the resource.

Copy link
Author

Choose a reason for hiding this comment

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

I did notice that's what the new ImageryProviders were doing. The problem is that HereMaps uses a subdomain [1,2,3, or 4] before all their requests. E.g. all urls start with http://2.aerial.... I couldn't see a good way of doing that with Resource, which seemed like it only wanted to handle Subresources (i.e. appending to the end of the url). That's also why I named it baseUrl, because there's no way of specifying a full url that would be useful.

Should I just have options.url expect something like "http://aerial.maps.api.here.com" and then manually stick the subdomain in the middle there?

* @param {String} [options.baseUrl="aerial.maps.api.here.com"] The URL for accessing tiles, without the Load Balancing prefix.
* You may use the *.maps.cit.api.here.com URLs during development. The first part of the URL determines which tileTypes
*. are available.
* @param {String} [options.tileType="maptile"] Determines which type of image will be delivered. E.g. Map, Labels, Streets, etc.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a list of all valid values we can provide?

* You may use the *.maps.cit.api.here.com URLs during development. The first part of the URL determines which tileTypes
*. are available.
* @param {String} [options.tileType="maptile"] Determines which type of image will be delivered. E.g. Map, Labels, Streets, etc.
* @param {String} [options.scheme="satellite.day"] Specifies the view scheme, e.g normal.day, normal.night, terrain.day, etc.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we know all the valid values here too? (Sorry to ask a bunch of questions. I don't know anything about here maps).

this._ready = false;
this._readyPromise = when.defer();

//@TODO: Do we need to support DiscardMissingTileImagePolicy?
Copy link
Contributor

Choose a reason for hiding this comment

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

Obviously figure out if this is needed. Add a DiscardMissingTileImagePolicy or remove the to do. Is there a way Here tells us that there isn't a tile here?

Copy link
Author

Choose a reason for hiding this comment

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

I'm looking into this. I can't find any mention of what they do in the case of missing tiles in their documentation, but I'll start searching Antarctica and see if I can find one 😄

Copy link
Author

Choose a reason for hiding this comment

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

After zooming into some remote parts of the world, it appears that they always return a valid tile for any zoom level. If they don't have true imagery for it they use a rescaled version of one of the lower zoom levels. I assume this means we should just use the default DiscardMissingTileImagePolicy?

*/
proxy : {
get : function() {
return this._proxy;
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't set anywhere. It is actually a property of the resource. You can remove this property. Other providers have it for backwards compatibility reasons from pre-Resource days and will probably be deprecated.

Copy link
Author

Choose a reason for hiding this comment

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

This gets set on line 86. But I assume this is no longer part of the ImageryProvider interface? I'll remove it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oops. Forgot about the interface. That's why we haven't deprecated it yet. Keep it in there, but pass it into the resource as an option to createIfNeeded.

Copy link
Author

Choose a reason for hiding this comment

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

OK I'll revert that change. It is passed in to the Resource on line 105. That resource is used to create all other requests. There is also a test case that covers usage of the proxy, and it's passing.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see that. If you look at Bing and the other providers, they no longer have a _proxy member. They do a return this._resource.proxy;

}

return HereMapsImageryProvider;
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Add newline at end of file.

Copy link
Author

Choose a reason for hiding this comment

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

Done!

var HereMapsImageryProvider = function HereMapsImageryProvider(options) {
options = defaultValue(options, {});

//>>includeStart('debug', pragmas.debug);
Copy link
Contributor

Choose a reason for hiding this comment

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

appId and appCode aren't in the doc section as options.

Copy link
Author

Choose a reason for hiding this comment

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

Done!

var mapId = 'newest';

var baseResource = new Resource({
url: '//{subdomain}.' + this._baseUrl,
Copy link
Contributor

Choose a reason for hiding this comment

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

This is an odd setup. We can change the URL, but all are required to have 4 subdomains?

Copy link
Author

Choose a reason for hiding this comment

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

That's right. HereMaps forces us to always use one of the four subdomains. Which is why I chose not to accept a Resource or full url in the options object. We basically have to always construct the URL.

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 the possible URLs? Are they all like aerial.maps.api.here.com? Do they always end in maps.api.here.com? I'm not sure of the cleanest way to handle this.

Copy link
Author

Choose a reason for hiding this comment

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

There's documentation in baseUrl description in the constructor docs. Basically the url is *.maps.api.here.com, where * is one of <aerial|base|pano|traffic>. They've got good API documentation here: https://developer.here.com/documentation/map-tile/topics/request-constructing.html.

The url construction is more complicated than Bing, and the *.maps.api subdomain that you pick determines a lot of the other settings that are viable. Because of this I chose to put more impetus on the user to read the docs and determine what options are usable, rather than try to enumerate all the options and their dependencies like BingMapsStyle. The documentation has links to all the HereMaps API documentation that a user might need. I hope this is an acceptable level of complexity for a Cesium user who wants to use Here. The default settings should cover the common case.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok. So essentially the subdomain and type are part of the REST API even though they are in the domain, which is a little odd. What do you think of this? Take a options.url that is a string or resource (http://maps.api.here.com) and a options.type. Then from there you build the URL.

I think this is the best option, since that is how the URL is formatted. Also, for parsing the url we have a ThirdParty/Uri that might help.

Copy link
Author

Choose a reason for hiding this comment

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

That scheme sounds good to me. ThirdParty/Uri looks nice, thanks for pointing me to it.

@pjcozzi
Copy link
Contributor

pjcozzi commented Jun 18, 2018

@themikelester I see that you made a bunch of commits to this after the last round of feedback. Is this ready for another review or do you still have more to do here?

@pjcozzi
Copy link
Contributor

pjcozzi commented Oct 6, 2018

@themikelester is this ready for another review? If not, do you still plan to finish this or should we close it?

@cesium-concierge
Copy link

Thanks again for your contribution @themikelester!

No one has commented on this pull request in 30 days. Maintainers, can you review, merge or close to keep things tidy?

I'm going to re-bump this in 30 days. If you'd like me to stop, just comment with @cesium-concierge stop. If you want me to start again, just delete the comment.


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

🌍 🌎 🌏

@hpinkos
Copy link
Contributor

hpinkos commented Dec 12, 2018

@themikelester I'm going to close the PR since we haven't heard from you. Please re-open this if you are still interested in getting this merged! Thanks for contributing =)

@hpinkos hpinkos closed this Dec 12, 2018
@cesium-concierge
Copy link

Congratulations on closing the issue! I found these Cesium forum links in the comments above:

https://groups.google.com/forum/#!topic/cesium-dev/-JZK_zVhYNA

If this issue affects any of these threads, please post a comment like the following:

The issue at #6241 has just been closed and may resolve your issue. Look for the change in the next stable release of Cesium or get it now in the master branch on GitHub https://github.com/AnalyticalGraphicsInc/cesium.


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

🌍 🌎 🌏

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.

None yet

6 participants