Skip to content

Implement the Cesium ion geocoder #582

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

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions Runtime/CesiumIonGeocoder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using Reinterop;
using System.Collections;
using System.Threading.Tasks;
using Unity.Mathematics;
using UnityEngine;

namespace CesiumForUnity
{
/**
* @brief The supported types of requests to geocoding API.
*/
public enum CesiumIonGeocoderRequestType
{
/**
* @brief Perform a full search from a complete query.
*/
Search,

/**
* @brief Perform a quick search based on partial input, such as while a user
* is typing.
* The search results may be less accurate or exhaustive than using {@link GeocoderRequestType::Search}.
*/
Autocomplete
}

/**
* @brief The supported providers that can be accessed through ion's geocoder
* API.
*/
public enum CesiumIonGeocoderProviderType
{
/**
* @brief Google geocoder, for use with Google data.
*/
Google,

/**
* @brief Bing geocoder, for use with Bing data.
*/
Bing,

/**
* @brief Use the default geocoder as set on the server. Used when neither
* Bing or Google data is used.
*/
Default
};

public class CesiumIonGeocoderFeature
{
/**
* @brief The user-friendly display name of this feature.
*/
public string displayName;

/**
* @brief The Longitude-Latitude-Height coordinates representing this feature.
*
* If the geocoder service returned a bounding box for this result, this will
* return the bounding box. If the geocoder service returned a coordinate for
* this result, this will return a zero-width rectangle at that coordinate.
*/
public double3 positionLlh;
}


/**
* @brief Attribution information for a query to a geocoder service.
*/
public class CesiumIonGeocoderAttribution
{
/**
* @brief An HTML string containing the necessary attribution information.
*/
public string html;

/**
* @brief If true, the credit should be visible in the main credit container.
* Otherwise, it can appear in a popover.
*/
public bool showOnScreen;
};

/**
* @brief The result of making a request to a geocoder service.
*/
public class CesiumIonGeocoderResult
{
/**
* @brief Any necessary attributions for this geocoder result.
*/
public CesiumIonGeocoderAttribution[] attributions;

/**
* @brief The features obtained from this geocoder service, if any.
*/
public CesiumIonGeocoderFeature[] features;
};

[ReinteropNativeImplementation("CesiumForUnityNative::CesiumIonGeocoderImpl", "CesiumIonGeocoderImpl.h")]
public partial class CesiumIonGeocoder
{
public partial Task<CesiumIonGeocoderResult> Geocode(
CesiumIonServer ionServer,
string ionToken,
CesiumIonGeocoderProviderType providerType,
CesiumIonGeocoderRequestType requestType,
string query
);
}
}
11 changes: 11 additions & 0 deletions Runtime/CesiumIonGeocoder.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions Runtime/ConfigureReinterop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,23 @@ Cesium3DTilesetLoadFailureDetails tilesetDetails
TestReinterop.ThrowAnException();
System.Exception exception = null;
var message = exception.Message;

CesiumIonGeocoder geocoder = new CesiumIonGeocoder();
CesiumIonGeocoderProviderType providerType = CesiumIonGeocoderProviderType.Google;
CesiumIonGeocoderRequestType requestType = CesiumIonGeocoderRequestType.Autocomplete;
TaskCompletionSource<CesiumIonGeocoderResult> geocoderPromise = new TaskCompletionSource<CesiumIonGeocoderResult>();
geocoderPromise.SetException(new Exception("message"));
CesiumIonGeocoderResult geocoderResult = new CesiumIonGeocoderResult();
geocoderResult.features = new CesiumIonGeocoderFeature[1];
CesiumIonGeocoderFeature geocoderFeature = new CesiumIonGeocoderFeature();
geocoderResult.features[0].displayName = "";
geocoderResult.features[0].positionLlh = new double3(1, 2, 3);
geocoderResult.attributions = new CesiumIonGeocoderAttribution[1];
CesiumIonGeocoderAttribution attribution = new CesiumIonGeocoderAttribution();
attribution.html = "";
attribution.showOnScreen = true;
geocoderPromise.SetResult(geocoderResult);
Task<CesiumIonGeocoderResult> geocoderTask = geocoderPromise.Task;
}
}
}
171 changes: 171 additions & 0 deletions native~/Runtime/src/CesiumIonGeocoderImpl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#include "CesiumIonGeocoderImpl.h"

