private bool IsTileNext(TileSpecifier specifier) { lock (SleepingDownloads) { return(specifier.IsEqualTo(SleepingDownloads.Last())); } }
private void SetTileDownloading(TileSpecifier specifier) { lock (CurrentDownloads) { CurrentDownloads.Add(specifier); } }
private void EnqueueTile(TileSpecifier specifier) { lock (SleepingDownloads) { SleepingDownloads.Add(specifier); } }
private async Task <ImageSource> GetImageAsyncImpl(TileSpecifier specifier) { byte[] image = await GetCachedImageAsync(specifier); if (image == null) { EnqueueTile(specifier); while (GetCountDownloading() >= MAX_DOWNLOADS || !IsTileNext(specifier)) { await Task.Delay(500); } SetTileDownloading(specifier); DequeueTile(specifier); Task <byte[]> downloadedImage = DownloadImageAsync(specifier); CacheImageAsync(specifier, await downloadedImage); image = await downloadedImage; SetTileFinishedDownloading(specifier); } MemoryStream imageStream = new MemoryStream(image); BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.StreamSource = imageStream; bitmap.EndInit(); return(bitmap); }
private void SetTileFinishedDownloading(TileSpecifier specifier) { lock (CurrentDownloads) { CurrentDownloads.Remove(specifier); } }
public bool IsEqualTo(TileSpecifier other) { return(Coordinate == other.Coordinate && MapType == other.MapType && Size == other.Size && Zoom == other.Zoom); }
private void DequeueTile(TileSpecifier specifier) { lock (SleepingDownloads) { if (SleepingDownloads.Contains(specifier)) { SleepingDownloads.Remove(specifier); } } }
private async Task <byte[]> DownloadImageAsync(TileSpecifier spec) { StringBuilder uriBuilder = new StringBuilder("https://maps.googleapis.com/maps/api/staticmap"); uriBuilder.AppendFormat("?key={0}", API_KEY); uriBuilder.AppendFormat("¢er={0},{1}", spec.Coordinate.Latitude, spec.Coordinate.Longitude); uriBuilder.AppendFormat("&maptype={0}", spec.MapType.ToString().ToLower()); uriBuilder.AppendFormat("&size={0}x{1}", spec.Size.Width, spec.Size.Height); uriBuilder.AppendFormat("&zoom={0}", spec.Zoom); var client = new WebClient(); var data = client.DownloadDataTaskAsync(uriBuilder.ToString()); return(await data); }
private void CacheImageAsync(TileSpecifier spec, byte[] image) { Task ignore = Task.Run(() => { using (SQLiteCommand command = new SQLiteCommand(SqlStrings.WRITE_IMAGE, DbConnection)) { command.Parameters.AddWithValue("@latitude", spec.Coordinate.Latitude); command.Parameters.AddWithValue("@longitude", spec.Coordinate.Longitude); command.Parameters.AddWithValue("@width", spec.Size.Width); command.Parameters.AddWithValue("@height", spec.Size.Height); command.Parameters.AddWithValue("@zoom", spec.Zoom); command.Parameters.AddWithValue("@mapType", spec.MapType); command.Parameters.AddWithValue("@pngData", image); command.Parameters.AddWithValue("@pngDataLen", image.Length); command.ExecuteNonQuery(); } }); }
public async Task <ImageSource> GetImageAsync(TileSpecifier specifier) { if (!specifier.IsValidCoordinate()) { return(null); } if (Cache.ContainsKey(specifier)) { RequeueTile(specifier); return(await Cache[specifier]); } Task <ImageSource> task = GetImageAsyncImpl(specifier); Cache.Add(specifier, task); return(await task); }
private async Task <byte[]> GetCachedImageAsync(TileSpecifier spec) { byte[] buffer = null; using (SQLiteCommand command = new SQLiteCommand(SqlStrings.GET_IMAGE, DbConnection)) { command.Parameters.AddWithValue("@latitude", spec.Coordinate.Latitude); command.Parameters.AddWithValue("@longitude", spec.Coordinate.Longitude); command.Parameters.AddWithValue("@width", spec.Size.Width); command.Parameters.AddWithValue("@height", spec.Size.Height); command.Parameters.AddWithValue("@zoom", spec.Zoom); command.Parameters.AddWithValue("@mapType", spec.MapType); using (SQLiteDataReader reader = await Task.Run(() => command.ExecuteReader())) { if (reader.Read()) { int length = reader.GetInt32(1); buffer = new byte[length]; reader.GetBytes(0, 0, buffer, 0, length); } } } return(buffer); }