How to Use Cesium Geocoder in Unreal Engine 5.3 (v2.16.0) to Create a Google Earth-Style Fly-To Feature?

Hi everyone :waving_hand:,

I’m currently working on a Google Earth-style project in Unreal Engine 5.3 using the latest Cesium for Unreal v2.16.0.

I noticed that this new version includes a Blueprint function under:
:backhand_index_pointing_right: Cesium → Geocoder → Geocode
which allows us to query the Cesium ion geocoder directly.


:white_check_mark: What I’m Trying to Do

I want to create a search bar UI (like in Google Earth) where the user can type a location name (e.g., “Paris”, “Mount Everest”, “New York City”) and then the camera should fly to that location on the Cesium globe.


:red_question_mark:What I Need Help With

Can anyone guide me through these steps:

  1. How to use the new Geocode Blueprint function (or C++ API) in Cesium v2.16.0?
  2. How to extract coordinates (longitude, latitude, height) from the geocoder response?
  3. How to smoothly move or fly the camera to that new location using Cesium’s FlyTo function?
  4. Is there a way to do this all in C++ instead of Blueprints (for performance & flexibility)?
  5. Any tips for binding this to a UI search bar input?

:hammer_and_wrench: What I Have Done So Far

  • Cesium plugin is installed and working :white_check_mark:
  • Cesium World Terrain & Globe rendering fine :white_check_mark:
  • Created a basic UI using UMG for the search bar :white_check_mark:
  • Able to manually call FlyToLocation with hardcoded coordinates :white_check_mark:
  • But I’m not sure how to connect user input → geocode → flyTo.

:page_facing_up: System Info:

  • Unreal Engine 5.3 (Windows 11)
  • Cesium for Unreal v2.16.0
  • Cesium ion account linked properly
  • Blueprint + C++ hybrid project

Any help, sample Blueprints, C++ code snippets, or working project examples would be greatly appreciated! :folded_hands:

Thanks in advance,
Piyush Verma

To go step by step:

  1. How to use the new Geocode Blueprint function (or C++ API) in Cesium v2.16.0?

You’ll want a setup like this:


You can call the “Query Cesium ion Geocoder” node from your UI, maybe when a button is pressed, or as the user is typing, or something like that. The parameters are as follows:

  • Ion Access Token - the token you use to access Cesium ion. If you leave this empty, it will use your project’s default token (the same token you use to load tiles from ion). Check the ion tokens page to make sure this token has access to the geocode scope!
  • Cesium Ion Server - this is the object containing information on the Cesium ion server to connect to. If unspecified, your project’s default server will be used. You would probably only change this if you’re using Cesium ion Self-Hosted or something like that where you need to be able to specify a different URL for Cesium ion.
  • Provider Type - Cesium ion calls out to the Google or Bing geocoding services on the backend to actually perform the query. If you’re going to be using this geocoding query with Google data (like Google Photorealistic 3D Tiles), you should use the Google geocoder. If you’re using it with Bing data (like the Bing Maps raster overlays), you should use the Bing geocoder. If you aren’t using either of these, you can pick whichever you prefer or pick “Default” if you don’t care.
  • Request Type - This can be either Search or Autocomplete. Autocomplete should be used when you’re making queries as the user is typing - for example, the way Google Maps displays the list of results as you’re still typing in the address you’re looking for. Search should be used when the user completes their query - clicks the search button, presses enter, that sort of thing.
  • Query - this is the actual query string you obtained from the user. It’s whatever the user wants to search.

The “Query Cesium ion Geocoder” node is an asynchronous operation - it runs in the background while your code does other things. The first white exec pin off the node will run immediately after the query is sent, and the second white exec pin - the one marked On Geocode Request Complete - will run when the query finishes. When this second pin runs, the remaining pins will be set. Success will be true if the geocoding completed successfully or false if it failed. If the request failed, Error will be an error string with information on why the request failed. If it succeeded, Result will be a CesiumGeocoderServiceResult object. A CesiumGeocoderServiceResult object contains two fields - Attributions, which is a list of credits you should show on screen (you can put this into a RichTextBlock on your UI), and Features, which is an array of the locations found by the query. Which brings us to…

  1. How to extract coordinates (longitude, latitude, height) from the geocoder response?

This is pretty simple - just loop through the results (or some other way of getting elements from an array) and break the CesiumGeocoderServiceFeature structs the array contains:


The Display Name property is what you should show to users - for example, for my query “philadelphia,” the first result has the display name “Philadelphia, PA, USA.”