#include "UnityTilesetExternals.h"

#include <CesiumIonClient/Connection.h>
#include <CesiumIonClient/Geocoder.h>
#include <CesiumUtility/Assert.h>

#include <DotNet/CesiumForUnity/CesiumIonGeocoder.h>
#include <DotNet/CesiumForUnity/CesiumIonGeocoderAttribution.h>
#include <DotNet/CesiumForUnity/CesiumIonGeocoderFeature.h>
#include <DotNet/CesiumForUnity/CesiumIonGeocoderProviderType.h>
#include <DotNet/CesiumForUnity/CesiumIonGeocoderRequestType.h>
#include <DotNet/CesiumForUnity/CesiumIonGeocoderResult.h>
#include <DotNet/CesiumForUnity/CesiumIonServer.h>
#include <DotNet/System/Array1.h>
#include <DotNet/System/Exception.h>
#include <DotNet/System/Threading/Tasks/Task1.h>
#include <DotNet/System/Threading/Tasks/TaskCompletionSource1.h>
#include <DotNet/Unity/Mathematics/double3.h>

namespace {
CesiumIonClient::GeocoderProviderType geocoderProviderTypeEnumToNative(
DotNet::CesiumForUnity::CesiumIonGeocoderProviderType providerType) {
switch (providerType) {
case DotNet::CesiumForUnity::CesiumIonGeocoderProviderType::Bing:
return CesiumIonClient::GeocoderProviderType::Bing;
case DotNet::CesiumForUnity::CesiumIonGeocoderProviderType::Google:
return CesiumIonClient::GeocoderProviderType::Google;
case DotNet::CesiumForUnity::CesiumIonGeocoderProviderType::Default:
return CesiumIonClient::GeocoderProviderType::Default;
}

CESIUM_ASSERT(false && "Invalid CesiumIonGeocoderProviderType value");
return CesiumIonClient::GeocoderProviderType::Default;
}

CesiumIonClient::GeocoderRequestType geocoderRequestTypeEnumToNative(
DotNet::CesiumForUnity::CesiumIonGeocoderRequestType requestType) {
switch (requestType) {
case DotNet::CesiumForUnity::CesiumIonGeocoderRequestType::Autocomplete:
return CesiumIonClient::GeocoderRequestType::Autocomplete;
case DotNet::CesiumForUnity::CesiumIonGeocoderRequestType::Search:
return CesiumIonClient::GeocoderRequestType::Search;
}

CESIUM_ASSERT(false && "Invalid CesiumIonGeocoderRequestType value");
return CesiumIonClient::GeocoderRequestType::Search;
}
} // namespace

