/// <summary> /// helps when image file was corrupted, arranges reload. /// </summary> /// <param name="tile"></param> /// <param name="baseName"></param> public static void resetBackdrop(TileTerra tile, string baseName) { string imageFileName = tileImagePath(baseName); try { if (Project.serverAvailable) { string imageUrl = getImageUrl(baseName); DownloadThread dt = new DownloadThread(); dt.DownloadUrl = imageUrl; dt.tile = tile; dt.baseName = baseName; dt.fileName = imageFileName; dt.CompleteCallback += new DownloadCompleteHandler(imageDownloadCompleteCallback); dt.ProgressCallback += new DownloadProgressHandler(imageDownloadProgressCallback); dt.addMonitoredMethod = new AddMonitoredMethod(ProgressMonitor.addMonitored); // tilesBeingLoadedCount++; //add dt worker method to the thread pool / queue a task //Project.threadPool.PostRequest (new WorkRequestDelegate (dt.Download), baseName); ThreadPool2.QueueUserWorkItem(new WaitCallback(dt.Download), baseName); #if DEBUG LibSys.StatusBar.Trace("OK: TerraserverCache:resetBackdrop() - tile '" + baseName + "' - loading remote from " + imageUrl); #endif } } catch (Exception e) { LibSys.StatusBar.Error("file '" + imageFileName + "' failed to load on reset: " + e.Message); } }
protected void queryDisconnected() { GeoCoord covTL = m_cameraManager.CoverageTopLeft; GeoCoord covBR = m_cameraManager.CoverageBottomRight; double marginY = m_retilingSpecial ? 0.0d : ((covBR.Lng - covTL.Lng) / 40.0d); double marginX = m_retilingSpecial ? 0.0d : ((covTL.Lat - covBR.Lat) / 40.0d * m_cameraManager.xScaleFactor); double covTL_Lng = covTL.Lng - marginX; double covTL_Lat = covTL.Lat + marginY; double covBR_Lng = covBR.Lng + marginX; double covBR_Lat = covBR.Lat - marginY; int currentZone = getZone(m_cameraManager.Location); LonLatPt lonlat = new LonLatPt(); lonlat.Lat = covTL_Lat; lonlat.Lon = covTL_Lng; UtmPt utmptTL = Projection.LonLatPtToUtmNad83Pt(lonlat); // can be in other than currentZone lonlat.Lat = covBR_Lat; lonlat.Lon = covBR_Lng; UtmPt utmptBR = Projection.LonLatPtToUtmNad83Pt(lonlat); // can be in other than currentZone if(utmptTL.Zone != currentZone) { lonlat.Lat = m_cameraManager.Location.Lat; lonlat.Lon = m_cameraManager.Location.Lng; UtmPt utmptCam = Projection.LonLatPtToUtmNad83Pt(lonlat); // can be in other than currentZone double dX = utmptBR.X - utmptCam.X; utmptTL.X = utmptCam.X - dX; utmptTL.Zone = currentZone; } else if(utmptBR.Zone != currentZone) { lonlat.Lat = m_cameraManager.Location.Lat; lonlat.Lon = m_cameraManager.Location.Lng; UtmPt utmptCam = Projection.LonLatPtToUtmNad83Pt(lonlat); // can be in other than currentZone double dX = utmptCam.X - utmptTL.X; utmptBR.X = utmptCam.X + dX; utmptBR.Zone = currentZone; } int iScale = (int)m_tileScale; int metersPerPixel = (1 << ((int) iScale - 10)); int factor = 200 * metersPerPixel; if(!firstSuperframe || xEnd - xStart == 0 || m_lastFactor == 0) { xStart = (int)Math.Floor(utmptTL.X / factor); yStart = (int)Math.Ceiling(utmptTL.Y / factor); xEnd = (int)Math.Ceiling(utmptBR.X / factor); yEnd = (int)Math.Floor(utmptBR.Y / factor); m_lastFactor = factor; } else { xStart = xStart * m_lastFactor / factor; yStart = yStart * m_lastFactor / factor; xEnd = xEnd * m_lastFactor / factor; yEnd = yEnd * m_lastFactor / factor; firstSuperframe = false; } int numTilesX = xEnd - xStart; int numTilesY = yStart - yEnd; // we need to remember UTM coordinates for Projection operation: m_scale = m_tileScale; m_metersPerPixel = (1 << ((Int32) m_scale - 10)); screenUtmZone = currentZone; screenUtmX = xStart * factor; screenUtmY = (yStart - 1) * factor; cleanTiles(); // dispose of previous tile array, if any m_hCount = numTilesX; m_vCount = numTilesY; UtmPt utmpt = new UtmPt(); utmpt.X = xStart * factor; utmpt.Y = yStart * factor; utmpt.Zone = currentZone; lonlat = Projection.UtmNad83PtToLonLatPt(utmpt); double topLeftLat = lonlat.Lat; double topLeftLng = lonlat.Lon; utmpt.X = (xStart + numTilesX) * factor; utmpt.Y = (yStart - numTilesY) * factor; lonlat = Projection.UtmNad83PtToLonLatPt(utmpt); double bottomRightLat = lonlat.Lat; double bottomRightLng = lonlat.Lon; m_tileResolutionDegreesH = Math.Abs(bottomRightLng - topLeftLng) / m_hCount; m_tileResolutionDegreesV = Math.Abs(bottomRightLat - topLeftLat) / m_vCount; #if DEBUG LibSys.StatusBar.Trace("m_tileResolutionDegreesH=" + m_tileResolutionDegreesH + " m_tileResolutionDegreesV=" + m_tileResolutionDegreesV); #endif int themeCode = getThemeCode(); lock(tilesLock) { m_tiles = new TileTerra[m_vCount, m_hCount]; SnapList snapLat = new SnapList(m_tileResolutionDegreesV, true); SnapList snapLng = new SnapList(m_tileResolutionDegreesH, true); int xx = (int)xStart; for(int hhh=0; hhh < m_hCount ;hhh++) { int yy = (int)yStart; for(int vvv=0; vvv < m_vCount ;vvv++) { utmpt.X = xx * factor; utmpt.Y = (yy) * factor; utmpt.Zone = currentZone; lonlat = Projection.UtmNad83PtToLonLatPt(utmpt); double tllat = lonlat.Lat; double tllng = lonlat.Lon; utmpt.X = (xx + 1) * factor; utmpt.Y = (yy - 1) * factor; lonlat = Projection.UtmNad83PtToLonLatPt(utmpt); double brlat = lonlat.Lat; double brlng = lonlat.Lon; GeoCoord tileTopLeft = new GeoCoord(tllng, tllat); GeoCoord tileBottomRight = new GeoCoord(brlng, brlat); String baseName = String.Format("T{0}-S{1}-Z{2}-X{3}-Y{4}", themeCode, (Int32)m_tileScale, currentZone, xx, (yy - 1)); //String baseName = "T" + themeCode + "-S" + (Int32)m_tileScale + "-Z" + currentZone + "-X" + xx + "-Y" + (yy - 1); if(!m_retilingSpecial) { // adding to snap lists prepares them for calculating snap points: snapLat.Add(tllat); snapLat.Add(brlat); snapLng.Add(tllng); snapLng.Add(brlng); } m_tiles[vvv, hhh] = new TileTerra(this, m_tileScale, tileTopLeft, tileBottomRight); m_tiles[vvv, hhh].baseName = baseName; m_tiles[vvv, hhh].init(); // gets backdrop, or starts the process of loading backdrop #if DEBUG //LibSys.StatusBar.Trace("[" + vvv + "," + hhh + "] " + baseName); //LibSys.StatusBar.Trace(" -- topLeft=" + tileTopLeft + " bottomRight=" + tileBottomRight); #endif yy--; } xx++; } // snap to the grid. If special retiling, distortion is ok: for(int vvv=0; !m_retilingSpecial && vvv < m_vCount ;vvv++) { for(int hhh=0; hhh < m_hCount ;hhh++) { TileTerra tile = m_tiles[vvv, hhh]; // snap the tile's corners to grid: tile.getBottomRight().X = snapLng.snap(tile.getBottomRight().X); tile.getBottomRight().Y = snapLat.snap(tile.getBottomRight().Y); tile.getTopLeft().X = snapLng.snap(tile.getTopLeft().X); tile.getTopLeft().Y = snapLat.snap(tile.getTopLeft().Y); } } // we need topleft tile for Projection: m_topLeftTile = m_tiles[0, 0]; calcRatios(); // compute resolution to display, meters per pixel, with overzoom indicator: double ratio = (m_ratioX + m_ratioY) / 2.0d; string overzoom = ("1m".Equals(m_tileScaleName) && ratio > 1.1d) ? " (overzoom)" : ""; hasRenderedTiles = true; m_placeDescription = "[" + abbMessage + "]"; m_formText = Project.PROGRAM_NAME_HUMAN + " - " + m_placeDescription + " " + m_tileScaleName + "/pixel * " + ratio + overzoom; // + " (" + m_tileScale + ")"; } // end lock #region old code relying on Tiles DB in TerraserverCache /* int iTheme = (int)m_curTheme; string where = "theme = " + iTheme + " AND scale = " + iScale + " AND name LIKE '%-Z" + currentZone + "-%'" + " AND brlng > " + covTL_Lng + " AND tllng <" + covBR_Lng + " AND brlat < " + covTL_Lat + " AND tllat > " + covBR_Lat; #if DEBUG LibSys.StatusBar.Trace("WHERE " + where); #endif // sort by name gives us rows sorted from bottom left up to top left (per line scan) all the way to top right - // like a TV scanning, turned on the left side. The Y coord axis goes up, the X - to the right. string sort = "name"; DataRow[] rows = TerraserverCache.TilesDS.Tables[0].Select(where, sort); // not all tiles may be present in the grid. Restore the grid structure: if(rows != null && rows.Length > 0) { // use the first tile for grid evaluation: int tileScale = (int)rows[0]["scale"]; double tllng = (double)rows[0]["tllng"]; double tllat = (double)rows[0]["tllat"]; double brlng = (double)rows[0]["brlng"]; double brlat = (double)rows[0]["brlat"]; m_tileResolutionDegreesH = Math.Abs(brlng - tllng); m_tileResolutionDegreesV = Math.Abs(brlat - tllat); #if DEBUG LibSys.StatusBar.Trace("tl=" + tllng + "," + tllat + " br=" + brlng + "," + brlat); LibSys.StatusBar.Trace("m_tileResolutionDegreesH=" + m_tileResolutionDegreesH + " m_tileResolutionDegreesV=" + m_tileResolutionDegreesV); LibSys.StatusBar.Trace("tile 0 -- topLeft=" + (new GeoCoord(tllng,tllat)) + " bottomRight=" + (new GeoCoord(brlng,brlat))); #endif // evaluate dimensions of tile matrix and corners of the tile-covered frame: double d; int hCount = 0; for (d=tllng; d > covTL.Lng ;d -= m_tileResolutionDegreesH) { //LibSys.StatusBar.Trace("working left -- topLeft=" + (new GeoCoord(d,tllat))); hCount++; } double topLeftLng = d; for (d=tllng; d < covBR.Lng ;d += m_tileResolutionDegreesH) { //LibSys.StatusBar.Trace("working right -- topLeft=" + (new GeoCoord(d,tllat))); hCount++; } double bottomRightLng = d; int vCount = 0; for (d=tllat; d < covTL.Lat ;d += m_tileResolutionDegreesV) { //LibSys.StatusBar.Trace("working up -- topLeft=" + (new GeoCoord(tllng, d))); vCount++; } double topLeftLat = d; for (d=tllat; d > covBR.Lat ;d -= m_tileResolutionDegreesV) { //LibSys.StatusBar.Trace("working down -- topLeft=" + (new GeoCoord(tllng, d))); vCount++; } double bottomRightLat = d; #if DEBUG LibSys.StatusBar.Trace("hCount=" + hCount + " vCount=" + vCount); LibSys.StatusBar.Trace("topLeft=" + topLeftLng + "," + topLeftLat + " bottomRight=" + bottomRightLng + "," + bottomRightLat); LibSys.StatusBar.Trace("topLeft=" + (new GeoCoord(topLeftLng,topLeftLat)) + " bottomRight=" + (new GeoCoord(bottomRightLng,bottomRightLat))); #endif cleanTiles(); // dispose of previous tile array, if any m_vCount = vCount+2; // make more cells for inperfections in tile corners. m_hCount = hCount+2; // extra tiles will be initialized as "empty". The order of the tiles is random. lock(tilesLock) { m_tiles = new TileTerra[m_vCount, m_hCount]; SnapList snapLat = new SnapList(m_tileResolutionDegreesV, true); SnapList snapLng = new SnapList(m_tileResolutionDegreesH, true); int vv = 0; int hh = 0; int rowCount = 0; foreach(DataRow row in rows) { string basename = (string)row["name"]; tileScale = (int)row["scale"]; tllng = (double)row["tllng"]; tllat = (double)row["tllat"]; brlng = (double)row["brlng"]; brlat = (double)row["brlat"]; // adding to snap lists prepares them for calculating snap points: snapLat.Add(tllat); snapLat.Add(brlat); snapLng.Add(tllng); snapLng.Add(brlng); // find the right position for the tile: // (turns out that order of tiles does not matter) // place the tile: GeoCoord tileTopLeft = new GeoCoord(tllng, tllat, 0.0d); GeoCoord tileBottomRight = new GeoCoord(brlng, brlat, 0.0d); m_tiles[vv, hh] = new TileTerra(this, (Scale)tileScale, tileTopLeft, tileBottomRight); #if DEBUG LibSys.StatusBar.Trace(" ----- tile: " + basename + " --- tl=" + tllng + "," + tllat + " br=" + brlng + "," + brlat); #endif m_tiles[vv, hh].baseName = basename; m_tiles[vv, hh].init(); // gets backdrop, or starts the process of loading backdrop if(++rowCount >= m_hCount * m_vCount) { // no matter what, we don't want to overflow the array and get an exception. Shouldn't happen though. LibSys.StatusBar.Error("too many tiles in rowset"); break; } hh++; if(hh >= m_hCount) { hh = 0; vv++; } // adjust frame corners to eliminate rounding errors, if possible: topLeftLng = Math.Min(topLeftLng, tllng); topLeftLat = Math.Max(topLeftLat, tllat); bottomRightLng = Math.Max(bottomRightLng, brlng); bottomRightLat = Math.Min(bottomRightLat, brlat); //break; } m_cameraManager.terraTopLeft = new GeoCoord(topLeftLng, topLeftLat); m_cameraManager.terraBottomRight = new GeoCoord(bottomRightLng, bottomRightLat); // make sure there are no null tiles in the array: tllng = topLeftLng; tllat = topLeftLat; brlng = tllng + m_tileResolutionDegreesH; brlat = tllat - m_tileResolutionDegreesV; for(int vvv=0; vvv < m_vCount ;vvv++) { for(int hhh=0; hhh < m_hCount ;hhh++) { TileTerra tile = m_tiles[vvv, hhh]; if(tile == null) { GeoCoord tileTopLeft = new GeoCoord(snapLng.snap(tllng), snapLat.snap(tllat), 0.0d); GeoCoord tileBottomRight = new GeoCoord(snapLng.snap(brlng), snapLat.snap(brlat), 0.0d); m_tiles[vvv, hhh] = new TileTerra(this, (Scale)tileScale, tileTopLeft, tileBottomRight); m_tiles[vvv, hhh].baseName = "empty"; tile = m_tiles[vvv, hhh]; //m_tiles[vvv, hhh].init(); // gets backdrop, or starts the process of loading backdrop } else { // snap the tile's corners to grid: tile.getBottomRight().X = snapLng.snap(tile.getBottomRight().X); tile.getBottomRight().Y = snapLat.snap(tile.getBottomRight().Y); tile.getTopLeft().X = snapLng.snap(tile.getTopLeft().X); tile.getTopLeft().Y = snapLat.snap(tile.getTopLeft().Y); } // we need topleft tile for Projection: if(m_topLeftTile == null || tile.getTopLeft().X <= m_topLeftTile.getTopLeft().X && tile.getTopLeft().Y >= m_topLeftTile.getTopLeft().Y) { m_topLeftTile = tile; } tllng += m_tileResolutionDegreesH; brlng += m_tileResolutionDegreesH; } tllat -= m_tileResolutionDegreesV; brlat -= m_tileResolutionDegreesV; } } // end lock // compute parameters for Projection: Rectangle tileRect = m_topLeftTile.getFrameRectangle(); m_ratioX = ((double)tileRect.Width - 1.5d) / 200.0d; // -1.5 corrects added 1 in getFrameRectangle(), and probability of rounding m_ratioY = ((double)tileRect.Height - 1.5d) / 200.0d; m_offsetX = tileRect.X; m_offsetY = tileRect.Y; // compute resolution to display, meters per pixel, with overzoom indicator: double ratio = (m_ratioX + m_ratioY) / 2.0d; string overzoom = ("1m".Equals(m_tileScaleName) && ratio > 1.1d) ? " (overzoom)" : ""; try { // compute UTMP reference values for Projection operation: screenUtmZone = currentZone; m_scale = (Scale)m_tileScale; m_metersPerPixel = (1 << ((Int32) m_scale - 10)); // we have to parse tile name here - something like T1-S16-Z17-X57-Y368 char[] sep = new Char[1] { '-' }; string[] split = m_topLeftTile.baseName.Split(sep); int utmX = Convert.ToInt32(split[3].Substring(1)); int utmY = Convert.ToInt32(split[4].Substring(1)); screenUtmX = (utmX * 200 * m_metersPerPixel); screenUtmY = (utmY * 200 * m_metersPerPixel); hasRenderedTiles = true; } catch {} m_placeDescription = "[" + abbMessage + "]"; m_formText = Project.PROGRAM_NAME_HUMAN + " - " + m_placeDescription + " " + m_tileScaleName + "/pixel * " + ratio + overzoom; // + " (" + m_tileScale + ")"; } else { // there are no tiles for this scale, but if we zoomed in the existing tiles may work. Make sure distortion is taken care of. try { // find which tile is now top-left (screen corner contained in this tile): Rectangle tileRect = new Rectangle(0, 0, 0, 0); for(int vvv=0; vvv < m_vCount ;vvv++) { for(int hhh=0; hhh < m_hCount ;hhh++) { TileTerra tile = m_tiles[vvv, hhh]; tileRect = tile.getFrameRectangle(); if(tileRect.Contains(0, 0)) { m_topLeftTile = tile; goto found; } } } goto notFound; found: // compute parameters for Projection: m_ratioX = ((double)tileRect.Width - 1.5d) / 200.0d; // -1.5 corrects added 1 in getFrameRectangle(), and probability of rounding m_ratioY = ((double)tileRect.Height - 1.5d) / 200.0d; m_offsetX = tileRect.X; m_offsetY = tileRect.Y; // compute resolution to display, meters per pixel, with overzoom indicator: double ratio = (m_ratioX + m_ratioY) / 2.0d; string overzoom = " (overzoom)"; // compute UTMP reference values for Projection operation: screenUtmZone = currentZone; m_metersPerPixel = (1 << ((Int32) m_scale - 10)); // we have to parse tile name here - something like T1-S16-Z17-X57-Y368 char[] sep = new Char[1] { '-' }; string[] split = m_topLeftTile.baseName.Split(sep); m_tileScale = (Scale)Convert.ToInt32(split[1].Substring(1)); m_scale = (Scale)m_tileScale; m_tileScaleName = scaleName(m_scale); int utmX = Convert.ToInt32(split[3].Substring(1)); int utmY = Convert.ToInt32(split[4].Substring(1)); screenUtmX = (utmX * 200 * m_metersPerPixel); screenUtmY = (utmY * 200 * m_metersPerPixel); hasRenderedTiles = true; m_placeDescription = "[" + abbMessage + "]"; m_formText = Project.PROGRAM_NAME_HUMAN + " - " + m_placeDescription + " " + m_tileScaleName + "/pixel * " + ratio + overzoom; // + " (" + m_tileScale + ")"; notFound: ; } catch {} } */ #endregion // Landmarks array was cleaned in the beginning of ReTile(). // now fill the landmarks from the database: string where = "lng > " + covTL_Lng + " AND lng <" + covBR_Lng + " AND lat < " + covTL_Lat + " AND lat > " + covBR_Lat; DataRow[] rows = TerraserverCache.LandmarksDS.Tables["lm"].Select(where); if(rows != null && rows.Length > 0) { int numLandmarks = rows.Length; if(numLandmarks > 0) { foreach(DataRow row in rows) { string name = (string)row["name"]; string type = (string)row["type"]; double lat = (double)row["lat"]; double lng = (double)row["lng"]; Landmark lm = new Landmark(name, new GeoCoord(lng, lat, 0.0d), type); TerraserverCache.AddLandmark(lm); } } } }
public void tileBackdropArrived(TileTerra tile) { // the backdrop may arrive when the tile has been phased out due to TileSetTerra.ReTile() // the tile then hangs around as a means to pass backdrop to TileSetTerra, which is supposed // to find appropriate location for the backdrop. bool found = false; #if DEBUG //LibSys.StatusBar.Trace("TileSetTerra::tileBackdropArrived() - " + tile.ToString()); #endif lock(tilesLock) { for(int vv=0; vv < m_vCount ;vv++) { for(int hh=0; hh < m_hCount ;hh++) { TileTerra tt = m_tiles[vv, hh]; // never null //LibSys.StatusBar.Trace(" = " + tt.baseName); if(tt == tile) { // tile still in the array #if DEBUG //LibSys.StatusBar.Trace(" - still in array : " + tt.baseName); #endif ArrangeBackdropRedraw(tt); found = true; } else if(tt.baseName.Equals(tile.baseName)) { // tile has been replaced by another tile with the same base name (due to ReTile()) #if DEBUG //LibSys.StatusBar.Trace(" - " + tt.baseName + " - replaced by " + tile.baseName + " " + tile.backdrop); #endif tt.backdrop = tile.backdrop; ArrangeBackdropRedraw(tt); found = true; } if(found) { goto endLoop; } } } endLoop: ; } // end lock // tile not found - bitmap/backdrop stays in file system and cache for the future. }
public void ArrangeBackdropRedraw(TileTerra tile) { try { //LibSys.StatusBar.Trace("TileSetTerra::ArrangeBackdropRedraw() - " + tile.ToString()); Rectangle tileRect = tile.getFrameRectangle(); //LibSys.StatusBar.Trace(" - tileRect " + tileRect); Rectangle toDrawRect = m_pictureManager.PictureBox.Bounds; //LibSys.StatusBar.Trace(" - toDrawRect " + toDrawRect); toDrawRect.Intersect(tileRect); //LibSys.StatusBar.Trace(" - " + tile.ToString() + " invalidating " + toDrawRect); m_pictureManager.Invalidate(toDrawRect); } catch {} }
// scaleIndex 0-24 from m_scales[], or -1 for automatic //private GeoCoord m_topLeftTileCorner = null; //private GeoCoord m_bottomRightTileCorner = null; private void ReTile(int scaleIndex) { #if DEBUG LibSys.StatusBar.Trace("IP: TileSetTerra.ReTile(" + scaleIndex + ") drawableReady=" + Project.drawableReady); #endif hasRenderedTiles = false; m_topLeftTile = null; abbMessage = "offline"; if(!Project.drawableReady) // when starting, we get several resize events with different sizes, as // layout settles. We want to ignore these and retile after the first paint. { return; } if(isPassiveSecond) { return; } lps = null; m_placeDescription = ""; Project.terraserverDisconnected = false; Project.terraserverAvailable = false; m_cameraManager.terraTopLeft = new GeoCoord(0.0d, 0.0d); // make sure we don't have stale values there for EarthquakesDisplayed m_cameraManager.terraBottomRight = new GeoCoord(0.0d, 0.0d); TerraserverCache.Landmarks.Clear(); if(!Project.drawTerraserver) { m_formText = Project.PROGRAM_NAME_HUMAN; return; } if(Project.terraserverUseServices) { // try to create ts and ls and to make connection, if they are missing: TerraserverCache.initTerraService(); if(TerraserverCache.ts == null) { // no connection, can't query terraserver data. Use disconnected mode. m_formText = Project.PROGRAM_NAME_HUMAN; Project.terraserverDisconnected = true; } } // what is the picture area in degrees? // use CameraManager.m_coverageXDegrees, m_coverageYDegrees for span in degrees if(m_isSecond) { m_curTheme = Theme.Topo; m_curThemeColor = false; } else { switch(Project.drawTerraserverMode) { default: case "aerial": m_curTheme = Theme.Photo; m_curThemeColor = false; break; case "color aerial": m_curTheme = Theme.Photo; m_curThemeColor = true; break; case "topo": m_curTheme = Theme.Topo; m_curThemeColor = false; break; case "relief": m_curTheme = Theme.Relief; m_curThemeColor = false; break; } } // what is appropriate tile resolution? if(!calcScale(scaleIndex)) { // sorry, no sense in aerial/topo at small scale if(Project.serverAvailable) { m_formText = Project.PROGRAM_NAME_HUMAN + " - [" + Project.drawTerraserverMode + " map not available at this scale]"; } else { m_formText = Project.PROGRAM_NAME_HUMAN + " - [" + abbMessage + "]"; } cleanTiles(); return; } // account for scaling of 200x200 pixel tiles into actual tile frame: m_imageWidth = (int)Math.Round(m_pictureManager.Width * m_cameraManager.MetersPerPixelX() * 1.1d / m_metersPerPixelTileExpected); m_imageHeight = (int)Math.Round(m_pictureManager.Height * m_cameraManager.MetersPerPixelY() * 1.1d / m_metersPerPixelTileExpected); if(Project.terraserverUseServices && Project.serverAvailable && scaleIndex == -1) { m_formText = Project.PROGRAM_NAME_HUMAN + " - reaching terraserver..."; setMainFormText(); queryTerraserver(); // will set Project.terraserverDisconnected on failure if(Project.terraserverDisconnected) { queryDisconnected(); } } else { if(Project.serverAvailable) { abbMessage = "no ws"; } queryDisconnected(); } #if DEBUG //LibSys.StatusBar.Trace("TileSetTerra:ReTile() ----------------- after " + TileCache.ToString()); #endif TerraserverCache.purge(); logCamtrackFrame(); if(m_needsRefresh) { m_needsRefresh = false; m_pictureManager.Refresh(); } }
protected void queryTerraserver() { LonLatPt centerPoint = new LonLatPt(); centerPoint.Lat = m_cameraManager.Location.Lat; centerPoint.Lon = m_cameraManager.Location.Lng; bool isValidAbb = false; int retriesMax = 2; #if DEBUG LibSys.StatusBar.Trace("IP: TileSetTerra.queryTerraserver() Fetching Area Bounding Box from TerraServer"); #endif bool canReuseAbb = false; try { if(abb != null && m_savedCurTheme == m_curTheme && m_savedCurThemeColor == m_curThemeColor && m_savedTileScale == m_tileScale && m_savedImageWidth == m_imageWidth && m_savedImageHeight == m_imageHeight && m_savedCenterPointLat == centerPoint.Lat && m_savedCenterPointLon == centerPoint.Lon) { canReuseAbb = true; isValidAbb = true; #if DEBUG LibSys.StatusBar.Trace("IP: TileSetTerra.queryTerraserver() reusing Area Bounding Box"); #endif } } catch {} int retries = 0; while (!canReuseAbb && retries <= retriesMax && Project.serverAvailable) { try { abb = TerraserverCache.ts.GetAreaFromPt(centerPoint, (int)m_curTheme, m_tileScale, m_imageWidth, m_imageHeight); #if DEBUG LibSys.StatusBar.Trace("IP: TileSetTerra.queryTerraserver() Got the Area Bounding Box from TerraServer"); #endif // make a real quick sanity check of acquired abb here: isValidAbb = abb != null; if(isValidAbb) { TileMeta tmm = abb.Center.TileMeta; if(tmm.Capture.CompareTo(date1970) < 0) { m_placeDescription = abb.NearestPlace; abbMessage = (m_placeDescription == null ? "" : (m_placeDescription + " - ")) + "this area not covered by Terraserver"; isValidAbb = false; break; } } // react if abb is invalid: if(isValidAbb) { abbMessage = "terraserver reached"; break; } else if (retries++ < retriesMax) { #if DEBUG LibSys.StatusBar.Error("TileSetTerra.queryTerraserver() while getting abb, retry # " + retries + " abb=null"); #endif continue; } else { abbMessage = "terraserver not reached"; warningCantReachServer(""); break; } } catch (Exception ie) { if (retries++ < retriesMax) { #if DEBUG LibSys.StatusBar.Error("TileSetTerra.queryTerraserver() while getting abb, retry # " + retries + " " + ie.Message); #endif // compensate for currently present bug around Seattle: if(ie.Message.IndexOf("There is an error in XML document") >= 0) { abbMessage = "terraserver ws failed"; break; } continue; } else { abbMessage = "terraserver not reached"; warningCantReachServer(ie.Message); break; } } } if(!isValidAbb) { LibSys.StatusBar.Error("TileSetTerra.queryTerraserver() couldn't get abb - working offline [" + abbMessage + "]"); Project.terraserverDisconnected = true; cleanTiles(); m_formText = Project.PROGRAM_NAME_HUMAN + " - [" + Project.drawTerraserverMode + " map not available - " + abbMessage + "]"; abb = null; return; } m_savedCurTheme = m_curTheme; m_savedCurThemeColor = m_curThemeColor; m_savedTileScale = m_tileScale; m_savedImageWidth = m_imageWidth; m_savedImageHeight = m_imageHeight; m_savedCenterPointLat = centerPoint.Lat; m_savedCenterPointLon = centerPoint.Lon; // calculate abb corners geo coordinates, keeping in mind that not all corner tiles exist (actually all four may be missing): double topLeftLng = 0.0d; double topLeftLat = 0.0d; double bottomRightLng = 0.0d; double bottomRightLat = 0.0d; if(abb.NorthWest.TileMeta.TileExists) { topLeftLng = abb.NorthWest.TileMeta.NorthWest.Lon; topLeftLat = abb.NorthWest.TileMeta.NorthWest.Lat; } else { if(abb.SouthWest.TileMeta.TileExists) { topLeftLng = abb.SouthWest.TileMeta.NorthWest.Lon; if(abb.NorthEast.TileMeta.TileExists) { topLeftLat = abb.NorthEast.TileMeta.NorthEast.Lat; } else { // both top corners are missing, go get the top lat by Utm to LonLat conversion: LonLatPt llpt = getTopLeftByTileId(abb.NorthWest.TileMeta.Id); topLeftLat = llpt.Lat; } } else { // both left side corners are missing, go get the top left corner by Utm to LonLat conversion: LonLatPt llpt = getTopLeftByTileId(abb.NorthWest.TileMeta.Id); topLeftLng = llpt.Lon; topLeftLat = llpt.Lat; } } if(abb.SouthEast.TileMeta.TileExists) { bottomRightLng = abb.SouthEast.TileMeta.SouthEast.Lon; bottomRightLat = abb.SouthEast.TileMeta.SouthEast.Lat; } else { if(abb.NorthEast.TileMeta.TileExists) { bottomRightLng = abb.NorthEast.TileMeta.SouthEast.Lon; if(abb.SouthWest.TileMeta.TileExists) { bottomRightLat = abb.SouthWest.TileMeta.SouthWest.Lat; } else { // both bottom corners are missing, go get the bottom lat by Utm to LonLat conversion: LonLatPt llpt = getBottomRightByTileId(abb.SouthEast.TileMeta.Id); bottomRightLat = llpt.Lat; } } else { // both right side corners are missing, go get the bottom right corner by Utm to LonLat conversion: LonLatPt llpt = getBottomRightByTileId(abb.SouthEast.TileMeta.Id); bottomRightLng = llpt.Lon; bottomRightLat = llpt.Lat; } } // more sanity check - in unlikely case we were unable to figure out abb corners: if(topLeftLng == 0.0d || topLeftLat == 0.0d || bottomRightLng == 0.0d || bottomRightLat == 0.0d) { abbMessage = "response from terraserver cannot be mapped"; LibSys.StatusBar.Error("TileSetTerra.queryTerraserver() couldn't get abb - working offline [" + abbMessage + "]"); Project.terraserverDisconnected = true; cleanTiles(); m_formText = Project.PROGRAM_NAME_HUMAN + " - [" + Project.drawTerraserverMode + " map not available - " + abbMessage + "]"; return; } m_placeDescription = abb.NearestPlace; TileMeta tm = abb.Center.TileMeta; /* if(tm.Capture.CompareTo(date1970) < 0) { // we won't get here as date is checked before, in sanity check m_placeDescription += " [" + Project.drawTerraserverMode + " map]"; } else { */ m_placeDescription += " [" + Project.drawTerraserverMode + " map from " + tm.Capture.ToString("D", null) + "]"; //} #if DEBUG LibSys.StatusBar.Trace("IP: retrieved info for " + m_placeDescription); #endif m_scale = abb.Center.TileMeta.Id.Scale; m_metersPerPixel = (1 << ((Int32) m_scale - 10)); int factor = 200 * m_metersPerPixel; m_lastFactor = factor; // even if a corner tile does not exist, the Id is filled with valid information: xStart = abb.NorthWest.TileMeta.Id.X; int yyStart = abb.NorthWest.TileMeta.Id.Y; // actually superframe is computed in offline mode, so the saved xStart...yEnd values will be used in queryDisconnected() yStart = yyStart + 1; xEnd = abb.NorthEast.TileMeta.Id.X + 1; int yyEnd = abb.SouthWest.TileMeta.Id.Y; yEnd = yyEnd; // we need to remember UTMP coordinates for Projection operation: screenUtmZone = abb.Center.TileMeta.Id.Scene; screenUtmX = xStart * factor; screenUtmY = yyStart * factor; cleanTiles(); // dispose of previous tile array, if any m_hCount = xEnd - xStart; m_vCount = yyStart - yyEnd + 1; #if DEBUG LibSys.StatusBar.Trace("TileSetTerra:queryTerraserver() m_vCount=" + m_vCount + " m_hCount=" + m_hCount); #endif int themeCode = getThemeCode(); lock(tilesLock) { m_tiles = new TileTerra[m_vCount, m_hCount]; #if DEBUG LibSys.StatusBar.Trace("TileSetTerra:queryTerraserver() ----------------- before " + TileCache.ToString()); #endif GeoCoord covTL = m_cameraManager.CoverageTopLeft; GeoCoord covBR = m_cameraManager.CoverageBottomRight; m_cameraManager.terraTopLeft = new GeoCoord(topLeftLng, topLeftLat); m_cameraManager.terraBottomRight = new GeoCoord(bottomRightLng, bottomRightLat); m_tileResolutionDegreesH = Math.Abs(bottomRightLng - topLeftLng) / m_hCount; m_tileResolutionDegreesV = Math.Abs(bottomRightLat - topLeftLat) / m_vCount; #if DEBUG LibSys.StatusBar.Trace("abb: topleft=" + topLeftLat + "," + topLeftLng + " bottomRight=" + bottomRightLat + "," + bottomRightLng); LibSys.StatusBar.Trace(" : m_tileResolutionDegreesH=" + m_tileResolutionDegreesH + " m_tileResolutionDegreesV=" + m_tileResolutionDegreesV); #endif SnapList snapLat = new SnapList(m_tileResolutionDegreesV, true); SnapList snapLng = new SnapList(m_tileResolutionDegreesH, true); int x = 0; int y = 0; int vv = 0; int hh = 0; // for corners of the current tile: double tileTopLeftLng = topLeftLng; double tileBottomRightLng = tileTopLeftLng + m_tileResolutionDegreesH; double tileTopLeftLat; double tileBottomRightLat; TileId tid = new TileId(); // we need to clone abb.NorthWest.TileMeta.Id and leave abb intact for ( x = xStart; hh < m_hCount; x++, hh++) { vv = 0; tileTopLeftLat = topLeftLat; tileBottomRightLat = tileTopLeftLat - m_tileResolutionDegreesV; for ( y = yyStart; vv < m_vCount; y--, vv++) { tid.X = x; tid.Y = y; tid.Scale = abb.NorthWest.TileMeta.Id.Scale; tid.Scene = abb.NorthWest.TileMeta.Id.Scene; tid.Theme = (int)m_curTheme; // why isn't Theme already set? String baseName = String.Format("T{0}-S{1}-Z{2}-X{3}-Y{4}", themeCode, (Int32)tid.Scale, tid.Scene, tid.X, tid.Y); //String baseName = "T" + themeCode + "-S" + (Int32)tid.Scale + "-Z" + tid.Scene + "-X" + tid.X + "-Y" + tid.Y; // adding to snap lists prepares them for calculating snap points: snapLat.Add(tileTopLeftLat); snapLat.Add(tileBottomRightLat); snapLng.Add(tileTopLeftLng); snapLng.Add(tileBottomRightLng); GeoCoord tileTopLeft = new GeoCoord(tileTopLeftLng, tileTopLeftLat, 0.0d); GeoCoord tileBottomRight = new GeoCoord(tileBottomRightLng, tileBottomRightLat, 0.0d); m_tiles[vv, hh] = new TileTerra(this, m_tileScale, tileTopLeft, tileBottomRight); m_tiles[vv, hh].baseName = baseName; m_tiles[vv, hh].init(); // gets backdrop, or starts the process of loading backdrop #if DEBUG //LibSys.StatusBar.Trace("[" + vv + "," + hh + "] " + baseName); //LibSys.StatusBar.Trace(" -- topLeft=" + tileTopLeft + " bottomRight=" + tileBottomRight); #endif // we know a lot about this tile now. // register the tile with local database for disconnected operation. // it may turn out to be a cottage cheese or non-arrival though, and the registration would stay there. //TerraserverCache.registerTerraTile(baseName, m_curTheme, m_tileScale, tileTopLeft, tileBottomRight); tileTopLeftLat -= m_tileResolutionDegreesV; tileBottomRightLat -= m_tileResolutionDegreesV; } tileTopLeftLng += m_tileResolutionDegreesH; tileBottomRightLng += m_tileResolutionDegreesH; } // snap to the grid (corrects small gaps at maximum zoom): for(int vvv=0; vvv < m_vCount ;vvv++) { for(int hhh=0; hhh < m_hCount ;hhh++) { TileTerra tile = m_tiles[vvv, hhh]; // snap the tile's corners to grid: tile.getBottomRight().X = snapLng.snap(tile.getBottomRight().X); tile.getBottomRight().Y = snapLat.snap(tile.getBottomRight().Y); tile.getTopLeft().X = snapLng.snap(tile.getTopLeft().X); tile.getTopLeft().Y = snapLat.snap(tile.getTopLeft().Y); } } // we need topleft tile for Projection: m_topLeftTile = m_tiles[0, 0]; Project.terraserverAvailable = true; } // end lock calcRatios(); hasRenderedTiles = true; // compute visible magnification ratio: double ratio = (m_ratioX + m_ratioY) / 2.0d; string overzoom = ("1m".Equals(m_tileScaleName) && ratio > 1.1d) ? " (overzoom)" : ""; m_formText = Project.PROGRAM_NAME_HUMAN + " - " + m_placeDescription + " " + m_tileScaleName + "/pixel x" + ratio + overzoom; // + " (" + m_tileScale + ")"; if(Project.drawLandmarks) { TerraserverCache.initLandmarkService(); if(TerraserverCache.ls != null && TerraserverCache.landmarkPointTypes != null && TerraserverCache.landmarkPointTypes.Length > 0) { // retrieve lanfdmarks information: BoundingRect br = new BoundingRect(); LonLatPt tmp = abb.SouthEast.TileMeta.SouthEast; br.LowerRight = new LibNet.LandmarkServer.LonLatPt(); br.LowerRight.Lon = tmp.Lon; br.LowerRight.Lat = tmp.Lat; tmp = abb.NorthWest.TileMeta.NorthWest; br.UpperLeft = new LibNet.LandmarkServer.LonLatPt(); br.UpperLeft.Lon = tmp.Lon; br.UpperLeft.Lat = tmp.Lat; m_hasPutOnMap = false; bool isValidLps = false; retries = 0; //string[] types = new string[] { "Building", "Cemetery", "Church", "Encarta Article", // "Golf Course", "Hospital", "Institution", "Landmark", "Locale", // "Parks", "Populated Place", "Recreation Area", "Retail Center", // "Stream Gauge", "Summit", "Transportation Terminal", "Unknown Type" }; /* string[] types = new string[] { "Building", "Cemetery", "Church", "Encarta Article", "Golf Course", "Hospital", "Landmark", "Locale", "Parks", "Populated Place", "Retail Center", "Stream Gauge", "Summit", "Transportation Terminal", "Unknown Type"}; */ // as of May 31,03 , "Institution" and "Recreation Area" cause exception: // Server was unable to process request. --> Data is Null. This method or property cannot be called on Null values. // see TerraserverCache:295 correcting this. /* string[] types = new string[TerraserverCache.landmarkPointTypes.Length]; for(int i=0; i < types.Length ;i++) { types[i] = "" + TerraserverCache.landmarkPointTypes[i]; } */ while (retries <= retriesMax) { try { lps = TerraserverCache.ls.GetLandmarkPointsByRect(br, TerraserverCache.landmarkPointTypes); // ,types); // make a sanity check of acquired lps here: isValidLps = lps != null; break; } catch (Exception e) { if (retries == retriesMax) { MessageBox.Show("Unable to get landmark information" + e.Message, "TerraService Error"); break; } else { retries++; } } catch { if (retries == retriesMax) { MessageBox.Show("Unable to get landmark information", "TerraService Error"); break; } else { retries++; } } } if (isValidLps) { int lpsCount = lps.Length; foreach (LandmarkPoint lp in lps) { GeoCoord location = new GeoCoord(lp.Point.Lon, lp.Point.Lat); string name = lp.Name; string type = lp.Type; Landmark lm = new Landmark(name, location, type); TerraserverCache.AddLandmark(lm); // to ArrayList, for this immediate display TerraserverCache.RegisterLandmark(lm); // add to DataSet, for disconnected operation } } } } }
public static void AddTerraTile(string baseName, double lngPerTile, double latPerTile, TileTerra tile) { if(snapLat == null) { snapLng = new SnapList(lngPerTile, false); snapLat = new SnapList(latPerTile, false); } if(!CameraTrack.camTrackTerraTiles.Contains(baseName)) { CameraTrack.camTrackTerraTiles.Add(baseName); // adding to snap lists prepares them for calculating snap points: GeoCoord tl = tile.getTopLeft(); GeoCoord br = tile.getBottomRight(); snapLat.Add(tl.Lat); snapLat.Add(br.Lat); snapLng.Add(tl.Lng); snapLng.Add(br.Lng); } }
private static void imageDownloadCompleteCallback(object otile, DownloadInfo info, string imageFileName, byte[] dataDownloaded) { #if DEBUG LibSys.StatusBar.Trace("IP: TerraserverCache:imageDownloadCompleteCallback() - " + info.baseName + " " + (dataDownloaded == null? "null" : "" + dataDownloaded.Length) + " bytes loaded"); #endif // tilesBeingLoadedCount = tilesBeingLoadedCount > 0 ? tilesBeingLoadedCount - 1 : 0; Backdrop backdrop = (Backdrop)m_backdropCache[info.baseName]; TileTerra tile = (TileTerra)otile; // can be null for preload if (dataDownloaded == null || dataDownloaded.Length < 100 || Project.is404(dataDownloaded)) { string comment = dataDownloaded == null ? "no data" : "404"; if (backdrop != null) { backdrop.IsEmpty = true; // proven empty } ProgressMonitor.markComplete(info.monitored, false, comment); } /* * else if(dataDownloaded.Length == 8321) // cottage cheese * { * string comment = "cottage cheese tile"; * backdrop.IsEmpty = true; // proven empty * tile.IsCottageCheese = true; * ProgressMonitor.markComplete(info.monitored, false, comment); * } */ else { FileStream fs = null; try { string comment = "" + dataDownloaded.Length + " bytes"; if (dataDownloaded.Length == 8321) // cottage cheese { if (tile != null) { tile.IsCottageCheese = true; } comment = "cottage cheese tile"; } fs = new FileStream(imageFileName, FileMode.Create); fs.Write(dataDownloaded, 0, dataDownloaded.Length); fs.Close(); fs = null; #if DEBUG LibSys.StatusBar.Trace("OK: file " + imageFileName + " created"); #endif if (backdrop != null) { backdrop.Fill(); } ProgressMonitor.markComplete(info.monitored, true, comment); } catch (Exception e) { #if DEBUG LibSys.StatusBar.Error("" + e.Message); #endif if (backdrop != null) { backdrop.IsEmpty = true; // proven empty } ProgressMonitor.markComplete(info.monitored, false, e.Message); } finally { if (fs != null) { fs.Close(); } } } if (tile != null) { tile.backdropArrived(backdrop); } }
public static Backdrop getBackdrop(TileTerra tile, string baseName) { string imageFileName = tileImagePath(baseName); Backdrop ret = null; try { if (m_backdropCache.ContainsKey(baseName)) { ret = (Backdrop)m_backdropCache[baseName]; // may be IsEmpty, if proven that can't download ret.MarkUsed(); //LibSys.StatusBar.Trace("OK: TerraserverCache:getBackdrop() - tile '" + baseName + "' - found in cache - " + ret); return(ret); } bool loadedFromFile = false; if (!Project.reloadRefresh && File.Exists(imageFileName)) { try { ret = new Backdrop(imageFileName, baseName, true); //LibSys.StatusBar.Trace("OK: TerraserverCache:getBackdrop() - tile '" + baseName + "' - loaded from file"); AddBackdrop(baseName, ret); loadedFromFile = true; } catch {} } if (!loadedFromFile && Project.serverAvailable) { string imageUrl = getImageUrl(baseName); if (!m_backdropCache.ContainsKey(baseName)) { ret = new Backdrop(imageFileName, baseName, false); // fill later AddBackdrop(baseName, ret); DownloadThread dt = new DownloadThread(); dt.DownloadUrl = imageUrl; dt.tile = tile; dt.baseName = baseName; dt.fileName = imageFileName; dt.CompleteCallback += new DownloadCompleteHandler(imageDownloadCompleteCallback); dt.ProgressCallback += new DownloadProgressHandler(imageDownloadProgressCallback); dt.addMonitoredMethod = new AddMonitoredMethod(ProgressMonitor.addMonitored); // tilesBeingLoadedCount++; //add dt worker method to the thread pool / queue a task //Project.threadPool.PostRequest (new WorkRequestDelegate (dt.Download), baseName); ThreadPool2.QueueUserWorkItem(new WaitCallback(dt.Download), baseName); #if DEBUG LibSys.StatusBar.Trace("OK: TerraserverCache:getBackdrop() - tile '" + baseName + "' - loading remote from " + imageUrl); #endif } else { //LibSys.StatusBar.Trace("OK: TerraserverCache:getBackdrop() - tile '" + baseName + "' - already in cache"); } } } catch (Exception e) { LibSys.StatusBar.Error("file '" + imageFileName + "' failed to load: " + e.Message); } // whatever happened before, returning null is not an option. if (ret == null) { ret = new Backdrop(null, baseName, true); // doFill with null name makes it Empty AddBackdrop(baseName, ret); } return(ret); }
/// <summary> /// helps when image file was corrupted, arranges reload. /// </summary> /// <param name="tile"></param> /// <param name="baseName"></param> public static void resetBackdrop(TileTerra tile, string baseName) { string imageFileName = tileImagePath(baseName); try { if(Project.serverAvailable) { string imageUrl = getImageUrl(baseName); DownloadThread dt = new DownloadThread(); dt.DownloadUrl = imageUrl; dt.tile = tile; dt.baseName = baseName; dt.fileName = imageFileName; dt.CompleteCallback += new DownloadCompleteHandler( imageDownloadCompleteCallback ); dt.ProgressCallback += new DownloadProgressHandler( imageDownloadProgressCallback ); dt.addMonitoredMethod = new AddMonitoredMethod(ProgressMonitor.addMonitored); // tilesBeingLoadedCount++; //add dt worker method to the thread pool / queue a task //Project.threadPool.PostRequest (new WorkRequestDelegate (dt.Download), baseName); ThreadPool2.QueueUserWorkItem (new WaitCallback (dt.Download), baseName); #if DEBUG LibSys.StatusBar.Trace("OK: TerraserverCache:resetBackdrop() - tile '" + baseName + "' - loading remote from " + imageUrl); #endif } } catch (Exception e) { LibSys.StatusBar.Error("file '" + imageFileName + "' failed to load on reset: " + e.Message); } }
public static Backdrop getBackdrop(TileTerra tile, string baseName) { string imageFileName = tileImagePath(baseName); Backdrop ret = null; try { if(m_backdropCache.ContainsKey(baseName)) { ret = (Backdrop)m_backdropCache[baseName]; // may be IsEmpty, if proven that can't download ret.MarkUsed(); //LibSys.StatusBar.Trace("OK: TerraserverCache:getBackdrop() - tile '" + baseName + "' - found in cache - " + ret); return ret; } bool loadedFromFile = false; if(!Project.reloadRefresh && File.Exists(imageFileName)) { try { ret = new Backdrop(imageFileName, baseName, true); //LibSys.StatusBar.Trace("OK: TerraserverCache:getBackdrop() - tile '" + baseName + "' - loaded from file"); AddBackdrop(baseName, ret); loadedFromFile = true; } catch {} } if(!loadedFromFile && Project.serverAvailable) { string imageUrl = getImageUrl(baseName); if(!m_backdropCache.ContainsKey(baseName)) { ret = new Backdrop(imageFileName, baseName, false); // fill later AddBackdrop(baseName, ret); DownloadThread dt = new DownloadThread(); dt.DownloadUrl = imageUrl; dt.tile = tile; dt.baseName = baseName; dt.fileName = imageFileName; dt.CompleteCallback += new DownloadCompleteHandler( imageDownloadCompleteCallback ); dt.ProgressCallback += new DownloadProgressHandler( imageDownloadProgressCallback ); dt.addMonitoredMethod = new AddMonitoredMethod(ProgressMonitor.addMonitored); // tilesBeingLoadedCount++; //add dt worker method to the thread pool / queue a task //Project.threadPool.PostRequest (new WorkRequestDelegate (dt.Download), baseName); ThreadPool2.QueueUserWorkItem (new WaitCallback (dt.Download), baseName); #if DEBUG LibSys.StatusBar.Trace("OK: TerraserverCache:getBackdrop() - tile '" + baseName + "' - loading remote from " + imageUrl); #endif } else { //LibSys.StatusBar.Trace("OK: TerraserverCache:getBackdrop() - tile '" + baseName + "' - already in cache"); } } } catch (Exception e) { LibSys.StatusBar.Error("file '" + imageFileName + "' failed to load: " + e.Message); } // whatever happened before, returning null is not an option. if(ret == null) { ret = new Backdrop(null, baseName, true); // doFill with null name makes it Empty AddBackdrop(baseName, ret); } return ret; }
public static void AddTerraTile(string baseName, double lngPerTile, double latPerTile, TileTerra tile) { if (snapLat == null) { snapLng = new SnapList(lngPerTile, false); snapLat = new SnapList(latPerTile, false); } if (!CameraTrack.camTrackTerraTiles.Contains(baseName)) { CameraTrack.camTrackTerraTiles.Add(baseName); // adding to snap lists prepares them for calculating snap points: GeoCoord tl = tile.getTopLeft(); GeoCoord br = tile.getBottomRight(); snapLat.Add(tl.Lat); snapLat.Add(br.Lat); snapLng.Add(tl.Lng); snapLng.Add(br.Lng); } }