From 6fa1099490ed9797a2dbb770658512bca2dd3ca8 Mon Sep 17 00:00:00 2001 From: Baran Kahyaoglu Date: Fri, 13 Feb 2026 21:52:37 +0300 Subject: [PATCH 1/3] custom image api module and terrain fixes add LoadTileData to Terrain module add mapbox map extensions class with TryGetElevation, TryGetMapTile methods fix map visualizer to check inside composite modules when searching fix a bug where terrain module target tile id method wasn't clamped add custom image api module change unity map service to have public getters for data fetcher and cache manager --- .../Data/Interfaces/ITerrainLayerModule.cs | 4 + .../Map/MapInformationStaticMethods.cs | 14 ++- .../BaseModule/Map/MapboxMapExtensions.cs | 68 +++++++++++++++ .../Map/MapboxMapExtensions.cs.meta | 3 + .../BaseModule/Map/MapboxMapVisualizer.cs | 8 ++ Runtime/Mapbox/CustomImageryModule.meta | 8 ++ .../CustomApiLayerModuleScript.cs | 55 ++++++++++++ .../CustomApiLayerModuleScript.cs.meta | 3 + .../CustomImageryModule/CustomSource.cs | 59 +++++++++++++ .../CustomImageryModule/CustomSource.cs.meta | 3 + .../CustomSourceSettings.cs | 14 +++ .../CustomSourceSettings.cs.meta | 3 + .../CustomImageryModule/CustomTMSTile.cs | 35 ++++++++ .../CustomImageryModule/CustomTMSTile.cs.meta | 3 + .../CustomTerrainLayerModuleScript.cs | 46 ++++++++++ .../CustomTerrainLayerModuleScript.cs.meta | 3 + .../CustomTerrainSource.cs | 53 ++++++++++++ .../CustomTerrainSource.cs.meta | 3 + .../Mapbox/CustomImageryModule/Editor.meta | 8 ++ .../CustomApiLayerModuleScriptEditor.cs | 47 ++++++++++ .../CustomApiLayerModuleScriptEditor.cs.meta | 11 +++ .../MapboxCustomImageryModule.Editor.asmdef | 18 ++++ ...pboxCustomImageryModule.Editor.asmdef.meta | 7 ++ .../MapboxCustomImageryModule.asmdef | 18 ++++ .../MapboxCustomImageryModule.asmdef.meta | 7 ++ .../ImageModule/Terrain/TerrainLayerModule.cs | 85 ++++++++++++++----- .../DataSources/ImageSource.cs | 2 +- .../DataSources/TerrainSource.cs | 2 +- .../Mapbox/UnityMapService/MapUnityService.cs | 21 +++-- Tests/Runtime/BaseModule/MapboxMapTests.cs | 48 +++++++++++ 30 files changed, 625 insertions(+), 34 deletions(-) create mode 100644 Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs create mode 100644 Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs.meta create mode 100644 Runtime/Mapbox/CustomImageryModule.meta create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs.meta create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomSource.cs create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomSource.cs.meta create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs.meta create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs.meta create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs.meta create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs create mode 100644 Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs.meta create mode 100644 Runtime/Mapbox/CustomImageryModule/Editor.meta create mode 100644 Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs create mode 100644 Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs.meta create mode 100644 Runtime/Mapbox/CustomImageryModule/Editor/MapboxCustomImageryModule.Editor.asmdef create mode 100644 Runtime/Mapbox/CustomImageryModule/Editor/MapboxCustomImageryModule.Editor.asmdef.meta create mode 100644 Runtime/Mapbox/CustomImageryModule/MapboxCustomImageryModule.asmdef create mode 100644 Runtime/Mapbox/CustomImageryModule/MapboxCustomImageryModule.asmdef.meta diff --git a/Runtime/Mapbox/BaseModule/Data/Interfaces/ITerrainLayerModule.cs b/Runtime/Mapbox/BaseModule/Data/Interfaces/ITerrainLayerModule.cs index ef892eb4c..032a06ae1 100644 --- a/Runtime/Mapbox/BaseModule/Data/Interfaces/ITerrainLayerModule.cs +++ b/Runtime/Mapbox/BaseModule/Data/Interfaces/ITerrainLayerModule.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections; +using Mapbox.BaseModule.Data.DataFetchers; using Mapbox.BaseModule.Data.Tiles; namespace Mapbox.BaseModule.Data.Interfaces @@ -5,5 +8,6 @@ namespace Mapbox.BaseModule.Data.Interfaces public interface ITerrainLayerModule : ILayerModule { float QueryElevation(CanonicalTileId tileId, float x, float y); + IEnumerator LoadTileData(CanonicalTileId tileId, Action callback = null); } } \ No newline at end of file diff --git a/Runtime/Mapbox/BaseModule/Map/MapInformationStaticMethods.cs b/Runtime/Mapbox/BaseModule/Map/MapInformationStaticMethods.cs index e3a6a2884..4ce7bf236 100644 --- a/Runtime/Mapbox/BaseModule/Map/MapInformationStaticMethods.cs +++ b/Runtime/Mapbox/BaseModule/Map/MapInformationStaticMethods.cs @@ -30,12 +30,22 @@ public static Vector3 ConvertLatLngToPositionForScale(this IMapInformation mapIn return scaledDeltaMercatorVector3; } - public static Vector3 ConvertLatLngToPosition(this IMapInformation mapInfo, LatitudeLongitude latlng) + public static Vector3 ConvertLatLngToPosition(this IMapInformation mapInfo, LatitudeLongitude latlng, bool queryElevation = false) { var mercator = Conversions.LatitudeLongitudeToWebMercator(latlng); var deltaMercator = mercator - mapInfo.CenterMercator; var scaledDeltaMercator = deltaMercator / mapInfo.Scale; - var scaledDeltaMercatorVector3 = scaledDeltaMercator.ToVector3xz(); + var elevation = 0f; + + if (queryElevation) + { + var tileId = Conversions.LatitudeLongitudeToTileId(latlng, 14).Canonical; + var pointPosition = Conversions.LatitudeLongitudeToInTile01(latlng, tileId); + elevation = mapInfo.QueryElevation(tileId, pointPosition.x, pointPosition.y); + } + + //var scaledDeltaMercatorVector3 = scaledDeltaMercator.ToVector3xz(); + var scaledDeltaMercatorVector3 = new Vector3((float)scaledDeltaMercator.x, elevation, (float)scaledDeltaMercator.y); return scaledDeltaMercatorVector3; } diff --git a/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs b/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs new file mode 100644 index 000000000..8ca7462ca --- /dev/null +++ b/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs @@ -0,0 +1,68 @@ +using Mapbox.BaseModule.Data.Tiles; +using Mapbox.BaseModule.Data.Vector2d; +using Mapbox.BaseModule.Unity; +using Mapbox.BaseModule.Utilities; + +namespace Mapbox.BaseModule.Map +{ + public static class MapboxMapExtensions + { + public static bool TryGetMapTile(this MapboxMap map, UnwrappedTileId tileId, out UnityMapTile tile) + { + if (map.MapVisualizer.ActiveTiles.TryGetValue(tileId, out tile)) + { + return true; + } + + tile = null; + return false; + } + + public static bool TryGetMapTile(this MapboxMap map, LatitudeLongitude coordinates, out UnityMapTile tile, int maxZoomLevel = 20) + { + var maxTileId = Conversions.LatitudeLongitudeToTileId(coordinates, maxZoomLevel); + for (int i = maxZoomLevel; i > 1; i--) + { + if (map.MapVisualizer.ActiveTiles.TryGetValue(maxTileId, out tile)) + { + return true; + } + } + + tile = null; + return false; + } + + /// + /// Only queries active tiles / visible world + /// + /// + /// + /// + /// + /// + /// + public static bool TryGetElevation(this MapboxMap map, LatitudeLongitude location, out float elevation, int maxZoomLevel = 20, int minZoomLevel = 2) + { + var maxTileId = Conversions.LatitudeLongitudeToTileId(location, maxZoomLevel); + UnityMapTile tile = null; + for (int i = maxZoomLevel; i >= minZoomLevel; i--) + { + if (map.MapVisualizer.ActiveTiles.TryGetValue(maxTileId, out tile)) + { + break; + } + } + + if (tile != null) + { + var tilePos = Conversions.LatitudeLongitudeToInTile01(location, tile.TerrainContainer.TerrainData.TileId); + elevation = tile.TerrainContainer.QueryHeightData(tilePos.x, tilePos.y); + return true; + } + + elevation = float.MinValue; + return false; + } + } +} \ No newline at end of file diff --git a/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs.meta b/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs.meta new file mode 100644 index 000000000..8ca4b59f3 --- /dev/null +++ b/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3d874d1186584faf95af2fa2761ddcbb +timeCreated: 1767092724 \ No newline at end of file diff --git a/Runtime/Mapbox/BaseModule/Map/MapboxMapVisualizer.cs b/Runtime/Mapbox/BaseModule/Map/MapboxMapVisualizer.cs index 681dc1f4e..3c04f2164 100644 --- a/Runtime/Mapbox/BaseModule/Map/MapboxMapVisualizer.cs +++ b/Runtime/Mapbox/BaseModule/Map/MapboxMapVisualizer.cs @@ -194,6 +194,14 @@ public void OnDestroy() public bool TryGetLayerModule(out T module) where T : ILayerModule { module = (T)LayerModules.FirstOrDefault(x => x is T); + if (module == null) + { + var composite = LayerModules.FirstOrDefault(x => x is CompositeLayerModule) as CompositeLayerModule; + if (composite != null) + { + module = (T)composite.LayerModules.FirstOrDefault(x => x is T); + } + } return module != null; } diff --git a/Runtime/Mapbox/CustomImageryModule.meta b/Runtime/Mapbox/CustomImageryModule.meta new file mode 100644 index 000000000..ee0e1a460 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9957d55bdc494407c87f742bb99a0cc8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs b/Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs new file mode 100644 index 000000000..393b5a0a7 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs @@ -0,0 +1,55 @@ +using Mapbox.BaseModule.Data.Interfaces; +using Mapbox.BaseModule.Map; +using Mapbox.BaseModule.Unity; +using Mapbox.BaseModule.Utilities; +using Mapbox.ImageModule; +using Mapbox.UnityMapService; +using UnityEngine; + +namespace Mapbox.Example.Scripts.ModuleBehaviours +{ + public class CustomApiLayerModuleScript : ModuleConstructorScript + { + public CustomSourceSettings CustomSourceSettings; + public StaticLayerModuleSettings Settings = new StaticLayerModuleSettings() + { + RejectTilesOutsideZoom = new Vector2(2, 25), + DataSettings = new ImageSourceSettings() + { + ClampDataLevelToMax = 25 + } + }; + public override ILayerModule ModuleImplementation { get; protected set; } + + private void Start() + { + + } + + public override ILayerModule ConstructModule(MapService service, IMapInformation mapInformation, + UnityContext unityContext) + { + if (Settings.SourceType == ImagerySourceType.None) + { + + } + else if (Settings.SourceType == ImagerySourceType.Custom) + { + Settings.DataSettings.TilesetId = Settings.CustomSourceId; + } + else + { + var imageryTileset = MapboxDefaultImagery.GetParameters(Settings.SourceType); + Settings.DataSettings.TilesetId = imageryTileset.Id; + } + + var unityService = service as MapUnityService; + var source = new CustomSource(CustomSourceSettings, unityService.FetchingManager, unityService.CacheManager, new ImageSourceSettings() + { + TilesetId = "CustomImagery" + }); + ModuleImplementation = new StaticApiLayerModule(source, Settings); + return ModuleImplementation; + } + } +} \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs.meta b/Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs.meta new file mode 100644 index 000000000..64db1dc66 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6aed0ab09c9749069b3359d261d35ae4 +timeCreated: 1767099820 \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomSource.cs b/Runtime/Mapbox/CustomImageryModule/CustomSource.cs new file mode 100644 index 000000000..53d385475 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomSource.cs @@ -0,0 +1,59 @@ +using Mapbox.BaseModule.Data.DataFetchers; +using Mapbox.BaseModule.Data.Platform.Cache; +using Mapbox.BaseModule.Data.Tiles; +using Mapbox.BaseModule.Map; +using Mapbox.UnityMapService.DataSources; + +namespace Mapbox.Example.Scripts.ModuleBehaviours +{ + public class CustomSource : ImageSource + { + protected CustomSourceSettings _customSourceSettings; + protected ImageSourceSettings _settings; + + public CustomSource(CustomSourceSettings customSourceSettings, DataFetchingManager dataFetchingManager, + MapboxCacheManager mapboxCacheManager, ImageSourceSettings settings) + : base(dataFetchingManager, mapboxCacheManager, settings) + { + _settings = settings; + _customSourceSettings = customSourceSettings; + } + + protected override RasterTile CreateTile(CanonicalTileId tileId, string tilesetId) + { + if (_customSourceSettings.InvertY) + { + return new CustomTMSTile(_customSourceSettings.UrlFormat, tileId, tilesetId, true); + } + else + { + return new RasterTile(tileId, tilesetId, true); + } + } + + protected override RasterData CreateRasterDataWrapper(RasterTile tile) + { + RasterData rasterData; + rasterData = new RasterData() + { + TileId = tile.Id, + TilesetId = tile.TilesetId, + Texture = tile.Texture2D, + CacheType = tile.FromCache, + Data = tile.Data, + ETag = tile.ETag, + ExpirationDate = tile.ExpirationDate + }; + //_dataTileMatch.Add(rasterData, tile); + + return rasterData; + } + + protected override void CheckExpiration(RasterData cacheItem) + { + //not checking for expiration and updating for custom sources + //just using whatever is in cache + return; + } + } +} \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomSource.cs.meta b/Runtime/Mapbox/CustomImageryModule/CustomSource.cs.meta new file mode 100644 index 000000000..5e19cd35a --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomSource.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: db00866e0fd14890ad560a64229aae45 +timeCreated: 1767707026 \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs b/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs new file mode 100644 index 000000000..230db2149 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs @@ -0,0 +1,14 @@ +using System; +using UnityEngine; + +namespace Mapbox.Example.Scripts.ModuleBehaviours +{ + [Serializable] + public class CustomSourceSettings + { + [Tooltip("Url format string, structured as C# string format with '{}' fields for X/Y/Z coordinates")] + public string UrlFormat; + [Tooltip("Invert Y axis coordinates for TMS coordinate system, which starts from bottom left and grows to top-right")] + public bool InvertY; + } +} \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs.meta b/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs.meta new file mode 100644 index 000000000..cd1886295 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 83855a3135724ccd938059a88012027d +timeCreated: 1767707253 \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs b/Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs new file mode 100644 index 000000000..1e7515247 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs @@ -0,0 +1,35 @@ +using System; +using Mapbox.BaseModule.Data.DataFetchers; +using Mapbox.BaseModule.Data.Platform; +using Mapbox.BaseModule.Data.Tiles; +using UnityEngine; + +namespace Mapbox.Example.Scripts.ModuleBehaviours +{ + /// + /// TMS tile in the name means Y axis is inverted in the tile ids + /// + public class CustomTMSTile : RasterTile + { + private string _urlFormat; + public CustomTMSTile(string urlFormat, CanonicalTileId tileId, string tilesetId, bool useNonReadableTexture) : base(tileId, tilesetId, useNonReadableTexture) + { + _urlFormat = urlFormat; + } + + public override void Initialize(IFileSource fileSource, Action p) + { + TileState = TileState.Loading; + _callback = p; + + var invertY = (Mathf.Pow(2, Id.Z))- Id.Y - 1; + _generatedUrl = string.Format(_urlFormat, Id.Z, Id.X, (int)invertY); + DoTheRequest(fileSource); + } + + protected override void DoTheRequest(IFileSource fileSource) + { + _webRequest = fileSource.CustomImageRequest(_generatedUrl, HandleTileResponse, ETag, 10, IsTextureNonreadable); + } + } +} \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs.meta b/Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs.meta new file mode 100644 index 000000000..25a8c0e9f --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f1f46f6d333e4d25a4ccd278b71cecdc +timeCreated: 1767706943 \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs b/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs new file mode 100644 index 000000000..f227f880c --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs @@ -0,0 +1,46 @@ +using System; +using Mapbox.BaseModule.Data.Interfaces; +using Mapbox.BaseModule.Data.Platform; +using Mapbox.BaseModule.Map; +using Mapbox.BaseModule.Unity; +using Mapbox.BaseModule.Utilities; +using Mapbox.ImageModule; +using Mapbox.ImageModule.Terrain; +using Mapbox.UnityMapService; +using UnityEngine; + +namespace Mapbox.Example.Scripts.ModuleBehaviours +{ + public class CustomTerrainLayerModuleScript : ModuleConstructorScript + { + public CustomSourceSettings CustomSourceSettings; + public TerrainLayerModuleSettings Settings = new TerrainLayerModuleSettings() + { + RejectTilesOutsideZoom = new Vector2(2, 25), + DataSettings = new ImageSourceSettings() + { + ClampDataLevelToMax = 25 + } + }; + public override ILayerModule ModuleImplementation { get; protected set; } + + private void Start() + { + + } + + public override ILayerModule ConstructModule(MapService service, IMapInformation mapInformation, + UnityContext unityContext) + { + Settings.DataSettings.TilesetId = "mars_elevation"; + + var unityService = service as MapUnityService; + var source = new CustomTerrainSource(CustomSourceSettings, unityService.FetchingManager, unityService.CacheManager, new ImageSourceSettings() + { + TilesetId = "mars_elevation" + }); + ModuleImplementation = new TerrainLayerModule(source, Settings); + return ModuleImplementation; + } + } +} \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs.meta b/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs.meta new file mode 100644 index 000000000..ccdbd7c1a --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 83ddcee6d2844b7e9f15508beb22c72b +timeCreated: 1767632785 \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs b/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs new file mode 100644 index 000000000..2e371f7f0 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs @@ -0,0 +1,53 @@ +using Mapbox.BaseModule.Data.DataFetchers; +using Mapbox.BaseModule.Data.Platform.Cache; +using Mapbox.BaseModule.Data.Tiles; +using Mapbox.BaseModule.Map; +using Mapbox.UnityMapService.DataSources; + +namespace Mapbox.Example.Scripts.ModuleBehaviours +{ + public class CustomTerrainSource : TerrainSource + { + protected CustomSourceSettings _customSourceSettings; + protected ImageSourceSettings _settings; + + public CustomTerrainSource(CustomSourceSettings customSettings, DataFetchingManager dataFetchingManager, MapboxCacheManager mapboxCacheManager, ImageSourceSettings settings) + : base(dataFetchingManager, mapboxCacheManager, settings) + { + _customSourceSettings = customSettings; + _settings = settings; + } + + protected override RasterTile CreateTile(CanonicalTileId tileId, string tilesetId) + { + if (_customSourceSettings.InvertY) + { + return new CustomTMSTile( + _customSourceSettings.UrlFormat, + tileId, tilesetId, true); + } + else + { + return new RasterTile(tileId, tilesetId, true); + } + } + + protected override TerrainData CreateRasterDataWrapper(RasterTile tile) + { + TerrainData rasterData; + rasterData = new TerrainData() + { + TileId = tile.Id, + TilesetId = tile.TilesetId, + Texture = tile.Texture2D, + CacheType = tile.FromCache, + Data = tile.Data, + ETag = tile.ETag, + ExpirationDate = tile.ExpirationDate + }; + //_dataTileMatch.Add(rasterData, tile); + + return rasterData; + } + } +} \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs.meta b/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs.meta new file mode 100644 index 000000000..29c8d3b8c --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cfc3281b14f542aa8d2164cabb8967c7 +timeCreated: 1767707245 \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/Editor.meta b/Runtime/Mapbox/CustomImageryModule/Editor.meta new file mode 100644 index 000000000..68a67e75e --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0b6b51283dd7d417a962d32657e3e2f5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs b/Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs new file mode 100644 index 000000000..944468927 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs @@ -0,0 +1,47 @@ +using Mapbox.Example.Scripts.ModuleBehaviours; +using UnityEditor; + +namespace Mapbox.CustomImageryModule.Editor +{ + [CustomEditor(typeof(CustomApiLayerModuleScript))] + public class CustomApiLayerModuleScriptEditor : UnityEditor.Editor + { + SerializedProperty customSourceSettingsProp; + + SerializedProperty rejectTilesOutsideZoomProp; + SerializedProperty clampDataLevelToMaxProp; + + void OnEnable() + { + // Root properties + customSourceSettingsProp = serializedObject.FindProperty("CustomSourceSettings"); + + // Settings.RejectTilesOutsideZoom + rejectTilesOutsideZoomProp = + serializedObject.FindProperty("Settings") + .FindPropertyRelative("RejectTilesOutsideZoom"); + + // Settings.DataSettings.ClampDataLevelToMax + clampDataLevelToMaxProp = + serializedObject.FindProperty("Settings") + .FindPropertyRelative("DataSettings") + .FindPropertyRelative("ClampDataLevelToMax"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + EditorGUILayout.LabelField("Custom Source Settings", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(customSourceSettingsProp, true); + + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Tile Settings", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(rejectTilesOutsideZoomProp); + EditorGUILayout.PropertyField(clampDataLevelToMaxProp); + + serializedObject.ApplyModifiedProperties(); + } + } +} \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs.meta b/Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs.meta new file mode 100644 index 000000000..e758ce0e4 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c31619c32fa2549edbbc6761da29703b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Mapbox/CustomImageryModule/Editor/MapboxCustomImageryModule.Editor.asmdef b/Runtime/Mapbox/CustomImageryModule/Editor/MapboxCustomImageryModule.Editor.asmdef new file mode 100644 index 000000000..bc263dd76 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/Editor/MapboxCustomImageryModule.Editor.asmdef @@ -0,0 +1,18 @@ +{ + "name": "MapboxCustomImageryModule.Editor", + "rootNamespace": "", + "references": [ + "GUID:60dcad938ceef450e9b8d773e5c61b99" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/Editor/MapboxCustomImageryModule.Editor.asmdef.meta b/Runtime/Mapbox/CustomImageryModule/Editor/MapboxCustomImageryModule.Editor.asmdef.meta new file mode 100644 index 000000000..76a5b8ec5 --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/Editor/MapboxCustomImageryModule.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4c80974ccb411472e8e926051beeec6f +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Mapbox/CustomImageryModule/MapboxCustomImageryModule.asmdef b/Runtime/Mapbox/CustomImageryModule/MapboxCustomImageryModule.asmdef new file mode 100644 index 000000000..34eca74fd --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/MapboxCustomImageryModule.asmdef @@ -0,0 +1,18 @@ +{ + "name": "MapboxCustomImageryModule", + "rootNamespace": "", + "references": [ + "GUID:093b9fb2cd4794a8c94472d55c8bb0a9", + "GUID:36ca6af6e2b304d4090888554d6ce199", + "GUID:5ff00896142b94bc7a58a7c72b2faf57" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Runtime/Mapbox/CustomImageryModule/MapboxCustomImageryModule.asmdef.meta b/Runtime/Mapbox/CustomImageryModule/MapboxCustomImageryModule.asmdef.meta new file mode 100644 index 000000000..3e2d8598f --- /dev/null +++ b/Runtime/Mapbox/CustomImageryModule/MapboxCustomImageryModule.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 60dcad938ceef450e9b8d773e5c61b99 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Mapbox/ImageModule/Terrain/TerrainLayerModule.cs b/Runtime/Mapbox/ImageModule/Terrain/TerrainLayerModule.cs index 310f1f4c5..01ca4d54d 100644 --- a/Runtime/Mapbox/ImageModule/Terrain/TerrainLayerModule.cs +++ b/Runtime/Mapbox/ImageModule/Terrain/TerrainLayerModule.cs @@ -5,8 +5,10 @@ using Mapbox.BaseModule.Data.DataFetchers; using Mapbox.BaseModule.Data.Interfaces; using Mapbox.BaseModule.Data.Tiles; +using Mapbox.BaseModule.Data.Vector2d; using Mapbox.BaseModule.Map; using Mapbox.BaseModule.Unity; +using Mapbox.BaseModule.Utilities; using Mapbox.ImageModule.Terrain.TerrainStrategies; using UnityEngine; using TerrainData = Mapbox.BaseModule.Data.DataFetchers.TerrainData; @@ -91,22 +93,6 @@ public virtual bool RetainTiles(HashSet retainedTiles) isReady = _rasterSource.RetainTiles(_retainedTerrainTiles); return isReady; } - - public float QueryElevation(CanonicalTileId tileId, float x, float y) - { - var originalTileId = tileId; - var targetTileId = tileId; - for (int i = 0; i < 5; i++) - { - if (_rasterSource.GetInstantData(targetTileId, out var instantData)) - { - return instantData.QueryHeightData(originalTileId, x, y); - } - targetTileId.MoveToParent(); - } - - return 0; - } public void UpdatePositioning(IMapInformation mapInfo) { @@ -120,7 +106,7 @@ public void OnDestroy() //COROUTINE METHODS only used in initialization so far #region coroutine methods - public virtual IEnumerator LoadTileData(CanonicalTileId tileId, Action callback = null) + public virtual IEnumerator LoadTileData(CanonicalTileId tileId, Action callback = null) { return _rasterSource.LoadTileCoroutine(tileId, callback); } @@ -133,13 +119,11 @@ public virtual IEnumerator LoadTiles(IEnumerable tiles) public IEnumerable GetTileCoverCoroutines(IEnumerable tiles) { var targetTiles = GetDataId(tiles).Distinct(); - return targetTiles.Select(x => _rasterSource.LoadTileCoroutine(x)).Where(x => x != null); + return targetTiles.Select(x => LoadTileData(x)).Where(x => x != null); } #endregion - - //PRIVATE METHODS private bool IsZinSupportedRange(int targetZ) { @@ -150,7 +134,7 @@ private CanonicalTileId GetDataId(CanonicalTileId tileId) { var maxZoom = _settings.DataSettings.ClampDataLevelToMax; var currentZ = tileId.Z; - var targetZ = currentZ - 2; + var targetZ = (int)Mathf.Max(currentZ - 2, _settings.RejectTilesOutsideZoom.x); if (targetZ >= maxZoom) { return tileId.ParentAt(maxZoom); @@ -161,10 +145,69 @@ private CanonicalTileId GetDataId(CanonicalTileId tileId) } } + + //API + + /// + /// This method will only search the memory cache for available data. + /// + /// TileId of the elevation data + /// Point in texture coordinate space, origin is bottom left. + /// Point in texture coordinate space, origin is bottom left. + /// + public float QueryElevation(CanonicalTileId tileId, float x, float y) + { + var originalTileId = tileId; + var targetTileId = tileId; + for (int i = 0; i < 5; i++) + { + if (_rasterSource.GetInstantData(targetTileId, out var instantData)) + { + return instantData.QueryHeightData(originalTileId, x, y); + } + targetTileId.MoveToParent(); + } + + return 0; + } + public IEnumerable GetDataId(IEnumerable tileIdList) { return tileIdList.Where(x => IsZinSupportedRange(x.Z)).Select(GetDataId).Distinct(); } + /// + /// This method will cause tile requests if data isn't already available on memory cache. Use with caution. + /// + /// Latitude longitude of the location you want to query + /// Callback method returning the elevation in float + /// + public IEnumerator GetElevationData(LatitudeLongitude latLng, Action callback = null) + { + var tileId = Conversions.LatitudeLongitudeToTileId(latLng, 14).Canonical; + var dataFound = false; + for (int i = 14; i >= 2; i--) + { + if (_rasterSource.GetInstantData(tileId, out var instantData)) + { + var tilePos = Conversions.LatitudeLongitudeToInTile01(latLng, instantData.TileId); + var elevation = instantData.QueryHeightData(tilePos); + callback?.Invoke(elevation); + dataFound = true; + break; + } + } + + if (!dataFound) + { + tileId = Conversions.LatitudeLongitudeToTileId(latLng, 14).Canonical; + yield return LoadTileData(tileId, terrainData => + { + var tilePos = Conversions.LatitudeLongitudeToInTile01(latLng, terrainData.TileId); + var elevation = terrainData.QueryHeightData(tilePos); + callback?.Invoke(elevation); + }); + } + } } } \ No newline at end of file diff --git a/Runtime/Mapbox/UnityMapService/DataSources/ImageSource.cs b/Runtime/Mapbox/UnityMapService/DataSources/ImageSource.cs index 9068febbd..f3a10d8d2 100644 --- a/Runtime/Mapbox/UnityMapService/DataSources/ImageSource.cs +++ b/Runtime/Mapbox/UnityMapService/DataSources/ImageSource.cs @@ -362,7 +362,7 @@ protected void BackgroundLoad(CanonicalTileId tileId, string tilesetId) }); } - private void CheckExpiration(T cacheItem) + protected virtual void CheckExpiration(T cacheItem) { var dataTask = ReadEtagExpiration(cacheItem, 4); if (dataTask != null) //can be null if sqlite cache isn't available diff --git a/Runtime/Mapbox/UnityMapService/DataSources/TerrainSource.cs b/Runtime/Mapbox/UnityMapService/DataSources/TerrainSource.cs index 2e275d0f0..885caaa60 100644 --- a/Runtime/Mapbox/UnityMapService/DataSources/TerrainSource.cs +++ b/Runtime/Mapbox/UnityMapService/DataSources/TerrainSource.cs @@ -112,7 +112,7 @@ public override IEnumerator LoadTileCoroutine(CanonicalTileId requestedDataTileI { terrainData = data; })); - if (terrainData != null) + if (terrainData != null && terrainData.Texture != null) { yield return Runnable.Instance.StartCoroutine(ExtractElevationValues(terrainData)); } diff --git a/Runtime/Mapbox/UnityMapService/MapUnityService.cs b/Runtime/Mapbox/UnityMapService/MapUnityService.cs index a7327c719..12d884f2d 100644 --- a/Runtime/Mapbox/UnityMapService/MapUnityService.cs +++ b/Runtime/Mapbox/UnityMapService/MapUnityService.cs @@ -24,7 +24,10 @@ public sealed class MapUnityService : MapService, IUnityMapService private MapboxCacheManager _cacheManager; private DataFetchingManager _fetchingManager; - public override IFileSource FileSource => _fetchingManager; + public override IFileSource FileSource => FetchingManager; + + public MapboxCacheManager CacheManager => _cacheManager; + public DataFetchingManager FetchingManager => _fetchingManager; public MapUnityService( UnityContext unityContext, @@ -63,40 +66,40 @@ public override Source GetNewRasterSource(string name, string tilese public override Source GetTerrainRasterSource(ImageSourceSettings settings) { - var terrainSource = new TerrainSource(_fetchingManager, _cacheManager, settings); + var terrainSource = new TerrainSource(FetchingManager, CacheManager, settings); _dataSources.Add(terrainSource); return terrainSource; } public override Source GetStaticRasterSource(ImageSourceSettings settings) { - var staticRasterSource = new StaticSource(_fetchingManager, _cacheManager, settings); + var staticRasterSource = new StaticSource(FetchingManager, CacheManager, settings); _dataSources.Add(staticRasterSource); return staticRasterSource; } public override Source GetVectorSource(VectorSourceSettings settings) { - var vectorSource = new VectorSource(_fetchingManager, _cacheManager, settings); + var vectorSource = new VectorSource(FetchingManager, CacheManager, settings); _dataSources.Add(vectorSource); return vectorSource; } public override Source GetBuildingSource(VectorSourceSettings settings) { - var vectorSource = new BuildingSource(_fetchingManager, _cacheManager, settings); + var vectorSource = new BuildingSource(FetchingManager, CacheManager, settings); _dataSources.Add(vectorSource); return vectorSource; } - public MapboxCacheManager GetCacheManager() => _cacheManager; - public DataFetchingManager GetFetchingManager() => _fetchingManager; + public MapboxCacheManager GetCacheManager() => CacheManager; + public DataFetchingManager GetFetchingManager() => FetchingManager; public override void OnDestroy() { base.OnDestroy(); - _fetchingManager.OnDestroy(); - _cacheManager.OnDestroy(); + FetchingManager.OnDestroy(); + CacheManager.OnDestroy(); } } } diff --git a/Tests/Runtime/BaseModule/MapboxMapTests.cs b/Tests/Runtime/BaseModule/MapboxMapTests.cs index 95cd90dd5..cddecd05e 100644 --- a/Tests/Runtime/BaseModule/MapboxMapTests.cs +++ b/Tests/Runtime/BaseModule/MapboxMapTests.cs @@ -9,6 +9,7 @@ using Mapbox.BaseModule.Map; using Mapbox.BaseModule.Unity; using Mapbox.BaseModule.Utilities; +using Mapbox.ImageModule.Terrain; using Mapbox.ImageModule.Terrain.TerrainStrategies; using Mapbox.MapDebug.Scripts.Logging; using Mapbox.UnityMapService; @@ -62,6 +63,12 @@ public void OneTimeSetUp() _map = new MapboxMap(mapInfo, unityContext, mapService); var mapVisualizer = new MapboxMapVisualizer(mapInfo, unityContext, new TileCreator(unityContext)); + mapVisualizer.LayerModules.Add( + new TerrainLayerModule(mapService.GetTerrainRasterSource( + new ImageSourceSettings() + { + TilesetId = MapboxDefaultElevation.GetParameters(ElevationSourceType.MapboxTerrain).Id + }), new TerrainLayerModuleSettings())); _map.MapVisualizer = mapVisualizer; } @@ -148,6 +155,47 @@ public void ChangeViewToSF() Assert.AreEqual(_map.MapInformation.Pitch, 45); Assert.AreEqual(_map.MapInformation.Bearing, 30); } + + + private static IEnumerable LatLngElevationsource + { + get + { + yield return new TestCaseData(new LatitudeLongitude(27.9878, 86.9250), 8848f).Returns(null); // Mount Everest summit, Nepal/China + yield return new TestCaseData(new LatitudeLongitude(35.3606, 138.7274), 3776f).Returns(null); // Mount Fuji, Japan + yield return new TestCaseData(new LatitudeLongitude(36.5786, -118.2923), 4421f).Returns(null); // Mount Whitney, USA + yield return new TestCaseData(new LatitudeLongitude(51.1789, -1.8262), 102f).Returns(null); // Stonehenge, UK + + yield return new TestCaseData(new LatitudeLongitude(46.8523, -121.7603), 4372f).Returns(null); // Mount Rainier, USA + yield return new TestCaseData(new LatitudeLongitude(-13.1631, -72.5450), 2430f).Returns(null); // Machu Picchu, Peru + yield return new TestCaseData(new LatitudeLongitude(19.8207, -155.4681), 4207f).Returns(null); // Mauna Kea, USA + + yield return new TestCaseData(new LatitudeLongitude(-25.3444, 131.0369), 863f).Returns(null); // Uluru, Australia + yield return new TestCaseData(new LatitudeLongitude(43.6532, -79.3832), 92f).Returns(null); // Toronto, Canada + yield return new TestCaseData(new LatitudeLongitude(55.7558, 37.6176), 156f).Returns(null); // Moscow, Russia + yield return new TestCaseData(new LatitudeLongitude(35.6895, 139.6917), 38f).Returns(null); // Tokyo, Japan + yield return new TestCaseData(new LatitudeLongitude(-34.6037, -58.3816), 25f).Returns(null); // Buenos Aires, Argentina + + yield return new TestCaseData(new LatitudeLongitude(51.5074, -0.1278), 18f).Returns(null); // London, UK + yield return new TestCaseData(new LatitudeLongitude(37.7749, -122.4194), 16f).Returns(null); // San Francisco, USA + yield return new TestCaseData(new LatitudeLongitude(28.6139, 77.2090), 216f).Returns(null); // New Delhi, India + yield return new TestCaseData(new LatitudeLongitude(41.9028, 12.4964), 52f).Returns(null); // Rome, Italy + yield return new TestCaseData(new LatitudeLongitude(19.4326, -99.1332), 2240f).Returns(null); // Mexico City, Mexico + } + } + + [UnityTest] + [TestCaseSource(nameof(LatLngElevationsource))] + public IEnumerator TestElevations(LatitudeLongitude latLng, float expectedElevation) + { + if (_map.MapVisualizer.TryGetLayerModule(out var terrainModule)) + { + yield return terrainModule.GetElevationData(latLng, (elevation) => + { + Assert.AreEqual(elevation, expectedElevation, expectedElevation * 0.1f, $"{latLng} : {elevation} - {expectedElevation}"); + }); + } + } } public class DataFetcherTests From bbcd9067a88b237b1b50feb0f5ec090f5efb5390 Mon Sep 17 00:00:00 2001 From: Baran Kahyaoglu Date: Wed, 25 Feb 2026 17:07:27 +0300 Subject: [PATCH 2/3] fix tile parent loops in mapbox extensions fix namespaces for custom api module --- Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs | 8 ++++++++ .../CustomImageryModule/CustomApiLayerModuleScript.cs | 2 +- Runtime/Mapbox/CustomImageryModule/CustomSource.cs | 2 +- .../Mapbox/CustomImageryModule/CustomSourceSettings.cs | 2 +- Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs | 2 +- .../CustomImageryModule/CustomTerrainLayerModuleScript.cs | 6 +----- Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs | 2 +- .../Editor/CustomApiLayerModuleScriptEditor.cs | 1 - Runtime/Mapbox/ImageModule/Terrain/TerrainLayerModule.cs | 4 ++++ 9 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs b/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs index 8ca7462ca..5c0650504 100644 --- a/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs +++ b/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs @@ -27,6 +27,10 @@ public static bool TryGetMapTile(this MapboxMap map, LatitudeLongitude coordinat { return true; } + else + { + maxTileId = maxTileId.Parent; + } } tile = null; @@ -52,6 +56,10 @@ public static bool TryGetElevation(this MapboxMap map, LatitudeLongitude locatio { break; } + else + { + maxTileId = maxTileId.Parent; + } } if (tile != null) diff --git a/Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs b/Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs index 393b5a0a7..007c55f86 100644 --- a/Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs +++ b/Runtime/Mapbox/CustomImageryModule/CustomApiLayerModuleScript.cs @@ -6,7 +6,7 @@ using Mapbox.UnityMapService; using UnityEngine; -namespace Mapbox.Example.Scripts.ModuleBehaviours +namespace Mapbox.CustomImageryModule { public class CustomApiLayerModuleScript : ModuleConstructorScript { diff --git a/Runtime/Mapbox/CustomImageryModule/CustomSource.cs b/Runtime/Mapbox/CustomImageryModule/CustomSource.cs index 53d385475..58a27e9e5 100644 --- a/Runtime/Mapbox/CustomImageryModule/CustomSource.cs +++ b/Runtime/Mapbox/CustomImageryModule/CustomSource.cs @@ -4,7 +4,7 @@ using Mapbox.BaseModule.Map; using Mapbox.UnityMapService.DataSources; -namespace Mapbox.Example.Scripts.ModuleBehaviours +namespace Mapbox.CustomImageryModule { public class CustomSource : ImageSource { diff --git a/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs b/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs index 230db2149..4c6a665df 100644 --- a/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs +++ b/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs @@ -1,7 +1,7 @@ using System; using UnityEngine; -namespace Mapbox.Example.Scripts.ModuleBehaviours +namespace Mapbox.CustomImageryModule { [Serializable] public class CustomSourceSettings diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs b/Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs index 1e7515247..8f3b789f0 100644 --- a/Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs +++ b/Runtime/Mapbox/CustomImageryModule/CustomTMSTile.cs @@ -4,7 +4,7 @@ using Mapbox.BaseModule.Data.Tiles; using UnityEngine; -namespace Mapbox.Example.Scripts.ModuleBehaviours +namespace Mapbox.CustomImageryModule { /// /// TMS tile in the name means Y axis is inverted in the tile ids diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs b/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs index f227f880c..2f6dc9fc0 100644 --- a/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs +++ b/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs @@ -1,15 +1,11 @@ -using System; using Mapbox.BaseModule.Data.Interfaces; -using Mapbox.BaseModule.Data.Platform; using Mapbox.BaseModule.Map; using Mapbox.BaseModule.Unity; -using Mapbox.BaseModule.Utilities; -using Mapbox.ImageModule; using Mapbox.ImageModule.Terrain; using Mapbox.UnityMapService; using UnityEngine; -namespace Mapbox.Example.Scripts.ModuleBehaviours +namespace Mapbox.CustomImageryModule { public class CustomTerrainLayerModuleScript : ModuleConstructorScript { diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs b/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs index 2e371f7f0..dde6c86f1 100644 --- a/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs +++ b/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs @@ -4,7 +4,7 @@ using Mapbox.BaseModule.Map; using Mapbox.UnityMapService.DataSources; -namespace Mapbox.Example.Scripts.ModuleBehaviours +namespace Mapbox.CustomImageryModule { public class CustomTerrainSource : TerrainSource { diff --git a/Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs b/Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs index 944468927..5b05645c1 100644 --- a/Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs +++ b/Runtime/Mapbox/CustomImageryModule/Editor/CustomApiLayerModuleScriptEditor.cs @@ -1,4 +1,3 @@ -using Mapbox.Example.Scripts.ModuleBehaviours; using UnityEditor; namespace Mapbox.CustomImageryModule.Editor diff --git a/Runtime/Mapbox/ImageModule/Terrain/TerrainLayerModule.cs b/Runtime/Mapbox/ImageModule/Terrain/TerrainLayerModule.cs index 01ca4d54d..a018bbd23 100644 --- a/Runtime/Mapbox/ImageModule/Terrain/TerrainLayerModule.cs +++ b/Runtime/Mapbox/ImageModule/Terrain/TerrainLayerModule.cs @@ -196,6 +196,10 @@ public IEnumerator GetElevationData(LatitudeLongitude latLng, Action call dataFound = true; break; } + else + { + tileId = tileId.GetParentTileId; + } } if (!dataFound) From bc7e77b5470c6a2756ee768a61a32c5a8f336c94 Mon Sep 17 00:00:00 2001 From: Baran Kahyaoglu Date: Wed, 25 Feb 2026 18:40:12 +0300 Subject: [PATCH 3/3] cleanup remove commented out code fix tooltip add nullchecks --- Runtime/Mapbox/BaseModule/Map/MapInformationStaticMethods.cs | 1 - Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs | 5 ++++- Runtime/Mapbox/CustomImageryModule/CustomSource.cs | 1 - Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs | 2 +- .../CustomImageryModule/CustomTerrainLayerModuleScript.cs | 4 ++-- Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs | 1 - 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Runtime/Mapbox/BaseModule/Map/MapInformationStaticMethods.cs b/Runtime/Mapbox/BaseModule/Map/MapInformationStaticMethods.cs index 4ce7bf236..1f6f28e78 100644 --- a/Runtime/Mapbox/BaseModule/Map/MapInformationStaticMethods.cs +++ b/Runtime/Mapbox/BaseModule/Map/MapInformationStaticMethods.cs @@ -44,7 +44,6 @@ public static Vector3 ConvertLatLngToPosition(this IMapInformation mapInfo, Lati elevation = mapInfo.QueryElevation(tileId, pointPosition.x, pointPosition.y); } - //var scaledDeltaMercatorVector3 = scaledDeltaMercator.ToVector3xz(); var scaledDeltaMercatorVector3 = new Vector3((float)scaledDeltaMercator.x, elevation, (float)scaledDeltaMercator.y); return scaledDeltaMercatorVector3; diff --git a/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs b/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs index 5c0650504..2930981bb 100644 --- a/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs +++ b/Runtime/Mapbox/BaseModule/Map/MapboxMapExtensions.cs @@ -62,7 +62,10 @@ public static bool TryGetElevation(this MapboxMap map, LatitudeLongitude locatio } } - if (tile != null) + // Check tile and nested properties for null to prevent NullReferenceException + if (tile != null && + tile.TerrainContainer != null && + tile.TerrainContainer.TerrainData != null) { var tilePos = Conversions.LatitudeLongitudeToInTile01(location, tile.TerrainContainer.TerrainData.TileId); elevation = tile.TerrainContainer.QueryHeightData(tilePos.x, tilePos.y); diff --git a/Runtime/Mapbox/CustomImageryModule/CustomSource.cs b/Runtime/Mapbox/CustomImageryModule/CustomSource.cs index 58a27e9e5..ee4c1efc8 100644 --- a/Runtime/Mapbox/CustomImageryModule/CustomSource.cs +++ b/Runtime/Mapbox/CustomImageryModule/CustomSource.cs @@ -44,7 +44,6 @@ protected override RasterData CreateRasterDataWrapper(RasterTile tile) ETag = tile.ETag, ExpirationDate = tile.ExpirationDate }; - //_dataTileMatch.Add(rasterData, tile); return rasterData; } diff --git a/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs b/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs index 4c6a665df..f2ac463b9 100644 --- a/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs +++ b/Runtime/Mapbox/CustomImageryModule/CustomSourceSettings.cs @@ -6,7 +6,7 @@ namespace Mapbox.CustomImageryModule [Serializable] public class CustomSourceSettings { - [Tooltip("Url format string, structured as C# string format with '{}' fields for X/Y/Z coordinates")] + [Tooltip("Url format string, structured as C# string format with '{}' fields for X/Y/Z coordinates. {0}=Z, {1}=X, {2}=Y")] public string UrlFormat; [Tooltip("Invert Y axis coordinates for TMS coordinate system, which starts from bottom left and grows to top-right")] public bool InvertY; diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs b/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs index 2f6dc9fc0..8087393b9 100644 --- a/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs +++ b/Runtime/Mapbox/CustomImageryModule/CustomTerrainLayerModuleScript.cs @@ -28,12 +28,12 @@ private void Start() public override ILayerModule ConstructModule(MapService service, IMapInformation mapInformation, UnityContext unityContext) { - Settings.DataSettings.TilesetId = "mars_elevation"; + Settings.DataSettings.TilesetId = "CustomTerrain"; var unityService = service as MapUnityService; var source = new CustomTerrainSource(CustomSourceSettings, unityService.FetchingManager, unityService.CacheManager, new ImageSourceSettings() { - TilesetId = "mars_elevation" + TilesetId = "CustomTerrain" }); ModuleImplementation = new TerrainLayerModule(source, Settings); return ModuleImplementation; diff --git a/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs b/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs index dde6c86f1..eb45d275f 100644 --- a/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs +++ b/Runtime/Mapbox/CustomImageryModule/CustomTerrainSource.cs @@ -45,7 +45,6 @@ protected override TerrainData CreateRasterDataWrapper(RasterTile tile) ETag = tile.ETag, ExpirationDate = tile.ExpirationDate }; - //_dataTileMatch.Add(rasterData, tile); return rasterData; }