Update SupportingScripts to 0.9.0.

This commit is contained in:
Brian Kircher 2020-06-12 01:51:47 -07:00
Родитель 41a59fff86
Коммит c388c149b2
123 изменённых файлов: 4055 добавлений и 1764 удалений

Просмотреть файл

@ -0,0 +1,19 @@
{
"name": "Microsoft.Maps.Unity.Editor",
"references": [
"Microsoft.Maps.Unity.SupportingScripts"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"precompiledReferences": [
"Microsoft.Maps.Unity.dll"
],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

Просмотреть файл

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 71c89d9c39160f144b624374c46f00f4
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cbcc9be67fcbf9246b07a75484c20866
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7b2e1c711acbd2041bfbf3767abb70fb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -30,6 +30,8 @@ namespace Microsoft.Maps.Unity
EditorGUI.BeginDisabledGroup(true);
var clusterMapPin = (ClusterMapPin)target;
var latLon = clusterMapPin.MercatorCoordinate.ToLatLon();
EditorGUILayout.TextField("Location", latLon.LatitudeInDegrees + ", " + latLon.LongitudeInDegrees);
EditorGUILayout.IntField("Size", clusterMapPin.Size);
EditorGUILayout.IntField("Level Of Detail", clusterMapPin.LevelOfDetail);
EditorGUI.EndDisabledGroup();

Просмотреть файл

@ -23,7 +23,7 @@ namespace Microsoft.Maps.Unity
/// <param name="targetType">The type to use the drawer for.</param>
public CustomTileLayerDrawer(Type targetType)
{
this.TargetType = targetType;
TargetType = targetType;
}
}
}

Просмотреть файл

@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Maps.Unity
{
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(MapDataCache))]
internal class MapDataCacheEditor : Editor
{
private SerializedProperty _percentUtilizationProperty;
private void OnEnable()
{
_percentUtilizationProperty = serializedObject.FindProperty("_percentUtilization");
}
public override void OnInspectorGUI()
{
serializedObject.UpdateIfRequiredOrScript();
var mapDataCache = (MapDataCache)target;
mapDataCache.MaxCacheSizeInBytes =
1024 *
1024 *
EditorGUILayout.LongField(
new GUIContent("Max Cache Size (MB)"),
mapDataCache.MaxCacheSizeInBytes / 1024 / 1024);
EditorGUILayout.PropertyField(_percentUtilizationProperty);
serializedObject.ApplyModifiedProperties();
}
}
}

Просмотреть файл

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 225701b175b10a74b8abdf19673869db
guid: 6c847bcdaad445644b3613d339b0d95a
MonoImporter:
externalObjects: {}
serializedVersion: 2

Просмотреть файл

