using System; using System.Text; using UnityEngine; using Adrenak.Unex; using System.Net; using System.Collections.Generic; using RestSharp; namespace Adrenak.UniMap { [Serializable] public class StreetViewDownloader : IDisposable { // ================================================ // EVENTS // ================================================ public delegate void FaceTextureDownloadedHandler(StreetView.Face face, Texture2D texture); public delegate void FaceTextureFailedHandler(StreetView.Face face, string error); /// /// Invoked when texture download for a is successful /// public event FaceTextureDownloadedHandler OnFaceTextureDownloaded; /// /// Invoked when texture download for a fails /// public event FaceTextureFailedHandler OnFaceTextureFailed; /// /// The base URL of the Street View API /// const string k_BaseURL = "https://maps.googleapis.com/maps/api/streetview?"; /// /// The used for the Street View API calls /// public StreetView.Options options = new StreetView.Options(); /// /// A one to one map of and Texture2D corresponding to it /// Dictionary textures = new Dictionary(); bool m_Disposed; // ================================================ // METHODS // ================================================ /// /// Starts downloads of face textures /// public void Download() { DownloadFace(StreetView.Face.Up); DownloadFace(StreetView.Face.Down); DownloadFace(StreetView.Face.Front); DownloadFace(StreetView.Face.Back); DownloadFace(StreetView.Face.Left); DownloadFace(StreetView.Face.Right); } /// /// Downloads a single face texture /// /// public void DownloadFace(StreetView.Face face) { var url = GetURL(face); var client = new RestClient(); var request = new RestRequest(url); client.ExecuteAsync(request, response => { Dispatcher.Enqueue(() => { if (m_Disposed) return; if (response.IsSuccessful()) { var tex = new Texture2D(1, 1, TextureFormat.RGB565, false); tex.LoadImage(response.RawBytes, false); tex.Apply(); SetFaceTexture(face, tex); OnFaceTextureDownloaded?.Invoke(face, tex); } else { OnFaceTextureFailed?.Invoke(face, response.GetException().ToString()); } }); }); } /// /// Gets the request URL for the given face given the API parameters. /// /// The whose texture is to be downloaded. /// The URL for downloading the texture of this public string GetURL(StreetView.Face face) { var sb = new StringBuilder(k_BaseURL).Append("key=").Append(options.key); switch (options.mode) { case StreetView.Mode.Coordinates: sb.Append("&location=").Append(options.location.lat).Append(",").Append(options.location.lng); break; case StreetView.Mode.PanoID: sb.Append("&pano=").Append(options.panoID); break; case StreetView.Mode.Location: sb.Append("&location=").Append(options.place); break; } sb.Append("&size=").Append(options.resolution).Append("x").Append(options.resolution) .Append("&fov=").Append(options.fov) .Append("&heading=").Append((options.heading % 360) + EnumUtility.HeadingFrom(face) + options.heading) .Append("&pitch=").Append(EnumUtility.PitchFrom(face) + options.pitch) .Append("&radius=").Append(options.radius) .Append("&source=").Append(EnumToString.From(options.source)); return sb.ToString(); } /// /// Gets the Texture2D corresponding to a /// /// The whose Texture2D is to be fetched. /// The Texture2D corresponding to the passed public Texture2D GetFaceTexture(StreetView.Face face) { if (textures.ContainsKey(face)) return textures[face]; else return null; } /// /// Sets a Texture2D to the given /// /// The whose texture is to be set. /// The texture to be set. public void SetFaceTexture(StreetView.Face face, Texture2D texture) { if (textures.ContainsKey(face)) { MonoBehaviour.Destroy(textures[face]); textures[face] = texture; } else textures.Add(face, texture); } public void Dispose() { m_Disposed = true; // Unsubscribe all listeners foreach (var listener in OnFaceTextureFailed.GetInvocationList()) OnFaceTextureFailed -= (FaceTextureFailedHandler)listener; foreach (var listener in OnFaceTextureDownloaded.GetInvocationList()) OnFaceTextureDownloaded -= (FaceTextureDownloadedHandler)listener; foreach (var pair in textures) MonoBehaviour.Destroy(pair.Value); } } }