public GeoCoord toGeoLocation(Point point, bool isPrint) { GeoCoord ret = new GeoCoord(0.0d, 0.0d); double pX, pY; if(isPrint) { double offsetX = m_offsetXPrint / m_ratioXPrint; double offsetY = m_offsetYPrint / m_ratioYPrint; // this would be pixel screen coord if there were no scaling: pX = point.X / m_ratioXPrint - offsetX; // tile pixels before scaling pY = - point.Y / m_ratioYPrint + offsetY + 200; } else { double offsetX = m_offsetX / m_ratioX; // tile pixels before scaling double offsetY = m_offsetY / m_ratioY; // this would be pixel screen coord if there were no scaling: pX = point.X / m_ratioX - offsetX; // tile pixels before scaling pY = - point.Y / m_ratioY + offsetY + 200; } // now calculate it in meters and offset the screen UTM pX = pX * m_metersPerPixel + screenUtmX; pY = pY * m_metersPerPixel + screenUtmY; UtmPt utmpt = new UtmPt(); utmpt.X = pX; utmpt.Y = pY; utmpt.Zone = screenUtmZone; LonLatPt lonlat = Projection.UtmNad83PtToLonLatPt(utmpt); ret.Lat = lonlat.Lat; ret.Lng = lonlat.Lon; return ret; }
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); } } } }
// goes to terraserver for UTM to LonLat conversion -- not any more: private LonLatPt getBottomRightByTileId(TileId tid) { UtmPt utm = new UtmPt(); utm.Zone = tid.Scene; int metersPerPixel = (1 << ((int) tid.Scale - 10)); // lower right: utm.X = (tid.X + 1) * 200 * metersPerPixel - 1; utm.Y = tid.Y * 200 * metersPerPixel; LonLatPt llpt = Projection.UtmNad83PtToLonLatPt(utm); //TerraserverCache.ts.ConvertUtmPtToLonLatPt(utm); return llpt; }
// goes to terraserver for UTM to LonLat conversion -- not any more: private LonLatPt getTopLeftByTileId(TileId tid) { // from http://terraserver.microsoft.net/about.aspx?n=AboutTerraServiceOverview (select Data Structures link): // Most TerraServer image tiles are in the UTM NAD 83 projection system. // The Scale, Scene, X, and Y fields can be used to compute the UTM NAD 83 coordinates // for the lower left hand pixel in the TerraServer tile (XOffset=0 and YOffset=200). // The following formulas are required to compute the UTM NAD 83 for the lower left hand pixel: // Int32 UtmZone = Scene; // Int32 metersPerPixel = (1 << ((Int32) Scale - 10)); // Int32 UtmEasting = X * 200 * metersPerPixel; // Int32 UtmNorthing = Y * 200 * metersPerPixel; UtmPt utm = new UtmPt(); utm.Zone = tid.Scene; int metersPerPixel = (1 << ((int) tid.Scale - 10)); // top left: utm.X = tid.X * 200 * metersPerPixel; utm.Y = (tid.Y + 1) * 200 * metersPerPixel - 1; LonLatPt llpt = Projection.UtmNad83PtToLonLatPt(utm); //TerraserverCache.ts.ConvertUtmPtToLonLatPt(utm); return llpt; }
/// <summary> /// this is complete cut-and-paste from the above - keep them in sync /// </summary> /// <param name="obj"></param> private void listQueryDisconnected(Hashtable list) { int xStart = 0; int yStart = 0; int xEnd = 0; int yEnd = 0; int m_lastFactor = 0; GeoCoord covTL = m_coverageTopLeft; GeoCoord covBR = m_coverageBottomRight; double marginY = 0.0d; double marginX = 0.0d; 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 = TileSetTerra.getZone(m_coverageCenter); 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_coverageCenter.Lat; lonlat.Lon = m_coverageCenter.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_coverageCenter.Lat; lonlat.Lon = m_coverageCenter.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(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; } int numTilesX = xEnd - xStart; int numTilesY = yStart - yEnd; int hCount = numTilesX; int 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; int themeCode = getThemeCode(); int xx = (int)xStart; for(int hhh=0; hhh < hCount ;hhh++) { int yy = (int)yStart; for(int vvv=0; vvv < 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)); if(!list.ContainsKey(baseName)) { list.Add(baseName, null); } #if DEBUG //LibSys.StatusBar.Trace("[" + vvv + "," + hhh + "] " + baseName); //LibSys.StatusBar.Trace(" -- topLeft=" + tileTopLeft + " bottomRight=" + tileBottomRight); #endif yy--; } xx++; } }
/// <summary> /// this is somewhat cut-and-paste from its namesake from the TileSetTerra.cs keep them in sync /// </summary> /// <param name="obj"></param> private void _queryDisconnected(object obj) { int xStart = 0; int yStart = 0; int xEnd = 0; int yEnd = 0; int m_lastFactor = 0; GeoCoord covTL = m_coverageTopLeft; GeoCoord covBR = m_coverageBottomRight; double marginY = 0.0d; double marginX = 0.0d; 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 = TileSetTerra.getZone(m_coverageCenter); 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_coverageCenter.Lat; lonlat.Lon = m_coverageCenter.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_coverageCenter.Lat; lonlat.Lon = m_coverageCenter.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(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; } int numTilesX = xEnd - xStart; int numTilesY = yStart - yEnd; int hCount = numTilesX; int 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; int themeCode = getThemeCode(); int xx = (int)xStart; for(int hhh=0; hhh < hCount ;hhh++) { int yy = (int)yStart; for(int vvv=0; vvv < 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)); if(TerraserverCache.TileNamesCollection != null) { if(!TerraserverCache.TileNamesCollection.ContainsKey(baseName)) { TerraserverCache.TileNamesCollection.Add(baseName, null); } } lock(m_duplicates) { if(!m_duplicates.ContainsKey(baseName)) { TerraserverCache.downloadIfMissing(baseName); m_duplicates.Add(baseName, null); } } #if DEBUG //LibSys.StatusBar.Trace("[" + vvv + "," + hhh + "] " + baseName); //LibSys.StatusBar.Trace(" -- topLeft=" + tileTopLeft + " bottomRight=" + tileBottomRight); #endif yy--; } xx++; } int totalCount = TileSetTerraLayout.DuplicatesCount; int newCount = ThreadPool2.WaitingCallbacks; if(newCount == 0) { LibSys.StatusBar.Trace("*Preload tiles: nothing to download - all " + totalCount + " tiles already in cache."); } else { if(newCount <= totalCount) { LibSys.StatusBar.Trace("*Preload tiles: trying to download " + newCount + " new of total " + totalCount + " tiles"); } else { LibSys.StatusBar.Trace("*Preload tiles: trying to download " + newCount + " new tiles"); } } }
/// <remarks/> public void ConvertUtmPtToLonLatPtAsync(UtmPt utm, object userState) { if ((this.ConvertUtmPtToLonLatPtOperationCompleted == null)) { this.ConvertUtmPtToLonLatPtOperationCompleted = new System.Threading.SendOrPostCallback(this.OnConvertUtmPtToLonLatPtOperationCompleted); } this.InvokeAsync("ConvertUtmPtToLonLatPt", new object[] { utm}, this.ConvertUtmPtToLonLatPtOperationCompleted, userState); }
/// <remarks/> public void ConvertUtmPtToLonLatPtAsync(UtmPt utm) { this.ConvertUtmPtToLonLatPtAsync(utm, null); }
/// <remarks/> public System.IAsyncResult BeginConvertUtmPtToLonLatPt(UtmPt utm, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("ConvertUtmPtToLonLatPt", new object[] { utm}, callback, asyncState); }
public LonLatPt ConvertUtmPtToLonLatPt(UtmPt utm) { object[] results = this.Invoke("ConvertUtmPtToLonLatPt", new object[] { utm}); return ((LonLatPt)(results[0])); }
// IMainCommand implementation: public bool fromUtmString(string text, out double lng, out double lat) { bool ret = false; lng = 0.0d; lat = 0.0d; try { // UTM = 11S E433603 N3778359 char[] sep = new Char[] { ' ' }; string[] split = text.Split(sep); string sZ = split[0]; string sE = split[1]; string sN = split[2]; if(sZ.ToUpper().EndsWith("S")) { sZ = sZ.Substring(0, sZ.Length - 1); } if(sE.ToUpper().EndsWith("E")) { sE = sE.Substring(0, sE.Length - 1); } if(sN.ToUpper().EndsWith("N")) { sN = sN.Substring(0, sN.Length - 1); } UtmPt utmpt = new UtmPt(); utmpt.Zone = Convert.ToInt32(sZ); utmpt.X = Convert.ToDouble(sE); utmpt.Y = Convert.ToDouble(sN); LonLatPt pt = Projection.UtmNad83PtToLonLatPt(utmpt); lat = pt.Lat; lng = pt.Lon; ret = true; } catch {} return ret; }