namespace CesiumForUnityNative {
CesiumIonGeocoderImpl::CesiumIonGeocoderImpl(
const DotNet::CesiumForUnity::CesiumIonGeocoder& geocoder)
: _pConnection(nullptr) {}

DotNet::System::Threading::Tasks::Task1<
DotNet::CesiumForUnity::CesiumIonGeocoderResult>
CesiumIonGeocoderImpl::Geocode(
const DotNet::CesiumForUnity::CesiumIonGeocoder& /*geocoder*/,
const DotNet::CesiumForUnity::CesiumIonServer& server,
DotNet::System::String ionToken,
DotNet::CesiumForUnity::CesiumIonGeocoderProviderType providerType,
DotNet::CesiumForUnity::CesiumIonGeocoderRequestType requestType,
DotNet::System::String query) {
CesiumAsync::AsyncSystem asyncSystem = getAsyncSystem();

DotNet::System::Threading::Tasks::TaskCompletionSource1<
DotNet::CesiumForUnity::CesiumIonGeocoderResult>
promise{};

getConnection(asyncSystem, server, ionToken)
.thenImmediately(
[providerType, requestType, query](
std::shared_ptr<CesiumIonClient::Connection>&& pConnection) {
return pConnection->geocode(
geocoderProviderTypeEnumToNative(providerType),
geocoderRequestTypeEnumToNative(requestType),
query.ToStlString());
})
.thenImmediately([promise](CesiumIonClient::Response<
CesiumIonClient::GeocoderResult>&& response) {
if (!response.errorCode.empty()) {
promise.SetException(DotNet::System::Exception(DotNet::System::String(
"Ion error code received: " + response.errorCode +
", message: " + response.errorMessage)));
} else {
DotNet::System::Array1<
DotNet::CesiumForUnity::CesiumIonGeocoderAttribution>
attributions(response.value->attributions.size());
for (size_t i = 0; i < response.value->attributions.size(); i++) {
DotNet::CesiumForUnity::CesiumIonGeocoderAttribution attribution;
attribution.html(
DotNet::System::String(response.value->attributions[i].html));
attribution.showOnScreen(
response.value->attributions[i].showOnScreen);
attributions.Item((int32_t)i, attribution);
}

DotNet::System::Array1<
DotNet::CesiumForUnity::CesiumIonGeocoderFeature>
features(response.value->features.size());
for (size_t i = 0; i < response.value->features.size(); i++) {
DotNet::CesiumForUnity::CesiumIonGeocoderFeature feature;
feature.displayName(DotNet::System::String(
response.value->features[i].displayName));
CesiumGeospatial::Cartographic point =
response.value->features[i].getCartographic();
feature.positionLlh(DotNet::Unity::Mathematics::double3(
point.longitude,
point.latitude,
point.height));
features.Item((int32_t)i, feature);
}

DotNet::CesiumForUnity::CesiumIonGeocoderResult geocoderResult;
geocoderResult.attributions(attributions);
geocoderResult.features(features);
promise.SetResult(geocoderResult);
}
});

return promise.Task();
}

CesiumAsync::Future<std::shared_ptr<CesiumIonClient::Connection>>
CesiumIonGeocoderImpl::getConnection(
const CesiumAsync::AsyncSystem& asyncSystem,
const DotNet::CesiumForUnity::CesiumIonServer& server,
DotNet::System::String ionToken) {
if (this->_pConnection != nullptr) {
return asyncSystem.createResolvedFuture(
std::shared_ptr(this->_pConnection));
}

std::shared_ptr<CesiumAsync::IAssetAccessor> pAssetAccessor =
getAssetAccessor();

return CesiumIonClient::Connection::appData(
asyncSystem,
pAssetAccessor,
server.apiUrl().ToStlString())
.thenImmediately(
[ionToken, server, this, asyncSystem, pAssetAccessor](
CesiumIonClient::Response<CesiumIonClient::ApplicationData>&&
response) {
if (!response.value) {
return std::shared_ptr<CesiumIonClient::Connection>(nullptr);
}

this->_connectionMutex.lock();
if (this->_pConnection != nullptr) {
// Another query has already created a connection before this one
// returned.
this->_connectionMutex.unlock();
return this->_pConnection;
}

this->_pConnection = std::make_shared<CesiumIonClient::Connection>(
asyncSystem,
pAssetAccessor,
DotNet::System::String::IsNullOrWhiteSpace(ionToken)
? server.defaultIonAccessToken().ToStlString()
: ionToken.ToStlString(),
*response.value,
server.apiUrl().ToStlString());
this->_connectionMutex.unlock();
return this->_pConnection;
});
}
} // namespace CesiumForUnityNative
54 changes: 54 additions & 0 deletions native~/Runtime/src/CesiumIonGeocoderImpl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#pragma once