@ -21,15 +21,15 @@ namespace Microsoft.Maps.Unity
private SerializedProperty _isLayerSynchronizedProperty;
private Vector3 _mouseDownMapPinPlanePositionInMapLocalSpace;
private Vector2D _mouseDownMapPinPositionInMercatorSpace;
private MercatorCoordinate _mouseDownMapPinPositionInMercatorSpace;
private bool _isHovered;
private bool _isDragging;
private void OnEnable()
{
_locationProperty = serializedObject.FindProperty("_location");
_altitude = serializedObject.FindProperty("Altitude");
_altitudeReferenceProperty = serializedObject.FindProperty("AltitudeReference");
_altitude = serializedObject.FindProperty("_altitude");
_altitudeReferenceProperty = serializedObject.FindProperty("_altitudeReference");
_useRealworldScaleProperty = serializedObject.FindProperty("UseRealWorldScale");
_scaleCurveProperty = serializedObject.FindProperty("ScaleCurve");
_isLayerSynchronizedProperty = serializedObject.FindProperty("IsLayerSynchronized");
@ -70,9 +70,8 @@ namespace Microsoft.Maps.Unity
var transform = mapPin.transform;
Tools.hidden = true;
var controlId = GUIUtility.GetControlID("MapPinEditorHandle".GetHashCode(), FocusType.Passive);
var screenPosition = Handles.matrix.MultiplyPoint(transform.position);
var size = 0.025f;
switch (Event.current.GetTypeForControl(controlId))
@ -105,7 +104,7 @@ namespace Microsoft.Maps.Unity
{
// Respond to a press on this handle. Drag starts automatically.
_mouseDownMapPinPlanePositionInMapLocalSpace = mapRenderer.transform.worldToLocalMatrix * ray.GetPoint(enter);
_mouseDownMapPinPositionInMercatorSpace = mapPin.Location.ToMercatorPosition();
_mouseDownMapPinPositionInMercatorSpace = mapPin.Location.ToMercatorCoordinate();
_isDragging = true;
GUIUtility.hotControl = controlId;
Event.current.Use();
@ -131,8 +130,8 @@ namespace Microsoft.Maps.Unity
{
Vector3 updatedHitPointInLocalSpace = mapRenderer.transform.worldToLocalMatrix * ray.GetPoint(enter);
var newDeltaInLocalSpace = updatedHitPointInLocalSpace - _mouseDownMapPinPlanePositionInMapLocalSpace;
var newDeltaInMercator = new Vector2D(newDeltaInLocalSpace.x, newDeltaInLocalSpace.z) / Math.Pow(2, mapRenderer.ZoomLevel - 1);
var newLocation = LatLon.FromMercatorPosition(_mouseDownMapPinPositionInMercatorSpace + newDeltaInMercator);
var newDeltaInMercator = new MercatorCoordinate(newDeltaInLocalSpace.x, newDeltaInLocalSpace.z) / Math.Pow(2, mapRenderer.ZoomLevel - 1);
var newLocation = (_mouseDownMapPinPositionInMercatorSpace + newDeltaInMercator).ToLatLon();
Undo.RecordObject(target, "Changed Location");
mapPin.Location = newLocation;

Просмотреть файл

@ -13,22 +13,21 @@ namespace Microsoft.Maps.Unity
[CanEditMultipleObjects]
internal class MapRendererEditor : Editor
{
private SerializedProperty _bingMapsKeyProperty;
private SerializedProperty _showMapDataInEditorProperty;
private static bool _showMapLocationOptions = true;
private static bool _showLocationOptions = true;
private SerializedProperty _centerProperty;
private SerializedProperty _zoomLevelProperty;
private SerializedProperty _minZoomLevelProperty;
private SerializedProperty _maxZoomLevelProperty;
private SerializedProperty _mapTerrainType;
private SerializedProperty _mapShapeProperty;
private static bool _showMapSizingOptions = true;
private SerializedProperty _mapEdgeColorProperty;
private SerializedProperty _mapEdgeColorFadeDistanceProperty;
private static bool _showLayoutOptions = true;
private SerializedProperty _localMapDimensionProperty;
private SerializedProperty _localMapRadiusProperty;
private SerializedProperty _localMapHeightProperty;
private static bool _terrainOptions = true;
private SerializedProperty _localMapBaseHeightProperty;
private SerializedProperty _mapColliderTypeProperty;
private static bool _showRenderingOptions = true;
private SerializedProperty _elevationScaleProperty;
private SerializedProperty _castShadowsProperty;
private SerializedProperty _receiveShadowsProperty;
@ -36,28 +35,29 @@ namespace Microsoft.Maps.Unity
private SerializedProperty _useCustomTerrainMaterialProperty;
private SerializedProperty _customTerrainMaterialProperty;
private SerializedProperty _isClippingVolumeWallEnabledProperty;
private SerializedProperty _mapEdgeColorProperty;
private SerializedProperty _mapEdgeColorFadeDistanceProperty;
private SerializedProperty _useCustomClippingVolumeMaterialProperty;
private SerializedProperty _customClippingVolumeMaterialProperty;
private SerializedProperty _clippingVolumeDistanceTextureResolution;
private SerializedProperty _labelPrefabProperty;
private static bool _showQualityOptions = true;
private SerializedProperty _detailOffsetProperty;
private SerializedProperty _maxCacheSizeInBytesProperty;
private SerializedProperty _mapColliderTypeProperty;
private static bool _showTileLayers = true;
private static bool _showTileLayerOptions = true;
private SerializedProperty _textureTileLayersProperty;
private SerializedProperty _elevationTileLayersProperty;
private SerializedProperty _hideTileLayerComponentsProperty;
private static bool _showLocalizationOptions = true;
private SerializedProperty _languageOverrideProperty;
private GUIStyle _baseStyle = null;
private GUIStyle _hyperlinkStyle = null;
private GUIStyle _errorIconStyle = null;
private GUIContent _errorIcon = null;
private SerializedProperty _languageChangedProperty;
private SerializedProperty _mapSessionProperty;
private GUIStyle _foldoutTitleStyle = null;
private GUIStyle _boxStyle = null;
private Texture2D _bannerWhite = null;
private Texture2D _bannerBlack = null;
private readonly GUIContent[] _layerOptions =
new GUIContent[]
{
@ -65,12 +65,14 @@ namespace Microsoft.Maps.Unity
new GUIContent("Elevated", "The map terrain consists only of elevation data. No high resolution 3D models are used."),
new GUIContent("Flat", "Both elevation and high resolution 3D models are disabled. The map will be flat.")
};
private readonly GUIContent[] _shapeOptions =
new GUIContent[]
{
new GUIContent("Block", "Default shape. The map is rendered on a rectangular block."),
new GUIContent("Cylinder", "Map is rendered on a cylinder."),
};
private readonly GUIContent[] _clippingVolumeDistanceTextureResolutionOptions =
new GUIContent[]
{
@ -78,6 +80,7 @@ namespace Microsoft.Maps.Unity
new GUIContent("Medium", "Medium quality texture size."),
new GUIContent("High", "High quality texture size. Uses more memory.")
};
private readonly GUIContent[] _colliderOptions =
new GUIContent[]
{
@ -85,26 +88,22 @@ namespace Microsoft.Maps.Unity
new GUIContent("Base Only", "Collider covering the base of the map."),
new GUIContent("Full Extents", "Collider covering the full extents of the map."),
};
private readonly GUILayoutOption[] _minMaxLabelsLayoutOptions =
new GUILayoutOption[]
{
GUILayout.MaxWidth(52.0f)
};
private readonly Tuple<UnityEngine.Object, UnityEngine.Object>[] _terrainMaterials =
new Tuple<UnityEngine.Object, UnityEngine.Object>[3];
private static int ControlIdHint = "MapRendererEditor".GetHashCode();
private readonly static int ControlIdHint = "MapRendererEditor".GetHashCode();
private bool _isDragging = false;
private Vector3 _startingHitPointInWorldSpace;
private Vector2D _startingCenterInMercatorSpace;
private MercatorCoordinate _startingCenterInMercator;
private void OnEnable()
{
_centerProperty = serializedObject.FindProperty("_center");
_bingMapsKeyProperty = serializedObject.FindProperty("_bingMapsKey");
_showMapDataInEditorProperty = serializedObject.FindProperty("_showMapDataInEditor");
_zoomLevelProperty = serializedObject.FindProperty("_zoomLevel");
_minZoomLevelProperty = serializedObject.FindProperty("_minimumZoomLevel");
_maxZoomLevelProperty = serializedObject.FindProperty("_maximumZoomLevel");
@ -112,7 +111,7 @@ namespace Microsoft.Maps.Unity
_mapShapeProperty = serializedObject.FindProperty("_mapShape");
_localMapDimensionProperty = serializedObject.FindProperty("LocalMapDimension");
_localMapRadiusProperty = serializedObject.FindProperty("LocalMapRadius");
_localMapHeightProperty = serializedObject.FindProperty("_localMapHeight");
_localMapBaseHeightProperty = serializedObject.FindProperty("_localMapBaseHeight");
_useCustomTerrainMaterialProperty = serializedObject.FindProperty("_useCustomTerrainMaterial");
_elevationScaleProperty = serializedObject.FindProperty("_elevationScale");
_castShadowsProperty = serializedObject.FindProperty("_castShadows");
@ -123,18 +122,16 @@ namespace Microsoft.Maps.Unity
_useCustomClippingVolumeMaterialProperty = serializedObject.FindProperty("_useCustomClippingVolumeMaterial");
_customClippingVolumeMaterialProperty = serializedObject.FindProperty("_customClippingVolumeMaterial");
_clippingVolumeDistanceTextureResolution = serializedObject.FindProperty("_clippingVolumeDistanceTextureResolution");
_labelPrefabProperty = serializedObject.FindProperty("_labelPrefab");
_mapEdgeColorProperty = serializedObject.FindProperty("_mapEdgeColor");
_mapEdgeColorFadeDistanceProperty = serializedObject.FindProperty("_mapEdgeColorFadeDistance");
_detailOffsetProperty = serializedObject.FindProperty("_detailOffset");
_mapColliderTypeProperty = serializedObject.FindProperty("_mapColliderType");
_maxCacheSizeInBytesProperty = serializedObject.FindProperty("_maxCacheSizeInBytes");
_bannerWhite = (Texture2D)Resources.Load("MapsSDK-EditorBannerWhite");
_bannerBlack = (Texture2D)Resources.Load("MapsSDK-EditorBannerBlack");
_textureTileLayersProperty = serializedObject.FindProperty("_textureTileLayers");
_elevationTileLayersProperty = serializedObject.FindProperty("_elevationTileLayers");
_hideTileLayerComponentsProperty = serializedObject.FindProperty("_hideTileLayerComponents");
_languageOverrideProperty = serializedObject.FindProperty("_languageOverride");
_languageChangedProperty = serializedObject.FindProperty("_languageChanged");
_mapSessionProperty = serializedObject.FindProperty("_mapSession");
EditorApplication.update += QueuePlayerLoopUpdate;
}
@ -188,7 +185,7 @@ namespace Microsoft.Maps.Unity
if (mapRenderer.Raycast(ray, out var hitInfo))
{
_startingHitPointInWorldSpace = hitInfo.Point;
_startingCenterInMercatorSpace = mapRenderer.Center.ToMercatorPosition();
_startingCenterInMercator = mapRenderer.Center.ToMercatorCoordinate();
_isDragging = true;
currentEvent.Use();
}
@ -203,8 +200,8 @@ namespace Microsoft.Maps.Unity
var updatedHitPointInWorldSpace = ray.GetPoint(enter);
var newDeltaInWorldSpace = updatedHitPointInWorldSpace - _startingHitPointInWorldSpace;
var newDeltaInLocalSpace = mapRenderer.transform.worldToLocalMatrix * newDeltaInWorldSpace;
var newDeltaInMercator = new Vector2D(newDeltaInLocalSpace.x, newDeltaInLocalSpace.z) / Math.Pow(2, mapRenderer.ZoomLevel - 1);
var newCenter = LatLon.FromMercatorPosition(_startingCenterInMercatorSpace - newDeltaInMercator);
var newDeltaInMercator = new MercatorCoordinate(newDeltaInLocalSpace.x, newDeltaInLocalSpace.z) / Math.Pow(2, mapRenderer.ZoomLevel - 1);
var newCenter = (_startingCenterInMercator - newDeltaInMercator).ToLatLon();
Undo.RecordObject(mapRenderer, "Change Center.");
mapRenderer.Center = newCenter;
@ -235,33 +232,11 @@ namespace Microsoft.Maps.Unity
serializedObject.UpdateIfRequiredOrScript();
RenderBanner();
// Setup and key.
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.LabelField("API Settings", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
_bingMapsKeyProperty.stringValue = EditorGUILayout.PasswordField("Bing Maps Key", _bingMapsKeyProperty.stringValue);
if (string.IsNullOrWhiteSpace(_bingMapsKeyProperty.stringValue))
{
Help(
"Provide a Bing Maps developer key to enable the map.",
"Sign up for a key at the Bing Maps Dev Center.",
"https://www.bingmapsportal.com/");
}
_showMapDataInEditorProperty.boolValue =
EditorGUILayout.Toggle(
new GUIContent(
"Show Map Data in Editor",
"Map data usage in the editor will apply the specified Bing Maps key."),
_showMapDataInEditorProperty.boolValue);
EditorGUILayout.EndVertical();
// Location Section
EditorGUILayout.BeginVertical(_boxStyle);
_showMapLocationOptions = EditorGUILayout.Foldout(_showMapLocationOptions, "Location", true, _foldoutTitleStyle);
if (_showMapLocationOptions)
_showLocationOptions = EditorGUILayout.Foldout(_showLocationOptions, "Location", true, _foldoutTitleStyle);
if (_showLocationOptions)
{
var latitudeProperty = _centerProperty.FindPropertyRelative("Latitude");
latitudeProperty.doubleValue = EditorGUILayout.DoubleField("Latitude", latitudeProperty.doubleValue);
@ -272,7 +247,7 @@ namespace Microsoft.Maps.Unity
// Get the zoomlevel values
var minZoomLevel = _minZoomLevelProperty.floatValue;
var maxZoomLevel = _maxZoomLevelProperty.floatValue;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Zoom Level Range");
EditorGUI.indentLevel--;
@ -281,19 +256,18 @@ namespace Microsoft.Maps.Unity
maxZoomLevel = EditorGUILayout.FloatField((float)Math.Round(maxZoomLevel, 2), _minMaxLabelsLayoutOptions);
EditorGUI.indentLevel++;
EditorGUILayout.EndHorizontal();
// Update it back
_minZoomLevelProperty.floatValue = minZoomLevel;
_maxZoomLevelProperty.floatValue = maxZoomLevel;
GUILayout.Space(4);
}
EditorGUILayout.EndVertical();
// Map Layout Section
EditorGUILayout.BeginVertical(_boxStyle);
_showMapSizingOptions = EditorGUILayout.Foldout(_showMapSizingOptions, "Map Layout", true, _foldoutTitleStyle);
if (_showMapSizingOptions)
_showLayoutOptions = EditorGUILayout.Foldout(_showLayoutOptions, "Map Layout", true, _foldoutTitleStyle);
if (_showLayoutOptions)
{
// Map Shape Controls
GUILayout.BeginHorizontal();
@ -306,20 +280,17 @@ namespace Microsoft.Maps.Unity
if (_mapShapeProperty.enumValueIndex == (int)MapShape.Block)
{
EditorGUILayout.PropertyField(_localMapDimensionProperty);
EditorGUILayout.LabelField(" ", "Scaled Map Dimension: " + ((MapRenderer)target).MapDimension.ToString());
GUILayout.Space(6f);
EditorGUILayout.PropertyField(_localMapHeightProperty);
EditorGUILayout.LabelField(" ", "Scaled Map Height: " + ((MapRenderer)target).MapHeight.ToString());
EditorGUILayout.LabelField(" ", "Scaled Map Dimension: " + mapRenderer.MapDimension.ToString());
}
else if (_mapShapeProperty.enumValueIndex == (int)MapShape.Cylinder)
{
EditorGUILayout.PropertyField(_localMapRadiusProperty);
EditorGUILayout.LabelField(" ", "Scaled Map Radius: " + (((MapRenderer)target).MapDimension.x / 2.0f).ToString());
GUILayout.Space(6f);
EditorGUILayout.PropertyField(_localMapHeightProperty);
EditorGUILayout.LabelField(" ", "Scaled Map Height: " + ((MapRenderer)target).MapHeight.ToString());
EditorGUILayout.LabelField(" ", "Scaled Map Radius: " + (mapRenderer.MapDimension.x / 2.0f).ToString());
}
GUILayout.Space(6f);
EditorGUILayout.PropertyField(_localMapBaseHeightProperty);
EditorGUILayout.LabelField(" ", "Scaled Map Base Height: " + mapRenderer.MapBaseHeight.ToString());
GUILayout.Space(6f);
// Map Collider Type Controls
GUILayout.BeginHorizontal();
@ -333,8 +304,8 @@ namespace Microsoft.Maps.Unity
// Render Settings Section
EditorGUILayout.BeginVertical(_boxStyle);
_terrainOptions = EditorGUILayout.Foldout(_terrainOptions, "Render Settings", true, _foldoutTitleStyle);
if (_terrainOptions)
_showRenderingOptions = EditorGUILayout.Foldout(_showRenderingOptions, "Render Settings", true, _foldoutTitleStyle);
if (_showRenderingOptions)
{
// Map Terrain Type Controls
GUILayout.BeginHorizontal();
@ -382,8 +353,9 @@ namespace Microsoft.Maps.Unity
EditorGUI.indentLevel--;
}
GUILayout.Space(6f);
}
GUILayout.Space(6f);
EditorGUILayout.EndVertical();
// Quality options.
@ -391,15 +363,6 @@ namespace Microsoft.Maps.Unity
_showQualityOptions = EditorGUILayout.Foldout(_showQualityOptions, "Quality", true, _foldoutTitleStyle);
if (_showQualityOptions)
{
EditorGUI.BeginDisabledGroup(Application.isPlaying);
_maxCacheSizeInBytesProperty.longValue =
1024 *
1024 *
EditorGUILayout.LongField(
new GUIContent("Max Cache Size (MB)"),
_maxCacheSizeInBytesProperty.longValue / 1024 / 1024);
EditorGUI.EndDisabledGroup();
var position = EditorGUILayout.GetControlRect(false, 2 * EditorGUIUtility.singleLineHeight);
position.height = EditorGUIUtility.singleLineHeight;
@ -440,8 +403,8 @@ namespace Microsoft.Maps.Unity
// Texture Tile Providers
EditorGUILayout.BeginVertical(_boxStyle);
_showTileLayers = EditorGUILayout.Foldout(_showTileLayers, "Tile Layers", true, _foldoutTitleStyle);
if (_showTileLayers)
_showTileLayerOptions = EditorGUILayout.Foldout(_showTileLayerOptions, "Tile Layers", true, _foldoutTitleStyle);
if (_showTileLayerOptions)
{
EditorGUILayout.PropertyField(_textureTileLayersProperty, true);
EditorGUILayout.PropertyField(_elevationTileLayersProperty, true);
@ -452,7 +415,7 @@ namespace Microsoft.Maps.Unity
// Localization
EditorGUILayout.BeginVertical(_boxStyle);
_showLocalizationOptions = EditorGUILayout.Foldout(_showTileLayers, "Localization", true, _foldoutTitleStyle);
_showLocalizationOptions = EditorGUILayout.Foldout(_showLocalizationOptions, "Localization", true, _foldoutTitleStyle);
if (_showLocalizationOptions)
{
var previousIsLanguageAutoDetected = _languageOverrideProperty.intValue == (int)SystemLanguage.Unknown;
@ -481,62 +444,26 @@ namespace Microsoft.Maps.Unity
EditorGUILayout.PropertyField(_languageOverrideProperty, new GUIContent("Language"));
}
GUILayout.Space(4);
EditorGUILayout.BeginHorizontal();
GUILayout.Space(12);
EditorGUILayout.PropertyField(_languageChangedProperty);
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
GUILayout.Space(4);
EditorGUILayout.PropertyField(_mapSessionProperty);
serializedObject.ApplyModifiedProperties();
}
private void Initialize()
{
if (_baseStyle == null)
{
_baseStyle = new GUIStyle
{
wordWrap = true,
font = EditorStyles.helpBox.font,
fontSize = EditorStyles.helpBox.fontSize,
normal = EditorStyles.helpBox.normal
};
_baseStyle.normal.background = null;
_baseStyle.stretchWidth = false;
_baseStyle.stretchHeight = false;
_baseStyle.margin = new RectOffset();
}
if (_errorIcon == null)
{
_errorIcon = EditorGUIUtility.TrIconContent("console.erroricon");
}
if (_errorIconStyle == null)
{
_errorIconStyle =
new GUIStyle(_baseStyle)
{
stretchHeight = false,
alignment = TextAnchor.MiddleLeft,
fixedWidth = _errorIcon.image.width,
fixedHeight = 1.0f * _errorIcon.image.height,
stretchWidth = false,
wordWrap = false
};
}
if (_hyperlinkStyle == null)
{
_hyperlinkStyle = new GUIStyle(_baseStyle);
_hyperlinkStyle.alignment = TextAnchor.UpperLeft;
_hyperlinkStyle.normal.textColor = new Color(0x00 / 255f, 0x78 / 255f, 0xDA / 255f, 1f);
_hyperlinkStyle.stretchWidth = false;
_hyperlinkStyle.padding = new RectOffset();
_hyperlinkStyle.alignment = TextAnchor.UpperLeft;
}
if (_foldoutTitleStyle == null)
{
{
_foldoutTitleStyle = new GUIStyle(EditorStyles.foldout)
{
fontStyle = UnityEngine.FontStyle.Bold
@ -549,56 +476,6 @@ namespace Microsoft.Maps.Unity
}
}
private void RenderBanner()
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.Label(EditorGUIUtility.isProSkin ? _bannerWhite : _bannerBlack, GUILayout.MaxHeight(96f));
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
private void Help(string message, string urlMessage, string url)
{
EditorGUI.indentLevel--;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel(" ");
var rect = EditorGUILayout.BeginHorizontal();
{
var iconWidth = _errorIcon.image.width;
EditorGUILayout.LabelField(_errorIcon, _errorIconStyle, GUILayout.Width(iconWidth));
EditorGUILayout.BeginVertical();
{
GUILayout.Space(8);
EditorGUILayout.LabelField(message, _baseStyle);
EditorGUILayout.BeginHorizontal();
{
EditorGUILayout.LabelField(urlMessage, _hyperlinkStyle);
var linkRect = GUILayoutUtility.GetLastRect();
if (Event.current.type == EventType.Repaint)
{
EditorGUIUtility.AddCursorRect(linkRect, MouseCursor.Link);
}
if (Event.current.type == EventType.MouseUp && linkRect.Contains(Event.current.mousePosition))
{
Application.OpenURL(url);
}
}
EditorGUILayout.EndHorizontal();
GUILayout.Space(4);
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel++;
}
private void QueuePlayerLoopUpdate()
{
EditorApplication.QueuePlayerLoopUpdate();

Просмотреть файл

@ -20,8 +20,8 @@ namespace Microsoft.Maps.Unity
Gizmos.matrix = mapRenderer.gameObject.transform.localToWorldMatrix;
Gizmos.color = color;
Gizmos.DrawCube(
new Vector3(0, mapRenderer.LocalMapHeight / 2, 0),
new Vector3(mapRenderer.LocalMapDimension.x, mapRenderer.LocalMapHeight, mapRenderer.LocalMapDimension.y));
new Vector3(0, mapRenderer.LocalMapBaseHeight / 2, 0),
new Vector3(mapRenderer.LocalMapDimension.x, mapRenderer.LocalMapBaseHeight, mapRenderer.LocalMapDimension.y));
}
}
}

Просмотреть файл

@ -0,0 +1,215 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Maps.Unity
{
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(MapSession))]
[CanEditMultipleObjects]
internal class MapSessionEditor : Editor
{
private SerializedProperty _developerKeyProperty;
private SerializedProperty _showMapDataInEditorProperty;
private GUIStyle _baseStyle = null;
private GUIStyle _hyperlinkStyle = null;
private GUIStyle _iconStyle = null;
private GUIContent _warnIcon = null;
private GUIStyle _foldoutTitleStyle = null;
private GUIStyle _boxStyle = null;
private Texture2D _bannerWhite = null;
private Texture2D _bannerBlack = null;
private void OnEnable()
{
_developerKeyProperty = serializedObject.FindProperty("_developerKey");
_showMapDataInEditorProperty = serializedObject.FindProperty("_showMapDataInEditor");
_bannerWhite = (Texture2D)Resources.Load("MapsSDK-EditorBannerWhite");
_bannerBlack = (Texture2D)Resources.Load("MapsSDK-EditorBannerBlack");
}
public override void OnInspectorGUI()
{
Initialize();
serializedObject.UpdateIfRequiredOrScript();
// This should just be done one time.
{
var mapSession = target as MapSession;
var components = mapSession.gameObject.GetComponents<Component>();
var mapRendererIndex = -1;
for (var i = 0; i < components.Length; i++)
{
if (components[i] is MapRenderer)
{
mapRendererIndex = i;
break;
}
}
var mapSessionIndex = -1;
for (var i = 0; i < components.Length; i++)
{
if (components[i] is MapSession)
{
mapSessionIndex = i;
break;
}
}
if (mapSessionIndex > mapRendererIndex)
{
var delta = mapSessionIndex - mapRendererIndex;
while (delta > 0)
{
UnityEditorInternal.ComponentUtility.MoveComponentUp(mapSession);
delta--;
}
}
}
RenderBanner();
// Setup and key.
_developerKeyProperty.stringValue = EditorGUILayout.PasswordField("Developer Key", _developerKeyProperty.stringValue);
if (string.IsNullOrWhiteSpace(_developerKeyProperty.stringValue))
{
EditorGUI.indentLevel++;
Help(
"Provide a developer key to enable Bing Maps services.",
"Sign up for a key at the Bing Maps Dev Center.",
"https://www.bingmapsportal.com/");
EditorGUI.indentLevel--;
}
_showMapDataInEditorProperty.boolValue =
EditorGUILayout.Toggle(
new GUIContent(
"Show Map Data in Editor",
"Map data usage in the editor will apply to the specified developer key."),
_showMapDataInEditorProperty.boolValue);
serializedObject.ApplyModifiedProperties();
}
private void Help(string message, string urlMessage, string url)
{
EditorGUI.indentLevel--;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel(" ");
EditorGUILayout.BeginHorizontal();
{
EditorGUILayout.BeginVertical();
GUILayout.Space(8);
var iconWidth = _warnIcon.image.width;
EditorGUILayout.LabelField(_warnIcon, _iconStyle, GUILayout.Width(iconWidth));
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical();
{
GUILayout.Space(8);
EditorGUILayout.LabelField(message, _baseStyle);
EditorGUILayout.BeginHorizontal();
{
EditorGUILayout.LabelField(urlMessage, _hyperlinkStyle);
var linkRect = GUILayoutUtility.GetLastRect();
if (Event.current.type == EventType.Repaint)
{
EditorGUIUtility.AddCursorRect(linkRect, MouseCursor.Link);
}
if (Event.current.type == EventType.MouseUp && linkRect.Contains(Event.current.mousePosition))
{
Application.OpenURL(url);
}
}
EditorGUILayout.EndHorizontal();
GUILayout.Space(4);
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel++;
}
private void Initialize()
{
if (_baseStyle == null)
{
_baseStyle = new GUIStyle
{
wordWrap = true,
font = EditorStyles.helpBox.font,
fontSize = EditorStyles.helpBox.fontSize,
normal = EditorStyles.helpBox.normal
};
_baseStyle.normal.background = null;
_baseStyle.stretchWidth = false;
_baseStyle.stretchHeight = false;
_baseStyle.margin = new RectOffset();
}
if (_warnIcon == null)
{
_warnIcon = EditorGUIUtility.TrIconContent("console.warnicon");
}
if (_iconStyle == null)
{
_iconStyle =
new GUIStyle(_baseStyle)
{
stretchHeight = false,
alignment = TextAnchor.MiddleLeft,
fixedWidth = _warnIcon.image.width,
fixedHeight = _warnIcon.image.height,
stretchWidth = false,
wordWrap = false
};
}
if (_hyperlinkStyle == null)
{
_hyperlinkStyle =
new GUIStyle(_baseStyle)
{
alignment = TextAnchor.UpperLeft
};
_hyperlinkStyle.normal.textColor = new Color(0x00 / 255f, 0x78 / 255f, 0xDA / 255f, 1f);
_hyperlinkStyle.stretchWidth = false;
_hyperlinkStyle.padding = new RectOffset();
_hyperlinkStyle.alignment = TextAnchor.UpperLeft;
}
if (_foldoutTitleStyle == null)
{
_foldoutTitleStyle = new GUIStyle(EditorStyles.foldout)
{
fontStyle = UnityEngine.FontStyle.Bold
};
}
if (_boxStyle == null)
{
_boxStyle = new GUIStyle(GUI.skin.box);
}
}
private void RenderBanner()
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.Label(EditorGUIUtility.isProSkin ? _bannerWhite : _bannerBlack, GUILayout.MaxHeight(96f));
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
}
}

Просмотреть файл

@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: b303ffbed90191b4dbbf76b03bf83d80
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: cab8e8f62b00b544f803696d2e169bf3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,106 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Maps.Unity
{
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
/// <summary>
/// This script provides a menu item under "Assets -> Maps SDK for Unity -> Upgrade Component GUIDs". This will find all old component GUIDs
/// which have had their GUIDs modified to a new value. This is typically a result of migrating a component from a DLL to a script.
/// Finds and replaces matching GUID usages in any scene or prefab.
/// </summary>
public static class SdkUpgradeUtility
{
// List of Tuples containing old guid (Item1) and the new guid (Item2).
private static readonly List<Tuple<string, string>> GuidsToUpdate =
new List<Tuple<string, string>>
{
// MapRenderer
new Tuple<string, string>(
"fileID: -194183520, guid: f58183a31672bf641bbeeaef3d4759c0, type: 3",
"fileID: 11500000, guid: 1cf6985fc3c122a4193d16fdcfb59784, type: 3"),
// CopyrightLayer
new Tuple<string, string>(
"fileID: 1914003294, guid: f58183a31672bf641bbeeaef3d4759c0, type: 3",
"fileID: 11500000, guid: 02c7d1b323594a144ac9b98fd93e0f7f, type: 3"),
// MapDataCache
new Tuple<string, string>(
"fileID: -1554650353, guid: f58183a31672bf641bbeeaef3d4759c0, type: 3",
"fileID: 11500000, guid: 1ef50f6f9318ded40b230c1eefb7f968, type: 3"),
// MapPinLayer
new Tuple<string, string>(
"fileID: 1083584769, guid: f58183a31672bf641bbeeaef3d4759c0, type: 3}",
"fileID: 11500000, guid: 5d8a6459eb3010b4f9751de03dca135a, type: 3}"),
// MapPin
new Tuple<string, string>(
"fileID: -404975296, guid: f58183a31672bf641bbeeaef3d4759c0, type: 3",
"fileID: 11500000, guid: 0bb87916f59f52349b237e7ce66a84a1, type: 3"),
// ClusterMapPin
new Tuple<string, string>(
"fileID: -2137691127, guid: f58183a31672bf641bbeeaef3d4759c0, type: 3",
"fileID: 11500000, guid: 10142379db1f9994e9e1ea54ee0ceb78, type: 3")
};
[MenuItem("Assets/Maps SDK for Unity/Upgrade Component GUIDs")]
public static void UpgradeScenes()
{
// Find all scene files in the assets directory.
// Replace old GUIDs with new GUIDs.
var output = "";
var needsAssetReimport = false;
// Scenes
var sceneFiles = Directory.GetFiles(Application.dataPath, "*.unity", SearchOption.AllDirectories);
foreach (var sceneFile in sceneFiles)
{
output += ScrubAssets(sceneFile);
needsAssetReimport = needsAssetReimport || !string.IsNullOrEmpty(output);
}
// Prefabs
var prefabFiles = Directory.GetFiles(Application.dataPath, "*.prefab", SearchOption.AllDirectories);
foreach (var prefabFile in prefabFiles)
{
output += ScrubAssets(prefabFile);
needsAssetReimport = needsAssetReimport || !string.IsNullOrEmpty(output);
}
// Reimport assets if there were changes to the scene files.
if (needsAssetReimport)
{
Debug.Log("Upgraded assets:\r\n" + output);
AssetDatabase.Refresh();
}
else
{
Debug.Log("No assets were modified.");
}
}
private static string ScrubAssets(string assetFile)
{
var assetText = File.ReadAllText(assetFile);
var newAssetText = assetText;
foreach (var guidToUpdate in GuidsToUpdate)
{
newAssetText = newAssetText.Replace(guidToUpdate.Item1, guidToUpdate.Item2);
}
var output = "";
if (newAssetText != assetText)
{
output += " " + Path.GetFileName(assetFile) + "\r\n";
File.WriteAllText(assetFile, newAssetText);
}
return output;
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 007c5a4f1ad183f4d82f32e5342af7df
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,3 +1,3 @@
{
"name": "Microsoft.Maps.Unity.SupportingScripts"
}
{
"name": "Microsoft.Maps.Unity.SupportingScripts"
}

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 733ffde8ec04390438678aec62001c8d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 609eb4e277e00424daf7838ab0ca87cd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,81 +1,81 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: StandardClippingVolumeMaterial-MapsSDK
m_Shader: {fileID: 4800000, guid: 4f3662d02ce27e74ba4365f3c0264722, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TerrainDistanceTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: StandardClippingVolumeMaterial-MapsSDK
m_Shader: {fileID: 4800000, guid: 4f3662d02ce27e74ba4365f3c0264722, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TerrainDistanceTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

Просмотреть файл

@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: d35f8f2bbaf569a418c0ddbcaa384840
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: d35f8f2bbaf569a418c0ddbcaa384840
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,76 +1,76 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: StandardTerrainMaterial-MapsSDK
m_Shader: {fileID: 4800000, guid: 8e4dab924fbdfc04a81deb2ea246a3ff, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 44bb6c7e1a380214fac3e1cca2195376, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: StandardTerrainMaterial-MapsSDK
m_Shader: {fileID: 4800000, guid: 8e4dab924fbdfc04a81deb2ea246a3ff, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 44bb6c7e1a380214fac3e1cca2195376, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

Просмотреть файл

@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 1d68ae504d313a4489795ec46e1c8f48
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 1d68ae504d313a4489795ec46e1c8f48
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 324e19c307bf7374b9a245a49fec9622
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 2.9 KiB

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Просмотреть файл

@ -1,119 +1,119 @@
fileFormatVersion: 2
guid: 44bb6c7e1a380214fac3e1cca2195376
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 2
aniso: 4
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Windows Store Apps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 44bb6c7e1a380214fac3e1cca2195376
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 6
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 2
aniso: 4
mipBias: -100
wrapU: -1
wrapV: -1
wrapW: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Windows Store Apps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d374608a22f6ddc40b7d42af63a0ca11
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a697e415a1022a54e87af4db75ea04c8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,132 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Maps.Unity
{
using System;
using UnityEngine;
/// <summary>
/// This component provides an interface to configure the cache size that is used to store <see cref="MapRenderer"/> data.
/// Because the cache is global, multiple instances of this component are not needed.
/// </summary>
[DisallowMultipleComponent]
[ExecuteInEditMode]
public class MapDataCache : MapDataCacheBase
{
private const long DefaultMaxCacheSizeInBytes = 2147483648L; // 2 GB
private const long MaxMaxCacheSizeInBytes = 4294967296L; // 4 GB
private const long MinCacheSizeInBytes = 209715200L; // 200 MB
/// <summary>
/// Determines how large the cache is relative to the estimated application memory limit, e.g. if the maximum app memory for the
/// application is determined to be 1GB, then a utilization value of 0.5 (50%), will result in a cache size of 512MB.
/// </summary>
[SerializeField]
[Range(0, 1)]
private float _percentUtilization = 0.3f;
/// <summary>
/// Determines how large the cache is relative to the estimated application memory limit, e.g. if the maximum app memory for the
/// application is determined to be 1GB, then a utilization value of 0.5 (50%), will result in a cache size of 512MB.
/// </summary>
public float PercentUtilization
{
get => _percentUtilization;
set
{
var newPercentUtilization = Mathf.Clamp01(_percentUtilization);
if (newPercentUtilization != _percentUtilization)
{
_percentUtilization = newPercentUtilization;
Refresh();
}
}
}
/// <summary>
/// The maximum possible cache size. Even if the device could support a larger cache, the cache size will not exceed this value.
/// </summary>
[SerializeField]
private long _maxCacheSizeInBytes = DefaultMaxCacheSizeInBytes;
/// <summary>
/// The maximum possible cache size. Even if the device could support a larger cache, the cache size will not exceed this value.
/// </summary>
public long MaxCacheSizeInBytes
{
get => _maxCacheSizeInBytes;
set
{
var newMaxCacheSizeInBytes = Math.Min(MaxMaxCacheSizeInBytes, _maxCacheSizeInBytes);
if (_maxCacheSizeInBytes != newMaxCacheSizeInBytes)
{
_maxCacheSizeInBytes = newMaxCacheSizeInBytes;
Refresh();
}
}
}
private void OnValidate()
{
_maxCacheSizeInBytes = Math.Min(MaxMaxCacheSizeInBytes, _maxCacheSizeInBytes);
_percentUtilization = Mathf.Clamp01(_percentUtilization);
Refresh();
}
/// <inheritdoc/>
protected override long ComputeCacheSizeInBytes()
{
var maximumAvailableBytes = 0L;
#if UNITY_ANDROID
// On Android, we can query the application's memory limit to get an accurate max size.
if (!Application.isEditor)
{
try
{
maximumAvailableBytes = GetAvailableMemory();
maximumAvailableBytes = (long)(maximumAvailableBytes * 0.9f); // Leave some room.
}
catch (Exception e)
{
Debug.LogException(e, gameObject);
}
}
#endif
// The fall back option is to just compute a maximum size based on the total available memory.
if (maximumAvailableBytes <= 0)
{
var totalSystemMemoryInBytes = SystemInfo.systemMemorySize /* <-- MB */ * 1000L * 1000L;
var managedBytes = GC.GetTotalMemory(true);
maximumAvailableBytes = totalSystemMemoryInBytes - managedBytes;
}
var percentUtilization = Mathf.Clamp01(_percentUtilization);
var cacheSizeInBytes = (long)(percentUtilization * maximumAvailableBytes);
return Math.Max(MinCacheSizeInBytes, Math.Min(cacheSizeInBytes, _maxCacheSizeInBytes));
}
#if UNITY_ANDROID
private static AndroidJavaObject GetMemoryInfo()
{
var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
var systemService = currentActivity.Call<AndroidJavaObject>("getSystemService", "activity");
var memoryInfo = new AndroidJavaObject("android.app.ActivityManager$MemoryInfo");
systemService.Call("getMemoryInfo", memoryInfo);
return memoryInfo;
}
private static long GetAvailableMemory()
{
using (var memoryInfo = GetMemoryInfo())
{
return memoryInfo.Get<long>("availMem");
}
}
#endif
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1ef50f6f9318ded40b230c1eefb7f968
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a1dc6775b63b0414fbe5f55b0f9a613a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b203a2e1986b2424cb9eb1e0df040324
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7a47178748d759746adc3412b40b1fde
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Maps.Unity
{
/// <summary>
/// Alignment options for <see cref="MapCopyrightLayer"/>.
/// </summary>
public enum MapCopyrightAlignment
{
/// <summary>
/// Default alignment. Copyright text is rendered at the bottom of the map.
/// </summary>
Bottom,
/// <summary>
/// Copyright text is rendered at the top of the map.
/// </summary>
Top
};
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 147b435955cf84a4fbad9fd9187c7b40
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,273 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Maps.Unity
{
using System;
using UnityEngine;
using UnityEngine.Rendering;
/// <summary>
/// Handles rendering and positioning of copyright text associated with the <see cref="MapRendererBase"/>.
/// This layer is automatically added when the <see cref="MapRendererBase"/> component is added to a <see cref="GameObject"/>.
/// </summary>
/// <remarks>
/// If the default placement of the copyright text displayed by the <see cref="MapRendererBase"/> is unacceptable, it can be disabled
/// and the text can be displayed manually by retrieving the copyright text string from <see cref="MapRendererBase.Copyright"/> and
/// rendering it with a TextMesh or TextMeshPro component. The copyright text must be displayed in a conspicuous manner near the map.
/// </remarks>
[DisallowMultipleComponent]
[ExecuteInEditMode]
[RequireComponent(typeof(MapRenderer))]
public class MapCopyrightLayer : MapLayer
{
private const float Margin = 0.015f;
/// <summary>
/// The font used for the copyright text.
/// </summary>
[SerializeField]
private Font _font = null;
/// <summary>
/// The color of the copyright text.
/// </summary>
[SerializeField]
private Color _textColor = new Color(0, 0, 0, 0.42f);
/// <summary>
/// The alignment of the copyright text.
/// </summary>
[SerializeField]
private MapCopyrightAlignment _mapCopyrightAlignment = MapCopyrightAlignment.Bottom;
// Reload these fields lazily...
// The corresponding text GameObjects will be marked HideAndDontSave, i.e. purely temporary.
private TextMesh _copyrightText1 = null;
private TextMesh _copyrightText2 = null;
private Shader _occludable3DTextShader = null;
private void Awake()
{
LayerName = "MapCopyrightLayer";
}
private void OnEnable()
{
MapRenderer.AfterUpdate -= UpdateDefaultCopyrights;
MapRenderer.AfterUpdate += UpdateDefaultCopyrights;
MapRenderer.AfterOnDisable -= MapRendererDisabled;
MapRenderer.AfterOnDisable += MapRendererDisabled;
if (_copyrightText1 != null)
{
_copyrightText1.gameObject.SetActive(true);
}
if (_copyrightText2 != null)
{
_copyrightText2.gameObject.SetActive(true);
}
}
private void OnDisable()
{
MapRenderer.AfterUpdate -= UpdateDefaultCopyrights;
MapRenderer.AfterOnDisable -= MapRendererDisabled;
_copyrightText1?.gameObject.SetActive(false);
_copyrightText2?.gameObject.SetActive(false);
}
private void OnDestroy()
{
if (_copyrightText1 != null)
{
DestroyImmediate(_copyrightText1.gameObject);
_copyrightText1 = null;
}
if (_copyrightText2 != null)
{
DestroyImmediate(_copyrightText2.gameObject);
_copyrightText2 = null;
}
}
private void UpdateDefaultCopyrights(object sender, EventArgs args)
{
const int fontSize = 46;
const float targetLocalSize = 0.175f;
const float targetLocalScale = targetLocalSize / fontSize;
var localYOffset = new Vector3(0, MapRenderer.LocalMapBaseHeight - 2 * targetLocalScale, 0);
// Load the default font, if it hasn't already been loaded.
if (_font == null)
{
_font = Resources.GetBuiltinResource<Font>("Arial.ttf");
Debug.Assert(_font != null);
}
// Create the copyright game objects if they haven't already been created.
EnsureCopyrightGameObjectSetup(ref _copyrightText1, "DefaultCopyright1", fontSize);
EnsureCopyrightGameObjectSetup(ref _copyrightText2, "DefaultCopyright2", fontSize);
// Sync the configurable properties.
{
var mapRendererGameObject = MapRenderer.gameObject;
_copyrightText1.gameObject.layer = mapRendererGameObject.layer;
_copyrightText1.text = MapRenderer.Copyright;
_copyrightText1.color = _textColor;
_copyrightText2.gameObject.layer = mapRendererGameObject.layer;
_copyrightText2.text = MapRenderer.Copyright;
_copyrightText2.color = _textColor;
}
// Update positions.
{
// First, determine which two sides of the map that we can see.
var mainCamera = Camera.main;
var cameraPosition = mainCamera == null ? Vector3.zero : mainCamera.transform.position;
var thisTransform = transform;
var cameraToPosition = thisTransform.position - cameraPosition;
var transformForward = thisTransform.forward;
var normal1Sign = Vector3.Dot(cameraToPosition, transformForward) > 0 ? -1.0f : 1.0f;
var normal2Sign = Vector3.Dot(cameraToPosition, transform.right) > 0 ? -1.0f : 1.0f;
var forward = transformForward * normal1Sign;
var localForward = Vector3.forward * normal1Sign;
var right = thisTransform.right * normal2Sign;
var localRight = Vector3.right * normal2Sign;
// Position the text meshes.
UpdateTextPositionAndAlignment(
_copyrightText1,
MapRenderer.LocalMapDimension.y,
MapRenderer.LocalMapDimension.x,
new Vector3(Margin, 0, 0),
localForward,
localYOffset,
targetLocalScale);
UpdateTextPositionAndAlignment(
_copyrightText2,
MapRenderer.LocalMapDimension.x,
MapRenderer.LocalMapDimension.y,
new Vector3(0, 0, Margin),
localRight,
localYOffset,
targetLocalScale);
// Align the text meshes correctly.
_copyrightText1.transform.rotation = Quaternion.LookRotation(-forward, transform.up);
_copyrightText2.transform.rotation = Quaternion.LookRotation(-right, transform.up);
// Enable / Disable the text depending on if the camera can see them.
var cameraToText1Position = _copyrightText1.transform.position - cameraPosition;
var cameraToText2Position = _copyrightText2.transform.position - cameraPosition;
var isText1VisibleToCamera = Vector3.Dot(cameraToText1Position, -_copyrightText1.transform.forward) <= 0;
var isText2VisibleToCamera = Vector3.Dot(cameraToText2Position, -_copyrightText2.transform.forward) <= 0;
_copyrightText1.gameObject.SetActive(isText1VisibleToCamera);
_copyrightText2.gameObject.SetActive(isText2VisibleToCamera);
}
}
private void UpdateTextPositionAndAlignment(
TextMesh textMesh,
float localNormalMagnitude,
float localCrossMagnitude,
Vector3 marginLeft,
Vector3 localNormal,
Vector3 localYOffset,
float localScale)
{
if (MapRenderer.MapShape == MapShape.Block)
{
var localCross = Vector3.Cross(localNormal, Vector3.up);
textMesh.transform.localPosition =
0.504f * localNormalMagnitude * localNormal +
0.5f * localCrossMagnitude * -localCross +
(IsVectorNegative(localCross) ? -marginLeft : marginLeft);
if (_mapCopyrightAlignment == MapCopyrightAlignment.Top)
{
textMesh.anchor = TextAnchor.UpperLeft;
textMesh.transform.localPosition += localYOffset;
}
else
{
textMesh.transform.localPosition += new Vector3(0, Margin, 0);
textMesh.anchor = TextAnchor.LowerLeft;
}
textMesh.alignment = TextAlignment.Left;
}
else
{
textMesh.transform.localPosition = MapRenderer.LocalMapRadius * localNormal;
if (_mapCopyrightAlignment == MapCopyrightAlignment.Top)
{
textMesh.anchor = TextAnchor.UpperCenter;
textMesh.transform.localPosition += localYOffset;
}
else
{
textMesh.transform.localPosition += new Vector3(0, Margin, 0);
textMesh.anchor = TextAnchor.LowerCenter;
}
textMesh.alignment = TextAlignment.Center;
}
textMesh.transform.localScale = new Vector3(localScale, localScale, localScale);
}
private bool IsVectorNegative(Vector3 v)
{
return v.x < 0 || v.z < 0;
}
private void EnsureCopyrightGameObjectSetup(ref TextMesh textMesh, string copyrightGameObjectName, int fontSize)
{
if (textMesh == null)
{
var defaultCopyrightText =
new GameObject(copyrightGameObjectName)
{
hideFlags = HideFlags.HideAndDontSave
};
defaultCopyrightText.transform.parent = transform;
textMesh = defaultCopyrightText.AddComponent<TextMesh>();
textMesh.font = _font;
textMesh.fontSize = fontSize;
textMesh.fontStyle = UnityEngine.FontStyle.Bold;
if (_occludable3DTextShader == null)
{
_occludable3DTextShader = Shader.Find("MapsSDK/Occludable3DTextShader");
}
if (_occludable3DTextShader != null)
{
var meshRenderer = textMesh.GetComponent<MeshRenderer>();
meshRenderer.sharedMaterial = new Material(_occludable3DTextShader);
meshRenderer.receiveShadows = true;
meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
if (textMesh.font != null)
{
meshRenderer.sharedMaterial.SetTexture("_MainTex", textMesh.font.material.mainTexture);
}
}
}
else
{
textMesh.gameObject.SetActive(true);
}
}
private void MapRendererDisabled(object sender, EventArgs args)
{
_copyrightText1?.gameObject.SetActive(false);
_copyrightText2?.gameObject.SetActive(false);
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 02c7d1b323594a144ac9b98fd93e0f7f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace Microsoft.Maps.Unity
{
using UnityEngine;
/// <summary>
/// Base class for any type of layer associated with a <see cref="Unity.MapRenderer"/>.
/// </summary>
[RequireComponent(typeof(MapRenderer))]
public abstract class MapLayer : MonoBehaviour
{
/// <summary>
/// The name of the <see cref="MapLayer"/>.
/// </summary>
[SerializeField]
private string _layerName;
/// <summary>
/// The name of the <see cref="MapLayer"/>.
/// </summary>
public string LayerName { get => _layerName; set => _layerName = value; }
private MapRenderer _mapRenderer;
/// <summary>
/// The <see cref="MapRenderer"/> that this layer has been attached to.
/// </summary>
public MapRenderer MapRenderer
{
get
{
if (_mapRenderer == null)
{
_mapRenderer = GetComponent<MapRenderer>();
if (_mapRenderer == null)
{
Debug.LogError($"Unable to find MapRenderer component on '{gameObject.name}'.");
return null;
}
}
return _mapRenderer;
}
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 924125f3911e8214282ec255b5f3324a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b2486b69a850b2749b2b81de84c6fd61
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace Microsoft.Maps.Unity
{
using UnityEngine;
/// <summary>
/// Represents a cluster of <see cref="MapPin"/>s at the specified level of detail.
/// </summary>
[HelpURL("https://github.com/Microsoft/MapsSDK-Unity/wiki/Attaching-GameObjects-to-the-map")]
public class ClusterMapPin : MapPin
{
/// <summary>
/// The level of detail represented by this cluster.
/// </summary>
public short LevelOfDetail
{
get;
internal set;
}
/// <summary>
/// The number of pins in this cluster.
/// </summary>
public int Size
{
get;
internal set;
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 10142379db1f9994e9e1ea54ee0ceb78
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,182 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Maps.Unity
{
using Microsoft.Geospatial;
using Microsoft.Geospatial.VectorMath;
using System;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// A MapPin can be used to pin a <see cref="GameObject"/> to a <see cref="MapRendererBase"/> at a specified
/// <see cref="Geospatial.LatLon"/> and altitude.
/// </summary>
[DisallowMultipleComponent]
[ExecuteInEditMode]
[HelpURL("https://github.com/Microsoft/MapsSDK-Unity/wiki/Attaching-GameObjects-to-the-map")]
public class MapPin : MonoBehaviour, IPinnable
{
[SerializeField]
private LatLonWrapper _location;
/// <summary>
/// The location of the <see cref="MapPin"/>.
/// </summary>
public LatLon Location
{
get
{
return _location.ToLatLon();
}
set
{
var oldLocation = _location.ToLatLon();
if (value != oldLocation)
{
_location = new LatLonWrapper(value);
LocationChanged?.Invoke(this, value);
}
}
}
/// <summary>
/// Action that is invoked when the <see cref="Location"/> is changed.
/// </summary>
public Action<MapPin, LatLon> LocationChanged;
private MercatorCoordinate _mercatorCoordinate;
/// <inheritdoc/>
public MercatorCoordinate MercatorCoordinate => _mercatorCoordinate;
[SerializeField]
private double _altitude;
/// <inheritdoc/>
public double Altitude { get => _altitude; set => _altitude = value; }
[SerializeField]
private AltitudeReference _altitudeReference = AltitudeReference.Surface;
/// <inheritdoc/>
public AltitudeReference AltitudeReference
{
get => _altitudeReference;
set => _altitudeReference = value;
}
/// <inheritdoc/>
public Vector3 PositionInMapLocalSpace
{
get => transform.localPosition;
set => transform.localPosition = value;
}
/// <inheritdoc/>
public bool HasBeenFullyPositioned { get; set; }
/// <summary>
/// If true, synchronizes this <see cref="GameObject"/>'s and it's childrens' layers to the same value as the
/// associated <see cref="MapRendererBase"/>'s layer.
/// </summary>
public bool IsLayerSynchronized = true;
/// <summary>
/// If true, the <see cref="ScaleCurve"/> is relative to the real-world scale at a given zoom level. As the map zooms out,
/// size falls off exponentially. If false, the ScaleCurve represents the direct scale of the MapPin at a given zoom level.
/// </summary>
public bool UseRealWorldScale;
/// <summary>
/// The scale of the pin relative to the map's zoom level.
/// </summary>
public AnimationCurve ScaleCurve = AnimationCurve.Linear(MapConstants.MinimumZoomLevel, 1, MapConstants.MaximumZoomLevel, 1);
/// <summary>
/// Reset the component to default values.
/// </summary>
protected virtual void Reset()
{
_mercatorCoordinate = Location.ToMercatorCoordinate();
}
/// <summary>
/// Awake is called when the component instance is being loaded.
/// </summary>
protected virtual void Awake()
{
_mercatorCoordinate = Location.ToMercatorCoordinate();
}
/// <summary>
/// OnEnable is called when the component is enabled and when scripts are reloaded.
/// </summary>
protected virtual void OnEnable()
{
_mercatorCoordinate = Location.ToMercatorCoordinate();
}
/// <summary>
/// This method is called when the script is loaded or a value is changed in the inspector. Called in the editor only.
/// </summary>
protected virtual void Validate()
{
_mercatorCoordinate = Location.ToMercatorCoordinate();
}
/// <summary>
/// Synchronizes the <see cref="MapPin"/>'s layers (and any of it's children layers) with the <see cref="MapRenderer"/>'s layer.
/// Whether or not a <see cref="MapPin"/>'s layer is synchronized depends on the value of <see cref="MapPin.IsLayerSynchronized"/>.
/// </summary>
public static void SynchronizeLayers(IReadOnlyList<MapPin> mapPins, MapRenderer mapRenderer)
{
var targetLayer = mapRenderer.gameObject.layer;
foreach (var mapPin in mapPins)
{
if (mapPin.IsLayerSynchronized && mapPin.gameObject.layer != targetLayer)
{
mapPin.gameObject.layer = targetLayer;
foreach (var child in mapPin.GetComponentsInChildren<Transform>())
{
child.gameObject.layer = targetLayer;
}
}
}
}
/// <summary>
/// Updates the <see cref="MapPin"/>s' scale based on <see cref="MapPin.ScaleCurve"/> and <see cref="MapPin.UseRealWorldScale"/>.
/// </summary>
public static void UpdateScales<T>(List<T> mapPins, MapRenderer mapRenderer) where T : MapPin
{
const double EquatorialCircumferenceInWgs84Meters = 40075016.685578488;
var mapZoomLevel = mapRenderer.ZoomLevel;
var mapTotalWidthInLocalSpace = Math.Pow(2, Math.Max(mapZoomLevel - 1.0, 0.0));
var mapElevationScale = mapRenderer.ElevationScale;
var mapRealisticScale = mapTotalWidthInLocalSpace / EquatorialCircumferenceInWgs84Meters;
foreach (var mapPin in mapPins)
{
if (mapPin.enabled && mapPin.gameObject.activeInHierarchy)
{
// Scale the pin depending on the scale curve and current ZoomLevel.
var mercatorScaleAtCoordinate = MercatorScale.AtMercatorLatitude(mapPin.MercatorCoordinate.Y);
{
var scale = mapPin.ScaleCurve.Evaluate(mapZoomLevel);
var additionalYScale = 1.0f;
if (mapPin.UseRealWorldScale)
{
scale *= (float)(mercatorScaleAtCoordinate * mapRealisticScale);
additionalYScale = mapElevationScale;
}
mapPin.transform.localScale = new Vector3(scale, scale * additionalYScale, scale);
}
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0bb87916f59f52349b237e7ce66a84a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,386 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace Microsoft.Maps.Unity
{
using Microsoft.Geospatial.VectorMath;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;
/// <summary>
/// Maintains a collection of <see cref="MapPin"/>s. Supports clustering. This layer is queried by the associated MapRenderer to get the
/// MapPins or clusters in the map's current view. All associated MapPins are parented to a child GameObject with
/// the same name as this MapPinLayer.
/// </summary>
[HelpURL("https://github.com/Microsoft/MapsSDK-Unity/wiki/Attaching-GameObjects-to-the-map")]
public class MapPinLayer : MapLayer
{
private MapPinSpatialIndex _mapPinSpatialIndex;
[SerializeField]
private ObservableMapPinList _mapPins = new ObservableMapPinList();
/// <summary>
/// All MapPins associated with this MapPinLayer.
/// </summary>
public ObservableList<MapPin> MapPins { get { return _mapPins; } }
/// <summary>
/// The MapPins which are active.
/// </summary>
public IReadOnlyCollection<MapPin> ActiveMapPins => _activeMapPins;
/// <summary>
/// The ClusterMapPins which are active.
/// </summary>
public IReadOnlyCollection<ClusterMapPin> ActiveClusterMapPins => _activeClusterMapPins;
/// <summary>
/// True if the MapPins in this data source should be clustered. Note, if this is set to true, it is expected that a prefab
/// has been provided to ClusterMapPinPrefab.
/// </summary>
[SerializeField]
private bool _isClusteringEnabled = false;
/// <summary>
/// True if the MapPins in this data source should be clustered. Note, if this is set to true, it is expected that a prefab
/// has been provided to ClusterMapPinPrefab.
/// </summary>
public bool IsClusteringEnabled
{
get => _isClusteringEnabled;
set
{
if (_isClusteringEnabled != value)
{
_isClusteringEnabled = value;
RebuildSpatialIndex();
}
}
}
/// <summary>
/// If the number of pins in a spatial region exceed the ClusterThreshold, a single cluster MapPin will be rendered instead.
/// </summary>
[SerializeField]
private int _clusterThreshold = 5;
/// <summary>
/// If the number of pins in a spatial region exceed the ClusterThreshold, a single cluster MapPin will be rendered instead.
/// </summary>
/// <remarks>
/// Modifying during ruintime will cause the MapPinLayer to rebuild, which may be expensive.
/// </remarks>
public int ClusterThreshold
{
get => _clusterThreshold;
set
{
value = Math.Max(2, value);
if (_clusterThreshold != value)
{
_clusterThreshold = value;
RebuildSpatialIndex();
}
}
}
/// <summary>
/// The prefab to use for clusters.
/// </summary>
[SerializeField]
private ClusterMapPin _clusterMapPinPrefab;
/// <summary>
/// The prefab to use for clusters.
/// </summary>
/// <remarks>
/// Modifying during ruintime will cause the MapPinLayer to rebuild, which may be expensive.
/// </remarks>
public ClusterMapPin ClusterMapPinPrefab
{
get => _clusterMapPinPrefab;
set
{
if (value != _clusterMapPinPrefab)
{
_clusterMapPinPrefab = value;
RebuildSpatialIndex();
}
}
}
private GameObject _containerGo;
private readonly HashSet<MapPin> _mapPinsInViewThisFrame = new HashSet<MapPin>();
private readonly HashSet<MapPin> _activeMapPins = new HashSet<MapPin>();
private readonly HashSet<ClusterMapPin> _clusterMapPinsInViewThisFrame = new HashSet<ClusterMapPin>();
private readonly HashSet<ClusterMapPin> _activeClusterMapPins = new HashSet<ClusterMapPin>();
private void OnValidate()
{
_clusterThreshold = Math.Max(_clusterThreshold, 2);
}
private void Awake()
{
if (string.IsNullOrEmpty(LayerName))
{
LayerName = "MapPinLayer";
}
}
private void OnEnable()
{
// Hook up ObservableList events.
MapPins.ItemAdded += OnItemAdded;
MapPins.RangeAdded += OnRangeAdded;
MapPins.ItemRemoved += OnItemRemoved;
MapPins.RangeRemoved += OnRangeRemoved;
EnsureContainerGameObjectIsCreated();
_containerGo.gameObject.SetActive(true);
EnsureSpatialIndexInitialized();
MapRenderer.AfterUpdate -= UpdateMapPinsInView;
MapRenderer.AfterUpdate += UpdateMapPinsInView;
MapRenderer.AfterOnDisable -= MapRendererDisabled;
MapRenderer.AfterOnDisable += MapRendererDisabled;
}
private void OnDisable()
{
_mapPinSpatialIndex.DestroyClusterMapPins();
_activeClusterMapPins.Clear();
foreach (var mapPin in _activeMapPins)
{
mapPin.gameObject.SetActive(false);
}
_activeMapPins.Clear();
// Unregister events.
MapRenderer.AfterUpdate -= UpdateMapPinsInView;
MapRenderer.AfterOnDisable -= MapRendererDisabled;
EnsureContainerGameObjectIsCreated();
_containerGo.gameObject.SetActive(false);
// Unhook ObservableList events.
MapPins.ItemAdded -= OnItemAdded;
MapPins.RangeAdded -= OnRangeAdded;
MapPins.ItemRemoved -= OnItemRemoved;
MapPins.RangeRemoved -= OnRangeRemoved;
}
private void OnDestroy()
{
MapPins.Clear();
Destroy(_containerGo);
_containerGo = null;
}
private void UpdateMapPinsInView(object sender, EventArgs args)
{
Profiler.BeginSample("UpdateMapPinsInView");
if (_mapPinSpatialIndex != null)
{
EnsureContainerGameObjectIsCreated();
_containerGo.gameObject.SetActive(true);
List<MapPin> mapPinsInView;
List<ClusterMapPin> clusterMapPinsInView;
if (MapRenderer.MapShape == MapShape.Block)
{
_mapPinSpatialIndex.GetPinsInView(
MapRenderer.MercatorBoundingBox,
MapRenderer.ZoomLevel,
_clusterMapPinPrefab,
_containerGo.transform,
out mapPinsInView,
out clusterMapPinsInView);
}
else // Cylinder.
{
_mapPinSpatialIndex.GetPinsInView(
MapRenderer.MercatorBoundingBox,
MapRenderer.MercatorBoundingCircle,
MapRenderer.ZoomLevel,
_clusterMapPinPrefab,
_containerGo.transform,
out mapPinsInView,
out clusterMapPinsInView);
}
// Update visible MapPins' position and other properties.
{
MapPin.SynchronizeLayers(mapPinsInView, MapRenderer);
MapPin.SynchronizeLayers(clusterMapPinsInView, MapRenderer);
MapRenderer.TrackAndPositionPinnables(mapPinsInView);
MapRenderer.TrackAndPositionPinnables(clusterMapPinsInView);
MapPin.UpdateScales(mapPinsInView, MapRenderer);
MapPin.UpdateScales(clusterMapPinsInView, MapRenderer);
}
// Disable MapPins that are no longer visible.
{
_mapPinsInViewThisFrame.Clear();
_mapPinsInViewThisFrame.UnionWith(mapPinsInView);
foreach (var previousActiveMapPin in _activeMapPins)
{
if (previousActiveMapPin != null && !_mapPinsInViewThisFrame.Contains(previousActiveMapPin))
{
MapRenderer.UntrackPinnable(previousActiveMapPin);
previousActiveMapPin.gameObject.SetActive(false);
}
}
_clusterMapPinsInViewThisFrame.Clear();
_clusterMapPinsInViewThisFrame.UnionWith(clusterMapPinsInView);
foreach (var previousActiveClusterMapPin in _activeClusterMapPins)
{
if (previousActiveClusterMapPin != null && !_clusterMapPinsInViewThisFrame.Contains(previousActiveClusterMapPin))
{
MapRenderer.UntrackPinnable(previousActiveClusterMapPin);
previousActiveClusterMapPin.gameObject.SetActive(false);
}
}
// Filter out pins that have not been fully positioned, i.e. are still awaiting an elevation sample.
// As a side effect, this will also enable any pins once any initial async op used to position them has completed.
_mapPinsInViewThisFrame.RemoveWhere(
(MapPin mapPin) =>
{
mapPin.gameObject.SetActive(mapPin.HasBeenFullyPositioned);
return !mapPin.HasBeenFullyPositioned;
});
_clusterMapPinsInViewThisFrame.RemoveWhere(
(ClusterMapPin clusterMapPin) =>
{
clusterMapPin.gameObject.SetActive(clusterMapPin.HasBeenFullyPositioned);
return !clusterMapPin.HasBeenFullyPositioned;
});
// Assign to the active properties.
_activeMapPins.Clear();
_activeMapPins.UnionWith(_mapPinsInViewThisFrame);
_mapPinsInViewThisFrame.Clear();
_activeClusterMapPins.Clear();
_activeClusterMapPins.UnionWith(_clusterMapPinsInViewThisFrame);
_clusterMapPinsInViewThisFrame.Clear();
}
}
Profiler.EndSample();
}
private void MapRendererDisabled(object sender, EventArgs args)
{
EnsureContainerGameObjectIsCreated();
_containerGo.gameObject.SetActive(false);
}
private void OnItemAdded(object sender, MapPin mapPin, int index)
{
_mapPinSpatialIndex.AddMapPin(mapPin);
mapPin.gameObject.SetActive(false);
EnsureContainerGameObjectIsCreated();
mapPin.transform.SetParent(_containerGo.transform, false);
}
private void OnRangeAdded(object sender, IEnumerable<MapPin> mapPins, int index)
{
foreach (var mapPin in mapPins)
{
_mapPinSpatialIndex.AddMapPin(mapPin);
}
foreach (var mapPin in mapPins)
{
mapPin.gameObject.SetActive(false);
}
EnsureContainerGameObjectIsCreated();
foreach (var mapPin in mapPins)
{
mapPin.transform.SetParent(_containerGo.transform, false);
}
}
private void OnItemRemoved(object sender, MapPin mapPin, int index)
{
_mapPinSpatialIndex.RemoveMapPin(mapPin);
}
private void OnRangeRemoved(object sender, IEnumerable<MapPin> mapPins, int index)
{
foreach (var mapPin in mapPins)
{
_mapPinSpatialIndex.RemoveMapPin(mapPin);
}
}
private void EnsureContainerGameObjectIsCreated()
{
if (_containerGo == null)
{
// Create a GO to hold the pins if one doesn't already exist.
var mapPinContainerName = string.IsNullOrEmpty(LayerName) ? "Unnamed MapPinLayer Container" : LayerName + " Container";
_containerGo = new GameObject(mapPinContainerName);
_containerGo.transform.SetParent(transform, false);
}
}
private void EnsureSpatialIndexInitialized()
{
if (_mapPinSpatialIndex != null)
{
return;
}
_mapPinSpatialIndex = new MapPinSpatialIndex(_isClusteringEnabled, _clusterThreshold);
// If there was already been MapPins added to the data source, add them to the spatial index as well.
{
foreach (var mapPin in MapPins)
{
_mapPinSpatialIndex.AddMapPin(mapPin);
}
foreach (var mapPin in MapPins)
{
mapPin.gameObject.SetActive(false);
}
foreach (var mapPin in MapPins)
{
mapPin.transform.SetParent(_containerGo.transform, false);
}
}
}
private void RebuildSpatialIndex()
{
if (_mapPinSpatialIndex != null)
{
_mapPinSpatialIndex.DestroyClusterMapPins();
_mapPinSpatialIndex = null;
}
EnsureSpatialIndexInitialized();
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5d8a6459eb3010b4f9751de03dca135a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,448 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace Microsoft.Maps.Unity
{
using Geospatial;
using System;
using System.Collections.Generic;
using UnityEngine;
#if DEBUG
using UnityEngine.Assertions;
#endif
internal class MapPinSpatialIndex
{
private class TileData
{
internal int MapPinCount;
internal double TotalLat;
internal double TotalLon;
internal ClusterMapPin ClusterMapPin;
// If non-null, the (unclustered) MapPins for this tile. If null, a cluster exists in this tile and MapPinCount should be
// greater than the ClusterThreshold.
internal List<MapPin> MapPins;
internal bool IsClustered()
{
// If the MapPins are null, then we are in clustering mode.
return MapPins == null;
}
}
private readonly int ClusterThreshold;
private readonly Dictionary<long, TileData>[] _tiledSpatialIndex;
private readonly TileLevelOfDetail _maxLod = new TileLevelOfDetail(18);
private readonly bool _isClusteringEnabled = false;
private readonly List<ClusterMapPin> _clusterMapPins = new List<ClusterMapPin>();
internal MapPinSpatialIndex(bool isClusteringEnabled, int clusterThreshold = 5)
{
_isClusteringEnabled = isClusteringEnabled;
if (clusterThreshold < 2)
{
throw new ArgumentException(nameof(clusterThreshold), "clusterThreshold should be greater than 1.");
}
ClusterThreshold = clusterThreshold;
// Initialize the spatial index. For each LOD, create a dictionary that maps TileIds to TileData.
_tiledSpatialIndex = new Dictionary<long, TileData>[_maxLod.Value];
for (var i = 0; i < _tiledSpatialIndex.Length; i++)
{
_tiledSpatialIndex[i] = new Dictionary<long, TileData>();
}
}
internal void AddMapPin(MapPin mapPinToAdd)
{
mapPinToAdd.LocationChanged += MapPinLocationChanged;
var latLon = mapPinToAdd.Location;
// Insert into max LOD.
TileId maxLodTileId;
{
var lodIndex = _maxLod.Value - 1;
maxLodTileId = new TileId(latLon, _maxLod);
if (!_tiledSpatialIndex[lodIndex].TryGetValue(maxLodTileId.Value, out TileData maxLodTileData))
{
maxLodTileData =
new TileData
{
MapPins = new List<MapPin> { mapPinToAdd }
};
_tiledSpatialIndex[lodIndex].Add(maxLodTileId.Value, maxLodTileData);
}
else
{
maxLodTileData.MapPins.Add(mapPinToAdd);
}
maxLodTileData.MapPinCount++;
maxLodTileData.TotalLat += latLon.LatitudeInDegrees;
maxLodTileData.TotalLon += latLon.LongitudeInDegrees;
}
// Bubble up tile into parent LODs.
maxLodTileId.TryGetParent(out var parentTileId);
var parentLodIndex = parentTileId.CalculateLevelOfDetail().Value - 1;
while (parentLodIndex >= 0)
{
if (!_tiledSpatialIndex[parentLodIndex].TryGetValue(parentTileId.Value, out var parentTileData))
{
// This is a new tile. Create and add a new TileData for this LOD.
parentTileData =
new TileData
{
MapPins = new List<MapPin> { mapPinToAdd },
MapPinCount = 1,
TotalLat = latLon.LatitudeInDegrees,
TotalLon = latLon.LongitudeInDegrees
};
_tiledSpatialIndex[parentLodIndex].Add(parentTileId.Value, parentTileData);
}
else
{
// We already have a tile with points or clusters.
// In either case, track the LatLong.
parentTileData.MapPinCount++;
parentTileData.TotalLat += latLon.LatitudeInDegrees;
parentTileData.TotalLon += latLon.LongitudeInDegrees;
var isCluster = _isClusteringEnabled && parentTileData.MapPinCount > ClusterThreshold;
if (isCluster)
{
parentTileData.MapPins = null;
}
else
{
parentTileData.MapPins.Add(mapPinToAdd);
}
}
parentLodIndex--;
parentTileId.TryGetParent(out parentTileId);
}
}
internal void RemoveMapPin(MapPin mapPinToRemove)
{
RemoveMapPin(mapPinToRemove, mapPinToRemove.Location);
}
private void RemoveMapPin(MapPin mapPinToRemove, LatLon locationOverride)
{
// Find the MapPin in the spatial index at the max LOD.
var lodIndex = _maxLod.Value - 1;
var maxLodTileId = new TileId(locationOverride, _maxLod);
var indexChanged = false;
if (_tiledSpatialIndex[lodIndex].TryGetValue(maxLodTileId.Value, out TileData maxLodTileData))
{
if (maxLodTileData.MapPins.Remove(mapPinToRemove))
{
indexChanged = true;
mapPinToRemove.LocationChanged -= MapPinLocationChanged;
maxLodTileData.MapPinCount--;
if (maxLodTileData.MapPinCount == 0)
{
// Remove tile if now empty.
_tiledSpatialIndex[lodIndex].Remove(maxLodTileId.Value);
}
else
{
maxLodTileData.TotalLat -= locationOverride.LatitudeInDegrees;
maxLodTileData.TotalLon -= locationOverride.LongitudeInDegrees;
}
}
}
// Bubble up change to parent tiles.
if (indexChanged)
{
maxLodTileId.TryGetParent(out var parentTileId);
var parentLodIndex = parentTileId.CalculateLevelOfDetail().Value - 1;
while (parentLodIndex >= 0)
{
_tiledSpatialIndex[parentLodIndex].TryGetValue(parentTileId.Value, out var parentTileData);
parentTileData.MapPinCount--;
if (parentTileData.MapPinCount == 0)
{
// No more pins left in this tile. Remove it from the spatial index.
_tiledSpatialIndex[parentLodIndex].Remove(parentTileId.Value);
#if DEBUG
// It shouldn't be clustered.
Assert.IsTrue(parentTileData.ClusterMapPin == null);
#endif
}
else
{
parentTileData.TotalLat -= locationOverride.LatitudeInDegrees;
parentTileData.TotalLon -= locationOverride.LongitudeInDegrees;
var isCluster = _isClusteringEnabled && parentTileData.MapPinCount > ClusterThreshold;
if (!isCluster)
{
if (parentTileData.MapPins != null)
{
parentTileData.MapPins.Remove(mapPinToRemove);
}
else
{
// When we remove the MapPin, this tile will fall under the cluster threshold so we will need to repopulate
// the children list.
parentTileData.MapPins = GatherChildren(parentTileId);
// Destroy the ClusterMapPin game object if it exists.
if (parentTileData.ClusterMapPin != null)
{
_clusterMapPins.Remove(parentTileData.ClusterMapPin);
UnityEngine.Object.Destroy(parentTileData.ClusterMapPin.gameObject);
parentTileData.ClusterMapPin = null;
}
}
}
}
parentLodIndex--;
parentTileId.TryGetParent(out parentTileId);
}
}
}
/// <summary>
/// Gets the pins in the specified bounding box.
/// </summary>
internal void GetPinsInView(
MercatorBoundingBox mercatorBox,
float levelOfDetail,
ClusterMapPin clusterMapPinPrefab,
Transform parentTransform,
out List<MapPin> mapPins,
out List<ClusterMapPin> clusterMapPins)
{
var box = mercatorBox.ToGeoBoundingBox();
var lod = (short)Mathf.Min(Mathf.Round(levelOfDetail), _maxLod.Value);
var tileLod = new TileLevelOfDetail(lod);
var tileLodData = _tiledSpatialIndex[lod - 1];
var tiles = TileOperations.GetCoveredTileIds(box, tileLod);
mapPins = new List<MapPin>();
clusterMapPins = new List<ClusterMapPin>();
foreach (var tile in tiles)
{
var tileBounds = tile.ToMercatorBoundingBox();
var isTileCompletelyInsideMap = mercatorBox.Contains(tileBounds);
if (tileLodData.TryGetValue(tile.Value, out var tileData))
{
if (tileData.IsClustered())
{
var latLon = new LatLon(tileData.TotalLat / tileData.MapPinCount, tileData.TotalLon / tileData.MapPinCount);
if (isTileCompletelyInsideMap || box.Intersects(latLon))
{
// Use the ClusterMapPin.
if (tileData.ClusterMapPin == null)
{
// Deactivate the GO to start with. It will get activated once elevation has been sampled and it's in view.
clusterMapPinPrefab.gameObject.SetActive(false);
var newClusterMapPin = UnityEngine.Object.Instantiate(clusterMapPinPrefab);
if (parentTransform != null)
{
newClusterMapPin.transform.SetParent(parentTransform, false);
}
newClusterMapPin.LevelOfDetail = tileLod.Value;
tileData.ClusterMapPin = newClusterMapPin;
_clusterMapPins.Add(newClusterMapPin);
}
tileData.ClusterMapPin.Size = tileData.MapPinCount;
tileData.ClusterMapPin.Location = new LatLon(latLon.LatitudeInDegrees, latLon.LongitudeInDegrees);
clusterMapPins.Add(tileData.ClusterMapPin);
}
}
else
{
// Add all of the MapPins in this tile to the list.
if (isTileCompletelyInsideMap)
{
foreach (var mapPin in tileData.MapPins)
{
mapPins.Add(mapPin);
}
}
else
{
foreach (var mapPin in tileData.MapPins)
{
if (box.Intersects(mapPin.Location))
{
mapPins.Add(mapPin);
}
}
}
}
}
}
}
/// <summary>
/// Gets the pins in the specified circular area.
/// </summary>
internal void GetPinsInView(
MercatorBoundingBox mercatorBox,
MercatorBoundingCircle mercatorBoundingCircle,
float levelOfDetail,
ClusterMapPin clusterMapPinPrefab,
Transform parentTransform,
out List<MapPin> mapPins,
out List<ClusterMapPin> clusterMapPins)
{
var lod = (short)Mathf.Min(Mathf.Round(levelOfDetail), _maxLod.Value);
var tileLod = new TileLevelOfDetail(lod);
var tileLodData = _tiledSpatialIndex[lod - 1];
var tiles = TileOperations.GetCoveredTileIds(mercatorBox, tileLod);
mapPins = new List<MapPin>();
clusterMapPins = new List<ClusterMapPin>();
foreach (var tile in tiles)
{
var tileBounds = tile.ToMercatorBoundingBox();
var isTileCompletelyInsideMap = mercatorBoundingCircle.Contains(tileBounds);
if (tileLodData.TryGetValue(tile.Value, out var tileData))
{
if (tileData.IsClustered())
{
var latLon = new LatLon(tileData.TotalLat / tileData.MapPinCount, tileData.TotalLon / tileData.MapPinCount);
var mercatorCoordinate = latLon.ToMercatorCoordinate();
if (isTileCompletelyInsideMap || mercatorBoundingCircle.Intersects(mercatorCoordinate))
{
// Use the ClusterMapPin.
if (tileData.ClusterMapPin == null)
{
// Deactivate the GO to start with. It will get activated once elevation has been sampled and it's in view.
clusterMapPinPrefab.gameObject.SetActive(false);
var newClusterMapPin = UnityEngine.Object.Instantiate(clusterMapPinPrefab);
if (parentTransform != null)
{
newClusterMapPin.transform.SetParent(parentTransform, false);
}
newClusterMapPin.LevelOfDetail = tileLod.Value;
tileData.ClusterMapPin = newClusterMapPin;
_clusterMapPins.Add(newClusterMapPin);
}
tileData.ClusterMapPin.Size = tileData.MapPinCount;
tileData.ClusterMapPin.Location = new LatLon(latLon.LatitudeInDegrees, latLon.LongitudeInDegrees);
clusterMapPins.Add(tileData.ClusterMapPin);
}
}
else
{
// Add all of the MapPins in this tile to the list.
if (isTileCompletelyInsideMap)
{
foreach (var mapPin in tileData.MapPins)
{
mapPins.Add(mapPin);
}
}
else
{
foreach (var mapPin in tileData.MapPins)
{
if (mercatorBoundingCircle.Intersects(mapPin.MercatorCoordinate))
{
mapPins.Add(mapPin);
}
}
}
}
}
}
}
/// <summary>
/// Destroys all ClusterMapPins associated with this index. When pins in view are requested in the future,
/// the ClusterMapPin will be recreated as needed.
/// </summary>
internal void DestroyClusterMapPins()
{
foreach (var clusterMapPin in _clusterMapPins)
{
if (clusterMapPin != null)
{
UnityEngine.Object.Destroy(clusterMapPin.gameObject);
}
}
_clusterMapPins.Clear();
}
private void MapPinLocationChanged(MapPin mapPinToUpdate, LatLon oldLocation)
{
RemoveMapPin(mapPinToUpdate, oldLocation);
AddMapPin(mapPinToUpdate);
}
private List<MapPin> GatherChildren(TileId tileId)
{
var result = new List<MapPin>();
var tempChildrenTileIds = new TileId[4];
var tilesToCheck = new Queue<TileId>();
tilesToCheck.Enqueue(tileId);
while (tilesToCheck.Count > 0)
{
var tileToCheck = tilesToCheck.Dequeue();
var lod = tileToCheck.CalculateLevelOfDetail();
var lodIndex = lod.Value - 1;
if (_tiledSpatialIndex[lodIndex].TryGetValue(tileToCheck.Value, out var tileData))
{
if (tileData.MapPins != null)
{
#if DEBUG
if (_isClusteringEnabled && lod != _maxLod)
{
Assert.IsTrue(tileData.MapPinCount <= ClusterThreshold);
}
#endif
result.AddRange(tileData.MapPins);
}
else if (lodIndex < (_maxLod.Value - 1))
{
#if DEBUG
if (_isClusteringEnabled)
{
Assert.IsTrue(tileData.MapPinCount <= ClusterThreshold);
}
Assert.IsTrue(lodIndex < _maxLod.Value);
#endif
tileToCheck.GetChildren(tempChildrenTileIds);
foreach (var childTile in tempChildrenTileIds)
{
tilesToCheck.Enqueue(childTile);
}
}
}
}
return result;
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 413fb67fbe5b52b4c86606f4fd7496bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace Microsoft.Maps.Unity
{
using System;
/// <summary>
/// List of MapPins with callbacks for item addition and removal. Also, this list can be serialized.
/// </summary>
[Serializable]
public class ObservableMapPinList : ObservableList<MapPin>
{
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a8e9f77ae9789a44ea91a49bc04a1ffc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,449 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Maps.Unity
{
using Microsoft.Geospatial;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;
/// <summary>
/// Manages streaming and rendering of map data.
/// </summary>
[ExecuteInEditMode]
[DisallowMultipleComponent]
[HelpURL("https://github.com/Microsoft/MapsSDK-Unity/wiki/Configuring-the-MapRenderer")]
public sealed class MapRenderer : MapRendererBase
{
/// <summary>
/// The type of collider that the map is using.
/// </summary>
[SerializeField]
private MapColliderType _mapColliderType = MapColliderType.BaseOnly;
/// <summary>
/// The type of collider that the map is using.
/// </summary>
public MapColliderType MapColliderType { get => _mapColliderType; set => _mapColliderType = value; }
private MapColliderType _previousMapColliderType = MapColliderType.BaseOnly;
/// <summary>
/// The <see cref="Collider"/> used for the map. The dimensions are synchronized to match the map's layout.
/// Null value if no <see cref="Collider"/> is active.
/// </summary>
public Collider MapCollider => _mapCollider;
/// <summary>
/// The <see cref="Collider"/> used for the map. The dimensions are synchronized to match the map's layout.
/// Null value if no <see cref="Collider"/> is active.
/// </summary>
[SerializeField]
private Collider _mapCollider = null;
/// <summary>
/// The collider used for all map shape types although in the future may just apply to box mode.
/// </summary>
private BoxCollider _mapBoxCollider = null;
private IMapSceneAnimationController _activeMapSceneAnimationController;
// Manages MapPins attached directly as children to the MapRenderer. Behaves like a MapPinLayer, but no clustering or indexing.
private bool _checkChildMapPins = true;
private readonly HashSet<MapPin> _mapPinChildrenSet = new HashSet<MapPin>();
private readonly List<MapPin> _lastMapPinsInView = new List<MapPin>();
private readonly List<MapPin> _mapPinsInView = new List<MapPin>();
private readonly HashSet<MapPin> _currentChildrenMapPins = new HashSet<MapPin>();
private readonly List<MapPin> _mapPinChildrenToRemove = new List<MapPin>();
/// <summary>
/// Called after the <see cref="MapRenderer"/> has exected Update().
/// </summary>
/// <remarks>
/// Use this callback when performing operations to a <see cref="MapLayer"/> that depend on various map properties.
/// At this point in the lifecycle, <see cref="MapRendererBase.Center"/>, <see cref="MapRendererBase.ZoomLevel"/>,
/// and other properties related to the position of the map will reflect the values used for this frame,
/// i.e. it is after any animations have ran and the properties used to position and render the map content in this frame
/// have already been determined.
/// </remarks>
public event EventHandler AfterUpdate;
/// <summary>
/// Sets the <see cref="MapRenderer"/>'s view to reflect the new <see cref="MapScene"/>.
/// </summary>
/// <returns>
/// A yieldable object is returned that can be used to wait for the end of the animation in a coroutine.
/// </returns>
public WaitForMapSceneAnimation SetMapScene(
MapScene mapScene,
MapSceneAnimationKind mapSceneAnimationKind = MapSceneAnimationKind.Bow,
float animationTimeScale = 1.0f)
{
return
SetMapScene(
mapScene,
new MapSceneAnimationController(),
mapSceneAnimationKind,
animationTimeScale);
}
/// <summary>
/// Sets the <see cref="MapRenderer"/>'s view to reflect the new <see cref="MapScene"/>
/// using the specified <see cref="IMapSceneAnimationController"/>.
/// </summary>
/// <returns>
/// A yieldable object is returned that can be used to wait for the end of the animation in a coroutine.
/// </returns>
public WaitForMapSceneAnimation SetMapScene(
MapScene mapScene,
IMapSceneAnimationController mapSceneAnimationController,
MapSceneAnimationKind mapSceneAnimationKind = MapSceneAnimationKind.Bow,
float animationTimeScale = 1.0f)
{
// If we were in the middle of a previous animation, make sure it has yielded and then reset it.
CancelAnimation();
mapScene.GetLocationAndZoomLevel(out var finalCenter, out var finalZoomLevel);
animationTimeScale = Mathf.Max(0, animationTimeScale);
if (mapSceneAnimationKind == MapSceneAnimationKind.None || animationTimeScale == 0.0)
{
// Snap the view.
ZoomLevel = (float)finalZoomLevel;
Center = finalCenter;
}
else
{
try
{
// Otherwise, setup an animation.
mapSceneAnimationController.Initialize(this, mapScene, animationTimeScale, mapSceneAnimationKind);
_activeMapSceneAnimationController = mapSceneAnimationController;
}
catch (Exception e)
{
Debug.LogError("Failed to initialize the IMapSceneAnimationController.\r\n" + e, gameObject);
_activeMapSceneAnimationController = null;
}
}
// Return a yield instruction from the animation controller itself (if we have one). Otherwise, we were setting a scene
// without animation, so just return a completed yield instruction.
return
_activeMapSceneAnimationController == null ?
new WaitForMapSceneAnimation(true /* isComplete */) :
_activeMapSceneAnimationController.YieldInstruction;
}
/// <inheritdoc/>
protected override bool RunAnimation(out LatLon newCenter, out float newZoomLevel)
{
if (_activeMapSceneAnimationController != null)
{
try
{
if (_activeMapSceneAnimationController.UpdateAnimation(ZoomLevel, Center, out newZoomLevel, out newCenter))
{
// Animation is complete.
_activeMapSceneAnimationController = null;
}
return true;
}
catch (Exception e)
{
Debug.LogError("Failed to update animation.\r\n" + e, gameObject);
_activeMapSceneAnimationController = null;
}
}
newCenter = new LatLon();
newZoomLevel = 0;
return false;
}
/// <inheritdoc/>
protected override void CancelAnimation()
{
if (_activeMapSceneAnimationController == null)
{
return;
}
_activeMapSceneAnimationController.YieldInstruction.SetComplete();
_activeMapSceneAnimationController = null;
}
/// <inheritdoc/>
protected override void OneTimeSetup(int lastVersion)
{
// Runs one-time setup to add sibling components which are present by default but can be removed later.
// The logic here also takes into account the "version" of the Maps SDK as some setup should only
// be ran when upgrading from one version to a newer version. See MapRenderer.Version docs for mapping of
// each version integer to Maps SDK version.
if (lastVersion < 1)
{
// Add a MapCopyrightLayer by default.
var existingMapCopyrightLayer = GetComponent<MapCopyrightLayer>();
if (existingMapCopyrightLayer == null)
{
gameObject.AddComponent<MapCopyrightLayer>();
}
// Initialize default layers.
if (TextureTileLayers.Count == 0)
{
gameObject.AddComponent<DefaultTextureTileLayer>();
}
}
if (lastVersion < 2)
{
if (ElevationTileLayers.Count == 0)
{
// Adds the DefaultElevationLayer to the now Serialized list of elevation layers.
gameObject.AddComponent<DefaultElevationTileLayer>();
}
}
if (lastVersion < 3)
{
// Grab a reference to the first box collider that is found (if any).
var existingColliders = GetComponents<BoxCollider>();
if (existingColliders != null)
{
foreach (var collider in existingColliders)
{
_mapCollider = collider;
_mapBoxCollider = collider;
break;
}
}
}
}
/// <inheritdoc/>
protected override void Awake()
{
base.Awake();
_checkChildMapPins = true;
// Create a MapDataCache if it doesn't exist.
if (FindObjectOfType<MapDataCacheBase>() == null)
{
gameObject.AddComponent<MapDataCache>();
}
}
/// <inheritdoc/>
protected override void OnEnable()
{
base.OnEnable();
_checkChildMapPins = true;
// Create a MapDataCache if it doesn't exist.
if (FindObjectOfType<MapDataCacheBase>() == null)
{
gameObject.AddComponent<MapDataCache>();
}
if (_mapCollider != null)
{
_mapCollider.enabled = true;
}
}
private void OnTransformChildrenChanged()
{
_checkChildMapPins = true;
}
/// <inheritdoc/>
protected override void Update()
{
base.Update();
UpdateChildrenMapPins();
UpdateMapCollider();
{
Profiler.BeginSample("AfterUpdate");
AfterUpdate?.Invoke(this, EventArgs.Empty);
Profiler.EndSample();
}
}
/// <inheritdoc/>
protected override void OnDisable()
{
base.OnDisable();
foreach (var childMapPin in _lastMapPinsInView)
{
childMapPin.gameObject.SetActive(false);
}
if (_mapCollider != null)
{
_mapCollider.enabled = false;
}
}
private void UpdateMapCollider()
{
if (_mapColliderType != MapColliderType.None)
{
if (_mapCollider == null)
{
_mapBoxCollider = gameObject.AddComponent<BoxCollider>();
_mapCollider = _mapBoxCollider;
}
else if (_mapBoxCollider == null)
{
// The box collider field is just used to prevent recasting _mapCollider every frame.
// Since it's not serialized it may be null even if _mapCollider isn't.
_mapBoxCollider = _mapCollider as BoxCollider;
}
_mapCollider.enabled = true;
var colliderHeight = (_mapColliderType == MapColliderType.BaseOnly) ? LocalMapBaseHeight : LocalMapHeight;
_mapBoxCollider.center = new Vector3(0, colliderHeight / 2, 0);
if (MapShape == MapShape.Block)
{
_mapBoxCollider.size = new Vector3(LocalMapDimension.x, colliderHeight, LocalMapDimension.y);
}
else
{
_mapBoxCollider.size = new Vector3(LocalMapRadius * 2.0f, colliderHeight, LocalMapRadius * 2.0f);
}
}
else
{
if (_previousMapColliderType != MapColliderType.None && _mapCollider != null)
{
DestroyImmediate(_mapCollider);
_mapCollider = null;
_mapBoxCollider = null;
}
}
_previousMapColliderType = _mapColliderType;
}
private void UpdateChildrenMapPins()
{
Profiler.BeginSample("UpdateChildrenMapPins");
_mapPinsInView.Clear();
// Get all the direct descendant MapPins of this GameObject that are in view.
{
if (_checkChildMapPins)
{
_currentChildrenMapPins.Clear();
var currentChildrenMapPins = GetComponentsInChildren<MapPin>(true);
foreach (var currentChildMapPin in currentChildrenMapPins)
{
if (currentChildMapPin.transform.parent == transform)
{
_currentChildrenMapPins.Add(currentChildMapPin);
}
}
// Add any new MapPin children.
foreach (var mapPin in _currentChildrenMapPins)
{
if (_mapPinChildrenSet.Add(mapPin))
{
// This is a new MapPin. Deactivate until it's position has been calculated.
mapPin.gameObject.SetActive(false);
}
}
// Remove any MapPins that are no longer children or have been disabled.
{
_mapPinChildrenToRemove.Clear();
foreach (var existingChildMapPin in _mapPinChildrenSet)
{
if (!_currentChildrenMapPins.Contains(existingChildMapPin))
{
_mapPinChildrenToRemove.Add(existingChildMapPin);
}
}
foreach (var mapPinChildToRemove in _mapPinChildrenToRemove)
{
_mapPinChildrenSet.Remove(mapPinChildToRemove);
}
}
_currentChildrenMapPins.Clear();
_mapPinChildrenToRemove.Clear();
_checkChildMapPins = false;
}
// Get the MapPins in view.
if (_mapPinChildrenSet.Count > 0)
{
if (MapShape == MapShape.Block)
{
var mercatorBoundingBox = MercatorBoundingBox;
foreach (var mapPin in _mapPinChildrenSet)
{
if (mercatorBoundingBox.Intersects(mapPin.Location))
{
_mapPinsInView.Add(mapPin);
}
}
}
else // Cylinder
{
var mercatorBoundingCircle = MercatorBoundingCircle;
foreach (var mapPin in _mapPinChildrenSet)
{
if (mercatorBoundingCircle.Intersects(mapPin.MercatorCoordinate))
{
_mapPinsInView.Add(mapPin);
}
}
}
}
}
TrackAndPositionPinnables(_mapPinsInView);
// Disable any MapPins that were in the last view but is not the current view.
{
foreach (var lastMapPinInView in _lastMapPinsInView)
{
if (lastMapPinInView != null && !_mapPinsInView.Contains(lastMapPinInView))
{
UntrackPinnable(lastMapPinInView);
lastMapPinInView.gameObject.SetActive(false);
}
}
_lastMapPinsInView.Clear();
_lastMapPinsInView.AddRange(_mapPinsInView);
}
MapPin.SynchronizeLayers(_mapPinsInView, this);
MapPin.UpdateScales(_mapPinsInView, this);
// Ensure the MapPins that have had their positions computed have been enabled.
foreach (var mapPinInView in _mapPinsInView)
{
mapPinInView.gameObject.SetActive(mapPinInView.HasBeenFullyPositioned && mapPinInView.enabled);
}
Profiler.EndSample();
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1cf6985fc3c122a4193d16fdcfb59784
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -1,166 +1,165 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Maps.Unity
{
using Microsoft.Geospatial;
using Microsoft.Geospatial.VectorMath;
using System;
using UnityEngine;
/// <summary>
/// Helpers to transform between Unity's world and local spaces to the geographic coordinate system of the <see cref="MapRenderer"/>.
/// </summary>
public static class MapRendererTransformExtensions
{
/// <summary>
/// The WGS84 ellipsoid circumference measured in meters.
/// </summary>
public const double EquatorialCircumferenceInWgs84Meters = 40075016.685578488;
/// <summary>
/// Constat for 2 * Math.PI.
/// </summary>
public const double TwoPi = 2 * Math.PI;
/// <summary>
/// Transforms an XYZ point in the <see cref="MapRenderer"/>'s local space to a Mercator position.
/// </summary>
public static Vector2D TransformLocalPointToMercator(this MapRenderer mapRenderer, Vector3 pointInLocalSpace)
{
var deltaFromMapCenterToPointInMercatorSpace = TransformLocalDirectionToMercator(mapRenderer, pointInLocalSpace);
return mapRenderer.Center.ToMercatorPosition() + deltaFromMapCenterToPointInMercatorSpace;
}
/// <summary>
/// Transforms an XYZ point in the <see cref="MapRenderer"/>'s local space to a Mercator position. Includes the altitude
/// measured as meters from the WGS84 ellipsoid.
/// </summary>
public static Vector2D TransformLocalPointToMercatorWithAltitude(
this MapRenderer mapRenderer,
Vector3 pointInLocalSpace,
out double altitudeInMeters,
out double mercatorScale)
{
var mercatorPosition = TransformLocalPointToMercator(mapRenderer, pointInLocalSpace);
mercatorScale = Math.Cosh(TwoPi * mercatorPosition.Y);
var equatorialCircumferenceInLocalSpace = Math.Pow(2, mapRenderer.ZoomLevel - 1);
var elevationScale = (EquatorialCircumferenceInWgs84Meters / equatorialCircumferenceInLocalSpace) / mercatorScale;
altitudeInMeters = (pointInLocalSpace.y - mapRenderer.LocalMapHeight) * elevationScale + mapRenderer.ElevationBaseline;
return mercatorPosition;
}
/// <summary>
/// Transforms an XYZ direction in the <see cref="MapRenderer"/>'s local space to a direction in Mercator space.
/// </summary>
public static Vector2D TransformLocalDirectionToMercator(this MapRenderer mapRenderer, Vector3 directionInLocalSpace)
{
return TransformLocalDirectionToMercator(directionInLocalSpace, mapRenderer.ZoomLevel);
}
/// <summary>
/// Transforms an XYZ direction in the <see cref="MapRenderer"/>'s local space to a direction in Mercator space.
/// Uses the specified zoom level rather than the <see cref="MapRenderer"/>'s zoom level for the transformation.
/// </summary>
public static Vector2D TransformLocalDirectionToMercator(Vector3 directionInLocalSpace, double zoomLevel)
{
var mercatorMapSizeInLocalSpace = Math.Pow(2, zoomLevel - 1);
var directionInMercator = new Vector2D(directionInLocalSpace.x, directionInLocalSpace.z) / mercatorMapSizeInLocalSpace;
return directionInMercator;
}
/// <summary>
/// Transforms an XYZ direction in the <see cref="MapRenderer"/>'s local space to a direction in Mercator space.
/// </summary>
public static Vector2D TransformWorldDirectionToMercator(this MapRenderer mapRenderer, Vector3 directionInWorldSpace)
{
return TransformWorldDirectionToMercator(mapRenderer, directionInWorldSpace, mapRenderer.ZoomLevel);
}
/// <summary>
/// Transforms an XYZ direction in the <see cref="MapRenderer"/>'s local space to a direction in Mercator space.
/// Uses the specified zoom level rather than the <see cref="MapRenderer"/>'s zoom level for the transformation.
/// </summary>
public static Vector2D TransformWorldDirectionToMercator(this MapRenderer mapRenderer, Vector3 directionInWorldSpace, double zoomLevel)
{
var directionInLocalSpace = mapRenderer.transform.InverseTransformDirection(directionInWorldSpace);
directionInLocalSpace.x /= mapRenderer.transform.localScale.x;
directionInLocalSpace.y /= mapRenderer.transform.localScale.y;
directionInLocalSpace.z /= mapRenderer.transform.localScale.z;
return TransformLocalDirectionToMercator(directionInLocalSpace, zoomLevel);
}
/// <summary>
/// Transforms an XYZ point in world space to a Mercator position.
/// </summary>
public static Vector2D TransformWorldPointToMercator(this MapRenderer mapRenderer, Vector3 pointInWorldSpace)
{
var localSpacePoint = mapRenderer.transform.InverseTransformPoint(pointInWorldSpace);
return TransformLocalPointToMercator(mapRenderer, localSpacePoint);
}
/// <summary>
/// Transforms an XYZ point in world space to a Mercator position.
/// </summary>
public static Vector2D TransformWorldPointToMercatorWithAltitude(
this MapRenderer mapRenderer,
Vector3 pointInWorldSpace,
out double altitudeInMeters,
out double mercatorScale)
{
var localSpacePoint = mapRenderer.transform.InverseTransformPoint(pointInWorldSpace);
return TransformLocalPointToMercatorWithAltitude(mapRenderer, localSpacePoint, out altitudeInMeters, out mercatorScale);
}
/// <summary>
/// Transforms an XYZ point in world space to a <see cref="LatLon"/>.
/// </summary>
public static LatLon TransformWorldPointToLatLon(this MapRenderer mapRenderer, Vector3 pointInWorldSpace)
{
return LatLon.FromMercatorPosition(mapRenderer.TransformWorldPointToMercator(pointInWorldSpace));
}
/// <summary>
/// Transforms an XYZ point in world space to a <see cref="LatLonAlt"/>.
/// </summary>
public static LatLonAlt TransformWorldPointToLatLonAlt(this MapRenderer mapRenderer, Vector3 pointInWorldSpace)
{
var mercatorPosition =
TransformLocalPointToMercatorWithAltitude(
mapRenderer,
pointInWorldSpace,
out var altitudeInMeters,
out var mercatorScale);
var latLon = LatLon.FromMercatorPosition(mercatorPosition);
return new LatLonAlt(ref latLon, altitudeInMeters);
}
/// <summary>
/// Transforms an XYZ point in world space to a <see cref="LatLonAlt"/>.
/// </summary>
public static Vector3 TransformLatLonAltToWorldPoint(this MapRenderer mapRenderer, LatLonAlt location)
{
// Can compute XZ coords in local space from the Mercator position and map center.
var mercatorPosition = location.LatLon.ToMercatorPosition();
var mercatorPositionRelativeToCenter = mercatorPosition - mapRenderer.Center.ToMercatorPosition();
var equatorialCircumferenceInLocalSpace = Math.Pow(2, mapRenderer.ZoomLevel - 1);
var localSpaceXZ = equatorialCircumferenceInLocalSpace * mercatorPositionRelativeToCenter;
// Altitude to local y value.
var offsetMapAltitudeInMeters = location.AltitudeInMeters - mapRenderer.ElevationBaseline;
var mercatorScale = 1.0 / Math.Cos(location.LatLon.LatitudeInRadians);
var altitudeInLocalSpace = offsetMapAltitudeInMeters * mercatorScale * (equatorialCircumferenceInLocalSpace / EquatorialCircumferenceInWgs84Meters);
var pointInLocalSpace =
new Vector3(
(float)localSpaceXZ.X,
(float)(altitudeInLocalSpace + mapRenderer.LocalMapHeight),
(float)localSpaceXZ.Y);
return mapRenderer.transform.TransformPoint(pointInLocalSpace);
}
}
}
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.Maps.Unity
{
using Microsoft.Geospatial;
using System;
using UnityEngine;
/// <summary>
/// Helpers to transform between Unity's world and local spaces to the geographic coordinate system of the <see cref="MapRenderer"/>.
/// </summary>
public static class MapRendererTransformExtensions
{
/// <summary>
/// The WGS84 ellipsoid circumference measured in meters.
/// </summary>
public const double EquatorialCircumferenceInWgs84Meters = 40075016.685578488;
/// <summary>
/// Transforms an XYZ point in the <see cref="MapRenderer"/>'s local space to a <see cref="MercatorCoordinate"/>.
/// </summary>
public static MercatorCoordinate TransformLocalPointToMercator(this MapRenderer mapRenderer, Vector3 pointInLocalSpace)
{
var deltaFromMapCenterToPointInMercator = TransformLocalDirectionToMercator(mapRenderer, pointInLocalSpace);
return mapRenderer.Center.ToMercatorCoordinate() + deltaFromMapCenterToPointInMercator;
}
/// <summary>
/// Transforms an XYZ point in the <see cref="MapRenderer"/>'s local space to a <see cref="MercatorCoordinate"/>.
/// Includes the altitude measured as meters from the WGS84 ellipsoid.
/// </summary>
public static MercatorCoordinate TransformLocalPointToMercatorWithAltitude(
this MapRenderer mapRenderer,
Vector3 pointInLocalSpace,
out double altitudeInMeters,
out double mercatorScale)
{
var mercatorCoordinate = TransformLocalPointToMercator(mapRenderer, pointInLocalSpace);
mercatorScale = MercatorScale.AtMercatorLatitude(mercatorCoordinate.Y);
var equatorialCircumferenceInLocalSpace = Math.Pow(2, mapRenderer.ZoomLevel - 1);
var elevationScale = (EquatorialCircumferenceInWgs84Meters / equatorialCircumferenceInLocalSpace) / mercatorScale / mapRenderer.ElevationScale;
altitudeInMeters = (pointInLocalSpace.y - mapRenderer.LocalMapBaseHeight) * elevationScale + mapRenderer.ElevationBaseline;
return mercatorCoordinate;
}
/// <summary>
/// Transforms an XYZ direction in the <see cref="MapRenderer"/>'s local space to a direction in Mercator space.
/// </summary>
public static MercatorCoordinate TransformLocalDirectionToMercator(this MapRenderer mapRenderer, Vector3 directionInLocalSpace)
{
return TransformLocalDirectionToMercator(directionInLocalSpace, mapRenderer.ZoomLevel);
}
/// <summary>
/// Transforms an XYZ direction in the <see cref="MapRenderer"/>'s local space to a direction in Mercator space.
/// Uses the specified zoom level rather than the <see cref="MapRenderer"/>'s zoom level for the transformation.
/// </summary>
public static MercatorCoordinate TransformLocalDirectionToMercator(Vector3 directionInLocalSpace, double zoomLevel)
{
var mercatorMapSizeInLocalSpace = Math.Pow(2, zoomLevel - 1);
var directionInMercator = new MercatorCoordinate(directionInLocalSpace.x, directionInLocalSpace.z) / mercatorMapSizeInLocalSpace;
return directionInMercator;
}
/// <summary>
/// Transforms an XYZ direction in the <see cref="MapRendererBase"/>'s local space to a direction in Mercator space.
/// </summary>
public static MercatorCoordinate TransformWorldDirectionToMercator(this MapRenderer mapRenderer, Vector3 directionInWorldSpace)
{
return TransformWorldDirectionToMercator(mapRenderer, directionInWorldSpace, mapRenderer.ZoomLevel);
}
/// <summary>
/// Transforms an XYZ direction in the <see cref="MapRendererBase"/>'s local space to a direction in Mercator space.
/// Uses the specified zoom level rather than the <see cref="MapRendererBase"/>'s zoom level for the transformation.
/// </summary>
public static MercatorCoordinate TransformWorldDirectionToMercator(this MapRenderer mapRenderer, Vector3 directionInWorldSpace, double zoomLevel)
{
var directionInLocalSpace = mapRenderer.transform.InverseTransformDirection(directionInWorldSpace);
directionInLocalSpace.x /= mapRenderer.transform.localScale.x;
directionInLocalSpace.y /= mapRenderer.transform.localScale.y;
directionInLocalSpace.z /= mapRenderer.transform.localScale.z;
return TransformLocalDirectionToMercator(directionInLocalSpace, zoomLevel);
}
/// <summary>
/// Transforms an XYZ point in world space to a <see cref="MercatorCoordinate"/>.
/// </summary>
public static MercatorCoordinate TransformWorldPointToMercator(this MapRenderer mapRenderer, Vector3 pointInWorldSpace)
{
var pointInLocalSpace = mapRenderer.transform.InverseTransformPoint(pointInWorldSpace);
return TransformLocalPointToMercator(mapRenderer, pointInLocalSpace);
}
/// <summary>
/// Transforms an XYZ point in world space to a <see cref="MercatorCoordinate"/>.
/// </summary>
public static MercatorCoordinate TransformWorldPointToMercatorWithAltitude(
this MapRenderer mapRenderer,
Vector3 pointInWorldSpace,
out double altitudeInMeters,
out double mercatorScale)
{
var pointInLocalSpace = mapRenderer.transform.InverseTransformPoint(pointInWorldSpace);
return TransformLocalPointToMercatorWithAltitude(mapRenderer, pointInLocalSpace, out altitudeInMeters, out mercatorScale);
}
/// <summary>
/// Transforms an XYZ point in world space to a <see cref="LatLon"/>.
/// </summary>
public static LatLon TransformWorldPointToLatLon(this MapRenderer mapRenderer, Vector3 pointInWorldSpace)
{
return mapRenderer.TransformWorldPointToMercator(pointInWorldSpace).ToLatLon();
}
/// <summary>
/// Transforms an XYZ point in world space to a <see cref="LatLonAlt"/>.
/// </summary>
public static LatLonAlt TransformWorldPointToLatLonAlt(this MapRenderer mapRenderer, Vector3 pointInWorldSpace)
{
var pointInLocalSpace = mapRenderer.transform.InverseTransformPoint(pointInWorldSpace);
var mercatorCoordinate =
TransformLocalPointToMercatorWithAltitude(
mapRenderer,
pointInLocalSpace,
out var altitudeInMeters,
out var mercatorScale);
var latLon = mercatorCoordinate.ToLatLon();
return new LatLonAlt(ref latLon, altitudeInMeters);
}
/// <summary>
/// Transforms a <see cref="LatLonAlt"/> to an XYZ point in world space.
/// </summary>
public static Vector3 TransformLatLonAltToWorldPoint(this MapRenderer mapRenderer, LatLonAlt location)
{
// Can compute XZ coords in local space from the Mercator coordinate of thie location and the map center.
var mercatorCoordinate = location.LatLon.ToMercatorCoordinate();
var mercatorCoordinateRelativeToCenter = mercatorCoordinate - mapRenderer.Center.ToMercatorCoordinate();
var equatorialCircumferenceInLocalSpace = Math.Pow(2, mapRenderer.ZoomLevel - 1);
var localSpaceXZ = equatorialCircumferenceInLocalSpace * mercatorCoordinateRelativeToCenter;
// Altitude to local y value.
var offsetMapAltitudeInMeters = location.AltitudeInMeters - mapRenderer.ElevationBaseline;
var mercatorScale = MercatorScale.AtMercatorLatitude(mercatorCoordinate.Y);
var altitudeInLocalSpace =
mapRenderer.ElevationScale *
offsetMapAltitudeInMeters *
mercatorScale *
(equatorialCircumferenceInLocalSpace / EquatorialCircumferenceInWgs84Meters);
var pointInLocalSpace =
new Vector3(
(float)localSpaceXZ.X,
(float)(altitudeInLocalSpace + mapRenderer.LocalMapBaseHeight),
(float)localSpaceXZ.Y);
return mapRenderer.transform.TransformPoint(pointInLocalSpace);
}
}
}

Просмотреть файл

@ -1,11 +1,11 @@
fileFormatVersion: 2
guid: 4f8f52b76722377449d9c99ec5de9961
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 4f8f52b76722377449d9c99ec5de9961
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4a6978be5245b5244a3040509b70baf7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace Microsoft.Maps.Unity
{
using Microsoft.Geospatial;
/// <summary>
/// Animates a MapRenderer to the specified <see cref="MapScene"/>.
/// </summary>
public interface IMapSceneAnimationController
{
/// <summary>
/// Returns a yieldable object that can be used to wait for animation to complete.
/// </summary>
WaitForMapSceneAnimation YieldInstruction { get; }
/// <summary>
/// Initializes the controller to animate the specified <see cref="MapScene"/>.
/// </summary>
void Initialize(MapRendererBase mapRenderer, MapScene mapScene, float animationTimeScale, MapSceneAnimationKind mapSceneAnimationKind);
/// <summary>
/// Updates the zoom level and location for this frame of the animation.
/// </summary>
bool UpdateAnimation(float currentZoomLevel, LatLon currentLocation, out float zoomLevel, out LatLon location);
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a77f095839516184bb1bd32efb79760f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -9,15 +9,16 @@ namespace Microsoft.Maps.Unity
using UnityEngine;
/// <summary>
/// Animates a MapRenderer to the specified MapScene. Derives the animation duration and preforms a preceptually smooth animation,
/// based on the work of van Wijk and Nuij, "Smooth and Efficient Zooming and Panning". https://www.win.tue.nl/~vanwijk/zoompan.pdf
/// Animates a <see cref="MapRenderer"/> to the specified <see cref="MapScene"/>. Derives the animation duration and preforms a
/// preceptually smooth animation, based on the work of van Wijk and Nuij, "Smooth and Efficient Zooming and Panning".
/// https://www.win.tue.nl/~vanwijk/zoompan.pdf
/// </summary>
public class MapSceneAnimationController : IMapSceneAnimationController
{
private double _startZoomLevel;
private double _endZoomLevel;
private Vector2D _startMercatorCenter;
private Vector2D _endMercatorCenter;
private MercatorCoordinate _startMercatorCenter;
private MercatorCoordinate _endMercatorCenter;
private double _animationTime;
private double _startHeightInMercator;
private double _endHeightInMercator;
@ -41,17 +42,17 @@ namespace Microsoft.Maps.Unity
/// <inheritdoc/>
public void Initialize(
MapRenderer mapRenderer,
MapRendererBase mapRenderer,
MapScene mapScene,
float animationTimeScale,
MapSceneAnimationKind mapSceneAnimationKind)
{
_runningTime = 0;
_startMercatorCenter = mapRenderer.Center.ToMercatorPosition();
_startMercatorCenter = mapRenderer.Center.ToMercatorCoordinate();
_startZoomLevel = mapRenderer.ZoomLevel;
mapScene.GetLocationAndZoomLevel(out var endLocation, out _endZoomLevel);
_endMercatorCenter = endLocation.ToMercatorPosition();
_endMercatorCenter = endLocation.ToMercatorCoordinate();
_startHeightInMercator = ZoomLevelToMercatorAltitude(_startZoomLevel);
_endHeightInMercator = ZoomLevelToMercatorAltitude(_endZoomLevel);
@ -76,7 +77,7 @@ namespace Microsoft.Maps.Unity
out _animationTime);
// Tweaking the resulting animation time to speed up slower animations and slow down the shorter animation.
_animationTime = _animationTime / 6.0; // Normalize.
_animationTime /= 6.0; // Normalize.
_animationTime = Math.Pow(_animationTime, 1.0 / 3.0); // Rescale.
_animationTime *= 6.0; // Convert back to original range.
}
@ -112,7 +113,7 @@ namespace Microsoft.Maps.Unity
// First, update the zoom.
zoomLevel = (float)(_startZoomLevel + (_endZoomLevel - _startZoomLevel) * t);
// Update the location.
// Update the location.
if (_startMercatorCenter != _endMercatorCenter)
{
if (_startZoomLevel != _endZoomLevel)
@ -120,18 +121,18 @@ namespace Microsoft.Maps.Unity
// Adjust t so that it depends on the zoom level. This keeps the position animating correctly at a logarthmic scale to
// match how zoom level is being calculated.
var adjustedT = (_startHeightInMercator - ZoomLevelToMercatorAltitude(zoomLevel)) / (_startHeightInMercator - _endHeightInMercator);
var mercatorPosition = Interpolate(_startMercatorCenter, _endMercatorCenter, Math.Pow(adjustedT, 0.8));
location = LatLon.FromMercatorPosition(mercatorPosition);
var mercatorCoordinate = Interpolate(_startMercatorCenter, _endMercatorCenter, Math.Pow(adjustedT, 0.8));
location = mercatorCoordinate.ToLatLon();
}
else
{
var mercatorPosition = Interpolate(_startMercatorCenter, _endMercatorCenter, t);
location = LatLon.FromMercatorPosition(mercatorPosition);
var mercatorCoordinate = Interpolate(_startMercatorCenter, _endMercatorCenter, t);
location = mercatorCoordinate.ToLatLon();
}
}
else
{
location = LatLon.FromMercatorPosition(_endMercatorCenter);
location = _endMercatorCenter.ToLatLon();
}
}
@ -151,7 +152,7 @@ namespace Microsoft.Maps.Unity
out double animationTime)
{
u0 = 0;
u1 = (_endMercatorCenter - _startMercatorCenter).Length();
u1 = MercatorCoordinate.Distance(_endMercatorCenter, _startMercatorCenter);
w0 = 1.0 / Math.Pow(2, _startZoomLevel - 1);
w1 = 1.0 / Math.Pow(2, _endZoomLevel - 1);
@ -192,7 +193,7 @@ namespace Microsoft.Maps.Unity
u = Math.Max(0, Math.Min(u / _u1, 1.0));
zoomLevel = (float)MercatorAltitudeToZoomLevel(w);
location = LatLon.FromMercatorPosition(Vector2D.Lerp(_startMercatorCenter, _endMercatorCenter, u));
location = Interpolate(_startMercatorCenter, _endMercatorCenter, u).ToLatLon();
}
/// <summary>
@ -225,11 +226,12 @@ namespace Microsoft.Maps.Unity
return Math.Log(1.0 / mercatorAltitude, 2.0) + 1;
}
private static Vector2D Interpolate(Vector2D from, Vector2D to, double t)
private static MercatorCoordinate Interpolate(in MercatorCoordinate from, in MercatorCoordinate to, double t)
{
return new Vector2D(
from.X + (to.X - from.X) * t,
from.Y + (to.Y - from.Y) * t);
return
new MercatorCoordinate(
from.X + (to.X - from.X) * t,
from.Y + (to.Y - from.Y) * t);
}
private static double SmoothStep(double from, double to, double t)

Просмотреть файл

@ -0,0 +1,23 @@
namespace Microsoft.Maps.Unity
{
/// <summary>
/// Specifies the animation to use when setting a MapScene.
/// </summary>
public enum MapSceneAnimationKind
{
/// <summary>
/// No animation.
/// </summary>
None,
/// <summary>
/// A linear animation.
/// </summary>
Linear,
/// <summary>
/// A parabolic animation.
/// </summary>
Bow
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3d31f867dfde6b54c9cd895b72ba1538
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -6,7 +6,7 @@ namespace Microsoft.Maps.Unity
using Microsoft.Geospatial;
/// <summary>
/// The most basic MapScene that can be used to change the map's location and zoom level.
/// A basic <see cref="MapScene"/> that can be used to change the map's location and zoom level.
/// </summary>
public class MapSceneOfLocationAndZoomLevel : MapScene
{
@ -21,7 +21,7 @@ namespace Microsoft.Maps.Unity
public float ZoomLevel { get; }
/// <summary>
/// Constructs a MapSceneOfLocationAndZoomLevel from the specified location and zoom level.
/// Constructs a <see cref="MapSceneOfLocationAndZoomLevel"/> from the specified location and zoom level.
/// </summary>
public MapSceneOfLocationAndZoomLevel(LatLon location, float zoomLevel)
{

Просмотреть файл

@ -0,0 +1,34 @@
namespace Microsoft.Maps.Unity
{
using System.Reflection;
using UnityEngine;
/// <summary>
/// Used to suspend coroutine execution once the associated MapScene animation has been completed or cancelled.
/// </summary>
public class WaitForMapSceneAnimation : CustomYieldInstruction
{
private bool _keepWaiting = true;
/// <summary>
/// Returns false once the animation has been completed or cancelled.
/// </summary>
public override bool keepWaiting => _keepWaiting;
/// <summary>
/// Constructs the yieldable instance.
/// </summary>
public WaitForMapSceneAnimation(bool isCompleted = false)
{
_keepWaiting = !isCompleted;
}
/// <summary>
/// Completes the yield instruction.
/// </summary>
public void SetComplete()
{
_keepWaiting = false;
}
}
}

Просмотреть файл

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bb7373b1ea3896d438d2e23843712aa9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 424715533f7464745a37e0bacd374d56, type: 3}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7a29a412c84fbd74ea026071161116bd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0079aaf4dc00c3448978c59fca500583
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -15,8 +15,8 @@ namespace Microsoft.Maps.Unity.Services
RestServiceDomain +
$"{restApi}?" +
(string.IsNullOrWhiteSpace(Uri.EscapeDataString(queryParameters)) ?
$"key={MapServices.BingMapsKey ?? ""}" :
$"{queryParameters}&key={MapServices.BingMapsKey ?? ""}");
$"key={MapSession.Current.DeveloperKey ?? ""}" :
$"{queryParameters}&key={MapSession.Current.DeveloperKey ?? ""}");
// Useful for debugging.
//UnityEngine.Debug.Log(url);

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aa85fa9a0f235804bb1a8f841dc16f42
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -9,14 +9,14 @@ namespace Microsoft.Maps.Unity.Search
public class MapLocationAddress
{
/// <summary>
/// Specifies the address in a local format. This address may not include the country or region, e.g.
/// Specifies the address in a local format. This address may not include the country/region, e.g.
/// "1 Microsoft Way, Redmond, WA 98052-8300"
/// </summary>
public string FormattedAddress { get; }
/// <summary>
/// A string specifying the populated place for the address.
/// This typically refers to a city, but may refer to a suburb or a neighborhood in certain countries.
/// This typically refers to a city, but may refer to a suburb or a neighborhood depending on the country/region.
/// </summary>
public string AddressLine { get; }
@ -27,19 +27,19 @@ namespace Microsoft.Maps.Unity.Search
/// <summary>
/// A string specifying the populated place for the address.
/// This typically refers to a city, but may refer to a suburb or a neighborhood in certain countries.
/// This typically refers to a city, but may refer to a suburb or a neighborhood depending on the country/region.
/// </summary>
public string Locality { get; }
/// <summary>
/// A string specifying the subdivision name in the country or region for an address.
/// A string specifying the subdivision name in the country/region for an address.
/// This element is typically treated as the first order administrative subdivision,
/// but in some cases it is the second, third, or fourth order subdivision in a country, dependency, or region.
/// but in some cases it is the second, third, or fourth order subdivision in a country/region.
/// </summary>
public string AdminDistrict { get; }
/// <summary>
/// A string specifying the subdivision name in the country or region for an address.
/// A string specifying the subdivision name in the country/region for an address.
/// This element is used when there is another level of subdivision information for a location, such as the county.
/// </summary>
public string AdminDistrict2 { get; }
@ -50,12 +50,12 @@ namespace Microsoft.Maps.Unity.Search
public string PostalCode { get; }
/// <summary>
/// A string specifying the country or region name of an address.
/// A string specifying the country/region name of an address.
/// </summary>
public string CountryRegion { get; }
/// <summary>
/// A string specifying the two-letter ISO country code.
/// A string specifying the two-letter ISO country/region code.
/// </summary>
public string CountryCode { get; }

Просмотреть файл

@ -21,7 +21,7 @@ namespace Microsoft.Maps.Unity.Search
public LatLon Point { get; }
/// <summary>
/// A structured address including common adress components like city, state, neighborhood, country, etc.
/// A structured address including common adress components like city, state, neighborhood, country/region, etc.
/// </summary>
public MapLocationAddress Address { get; }

Просмотреть файл

@ -71,7 +71,7 @@ namespace Microsoft.Maps.Unity.Search
string resource = "Locations",
bool startWithAmpersand = true)
{
string url = null;
string url;
if (mapLocationOptions != null)
{
var parameters =

Просмотреть файл

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 86fa9bec97cbd464dafca8bfd11a2308
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Просмотреть файл

@ -21,13 +21,13 @@ namespace Microsoft.Maps.Unity.Search
public string Culture { get; set; } = null;
/// <summary>
/// A string that an ISO 3166-1 Alpha-2 region/country code. This will alter geopolitically disputed results to align with the specified region.
/// A string that an ISO 3166-1 Alpha-2 country/region code. This will alter geopolitically disputed results to align with the specified region.
/// https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
/// </summary>
public string Region { get; set; } = null;
/// <summary>
/// Specifies to include the two-letter ISO country code with the address information in the response.
/// Specifies to include the two-letter ISO country/region code with the address information in the response.
/// By default, MapLocationAddress will not include this.
/// </summary>
public bool IncludeCountryCode { get; set; }

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше