Do REST calls work within Sandcastle?

1. A concise explanation of the problem you’re experiencing.

I have developed a reverse geocoder for Cesium using the BingMaps API. It works perfectly in my html page, running locally on my Cesium server.

I was thinking of checking it in as a Sandcastle example…it works around CORS which BingMaps doesn’t support.

But the call fails every time. Is this expected? Or am I missing something?

2. A minimal code example. If you’ve found a bug, this helps us reproduce and repair it.

**** var requestString = “http://dev.virtualearth.net/REST/v1/Locations/” + latitude + “,” + longitude + “?jsonp=GeocodeCallback&key=”;

// Call the Cesium jsonp

Cesium.loadJsonp(requestString).then(function(data) {

console.log(“Success in getting response”);

}).otherwise(function(error) {

**console.log("Error in getting response: " + error); ** //It always ends up here…

});

When I run it in my html page on the local server, it works only with my key, and not with the Cesium default key…

In Sandcastle, it doesn’t work no matter which key I use.

I am using as a starting point the “HelloWorld” Sandcastle example.

3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

The specification for the reverse geocoder, is:

If the user clicks any location on the map, the location will be marked by a red point, and the address (or zip code if no address) will show in the entity label.

4. The Cesium version you’re using, your operating system and browser.

Version 1.39, Mac Sierra, Chrome

Not related to Sandcastle. The Cesium jsonp function handles the callback function name automatically. You should not include it in the query string. Compare your code with how the Bing Geocoder service calls the jsonp function correctly:

https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Core/BingMapsGeocoderService.js#L85

Thank you Scott…yeah…I had seen this, and I will try to work more with it, see what can be done.
Thanks again,

Martine

Well I tried as many ways I could think of to approach this, but I definitely must be doing something wrong…

Looking at the parameters for loadJsonp, there is the url…OK…the query…I guess in the case of a reverse geocoder, it should be **latitude + ‘,’ + longitude **

Do I need to add anything to the query? like format, or something like that (since BingMaps loves to return XML)? Anything else?

As for the callbackParameterName, I looked at the loadJsonp code in loadJsonp.js, and still can’t figure out how to call it…

The callbackParameterName is set to ‘jsonp’, so I tried to set it to my own callback and set a breakpoint, but it was never called.

If I leave the callbackParameterName as ‘jsonp’, i always get the same address in response…somewhere in TX :slight_smile:

Obviously, I am missing something…

What is the recommended way to call loadJsonp? Is there another example I can look at?

On my local server, everything works, whether I use jsonp or the example here: https://blogs.bing.com/maps/2015/03/05/accessing-the-bing-maps-rest-services-from-various-javascript-frameworks

I am trying to get something to work in sandcastle, so I can add a reverse geocoder into Cesium…is this a worthwhile endeavor?

Thank you!

Martine

Here’s a working Sandcastle example that calls the reverse geocoder service and prints the result to the console. You can compare with your code to see where you went wrong.

https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=Hello%20World.html&label=Showcases&gist=ddcfdb9cbeaa63026823212f0d17f49f

Ah, thank you Scott! It was not really evident that the lat/long position had to be added to the url, and not to the query…
Thanks to you and Gabby, I finished my reverse geocoder, and it now works fine in Sandcastle…

When the user clicks on a spot on the map, a point is generated in this spot, and the label displays the address, or state and zip if there is no definite address.

I am attaching the file reverseGeocoder.js with the code. It can be pasted into Sandcastle.

If there is any interest, I will be happy to add it to Sandcastle once I know how :slight_smile:

Thanks again for your help!!

Martine

OK. It looks like attaching the file will not work…So here is the code, ready to be pasted into Sandcastle.

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var baseUrl = ‘https://dev.virtualearth.net/REST/v1/Locations/’;

// To display our results

var geoLocation = {

latitude: 0.00,

longitude: 0.00,

address: ‘default address’

};

//Start reverse geocoding process

function getAddressFromLocation(geoLocation) {

var url = baseUrl + geoLocation.latitude + “,” + geoLocation.longitude;

var promise = Cesium.loadJsonp(url, {

parameters : {

key : Cesium.BingMapsApi.getKey()

},

callbackParameterName : ‘jsonp’

});

promise.then(function(result) {

geoLocation.address = result.resourceSets[0].resources[0].name;

setLocationPoint();

}).otherwise(function(error) {

console.log("ERROR getting address: " + error);

});

};

// handler for left click of the mouse on the map, and get latitude and longitude.

var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

// Catch the mouse click, and convert the location into degrees

handler.setInputAction(

// Translate mouse click into Geographic coordinates

function (click) {

var position = viewer.camera.pickEllipsoid(click.position);

var location = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);

geoLocation.latitude = Cesium.Math.toDegrees(location.latitude);

geoLocation.longitude = Cesium.Math.toDegrees(location.longitude);

// Reverse geocode to get the address

getAddressFromLocation(geoLocation);

},

Cesium.ScreenSpaceEventType.LEFT_CLICK

);

// Set a point, and mark reverse geocoded location

function setLocationPoint() {

var entity = viewer.entities.add({

name : ‘address location’,

// Reverse the latitude and longitude when calling “fromDegrees”

position : Cesium.Cartesian3.fromDegrees(geoLocation.longitude, geoLocation.latitude),

point : {

pixelSize : 5,

color : Cesium.Color.RED,

outlineColor : Cesium.Color.WHITE,

outlineWidth : 2

},

label : {

text : geoLocation.address,

font : ‘14pt monospace’,

style: Cesium.LabelStyle.FILL_AND_OUTLINE,

outlineWidth : 2,

verticalOrigin : Cesium.VerticalOrigin.BOTTOM,

pixelOffset : new Cesium.Cartesian2(0, -9)

}

});

};

Awesome, thanks for the code sample!

We’d love to have contributions to Sandcastle. Perhaps you can add your reverse geocoder to the already existing Geocoder example. To get started contributing, checkout CONTRIBUTING.md on GitHub. You’ll need to fill out a Contributor Licence Agreement (CLA), and then you should be good to open a pull request.

Thanks!

Gabby

Looks like the existing Geocoder is a custom geocoder that queries openstreetmap…
I can also write a custom Reverse Geocoder, but the one I wrote uses Cesium’s default geocoder service from BingMaps…

So should I file a “Beginner” issue, asking for a default reverse geocoder in Sandcastle?

Thank you!

Martine

Hi Martine,

You can add some additional code to that example, or create a whole new example. Using BingMaps is fine! No need to create a new issue, just open a pull request with the code changes.

Thanks,

Gabby