Пример #1
0
        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);
                    }
                }
            }
        }
Пример #2
0
 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);
     }
 }
Пример #3
0
        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
                        }
                    }
                }
            }
        }
Пример #4
0
        public void init()
        {
            m_camtrackFolderPath = Project.GetCleanCamtrackFolder();	// removes content of the folder, if any

            m_descrFilePath = Path.Combine(m_camtrackFolderPath, DESCR_FILE_NAME + ".xml");

            string seedXml = "<camtrack/>";
            xmlDoc.LoadXml(seedXml);
            root = xmlDoc.DocumentElement;
            m_currentFrameNode = null;

            CameraTrack.camTrackTerraTiles.Clear();
            snapLng = null;	// will be allocated as the first tile arrives
            snapLat = null;
        }