The Longitude Latitude Height and Globe Rectangle properties contain the actual location information. There’s a bit of subtlety here - some geocoding results return areas (like if you search up “Manhattan,” you might get back the box that includes Manhattan instead of just a point in Manhattan), while others just return positions. For ease of use, we paper over the difference - if you ask for a Longitude Latitude Height and the geocoding query returned a box, we will give you back the center of the box. If you ask for a Globe Rectangle and the geocoding query returned a point, we give you a “box” where all corners are set to that point we got back.

In short: to extract the coordinates, just use the Longitude Latitude Height pin on “Break Cesium Geocoder Service Feature.”

  1. How to smoothly move or fly the camera to that new location using Cesium’s FlyTo function?

This one is even simpler - just get your hands on a reference to the DynamicPawn you’re using and call “Fly to Location Longitude Latitude Height” on it:

  1. Is there a way to do this all in C++ instead of Blueprints (for performance & flexibility)?

Yes! Just take a look at how the Blueprint node is implemented.

  1. Any tips for binding this to a UI search bar input?

I don’t think there’s anything special here beyond how you would regularly add Blueprint nodes to a UI. Just try to find some way to handle the fact that georeference queries are async - for example, you could have a “QueryRunning” boolean that you set to true using the first exec pin off of the “Query Cesium ion Geocoder” node, and then set to false in the On Geocode Request Complete exec pin. You can then set up your blueprint to only run geocoding queries when QueryRunning is false, so that you don’t end up running multiple queries before the first one has completed. You could also add some kind of loading indicator using this boolean.

Hope this helps!

1 Like

Thanks for that.

If a character-by-character autocomplete is set up, will that be one Geocode counted towards plan limits per character typed? Or more like a root session thing?

@shimonko The geocoding quota (which I believe is 50,000 geocodes per month) is measured by requests, so more or less how often the “Query Cesium ion Geocoder” node is called. Both “autocomplete” and “search” requests count the same, so you could try to throttle the number of requests (use a timer to not request any faster than once every few seconds, for example), or turn off autocomplete if you’re worried about hitting this quota.

1 Like

I have no idea about the results from the autocomplete - both with Bing and Google. I did expect to see an operation similar to Geocoding in Cesium using Pelias – Cesium. Trying Google Places and LocationIQ’s AutoComplete APIs to make sure I’m not on crack, I do indeed get the sort of results that make sense. For the example of Statue of Liberty, Google Places and LocationIQ’s are homing in on what I wanted after 4 or 5 characters, but Cesium never seems to get there. Also tried urlencoding the search string in case spaces were making it fail, but that got even worse.

Here’s a character by character result list:

Furthermore, the location returned when Cesium (Google) returned New York, NY 1004, USA was pretty close to where Google Maps would center a map if searching for New York, NY 1004, USA - which was 1.8 km from the Statue of Liberty.

Hi @shimonko,
Thanks for posting those results. I’ve reported this to the Cesium ion team, who are responsible for the geocoder.

Hi @shimonko,

Thanks for sharing those results. Cesium ion is using either the Bing or Google Geocoder API results (depending on how the client is configured). It is not currently using the Google Place API to search for places. It appears that the Google Geocoder API is may be expecting addresses only and not place names. Leveraging both of those APIs for results may be something we consider adding in the future.

Ok, I’m starting to see what’s going on. The demo at Google’s Geocoding API shows good Autocomplete functionality - however behind the scenes they’re additionally using their AutoComplete API. Bit sneaky.

Indeed Google say:

The Geocoding API is best for handling unambiguous queries: complete postal address strings (for example, “48 Pirrama Rd, Pyrmont, NSW, Australia”).

However, Geocoding API is not recommended if your application handles ambiguous or incomplete queries, such as “123 Main St”, or if it handles queries that may contain non-address information such as apartment numbers or business names.

I’ve found even something unique like “18 William St, Randwi” won’t match until “18 William St, Randwic” is typed - so I guess it more suited for filling out forms requiring full official addresses than searching for locations and picking the match from a dropdown of partial matches so far.

Not quite sure how CesiumIonClient::GeocoderRequestType::Autocomplete differs from CesiumIonClient::GeocoderRequestType::Search though. Both seem to give the same results.

Another curious observation is that is place names are somewhat matched - e.g. if I search for “Smithsonian” - it’ll return a street address and lat/lon.

It happens to be the Smithsonian Institution in DC, but it could have been the one in NY, or the Smithsonian Natural History Museum or any other Smithsonian.

Google’s Geocoding API also doesn’t return the matched name - but does include the Place ID - requiring another API call to indicate what was found. I’m definitely on a different wavelength…