Exemplo n.º 1
0
 // 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;
 }
Exemplo n.º 2
0
        // 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;
        }
Exemplo n.º 3
0
 /// <remarks/>
 public void GetTileAsync(TileId id, object userState) {
     if ((this.GetTileOperationCompleted == null)) {
         this.GetTileOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetTileOperationCompleted);
     }
     this.InvokeAsync("GetTile", new object[] {
                 id}, this.GetTileOperationCompleted, userState);
 }
Exemplo n.º 4
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
                        }
                    }
                }
            }
        }
Exemplo n.º 5
0
 /// <remarks/>
 public System.IAsyncResult BeginGetTile(TileId id, System.AsyncCallback callback, object asyncState) {
     return this.BeginInvoke("GetTile", new object[] {
                 id}, callback, asyncState);
 }
Exemplo n.º 6
0
 /// <remarks/>
 public void GetTileAsync(TileId id) {
     this.GetTileAsync(id, null);
 }
Exemplo n.º 7
0
 /// <remarks/>
 public void GetTileMetaFromTileIdAsync(TileId id) {
     this.GetTileMetaFromTileIdAsync(id, null);
 }
Exemplo n.º 8
0
 public byte[] GetTile(TileId id) {
     object[] results = this.Invoke("GetTile", new object[] {
                 id});
     return ((byte[])(results[0]));
 }
Exemplo n.º 9
0
 public TileMeta GetTileMetaFromTileId(TileId id) {
     object[] results = this.Invoke("GetTileMetaFromTileId", new object[] {
                 id});
     return ((TileMeta)(results[0]));
 }
Exemplo n.º 10
0
 /// <remarks/>
 public void GetAreaFromTileIdAsync(TileId id, int displayPixWidth, int displayPixHeight, object userState) {
     if ((this.GetAreaFromTileIdOperationCompleted == null)) {
         this.GetAreaFromTileIdOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetAreaFromTileIdOperationCompleted);
     }
     this.InvokeAsync("GetAreaFromTileId", new object[] {
                 id,
                 displayPixWidth,
                 displayPixHeight}, this.GetAreaFromTileIdOperationCompleted, userState);
 }
Exemplo n.º 11
0
 /// <remarks/>
 public void GetAreaFromTileIdAsync(TileId id, int displayPixWidth, int displayPixHeight) {
     this.GetAreaFromTileIdAsync(id, displayPixWidth, displayPixHeight, null);
 }
Exemplo n.º 12
0
 /// <remarks/>
 public System.IAsyncResult BeginGetAreaFromTileId(TileId id, int displayPixWidth, int displayPixHeight, System.AsyncCallback callback, object asyncState) {
     return this.BeginInvoke("GetAreaFromTileId", new object[] {
                 id,
                 displayPixWidth,
                 displayPixHeight}, callback, asyncState);
 }
Exemplo n.º 13
0
 public AreaBoundingBox GetAreaFromTileId(TileId id, int displayPixWidth, int displayPixHeight) {
     object[] results = this.Invoke("GetAreaFromTileId", new object[] {
                 id,
                 displayPixWidth,
                 displayPixHeight});
     return ((AreaBoundingBox)(results[0]));
 }