private LatLong CalculateCentreLocation(LatLong bottomLeftLocation, int logDelta) { double delta = Math.Pow(2.0, logDelta); double lat = bottomLeftLocation.Latitude + delta/2.0; double lng = bottomLeftLocation.Longitude + delta/2.0; return new LatLong(lat, lng); }
public CombinedMapData CreateEmptyMapAtLocation(LatLong location, double elevation, double delta) { CombinedMapData newMap = new CombinedMapData(); newMap.ShapeDelta = delta; newMap.BottomLeftLocation = location; newMap.ZoomLevel = EarthProjection.GetZoomFromElevation(elevation); return newMap; }
public static bool TryParse(string s, out LatLong value) { value = new LatLong(); try { value = LatLong.Parse(s); } catch (ArgumentException) { return false; } return true; }
public static LatLong Parse(string s) { LatLong value = new LatLong(); string[] split = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); if (split.Length != 2) throw new ArgumentException("LatLong should have a comma seperated pair of numbers."); double d = 0; if (!double.TryParse(split[0], out d)) throw new ArgumentException("LatLong should have a comma seperated pair of numbers."); value.Latitude = d; if (!double.TryParse(split[1], out d)) throw new ArgumentException("LatLong should have a comma seperated pair of numbers."); value.Longitude = d; return value; }
public static LatLong CalculateNearestLatLongAtDelta(LatLong latLong, double delta, bool roundToNearest) { double dLat = latLong.Latitude / delta; double dLng = latLong.Longitude / delta; if (!roundToNearest) { dLat = Math.Floor(dLat); dLng = Math.Floor(dLng); } long lat = Convert.ToInt64(dLat); long lng = Convert.ToInt64(dLng); LatLong ret = new LatLong((double)lat * delta, (double)lng * delta); return ret; }
public static LatLong CalculateNearestLatLongAtDelta(LatLong latLong, double delta) { return CalculateNearestLatLongAtDelta(latLong, delta, true); }
public LatLong(LatLong latLong) : this(latLong.Latitude, latLong.Longitude) { }
private CombinedMapData SwapTileToNewLocation(CombinedMapData prevTile, LatLong newLocation) { CombinedMapData newTile = new CombinedMapData(prevTile); newTile.BottomLeftLocation = newLocation; mapFactory.RetrieveOrUpdateMapTerrain(newTile); AddTileToEngine(newTile); RemoveTileFromEngine(prevTile); UpdateMapTexture(newTile, currentElevation); return newTile; }
private void InitializeTile(LatLong pos, double elevation, int row, int col) { LatLong newPos = new LatLong(pos.Latitude - currentDelta * (row - 1), pos.Longitude - currentDelta * (col - 1)); CombinedMapData expectedMap = mapFactory.CreateEmptyMapAtLocation(newPos, elevation, currentDelta); currentZoomLevel = EarthProjection.GetZoomFromElevation(elevation); if (TerrainUpdateRequired(currentTiles[row, col], expectedMap)) { if (currentTiles[row, col] != null) { RemoveTileFromEngine(currentTiles[row, col]); } mapFactory.RetrieveOrUpdateMapTerrain(expectedMap); AddTileToArray(expectedMap, row, col); currentTiles[row, col] = expectedMap; } UpdateMapTexture(currentTiles[row, col], elevation); }
private MapPosition CalculateTravelDirection(LatLong newLocation, LatLong oldLocation, double newElevation, double prevElevation) { MapPosition direction = MapPosition.None; direction |= HasElevationChanged(newElevation, prevElevation); if (newLocation.Equals(oldLocation)) return direction; LatLong diff = LatLong.Subtract(newLocation,oldLocation); double delta = GetDeltaFromElevation(prevElevation); double normLat = NormalizeDistance(newLocation.Latitude - minDisplayedLatLong.Latitude,currentDelta); double normLong = NormalizeDistance(newLocation.Longitude - minDisplayedLatLong.Longitude, currentDelta); if (normLat > 2.1 && diff.Latitude > 0) direction |= MapPosition.N; if (normLat < 0.9 && diff.Latitude < 0) direction |= MapPosition.S; if (normLong > 2.1 && diff.Longitude > 0) direction |= MapPosition.E; if (normLong < 0.9 && diff.Longitude < 0) direction |= MapPosition.W; if (normLat > 3 || normLat < 0 || normLong > 3 || normLong < 0) Console.WriteLine("Extreme travel!"); return direction; }
private Image GetImageFromSource(LatLong bottomLeftLocation, int desiredZoomLevel, int logDelta, out int actualZoomLevel) { actualZoomLevel = desiredZoomLevel; int imageDelta = CalculateLogDeltaFromZoom(desiredZoomLevel); LatLong centreLocation = CalculateCentreLocation(bottomLeftLocation, imageDelta); MapDescriptor d = new MapDescriptor(centreLocation.Latitude, centreLocation.Longitude, desiredZoomLevel); Image image = GetImageFromFile(d); if (image == null) { FetchImageFromWeb(d); return RecursivelyGetTiledImage(bottomLeftLocation, desiredZoomLevel - 1, logDelta, out actualZoomLevel); } return image; }
private Image CropFromLargerImage(LatLong bottomLeftLocation, int desiredZoomLevel, int logDelta, out int actualZoomLevel) { double delta = Math.Pow(2.0,logDelta+1); LatLong newLocation = EarthProjection.CalculateNearestLatLongAtDelta(bottomLeftLocation, delta,false); using (Image image = RecursivelyGetTiledImage(newLocation, desiredZoomLevel, logDelta + 1,out actualZoomLevel)) { float width = image.Width / 2; if (width < MIN_TEXTURE_SIZE) width = MIN_TEXTURE_SIZE; float height = image.Height / 2; if (height < MIN_TEXTURE_SIZE) height = MIN_TEXTURE_SIZE; float yOffset = height; if (bottomLeftLocation.Latitude > newLocation.Latitude) yOffset = 0; float xOffset = 0; if (bottomLeftLocation.Longitude > newLocation.Longitude) xOffset = width; Image ret = ImageConverter.CropImage(image, new RectangleF(xOffset, yOffset, width, height)); return ret; } }
public static LatLong Subtract(LatLong a, LatLong b) { return new LatLong(a.Latitude - b.Latitude, a.Longitude - b.Longitude); }
public static LatLong Min(LatLong a, LatLong b) { return new LatLong(Math.Min(a.Latitude, b.Latitude), Math.Min(a.Longitude, b.Longitude)); }
public static LatLong Add(LatLong a, LatLong b) { return new LatLong(a.Latitude + b.Latitude, a.Longitude + b.Longitude); }
public static Float3 ConvertLatLongElevationToCameraLocation(LatLong latLong, double elevation) { float units = (float)UnitsPerDegreeLatitude; return new Float3((float)latLong.Longitude * units, (float)(elevation * UnitsPerMetreElevation), (float)latLong.Latitude * units); }
public void CameraLocationChanged(Float3 newCameraLocation) { currentLocation = EarthProjection.ConvertCameraLocationToLatLong(newCameraLocation); currentElevation = EarthProjection.ConvertCameraLocationToElevation(newCameraLocation); ; MapPosition direction = CalculateTravelDirection(currentLocation, previousLocation,currentElevation,previousElevation); currentZoomLevel = EarthProjection.GetZoomFromElevation(currentElevation); if (direction != MapPosition.None && !FixTerrain) { MoveTerrainInDirection(direction, currentLocation, currentElevation); } UpdateAllTextures(currentElevation); previousLocation = currentLocation; previousElevation = currentElevation; }
private Image RecursivelyGetTiledImage(LatLong bottomLeftLocation, int desiredZoomLevel, int logDelta, out int actualZoomLevel) { if (desiredZoomLevel < 0) { actualZoomLevel = -1; return nullImage.ImageClone; } int minZoomLevel = CalculateZoomFromLogDelta(logDelta); if (minZoomLevel == desiredZoomLevel) { return GetImageFromSource(bottomLeftLocation, desiredZoomLevel, logDelta, out actualZoomLevel); } else if (minZoomLevel > desiredZoomLevel) { return CropFromLargerImage(bottomLeftLocation, desiredZoomLevel, logDelta, out actualZoomLevel); } else { return StitchFromImageTiles(bottomLeftLocation, desiredZoomLevel, logDelta, out actualZoomLevel); } }
private void InitializeAtGivenLatLongElevation(LatLong pos, double elevation) { currentDelta = GetDeltaFromElevation(elevation); mapFactory.EmptyQueue(); pos = EarthProjection.CalculateNearestLatLongAtDelta(pos, currentDelta, false); for (int row = 0; row < TILE_COUNT; row++) { for (int col = 0; col < TILE_COUNT; col++) { InitializeTile(pos, elevation, row, col); } } currentElevation = elevation; currentLocation = pos; }
private Image StitchFromImageTiles(LatLong bottomLeftLocation, int desiredZoomLevel, int logDelta, out int actualZoomLevel) { int nTiles = 2; Image[] imageTiles = new Image[nTiles * nTiles]; int newLogDelta = logDelta - 1; double delta = Math.Pow(2.0, newLogDelta); actualZoomLevel = desiredZoomLevel; for (int i = 0; i < nTiles; i++) { for (int k = 0; k < nTiles; k++) { LatLong tileLocation = new LatLong(bottomLeftLocation.Latitude + delta * i, bottomLeftLocation.Longitude + delta * k); imageTiles[(nTiles - i - 1) * nTiles + k] = RecursivelyGetTiledImage(tileLocation,desiredZoomLevel,newLogDelta, out actualZoomLevel); } } Image ret = ImageConverter.StitchImages(imageTiles,nTiles,nTiles); foreach (Image image in imageTiles) if (image != null) image.Dispose(); return ret; }
private void MoveTerrainInDirection(MapPosition direction, LatLong location, double elevation) { if ((direction & MapPosition.Up) == MapPosition.Up) { UpdateAllTerrainAtElevation(location,elevation); } else if ((direction & MapPosition.Down) == MapPosition.Down) { UpdateAllTerrainAtElevation(location,elevation); } else if(!pauseUpdates) { if ((direction & MapPosition.N) == MapPosition.N) { for (int col = 0; col < TILE_COUNT; col++) { LatLong locationOffset = new LatLong(TILE_COUNT * currentDelta, 0); LatLong newLocation = LatLong.Add(currentTiles[TILE_COUNT - 1, col].BottomLeftLocation, locationOffset); CombinedMapData newTile = SwapTileToNewLocation(currentTiles[TILE_COUNT - 1, col], newLocation); for (int row = TILE_COUNT - 1; row > 0; row--) { currentTiles[row, col] = currentTiles[row - 1, col]; } currentTiles[0, col] = newTile; } } if ((direction & MapPosition.S) == MapPosition.S) { for (int col = 0; col < TILE_COUNT; col++) { LatLong locationOffset = new LatLong(-TILE_COUNT * currentDelta, 0); LatLong newLocation = LatLong.Add(currentTiles[0, col].BottomLeftLocation, locationOffset); CombinedMapData newTile = SwapTileToNewLocation(currentTiles[0, col], newLocation); for (int row = 0; row < TILE_COUNT - 1; row++) { currentTiles[row, col] = currentTiles[row + 1, col]; } currentTiles[TILE_COUNT - 1, col] = newTile; } } if ((direction & MapPosition.W) == MapPosition.W) { for (int row = 0; row < TILE_COUNT; row++) { LatLong locationOffset = new LatLong(0, -TILE_COUNT * currentDelta); LatLong newLocation = LatLong.Add(currentTiles[row, 0].BottomLeftLocation, locationOffset); CombinedMapData newTile = SwapTileToNewLocation(currentTiles[row, 0], newLocation); for (int col = 0; col < TILE_COUNT - 1; col++) { currentTiles[row, col] = currentTiles[row, col + 1]; } currentTiles[row, TILE_COUNT - 1] = newTile; } } if ((direction & MapPosition.E) == MapPosition.E) { for (int row = 0; row < TILE_COUNT; row++) { LatLong locationOffset = new LatLong(0, TILE_COUNT * currentDelta); LatLong newLocation = LatLong.Add(currentTiles[row, TILE_COUNT - 1].BottomLeftLocation, locationOffset); CombinedMapData newTile = SwapTileToNewLocation(currentTiles[row, TILE_COUNT - 1], newLocation); for (int col = TILE_COUNT - 1; col > 0; col--) { currentTiles[row, col] = currentTiles[row, col - 1]; } currentTiles[row, 0] = newTile; } } } }
public Image GetTiledImage(LatLong bottomLeftLocation, int desiredZoomLevel, int logDelta, out int actualZoomLevel) { initialZoomLevel = desiredZoomLevel; nullImage.Text = "bottomLeft: " + bottomLeftLocation + "\ndesiredZoom: " + desiredZoomLevel; return RecursivelyGetTiledImage(bottomLeftLocation, desiredZoomLevel, logDelta, out actualZoomLevel); }
private void UpdateAllTerrainAtElevation(LatLong location, double elevation) { pauseUpdates = true; InitializeAtGivenLatLongElevation(location, elevation); pauseUpdates = false; }
public static string CalculateFilenameFromLatLong(LatLong latLong) { int latitude = (int)latLong.Latitude; int longitude = (int)latLong.Longitude; if (latitude < 1 && latLong.Latitude % 1 != 0) latitude -= 1; if (longitude < 1 && latLong.Longitude % 1 != 0) longitude -= 1; string ret = LatLongToString(latitude, longitude); string folder = TerrainFolder; if (TerrainFolder == null) folder = Properties.Settings.Default.MapTerrainFolder; return folder + "\\" + ret + ".hgt"; }