#include "CesiumImpl.h"

#include <CesiumAsync/Future.h>

#include <DotNet/System/String.h>
#include <DotNet/System/Threading/Tasks/Task1.h>

#include <mutex>
#include <memory>

namespace DotNet::CesiumForUnity {
class CesiumIonGeocoder;
class CesiumIonGeocoderResult;
enum class CesiumIonGeocoderRequestType;
enum class CesiumIonGeocoderProviderType;
class CesiumIonServer;

} // namespace DotNet::CesiumForUnity

namespace CesiumIonClient {
class Connection;
}

namespace CesiumForUnityNative {

class CesiumIonGeocoderImpl : public CesiumImpl<CesiumIonGeocoderImpl> {
public:
CesiumIonGeocoderImpl(
const DotNet::CesiumForUnity::CesiumIonGeocoder& geocoder);

DotNet::System::Threading::Tasks::Task1<
DotNet::CesiumForUnity::CesiumIonGeocoderResult>
Geocode(
const DotNet::CesiumForUnity::CesiumIonGeocoder& geocoder,
const DotNet::CesiumForUnity::CesiumIonServer& server,
DotNet::System::String ionToken,
DotNet::CesiumForUnity::CesiumIonGeocoderProviderType providerType,
DotNet::CesiumForUnity::CesiumIonGeocoderRequestType requestType,
DotNet::System::String query);

private:
CesiumAsync::Future<std::shared_ptr<CesiumIonClient::Connection>>
getConnection(
const CesiumAsync::AsyncSystem& asyncSystem,
const DotNet::CesiumForUnity::CesiumIonServer& server,
DotNet::System::String ionToken);

std::shared_ptr<CesiumIonClient::Connection> _pConnection;
std::mutex _connectionMutex;
};

} // namespace CesiumForUnityNative
2 changes: 1 addition & 1 deletion native~/extern/cesium-native
Submodule cesium-native updated 72 files
+23 −0 CHANGES.md
+6 −4 CMakeLists.txt
+4 −2 Cesium3DTilesSelection/include/Cesium3DTilesSelection/TileContent.h
+1 −1 Cesium3DTilesSelection/include/Cesium3DTilesSelection/TilesetContentLoaderResult.h
+10 −6 Cesium3DTilesSelection/src/CesiumIonTilesetLoader.cpp
+16 −15 Cesium3DTilesSelection/src/TilesetContentManager.cpp
+91 −19 Cesium3DTilesSelection/src/TilesetJsonLoader.cpp
+21 −0 Cesium3DTilesSelection/test/TestTilesetJsonLoader.cpp
+ Cesium3DTilesSelection/test/data/Voxels/subtrees/0.0.0.subtree
+11 −0 Cesium3DTilesSelection/test/data/Voxels/subtrees/0/0/0/0.json
+105 −0 Cesium3DTilesSelection/test/data/Voxels/tiles/0/0/0/0.gltf
+ Cesium3DTilesSelection/test/data/Voxels/tiles/0/0/0/a.bin
+79 −0 Cesium3DTilesSelection/test/data/Voxels/tileset.json
+45 −0 CesiumCurl/CMakeLists.txt
+130 −0 CesiumCurl/include/CesiumCurl/CurlAssetAccessor.h
+19 −0 CesiumCurl/include/CesiumCurl/Library.h
+538 −0 CesiumCurl/src/CurlAssetAccessor.cpp
+296 −0 CesiumCurl/test/TestCurlAssetAccessor.cpp
+79 −3 CesiumGeometry/src/OrientedBoundingBox.cpp
+22 −0 CesiumGeometry/test/TestOrientedBoundingBox.cpp
+24 −0 CesiumGeospatial/include/CesiumGeospatial/BoundingRegion.h
+26 −0 CesiumGeospatial/src/BoundingRegion.cpp
+2 −0 CesiumITwinClient/CMakeLists.txt
+53 −11 CesiumITwinClient/include/CesiumITwinClient/AuthenticationToken.h
+48 −14 CesiumITwinClient/include/CesiumITwinClient/Connection.h
+90 −0 CesiumITwinClient/include/CesiumITwinClient/GeospatialFeatureCollection.h
+2 −1 CesiumITwinClient/include/CesiumITwinClient/IModel.h
+2 −1 CesiumITwinClient/include/CesiumITwinClient/ITwinRealityData.h
+12 −0 CesiumITwinClient/include/CesiumITwinClient/PagedList.h
+47 −3 CesiumITwinClient/src/AuthenticationToken.cpp
+306 −20 CesiumITwinClient/src/Connection.cpp
+71 −24 CesiumITwinClient/test/MockITwinAssetAccessor.cpp
+5 −6 CesiumITwinClient/test/MockITwinAssetAccessor.h
+103 −7 CesiumITwinClient/test/TestConnection.cpp
+50 −0 CesiumITwinClient/test/data/FeatureCollections.json
+189 −0 CesiumITwinClient/test/data/FeatureService.json
+2 −0 CesiumNativeTests/CMakeLists.txt
+27 −1 CesiumUtility/include/CesiumUtility/JsonHelpers.h
+47 −5 CesiumUtility/src/JsonHelpers.cpp
+52 −0 CesiumVectorData/CMakeLists.txt
+133 −0 CesiumVectorData/include/CesiumVectorData/GeoJsonDocument.h
+715 −0 CesiumVectorData/include/CesiumVectorData/GeoJsonObject.h
+378 −0 CesiumVectorData/include/CesiumVectorData/GeoJsonObjectTypes.h
+18 −0 CesiumVectorData/include/CesiumVectorData/Library.h
+747 −0 CesiumVectorData/src/GeoJsonDocument.cpp
+77 −0 CesiumVectorData/src/GeoJsonObject.cpp
+69 −0 CesiumVectorData/src/GeoJsonObjectTypes.cpp
+560 −0 CesiumVectorData/test/TestGeoJsonObject.cpp
+749 −0 CesiumVectorData/test/TestGeoJsonParser.cpp
+1 −0 CesiumVectorData/test/data/geojson/README.md
+1 −0 CesiumVectorData/test/data/geojson/fire.json
+16 −0 CesiumVectorData/test/data/geojson/line-samples.geojson
+1 −0 CesiumVectorData/test/data/geojson/photovoltaic.json
+16 −0 CesiumVectorData/test/data/geojson/point-samples.geojson
+4 −0 CesiumVectorData/test/data/geojson/point.geojson
+16 −0 CesiumVectorData/test/data/geojson/polygon-samples.geojson
+4,139 −0 CesiumVectorData/test/data/geojson/roads-seoul.geojson
+1 −0 CesiumVectorData/test/data/geojson/ship-trajectories.json
+4 −0 CesiumVectorData/test/data/geojson/switzerland.geojson
+1 −0 CesiumVectorData/test/data/geojson/vienna-streets.geojson
+1 −0 CesiumVectorData/test/data/geojson/world-cities.geojson
+4 −0 README.md
+3 −0 doc/CMakeLists.txt
+12 −0 doc/diagrams/dependencies/CesiumCurl.mmd
+2 −2 doc/diagrams/dependencies/CesiumGltfReader.mmd
+12 −0 doc/diagrams/dependencies/CesiumVectorData.mmd
+17 −11 doc/diagrams/dependencies/all.mmd
+1 −1 doc/img/dependency-graph.svg
+2 −2 doc/topics/rendering-3d-tiles.md
+2 −2 package-lock.json
+1 −1 tools/dep-graph-gen/package-lock.json
+1 −0 vcpkg.json
Loading