private void PruneExpiredAndOutOfRangeLocations(GPSLatLong currentLatLong) { var cachedS2CellsToRemove = new HashSet <ulong>(); var utcNow = DateTime.UtcNow; foreach (var cell in this.s2CellsCache.Values) { bool isEntireCellExpired = cell.ExpirationUtc < utcNow; if (isEntireCellExpired) { cachedS2CellsToRemove.Add(cell.S2CellId); } // Removing Locations foreach (var location in cell.Locations) { if (isEntireCellExpired || this.IsLocationInLoadRange(location, currentLatLong) == false) { this.RemoveLocationFromMap(location); } } } foreach (var s2CellId in cachedS2CellsToRemove) { this.s2CellsCache.Remove(s2CellId); } }
private void OnGPSReceived(GPSLatLong latLong) { if (this.isInitialized == false) { this.isInitialized = true; this.InitializeMap(latLong); return; } // Keeping tracking of the current LatLong this.currentLatLong = latLong; // Tell the map service of our new location if (this.isMapServiceLoaded) { this.mapsService.MoveFloatingOrigin(new LatLng(this.currentLatLong.Latitude, this.currentLatLong.Longitude)); // Checking out if we need to reload maps content var lastLoadDistance = GPSUtil.DistanceInMeters(this.lastLoadLatLng, this.currentLatLong); if (lastLoadDistance > this.reloadDistanceInMeters) { if (this.printDebugOutput) { Debug.Log("GoogleMapsManager Reloading Map"); } this.LoadMap(); } } }
private async void OnGPSChanged(GPSLatLong latLong) { if (this.isInitialized == false || GPSUtil.DistanceInMeters(this.lastUpdateLatLong, latLong) > this.reloadDistanceInMeters) { this.isInitialized = true; await this.UpdateLocation(latLong); } }
private async Task UpdateLocation(GPSLatLong currentLatLong) { this.lastUpdateLatLong = currentLatLong; this.PruneExpiredAndOutOfRangeLocations(currentLatLong); await this.FindAndAddAllNewLocations(currentLatLong); // Since we moved, lets update the locations for all the lbe locations foreach (var location in this.locationIdToGameObject) { var locationId = location.Key; var lbeLocation = this.locationIdToLBELocation[locationId]; location.Value.transform.localPosition = GoogleMapsManager.Instance.GetPosition(lbeLocation.LatLong); } }
private async Task FindAndAddAllNewLocations(GPSLatLong currentLatLong) { foreach (var s2CellId in this.GetCurrentS2CellIds(currentLatLong)) { var s2Cell = await this.GetS2Cell(s2CellId.Id); foreach (var location in s2Cell.Locations) { if (this.IsLocationInLoadRange(location, currentLatLong)) { this.AddLocationToMap(location); } } } }
private void LoadMap() { this.lastLoadLatLng = this.currentLatLong; // Load map with default options this.mapsService .MakeMapLoadRegion() .AddCircle(Vector3.zero, this.loadRadiusInMeters) .Load(this.gameObjectOptions); // Adding flags so we know when the map is loading, and has finished being loaded this.mapsService.Events.MapEvents.Loaded.AddListener(this.MapLoadFinished); // If the serverice is already loaded, then probably have things to unload if (this.isMapServiceLoaded) { this.ExecuteDelayed(1.0f, this.UnloadOutside); } }
private IEnumerable <S2CellId> GetCurrentS2CellIds(GPSLatLong currentLatLong) { // Info on S2 Geometry - https://s2geometry.io/ // Code taken from this video - https://www.youtube.com/watch?v=UZsf3bqmmKs (6:26) // Min/Max Level and Max Cells taken from here - https://s2.sidewalklabs.com/regioncoverer/ // Using Nuget S2Geometry vs 1.0.3 (https://www.nuget.org/packages/S2Geometry/) S2RegionCoverer rc = new S2RegionCoverer(); rc.MaxCells = S2RegionCoverer.DefaultMaxCells; rc.MinLevel = rc.MaxLevel = 14; // var southwestLat = new GPSLatLong { Latitude = 47.013859, Longitude = -122.920682 }; // var northeast = new GPSLatLong { Latitude = 47.033532, Longitude = -122.894687 }; // // S2LatLng low = S2LatLng.FromDegrees(southwestLat.Latitude, southwestLat.Longitude); // S2LatLng high = S2LatLng.FromDegrees(northeast.Latitude, northeast.Longitude); // // S2LatLngRect latLngRect = new S2LatLngRect(low, high); // return rc.GetCovering(latLngRect); //// https://stackoverflow.com/questions/7477003/calculating-new-longitude-latitude-from-old-n-meters //// number of km per degree = ~111km (111.32 in google maps, but range varies //// between 110.567km at the equator and 111.699km at the poles) //// 1km in degree = 1 / 111.32km = 0.0089 //// 1m in degree = 0.0089 / 1000 = 0.0000089 double meters = this.loadRadiusInMeters; double coef = meters * 0.0000089; double new_lat = /*currentLatLong.Latitude +*/ coef; double new_long = /*currentLatLong.Longitude +*/ coef / Math.Cos(currentLatLong.Latitude * (Math.PI / 180.0)); S2LatLng center = S2LatLng.FromDegrees(currentLatLong.Latitude, currentLatLong.Longitude); S2LatLng size = S2LatLng.FromDegrees(new_lat, new_long); return(rc.GetCovering(S2LatLngRect.FromCenterSize(center, size))); }
private bool IsLocationInLoadRange(LBELocation location, GPSLatLong currentLatLong) { return(GPSUtil.DistanceInMeters(location.LatLong, currentLatLong) < this.loadRadiusInMeters); }
public Vector3 GetPosition(GPSLatLong latLong) { return(this.mapsService.Projection.FromLatLngToVector3(new LatLng(latLong.Latitude, latLong.Longitude))); }
private void InitializeMap(GPSLatLong latLong) { if (this.printDebugOutput) { Debug.Log($"GoogleMapsManager Initializing Map To ({latLong})"); } this.currentLatLong = latLong; // Registering for error handling (Taken from BaseMapLoader.cs) this.mapsService.Events.MapEvents.LoadError.AddListener(args => { switch (args.DetailedErrorCode) { case MapLoadErrorArgs.DetailedErrorEnum.NetworkError: { // Handle errors caused by a lack of internet connectivity (or other network problems). if (Application.internetReachability == NetworkReachability.NotReachable) { Debug.LogError("The Maps SDK for Unity must have internet access in order to run."); } else { Debug.LogErrorFormat( "The Maps SDK for Unity was not able to get a HTTP response after " + "{0} attempts.\nThis suggests an issue with the network, or with the " + "online Semantic Tile API, or that the request exceeded its deadline " + "(consider using MapLoadErrorArgs.TimeoutSeconds).\n{1}", args.Attempts, string.IsNullOrEmpty(args.Message) ? string.Concat("Specific error message received: ", args.Message) : "No error message received."); } return; } case MapLoadErrorArgs.DetailedErrorEnum.UnsupportedClientVersion: { Debug.LogError( "The specific version of the Maps SDK for Unity being used is no longer " + "supported (possibly in combination with the specific API key used)."); return; } } // For all other types of errors, just show the given error message, as this should describe // the specific nature of the problem. Debug.LogError(args.Message); // Note that the Maps SDK for Unity will automatically retry failed attempts, unless // args.Retry is specifically set to false during this callback. }); // Set real-world location to load this.mapsService.InitFloatingOrigin(new LatLng(latLong.Latitude, latLong.Longitude)); // Configure Map Styling this.gameObjectOptions = this.GetMapStyle(); this.LoadMap(); }