public void BuildBigImage(string filename, ProgressWindow pw) { //FreeImage.SetOutputMessage(FreeImage_OutputMessageFunction); int topleftx, toplefty, bottomrightx, bottomrighty; uint topleftzoom, bottomrightzoom; GMapTile.XYZoom(topleft, out topleftx, out toplefty, out topleftzoom); GMapTile.XYZoom(bottomright, out bottomrightx, out bottomrighty, out bottomrightzoom); //gkl changes - passed in new delegate td = new TileDownloader(outsidereportFunction, worker); FIBITMAP bigImage = new FIBITMAP(), image = new FIBITMAP(); try { imageWidth = (bottomrightx - topleftx + 1) * GMapTile.TILE_SIZE; imageHeight = (bottomrighty - toplefty + 1) * GMapTile.TILE_SIZE; if (imageFormat != FREE_IMAGE_FORMAT.FIF_UNKNOWN) { reportFunction("Allocating memory for image", 0); if ((imageWidth > 65535) || (imageHeight > 65535)) { throw new InvalidOperationException(Properties.Resources.ExceptionImageMemoryAllocation); } bigImage = FreeImage.Allocate(imageWidth, imageHeight, grayscale ? 8 : 24, 0, 0, 0); if (bigImage.IsNull) { throw new InvalidOperationException(Properties.Resources.ExceptionImageMemoryAllocation); } } int wholeQuant = (bottomrightx - topleftx + 1) * (bottomrighty - toplefty + 1); bool paletteInit = false; for (int yy = toplefty; yy <= bottomrighty; yy++) { for (int xx = topleftx; xx <= bottomrightx; xx++) { if (worker.CancellationPending) { return; } try { GMapTile g = new GMapTile(xx, yy, topleftzoom); while (pw.paused) { reportFunction("< Paused >", 0); Thread.Sleep(1000); } if (pw.allCancelled) { reportFunction("< Cancelled >", 0); return; } if (Properties.Settings.Default.OperatingMode == 3 || Properties.Settings.Default.OperatingMode == 4 || Properties.Settings.Default.OperatingMode == 5 || Properties.Settings.Default.OperatingMode == 6) reportFunction("(Down)loading image (" + xx + "," + yy + ")", 0); else reportFunction("(Down)loading image " + g.Quadtree, ((!grayscale && dither8bpp ? 0.0 : 50.0) + 100.0) / (double)wholeQuant); FIBITMAP image_alpha; FIBITMAP image_alpha2; FIBITMAP image_result; switch (tileTypeInt) { case 0: //map only image = LoadImageFromCache("GoogleMap", g); break; case 1: //satellite only image = LoadImageFromCache("GoogleSat", g); break; case 2: //hybrid image = LoadImageFromCache("GoogleSatH", g); if (worker.CancellationPending) { return; } image_alpha = LoadImageFromCache("GoogleHyb", g); if (FreeImage.GetBPP(image_alpha) != 32) { //sometimes alpha tile from GG is a 2bits image, it means tile is blank break; } if (Properties.Settings.Default.DrivingMapTransparency != 100) { image_alpha2 = FreeImage.Allocate(GMapTile.TILE_SIZE, GMapTile.TILE_SIZE, 32, 0, 0, 0); if (!FreeImage.Paste(image_alpha2, image_alpha, 0, 0, ((int)Properties.Settings.Default.DrivingMapTransparency * 256) / 100)) { //sometimes alpha tile from GG is corrupted, it means tile is blank //we keep tile } FreeImage.Unload(image_alpha); image_alpha = image_alpha2; } image_result = FreeImage.Composite(image_alpha, false, null, image); FreeImage.Unload(image_alpha); if (!image_result.IsNull) { FreeImage.Unload(image); image = image_result; } else { //sometimes alpha tile from GG is corrupted, it means tile is blank //we keep image } break; case 3: image = LoadImageFromCache("GoogleTer", g); break; case 4: image = LoadImageFromCache("GoogleChina", g); break; case 5: image = LoadImageFromCache("MicrosoftMap", g); break; case 6: image = LoadImageFromCache("MicrosoftSat", g); break; case 7: image = LoadImageFromCache("MicrosoftHyb", g); break; case 8: image = LoadImageFromCache("MicrosoftTer", g); break; case 9: image = LoadImageFromCache("MicrosoftBrMap", g); break; case 10: image = LoadImageFromCache("YahooMap", g); break; case 11: image = LoadImageFromCache("YahooSat", g); break; case 12: image = LoadImageFromCache("YahooSatH", g); if (worker.CancellationPending) { return; } image_alpha = LoadImageFromCache("YahooHyb", g); if (FreeImage.GetBPP(image_alpha) != 32) { //sometimes alpha tile from GG is a 2bits image, it means tile is blank break; } if (Properties.Settings.Default.DrivingMapTransparency != 100) { image_alpha2 = FreeImage.Allocate(GMapTile.TILE_SIZE, GMapTile.TILE_SIZE, 32, 0, 0, 0); if (!FreeImage.Paste(image_alpha2, image_alpha, 0, 0, ((int)Properties.Settings.Default.DrivingMapTransparency * 256) / 100)) { //sometimes alpha tile from GG is corrupted, it means tile is blank //we keep tile } FreeImage.Unload(image_alpha); image_alpha = image_alpha2; } image_result = FreeImage.Composite(image_alpha, false, null, image); FreeImage.Unload(image_alpha); if (!image_result.IsNull) { FreeImage.Unload(image); image = image_result; } else { //sometimes alpha tile from GG is corrupted, it means tile is blank //we keep image } break; case 13: image = LoadImageFromCache("YahooInMap", g); break; case 14: image = LoadImageFromCache("YahooSatH2", g); if (worker.CancellationPending) { return; } image_alpha = LoadImageFromCache("YahooInHyb", g); if (FreeImage.GetBPP(image_alpha) != 32) { //sometimes alpha tile from GG is a 2bits image, it means tile is blank break; } if (Properties.Settings.Default.DrivingMapTransparency != 100) { image_alpha2 = FreeImage.Allocate(GMapTile.TILE_SIZE, GMapTile.TILE_SIZE, 32, 0, 0, 0); if (!FreeImage.Paste(image_alpha2, image_alpha, 0, 0, ((int)Properties.Settings.Default.DrivingMapTransparency * 256) / 100)) { //sometimes alpha tile from GG is corrupted, it means tile is blank //we keep tile } FreeImage.Unload(image_alpha); image_alpha = image_alpha2; } image_result = FreeImage.Composite(image_alpha, false, null, image); FreeImage.Unload(image_alpha); if (!image_result.IsNull) { FreeImage.Unload(image); image = image_result; } else { //sometimes alpha tile from GG is corrupted, it means tile is blank //we keep image } break; case 15: image = LoadImageFromCache("OpenStreetMap", g); break; case 16: image = LoadImageFromCache("OSMARender", g); break; case 17: image = LoadImageFromCache("OpenAerialMap", g); break; case 18: image = LoadImageFromCache("OpenCycleMap", g); break; case 19: image = LoadImageFromCache("BrutMap", g); break; case 20: image = LoadImageFromCache("BrutMapAndNav", g); break; case 21: image = LoadImageFromCache("BrutMapSat", g); break; case 22: image = LoadImageFromCache("BrutMapAndNavSat", g); break; case 23: //hybrid image = LoadImageFromCache("BrutMapSatH", g); if (worker.CancellationPending) { return; } image_alpha = LoadImageFromCache("BrutMapHyb", g); if (FreeImage.GetBPP(image_alpha) < 8) { //sometimes alpha tile from GG is a 2bits image, it means tile is blank break; } if (Properties.Settings.Default.DrivingMapTransparency != 100) { image_alpha2 = FreeImage.Allocate(GMapTile.TILE_SIZE, GMapTile.TILE_SIZE, 32, 0, 0, 0); if (!FreeImage.Paste(image_alpha2, image_alpha, 0, 0, ((int)Properties.Settings.Default.DrivingMapTransparency * 256) / 100)) { //sometimes alpha tile from GG is corrupted, it means tile is blank //we keep tile } FreeImage.Unload(image_alpha); image_alpha = image_alpha2; } image_result = FreeImage.Composite(image_alpha, false, null, image); FreeImage.Unload(image_alpha); if (!image_result.IsNull) { FreeImage.Unload(image); image = image_result; } else { //sometimes alpha tile from GG is corrupted, it means tile is blank //we keep image } string hyb_file = td.BuildFileName("BrutMapSH", g); if (!FreeImage.Save(FREE_IMAGE_FORMAT.FIF_PNG, image, hyb_file, 0)) { throw new IOException(Properties.Resources.ExceptionCannotSaveFile); } break; case 24: //hybrid image = LoadImageFromCache("BrutMapAndNavSatH", g); if (worker.CancellationPending) { return; } image_alpha = LoadImageFromCache("BrutMapAndNavHyb", g); if (FreeImage.GetBPP(image_alpha) < 8) { //sometimes alpha tile from GG is a 2bits image, it means tile is blank break; } if (Properties.Settings.Default.DrivingMapTransparency != 100) { image_alpha2 = FreeImage.Allocate(GMapTile.TILE_SIZE, GMapTile.TILE_SIZE, 32, 0, 0, 0); if (!FreeImage.Paste(image_alpha2, image_alpha, 0, 0, ((int)Properties.Settings.Default.DrivingMapTransparency * 256) / 100)) { //sometimes alpha tile from GG is corrupted, it means tile is blank //we keep tile } FreeImage.Unload(image_alpha); image_alpha = image_alpha2; } image_result = FreeImage.Composite(image_alpha, false, null, image); FreeImage.Unload(image_alpha); if (!image_result.IsNull) { FreeImage.Unload(image); image = image_result; } else { //sometimes alpha tile from GG is corrupted, it means tile is blank //we keep image } string hyb_file_andnav = td.BuildFileName("BrutMapAndNavSH", g); if (!FreeImage.Save(FREE_IMAGE_FORMAT.FIF_PNG, image, hyb_file_andnav, 0)) { throw new IOException(Properties.Resources.ExceptionCannotSaveFile); } break; } if (Properties.Settings.Default.OperatingMode == 3 || Properties.Settings.Default.OperatingMode == 4 || Properties.Settings.Default.OperatingMode == 5 || Properties.Settings.Default.OperatingMode == 6) reportFunction("Image download completed (" + xx + "," + yy + ")", 100.0 / (double)wholeQuant); if (worker.CancellationPending) { return; } if (imageFormat == FREE_IMAGE_FORMAT.FIF_UNKNOWN) { continue; } if (grayscale) { //uint image2 = FreeImage.ConvertPalette(bigImage, image); FIBITMAP image3 = FreeImage.ConvertTo24Bits(image); if (image3.IsNull) { throw new InvalidOperationException(Properties.Resources.ExceptionCannotConvert24bpp); } FIBITMAP image2 = FreeImage.ConvertTo8Bits(image3); FreeImage.Unload(image3); if (image2.IsNull) { throw new InvalidOperationException(Properties.Resources.ExceptionCannotConvertGrayscale); } FreeImage.Unload(image); image = image2; /* FIXME * if (!paletteInit) { if (!FreeImage.PaletteCopy(image, bigImage)) { throw new InvalidOperationException(Properties.Resources.ExceptionGrayscalePalette); } paletteInit = true; } */ } reportFunction("Pasting " + g.Quadtree, 0); if (!FreeImage.Paste(bigImage, image, (xx - topleftx) * GMapTile.TILE_SIZE, (yy - toplefty) * GMapTile.TILE_SIZE, 256)) { throw new InvalidOperationException(Properties.Resources.ExceptionPastingImage); } } catch (Exception) { if (Properties.Settings.Default.OperatingMode == 3 || Properties.Settings.Default.OperatingMode == 4 || Properties.Settings.Default.OperatingMode == 5 || Properties.Settings.Default.OperatingMode == 6) reportFunction("Image download failed (" + xx + "," + yy + ")", 100.0 / (double)wholeQuant); } finally { FreeImage.Unload(image); image.SetNull(); } } } if (worker.CancellationPending || (imageFormat == FREE_IMAGE_FORMAT.FIF_UNKNOWN)) { return; } if (!grayscale && dither8bpp) { reportFunction("Converting image to 8bpp", 0.0); FIBITMAP bigImage8 = FreeImage.ColorQuantize(bigImage, FREE_IMAGE_QUANTIZE.FIQ_WUQUANT); if (bigImage8.IsNull) { throw new InvalidOperationException(Properties.Resources.ExceptionConversion24bpp8bpp); } FreeImage.Unload(bigImage); bigImage = bigImage8; reportFunction("Image converted", 50.0); } if (worker.CancellationPending) { return; } reportFunction("Saving image to " + Path.GetFileName(filename), 0.0); if (!FreeImage.Save(imageFormat, bigImage, filename, saveflags)) { throw new IOException(Properties.Resources.ExceptionCannotSaveFile); } reportFunction("Image saved", 50.0); } finally { FreeImage.Unload(bigImage); } }
FIBITMAP LoadImageFromCache(string tileType, GMapTile g) { FIBITMAP image = new FIBITMAP(); image.SetNull(); while (image.IsNull) { bool useProxy; string src_filename = td.BuildFileName(tileType, g); if (src_filename != null && src_filename.Length > 0) { string url = td.BuildURL(tileType, g, out useProxy); // using temp file if tiles_per_file != 1 if (Properties.Settings.Default.MGMapsTilesPerFile == 1) { if (!td.IsCached(src_filename, g)) td.DownloadImage(url, src_filename, useProxy); } else { // FIX check if the image exists String tempfile = Path.GetTempFileName(); #if DEBUG Console.WriteLine("Temp file: " + tempfile); #endif try { if (!td.IsCached(src_filename, g)) { td.DownloadImage(url, tempfile, useProxy); #if DEBUG Console.WriteLine("Downloaded image from {0}", url); #endif td.SaveImage(tempfile, src_filename, g); } } finally { try { File.Delete(tempfile); } catch (Exception) { } } } } if (worker.CancellationPending || Properties.Settings.Default.MGMapsTilesPerFile != 1) { break; } //gkl changes - added synchronization based upon filename bool createdNew = false; Mutex synchobj = new Mutex(true, Regex.Replace(src_filename, "\\\\", "_"), out createdNew); if (synchobj != null) { try { if (!createdNew) synchobj.WaitOne(); if (!File.Exists(src_filename)) { //blank image white image = FreeImage.Allocate(GMapTile.TILE_SIZE, GMapTile.TILE_SIZE, 24, 0, 0, 0); if (image.IsNull) { throw new InvalidOperationException(Properties.Resources.ExceptionCannotBuildBlankImage); } if (!FreeImage.Invert(image)) { throw new InvalidOperationException(Properties.Resources.ExceptionCannotBuildBlankImage); } if (Properties.Settings.Default.SaveBlankImageForMissingTiles) { if (tileType == "GoogleSat" || tileType == "GoogleSatH" || tileType == "GoogleTer" || tileType == "YahooMap" || tileType == "YahooInMap" || tileType == "YahooSat" || tileType == "YahooSatH" || tileType == "YahooSatH2" || tileType == "MicrosoftSat" || tileType == "OpenAerialMap" || tileType == "BrutMapSat" || tileType == "BrutMapSatH" || tileType == "BrutMapAndNavSat" || tileType == "BrutMapAndNavSatH") { if (!FreeImage.Save( FREE_IMAGE_FORMAT.FIF_JPEG, image, src_filename, FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYSUPERB)) { throw new InvalidOperationException(Properties.Resources.ExceptionCannotBuildBlankImage); } } else { if (!FreeImage.Save( FREE_IMAGE_FORMAT.FIF_PNG, image, src_filename, FREE_IMAGE_SAVE_FLAGS.PNG_Z_DEFAULT_COMPRESSION)) { throw new InvalidOperationException(Properties.Resources.ExceptionCannotBuildBlankImage); } } } } else { image = FreeImage.Load(FreeImage.GetFileType(src_filename, 0), src_filename, 0); if (image.IsNull) { File.Delete(src_filename); if (Properties.Settings.Default.HaltOnImageFileCorrupted) { throw new InvalidOperationException(String.Format(Properties.Resources.ExceptionLoadingImage, src_filename)); } } } } finally //always release mutex { //gkl changes - added synchronization based upon filename synchobj.ReleaseMutex(); synchobj.Close(); } } } return image; }
// copy image from temp file to destination file public void SaveImage(string tempfile, string src_filename, GMapTile g) { if (!File.Exists(tempfile)) return; byte dx = (byte)(g.X % tpfx); byte dy = (byte)(g.Y % tpfy); // mutex to avoid writing simultaneously bool createdNew; Mutex synchobj = new Mutex(true, Regex.Replace(src_filename, "\\\\", "_"), out createdNew); if (synchobj != null) { if (!createdNew) synchobj.WaitOne(); try { // do nothing if already cached if (IsCachedNoMutex(src_filename, g)) return; int num = 0; int ofs = tpf * 6 + 2; byte[] buf = new byte[ofs]; bool existed = File.Exists(src_filename); FileStream f = null; FileStream f2 = null; try { f = File.Open(src_filename, FileMode.OpenOrCreate, FileAccess.ReadWrite); if (existed) { // read the header f.Read(buf, 0, ofs); num = (((int)buf[0]) << 8) + (int)buf[1]; ofs = (((int)buf[2 + num * 6 - 6 + 2]) << 24) + (((int)buf[2 + num * 6 - 6 + 3]) << 16) + (((int)buf[2 + num * 6 - 6 + 4]) << 8) + (((int)buf[2 + num * 6 - 6 + 5])); } else { // write the header f.Write(buf, 0, ofs); } // seek to ofs f.Seek(ofs, SeekOrigin.Begin); FileInfo fi = new FileInfo(tempfile); int totalsize = (int) fi.Length; // copy data f2 = File.Open(tempfile, FileMode.Open, FileAccess.Read); byte[] databuf = new byte[BUFSIZE]; for (int sz = 0; sz < totalsize; ) { int cnt = Math.Min(BUFSIZE, totalsize - sz); f2.Read(databuf, 0, cnt); f.Write(databuf, 0, cnt); sz += cnt; } f2.Close(); f2 = null; totalsize += ofs; // seek to beginning to write the new header buf[0] = (byte)((num + 1) >> 8); buf[1] = (byte)((num + 1) & 0xFF); f.Seek(0, SeekOrigin.Begin); f.Write(buf, 0, 2); // new tile data buf[0] = dx; buf[1] = dy; buf[2] = (byte) (totalsize >> 24); buf[3] = (byte)((totalsize>>16)&0xFF); buf[4] = (byte)((totalsize >> 8) & 0xFF); buf[5] = (byte)(totalsize & 0xFF); f.Seek(6 * num + 2, SeekOrigin.Begin); f.Write(buf, 0, 6); // delete temp file File.Delete(tempfile); } finally { if (f != null) try { f.Close(); } catch (Exception) { } if (f2 != null) try { f2.Close(); } catch (Exception) { } } } finally { synchobj.ReleaseMutex(); synchobj.Close(); } } }
private bool IsCachedNoMutex(string filepath, GMapTile g) { // doesn't exist -- return false if (!File.Exists(filepath)) return false; FileInfo fi = new FileInfo(filepath); // zero length -- delete and return false if (fi.Length == 0) { File.Delete(filepath); return false; } // non-zero length and tpf=1 - return true, exists and is cached else if (tpf == 1) return true; // tpf>1, file exists byte dx = (byte)(g.X % tpfx); byte dy = (byte)(g.Y % tpfy); FileStream f = null; try { f = File.Open(filepath, FileMode.Open, FileAccess.Read); byte[] buf = new byte[6 * tpf + 2]; f.Read(buf, 0, 6 * tpf + 2); int num = (((int)buf[0]) << 8) + (int)buf[1]; for (int i = 0; i < num; i++) if (buf[2 + i * 6] == dx && buf[2 + i * 6 + 1] == dy) return true; } finally { if (f != null) try { f.Close(); } catch (Exception) { } } return false; }
public bool IsCached(string filepath, GMapTile g) { //gkl changes - added synchronization based upon filename bool createdNew = false; Mutex synchobj = new Mutex(true, Regex.Replace(filepath, "\\\\", "_"), out createdNew); if (synchobj != null) { if (!createdNew) synchobj.WaitOne(); try { bool result = IsCachedNoMutex(filepath, g); return result; } finally { synchobj.ReleaseMutex(); synchobj.Close(); } } return false; }
public string BuildURL(string tileType, GMapTile g, out bool useProxy) { useProxy = false; string url = ""; // Edited by Shustrik - compacted the switch statement string quadcode; switch (tileType) { case "GoogleSat": case "GoogleSatH": case "BrutMapSat": case "BrutMapAndNavSat": case "BrutMapSatH": case "BrutMapAndNavSatH": url = Properties.Settings.Default.GoogleSatURL; break; case "GoogleMap": case "BrutMap": case "BrutMapAndNav": url = Properties.Settings.Default.GoogleMapURL; break; case "GoogleHyb": case "BrutMapHyb": case "BrutMapAndNavHyb": url = Properties.Settings.Default.GoogleHybURL; break; case "GoogleTer": url = Properties.Settings.Default.GoogleTerURL; break; case "GoogleChina": url = Properties.Settings.Default.GoogleChinaURL; break; case "MicrosoftMap": url = Properties.Settings.Default.MicrosoftMapURL; break; case "MicrosoftSat": url = Properties.Settings.Default.MicrosoftSatURL; break; case "MicrosoftHyb": url = Properties.Settings.Default.MicrosoftHybURL; break; case "MicrosoftTer": url = Properties.Settings.Default.MicrosoftTerURL; break; case "MicrosoftBrMap": if (g.Zoom <= 10) url = Properties.Settings.Default.MicrosoftMapURL; else url = Properties.Settings.Default.MicrosoftBrMapURL; break; case "YahooMap": url = Properties.Settings.Default.YahooMapURL; break; case "YahooSat": case "YahooSatH": case "YahooSatH2": url = Properties.Settings.Default.YahooSatURL; break; case "YahooHyb": url = Properties.Settings.Default.YahooHybURL; break; case "YahooInMap": url = Properties.Settings.Default.YahooInMapURL; break; case "YahooInHyb": url = Properties.Settings.Default.YahooInHybURL; break; case "OpenStreetMap": url = Properties.Settings.Default.OpenStreetMapURL; break; case "OSMARender": url = Properties.Settings.Default.OSMARenderURL; break; case "OpenAerialMap": url = Properties.Settings.Default.OpenAerialMapURL; break; case "OpenCycleMap": url = Properties.Settings.Default.OpenCycleMapURL; break; } useProxy = Properties.Settings.Default.UseProxy && (Properties.Settings.Default.UseProxyForAllMapTypes || url == Properties.Settings.Default.GoogleSatURL); // Edited by Shustrik - added variables for configuration settings other than Google quadcode = ""; for (int i = (int)g.Zoom - 1; i >= 0; i--) quadcode = quadcode + (((((g.Y >> i) & 1) << 1) + ((g.X >> i) & 1))); url = url.Replace("{X}", g.X.ToString()); url = url.Replace("{Y}", g.Y.ToString()); url = url.Replace("{Z}", ((int)g.Zoom).ToString()); url = url.Replace("{ZOOM}", ((int)g.Zoom).ToString()); url = url.Replace("{QUAD}", quadcode); url = url.Replace("{YAHOO_Y}", (((1 << ((int)g.Zoom)) >> 1)-1-g.Y).ToString()); url = url.Replace("{YAHOO_ZOOM}", ((int)g.Zoom + 1).ToString()); url = url.Replace("{YAHOO_ZOOM_2}", (17 - (int)g.Zoom + 1).ToString()); url = url.Replace("{OAM_ZOOM}", (17 - (int)g.Zoom).ToString()); url = url.Replace("{GOOG_DIGIT}", ((g.X+g.Y) & 3).ToString()); url = url.Replace("{GOOG_QUAD}", g.Quadtree); url = url.Replace("{MS_DIGITBR}", ((((g.Y & 1) << 1) + (g.X & 1)) + 1).ToString()); url = url.Replace("{MS_DIGIT}", ((((g.Y & 3) << 1) + (g.X & 1))).ToString()); url = url.Replace("{Y_DIGIT}", rand.Next(1, 3).ToString()); url = url.Replace("{GALILEO}", "Galileo".Substring(0, ((3 * g.X + g.Y) & 7))); // support old style {} vars url = url.Replace("QQQQ", g.Quadtree); url = url.Replace("XXXX", g.X.ToString()); url = url.Replace("YYYY", g.Y.ToString()); url = url.Replace("ZZZZ", (17 - (int)g.Zoom).ToString()); url = url.Replace("{OSM_ZOOM}", ((int)g.Zoom).ToString()); url = url.Replace("{MS_QUADCODE}", quadcode); url = url.Replace("*", rand.Next(4).ToString()); return url; }
public string BuildFileName(string tileType, GMapTile g) { string src_filename = Properties.Settings.Default.CacheFullPath; string prefix_MGMaps = "", prefix_file="", extension_file=""; if (g.Zoom > 22) return ""; if (Properties.Settings.Default.MGMapsMode && !src_filename.EndsWith(MGMapsCacheFolderName)) { src_filename = Path.Combine(src_filename, MGMapsCacheFolderName); } switch (tileType) { default: case "GoogleSat": case "GoogleSatH": prefix_MGMaps = "GoogleSat_"; prefix_file = "kh"; extension_file = ".jpg"; break; case "GoogleMap": prefix_MGMaps = tileType + "_"; prefix_file = "mt"; extension_file = ".png"; break; case "GoogleHyb": prefix_MGMaps = tileType + "_"; prefix_file = "tt"; extension_file = ".png"; break; case "GoogleTer": prefix_MGMaps = tileType + "_"; prefix_file = "gt"; extension_file = ".jpg"; break; case "GoogleChina": prefix_MGMaps = tileType + "_"; prefix_file = "gc"; extension_file = ".png"; break; case "MicrosoftMap": prefix_MGMaps = tileType + "_"; prefix_file = "mm"; extension_file = ".png"; break; case "MicrosoftSat": prefix_MGMaps = tileType + "_"; prefix_file = "ms"; extension_file = ".jpg"; break; case "MicrosoftHyb": prefix_MGMaps = tileType + "_"; prefix_file = "mh"; extension_file = ".png"; break; case "MicrosoftTer": prefix_MGMaps = tileType + "_"; prefix_file = "mr"; extension_file = ".png"; break; case "MicrosoftBrMap": prefix_MGMaps = tileType + "_"; prefix_file = "mb"; extension_file = ".png"; break; case "YahooMap": prefix_MGMaps = tileType + "_"; prefix_file = "ym"; extension_file = ".jpg"; break; case "YahooSat": case "YahooSatH": case "YahooSatH2": prefix_MGMaps = "YahooSat_"; prefix_file = "ys"; extension_file = ".jpg"; break; case "YahooHyb": prefix_MGMaps = tileType + "_"; prefix_file = "yh"; extension_file = ".png"; break; case "YahooInMap": prefix_MGMaps = tileType + "_"; prefix_file = "yi"; extension_file = ".jpg"; break; case "YahooInHyb": prefix_MGMaps = tileType + "_"; prefix_file = "yy"; extension_file = ".png"; break; case "OpenStreetMap": prefix_MGMaps = tileType + "_"; prefix_file = "om"; extension_file = ".png"; break; case "OSMARender": prefix_MGMaps = tileType + "_"; prefix_file = "os"; extension_file = ".png"; break; case "OpenAerialMap": prefix_MGMaps = tileType + "_"; prefix_file = "oa"; extension_file = ".jpg"; break; case "OpenCycleMap": prefix_MGMaps = tileType + "_"; prefix_file = "oc"; extension_file = ".png"; break; case "BrutMap": case "BrutMapSat": case "BrutMapSatH": case "BrutMapSH": prefix_MGMaps = ""; prefix_file = ""; extension_file = ""; break; case "BrutMapAndNav": case "BrutMapAndNavSat": case "BrutMapAndNavSatH": case "BrutMapAndNavSH": prefix_MGMaps = ""; prefix_file = ""; extension_file = ".png.andnav"; break; case "BrutMapHyb": case "BrutMapAndNavHyb": prefix_MGMaps = ""; prefix_file = ""; extension_file = ".png.andnav"; break; } if (Properties.Settings.Default.MGMapsMode) { if (tileType.Equals("BrutMap")) { src_filename = Path.Combine(src_filename, "BrutMaps"); src_filename = Path.Combine(src_filename, prefix_MGMaps + (g.Zoom + 1).ToString()); } else if (tileType.Equals("BrutMapSat") || tileType.Equals("BrutMapSatH")) { src_filename = Path.Combine(src_filename, "BrutMapsSat"); src_filename = Path.Combine(src_filename, prefix_MGMaps + (g.Zoom + 1).ToString()); } else if (tileType.Equals("BrutMapSH")) { src_filename = Path.Combine(src_filename, "BrutMapsSH"); src_filename = Path.Combine(src_filename, prefix_MGMaps + (g.Zoom + 1).ToString()); } else if (tileType.Equals("BrutMapHyb")) { src_filename = Path.Combine(src_filename, "BrutMapsHyb"); src_filename = Path.Combine(src_filename, prefix_MGMaps + (g.Zoom + 1).ToString()); } else if (tileType.Equals("BrutMapAndNav")) { src_filename = Path.Combine(src_filename, "BrutMapsAndNav"); src_filename = Path.Combine(src_filename, prefix_MGMaps + (g.Zoom).ToString()); } else if (tileType.Equals("BrutMapAndNavSat") || tileType.Equals("BrutMapAndNavSatH") ) { src_filename = Path.Combine(src_filename, "BrutMapsAndNavSat"); src_filename = Path.Combine(src_filename, prefix_MGMaps + (g.Zoom).ToString()); } else if (tileType.Equals("BrutMapAndNavSH")) { src_filename = Path.Combine(src_filename, "BrutMapsAndNavSH"); src_filename = Path.Combine(src_filename, prefix_MGMaps + (g.Zoom).ToString()); } else if (tileType.Equals("BrutMapAndNavHyb")) { src_filename = Path.Combine(src_filename, "BrutMapsAndNavHyb"); src_filename = Path.Combine(src_filename, prefix_MGMaps + (g.Zoom).ToString()); } else { src_filename = Path.Combine(src_filename, prefix_MGMaps + g.Zoom.ToString()); } if (Properties.Settings.Default.MGMapsHashSize != 1) src_filename = Path.Combine(src_filename, ((g.X * 256 + g.Y) % Properties.Settings.Default.MGMapsHashSize).ToString()); if (Properties.Settings.Default.MGMapsTilesPerFile == 1) if (tileType.Equals("BrutMap") || tileType.Equals("BrutMapSat") || tileType.Equals("BrutMapSatH") || tileType.Equals("BrutMapHyb") || tileType.Equals("BrutMapSH")) { src_filename = Path.Combine(src_filename, g.Y.ToString()); src_filename = Path.Combine(src_filename, String.Format("{0:d}", g.X)); } else if (tileType.Equals("BrutMapAndNav") || tileType.Equals("BrutMapAndNavSat") || tileType.Equals("BrutMapAndNavSatH") || tileType.Equals("BrutMapAndNavHyb") || tileType.Equals("BrutMapAndNavSH")) { src_filename = Path.Combine(src_filename, String.Format("{0:d}", g.X)); src_filename = Path.Combine(src_filename, g.Y.ToString() + extension_file); } else { src_filename = Path.Combine(src_filename, String.Format("{0:d}_{1:d}.mgm", g.X, g.Y)); } else src_filename = Path.Combine(src_filename, String.Format("{0:d}_{1:d}.mgm", g.X / tpfx, g.Y / tpfy)); } else { src_filename = Path.Combine(src_filename, prefix_file); src_filename = Path.Combine(src_filename, (g.Zoom + 1).ToString()); src_filename = Path.Combine(src_filename, g.Quadtree + extension_file); } string downloadedFilePath = Path.GetDirectoryName(src_filename); if (!Directory.Exists(downloadedFilePath)) { Directory.CreateDirectory(downloadedFilePath); } //check if conf file exists in (MGMaps) cache folder string MGMapsConfFileFullPath; if (Properties.Settings.Default.MGMapsHashSize == 1) MGMapsConfFileFullPath = Path.Combine(downloadedFilePath, "../" + MGMapsConfFilename); else MGMapsConfFileFullPath = Path.Combine(downloadedFilePath, "../../" + MGMapsConfFilename); if (Properties.Settings.Default.MGMapsMode && needToWriteCenter) { needToWriteCenter = false; //creates MGMaps cache .conf file double lat = (g.TopLat + g.BottomLat) / 2; double lng = (g.RightLong + g.LeftLong) / 2; File.AppendAllText(MGMapsConfFileFullPath, String.Format(MGMapsConfFileContent, Properties.Settings.Default.MGMapsTilesPerFile, Properties.Settings.Default.MGMapsHashSize, lat.ToString("0.000000", CultureInfo.InvariantCulture), lng.ToString("0.000000", CultureInfo.InvariantCulture), (g.Zoom < 1 ? 1 : g.Zoom), (tileType == "GoogleSatH" ? "GoogleHyb" : tileType == "YahooSatH" ? "YahooHyb" : tileType == "YahooSatH2" ? "YahooInHyb" : tileType == "BrutMapSatH" ? "BrutMapHyb" : tileType == "BrutMapAndNavSatH" ? "BrutMapAndNavHyb" : tileType)), Encoding.ASCII); } return src_filename; }
private void worker_DoWork(object sender, DoWorkEventArgs e) { #if DEBUG TextWriterTraceListener textWriterTraceListener = new TextWriterTraceListener("log.txt"); textWriterTraceListener.TraceOutputOptions = TraceOptions.DateTime; Debug.Listeners.Add(textWriterTraceListener); #endif // Get the BackgroundWorker that raised this event. BackgroundWorker worker = sender as BackgroundWorker; WorkerArguments arg = (WorkerArguments)e.Argument; if (arg.TopLeft.Zoom != arg.BottomRight.Zoom) { throw new ArgumentException(); } //gkl changes - commented this and put this code in saveButton_click, so as to do it only once //check if cache folder exists /*if (!Directory.Exists(Properties.Settings.Default.CacheFullPath)) { Directory.CreateDirectory(Properties.Settings.Default.CacheFullPath); }*/ BigImage bi = new BigImage(arg.TopLeft.Quadtree, arg.BottomRight.Quadtree, ReportProgressFunction, worker); bi.grayscale = Properties.Settings.Default.GrayScale; bi.tileTypeInt = Properties.Settings.Default.TileType; bi.dither8bpp = Properties.Settings.Default.Dither; if ((Properties.Settings.Default.OperatingMode == 0) || (Properties.Settings.Default.OperatingMode == 3) || (Properties.Settings.Default.OperatingMode == 4) || (Properties.Settings.Default.OperatingMode == 5) || (Properties.Settings.Default.OperatingMode == 6)) { bi.imageFormat = FreeImageAPI.FREE_IMAGE_FORMAT.FIF_UNKNOWN; } else { switch (Properties.Settings.Default.ImageFormat) { case "PNG": bi.imageFormat = FreeImageAPI.FREE_IMAGE_FORMAT.FIF_PNG; bi.saveflags = FreeImageAPI.FREE_IMAGE_SAVE_FLAGS.PNG_Z_DEFAULT_COMPRESSION; break; case "JPEG": bi.imageFormat = FreeImageAPI.FREE_IMAGE_FORMAT.FIF_JPEG; bi.saveflags = FreeImageAPI.FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYSUPERB; break; case "TIFF": bi.imageFormat = FreeImageAPI.FREE_IMAGE_FORMAT.FIF_TIFF; bi.saveflags = FreeImageAPI.FREE_IMAGE_SAVE_FLAGS.TIFF_PACKBITS; break; } } //gkl changes - added try/catch for InvalidOperationException exceptions thrown from TileDownloader try { bi.BuildBigImage(arg.Filename, this); } catch (InvalidOperationException ex) { if (this.Visible) { MainForm.ShowErrorBoxEx(ex.Message); } ReportProgressFunction(worker, "Stopped on error", 0); return; } if (worker.CancellationPending) { return; } if (Properties.Settings.Default.OperatingMode == 2) { ReportProgressFunction(worker, "Saving map", 0); OziExplorerMap oem = new OziExplorerMap(); oem.MapName = Path.GetFileName(arg.Filename); oem.ImageFileFullPath = arg.Filename; oem.ImageHeight = bi.ImageHeight; oem.ImageWidth = bi.ImageWidth; oem.OnePixelLength = arg.TopLeft.OnePixelLength; oem.ReferencePoints.Add(new MapReferencePoint(0, 0, arg.TopLeft.TopLat, arg.TopLeft.LeftLong)); oem.ReferencePoints.Add(new MapReferencePoint(bi.ImageWidth, bi.ImageHeight, arg.BottomRight.BottomLat, arg.BottomRight.RightLong)); oem.ReferencePoints.Add(new MapReferencePoint(0, bi.ImageHeight, arg.BottomRight.BottomLat, arg.TopLeft.LeftLong)); oem.ReferencePoints.Add(new MapReferencePoint(bi.ImageWidth, 0, arg.TopLeft.TopLat, arg.BottomRight.RightLong)); int YY = arg.BottomRight.Y - arg.TopLeft.Y; int XX = arg.BottomRight.X - arg.TopLeft.X; if ((XX > 1) && (YY > 1)) { double R = Math.Abs(((double)XX + 1.0) / ((double)YY + 1.0)); int NY = (int)Math.Sqrt(30.0 / R); int NX = 30 / NY; double stepY = (double)YY / Math.Min(YY, NY - 1); double stepX = (double)XX / Math.Min(XX, NX - 1); int y = 0; double dy = 0; for (; y <= YY; dy += stepY, y = (int)Math.Round(dy)) { int x = 0; double dx = 0; for (; x <= XX; dx += stepX, x = (int)Math.Round(dx)) { if (((x == 0) && (y == 0)) || ((x == 0) && (y == YY)) || ((x == XX) && (y == 0)) || ((x == XX) && (y == YY))) { continue; } GMapTile g = new GMapTile(arg.TopLeft.X + x, arg.TopLeft.Y + y, arg.TopLeft.Zoom); oem.ReferencePoints.Add(new MapReferencePoint(x * GMapTile.TILE_SIZE, y * GMapTile.TILE_SIZE, g.TopLat, g.LeftLong)); } } } oem.SaveToMap(Path.ChangeExtension(arg.Filename, ".map")); } if (Properties.Settings.Default.OperatingMode == 3 || Properties.Settings.Default.OperatingMode == 4 || Properties.Settings.Default.OperatingMode == 5 || Properties.Settings.Default.OperatingMode == 6) ReportProgressFunction(worker, "Download complete", 0.0); else ReportProgressFunction(worker, "Map saved", 20.0); }
internal void AddPhase(string phase, GMapTile topleft, GMapTile bottomright, string filename) { WorkerArguments arguments = new WorkerArguments(); arguments.TopLeft = topleft; arguments.BottomRight = bottomright; arguments.Filename = filename; //gkl changes - passed in phase as well arguments.Phase = phase; syncQueue.Enqueue(arguments); numPhases++; }