예제 #1
0
        public void init()
        {
            GeoCoord topLeft = m_topLeft.Clone();
            topLeft.Normalize();
            GeoCoord bottomRight = m_bottomRight.Clone();
            bottomRight.Normalize();

            int iLat = (int)Math.Ceiling(topLeft.Lat);
            int iLng = (int)Math.Floor(topLeft.Lng);
            m_siLng = iLng;
            m_siLat = iLat;
            if(m_tileScale.Equals("z"))
            {
                // HACK:
                // compensate for the shift in z-level tiles
                // (their names point to the center, not the top left corner:
                iLat -= 2;
                iLng += 2;
            }
            string latDir = iLat < 0 ? "s" : "n";
            string lngDir = iLng < 0 ? "w" : "e";
            iLat = Math.Abs(iLat);
            iLng = Math.Abs(iLng);

            switch(m_tileScale)
            {
                case "w":
                    m_level = 0;
                    m_baseName = "world_good";
                    break;
                case "y":
                    m_level = 1;
                    if(iLat == 60 && latDir.Equals("s"))
                    {
                        m_tileBackdrop = null;
                        return;
                    }
                    else
                    {
                        string sLng = ("" + iLng).PadLeft(3,'0');
                        string sLat = "" + iLat;
                        m_baseName = m_tileScale + sLng + lngDir + sLat + latDir;
                    }
                    break;
                case "x":
                    m_level = 2;
                    m_baseName = m_tileScale + iLng + lngDir + iLat + latDir;
                    break;
                case "z":
                    m_level = 3;
                    m_baseName = m_tileScale + iLng + lngDir + iLat + latDir;
                    break;
                default:
                    m_level = 4;
                    iLat = (int)Math.Floor(bottomRight.Lat);
                    iLng = (int)Math.Ceiling(bottomRight.Lng);
                    if(iLng == -180)
                    {
                        // edge correction needed around Lng=180
                        iLng = 180;
                    }
                    latDir = iLat < 0 ? "s" : "n";
                    lngDir = iLng <= 0 ? "w" : "e";
                    m_siLng = iLng;
                    m_siLat = iLat;
                    iLat = Math.Abs(iLat);
                    iLng = Math.Abs(iLng);
                    m_baseName = m_tileScale + iLng + lngDir + iLat + latDir;
                    break;
                case "a":
                    m_level = 5;
                    iLat = (int)Math.Floor(bottomRight.Lat);
                    iLng = (int)Math.Ceiling(bottomRight.Lng);
                    if(iLng == -180)
                    {
                        // edge correction needed around Lng=180
                        iLng = 180;
                    }
                    latDir = iLat < 0 ? "s" : "n";
                    lngDir = iLng <= 0 ? "w" : "e";
                    m_siLng = iLng;
                    m_siLat = iLat;
                    iLat = Math.Abs(iLat);
                    iLng = Math.Abs(iLng);
                    // figure out quadrant and correct the tile scale letter:
                    double ty = topLeft.Lat - Math.Floor(topLeft.Lat);
                    double tx = topLeft.Lng - Math.Floor(topLeft.Lng);

                    if(ty > 0.01d && tx > 0.01d)
                    {
                        m_tileScale = "d";
                        m_aShiftX = 1;
                        m_aShiftY = 1;
                    }
                    else if(tx > 0.01d)
                    {
                        m_tileScale = "b";
                        m_aShiftX = 1;
                    }
                    else if(ty > 0.01d)
                    {
                        m_tileScale = "c";
                        m_aShiftY = 1;
                    }
                    m_baseName = m_tileScale + iLng + lngDir + iLat + latDir;
                    break;
            }

            if(MayUseSubstitute)
            {
                // calculate substitute backdrop parameters, just in case real backdrop will be missing:
                int substLat = (int)Math.Floor(bottomRight.Lat);
                if(substLat >= 0)
                {
                    substLat = substLat / 10 + 1;
                }
                else if(substLat < 0 && substLat >= -10)
                {
                    substLat = 0;
                    latDir = "n";
                }
                else
                {
                    substLat = (int)Math.Ceiling(bottomRight.Lat + 0.0001d);
                    substLat = substLat / 10;
                }
                substLat = substLat * 10;

                int substLng = (int)Math.Ceiling(bottomRight.Lng);
                if(substLng > 0)
                {
                    substLng = (int)Math.Floor(topLeft.Lng);
                    substLng = substLng / 10;
                }
                else if(substLng == 0)
                {
                    // edge correction needed around Lng=0
                    substLng = 1;
                }
                else if(substLng == -180)
                {
                    // edge correction needed around Lng=180
                    substLng = 17;
                }
                else
                {
                    substLng = substLng / 10 - 1;
                }
                substLng = substLng * 10;

                m_substLng = substLng;
                m_substLat = substLat;
                substLat = Math.Abs(substLat);
                substLng = Math.Abs(substLng);
                m_substituteName = "x" + substLng + lngDir + substLat + latDir;
            #if DEBUG
                LibSys.StatusBar.Trace("Tile::init() m_substituteName=" + m_substituteName);
                LibSys.StatusBar.Trace("siLng=" + m_siLng + " m_substLng=" + m_substLng + " siLat=" + m_siLat + " m_substLat=" + m_substLat);
            #endif
            }

            //LibSys.StatusBar.Trace("Tile:init() baseName=" + m_baseName);
            m_tileBackdrop = TileCache.getBackdrop(this, m_baseName);		// may be Empty, never null
            if(m_tileBackdrop.IsEmpty)
            {
                // unlikely, but we may know immediately that we need to use substitute, if feasible:
                if(MayUseSubstitute)
                {
                    // get substitute backdrop:
                    m_useSubstitute = true;
                    //LibSys.StatusBar.Trace("Tile::init() - requesting backdrop substitute " + m_substituteName);
                    m_tileBackdrop = TileCache.getBackdrop(this, m_substituteName);	// may be Empty, never null
                    if(m_tileBackdrop.IsEmpty)
                    {
                        m_isEmpty = true;
                    }
                    else if(m_tileBackdrop.HasImage)
                    {
                        CalculateSubstituteRectangle();  // may instead set IsEmpty
                    }
                    // else wait for arrival...
                }
                else
                {
                    m_isEmpty = true;
                }
            }
            m_tileFeatures = TileCache.getFeatures(this, m_baseName);		// may be Empty, never null
            if(m_tileFeatures.IsEmpty)
            {
                // unlikely, but we may know immediately that we need to use substitute, if feasible:
                if(MayUseSubstitute)
                {
                    // get substitute features:
            #if DEBUG
                    LibSys.StatusBar.Trace("Tile::init() - requesting features substitute " + m_substituteName);
            #endif
                    m_tileFeatures = TileCache.getFeatures(this, m_substituteName);	// may be Empty, never null
                    if(m_tileFeatures.HasLoaded)
                    {
                        CreateFeaturesSubset();
                        ProvokeFeaturesPutOnMap();		// provoke PutOnMap on the next Tile_Paint()
                    }
                    else
                    {
            #if DEBUG
                        LibSys.StatusBar.Trace("Tile::init() - " + m_baseName + " - features hasn't loaded -  nothing to copy...");
            #endif
                    }
                    // wait for arrival...
                }
            }
            else
            {
                ProvokeFeaturesPutOnMap();		// provoke PutOnMap on the next Tile_Paint()
            }
        }
예제 #2
0
 public void featuresArrived(Features features)
 {
     // the Features may arrive when this tile has been phased out due to TileSet.ReTile()
     // this tile then hangs around as a means to pass Features to TileSet, which is supposed
     // to find appropriate location for the Features.
     #if DEBUG
     LibSys.StatusBar.Trace("featuresArrived() - features=" + features);
     #endif
     m_tileFeatures = features;
     if(m_tileFeatures.IsEmpty)
     {
         // more likely, need to use substitute is discovered here.
         if(MayUseSubstitute)
         {
             // get substitute features:
     #if DEBUG
             LibSys.StatusBar.Trace("Tile::featuresArrived() - requesting substitute " + m_substituteName);
     #endif
             m_tileFeatures = TileCache.getFeatures(this, m_substituteName);	// may be Empty, never null
             if(m_tileFeatures.IsEmpty)
             {
     #if DEBUG
                 LibSys.StatusBar.Trace("Tile::featuresArrived() - got empty substitute " + m_substituteName);
     #endif
             }
             else
             {
     #if DEBUG
                 LibSys.StatusBar.Trace("Tile::featuresArrived() - copying relevant features");
     #endif
                 CreateFeaturesSubset();
                 ProvokeFeaturesPutOnMap();		// provoke PutOnMap on the next Tile_Paint()
             }
         }
     }
     else
     {
         ProvokeFeaturesPutOnMap();		// provoke PutOnMap on the next Tile_Paint()
     }
     m_tileSet.tileFeaturesArrived(this);
 }
예제 #3
0
 public void Dispose()
 {
     //LibSys.StatusBar.Trace("Tile:Dispose() baseName=" + m_baseName);
     if(m_tileBackdrop != null)
     {
         TileCache.BackdropMarkUnused(m_baseName);
         m_tileBackdrop = null;
     }
     if(m_tileFeatures != null)
     {
         TileCache.FeaturesMarkUnused(m_baseName);
         m_tileFeatures = null;
     }
 }
예제 #4
0
        /// <summary>
        /// for substitute tiles - 
        /// makes a subset of features out of existing features, adds it to cache (under this tile name), 
        /// so the next time this tile is called a cache-resident subset is ready for use
        /// </summary>
        public void CreateFeaturesSubset()
        {
            Features tileFeatures = TileCache.getFeatures(this, m_baseName);
            if(!m_tileFeatures.HasLoaded)
            {
            #if DEBUG
                LibSys.StatusBar.Trace("IP: Tile::CreateFeaturesSubset() - " + m_baseName + " - not loaded yet " + m_tileFeatures);
            #endif
                return;
            }
            if(tileFeatures.HasLoaded)
            {
            #if DEBUG
                LibSys.StatusBar.Trace("IP: Tile::CreateFeaturesSubset() - " + m_baseName + " - found in cache " + tileFeatures);
            #endif
            }
            else
            {
                GeoCoord bottomRight = m_bottomRight.Clone();
                bottomRight.Normalize();
                GeoCoord topLeft = m_topLeft.Clone();
                topLeft.Normalize();
                double rightLng = bottomRight.Lng;
                double leftLng = topLeft.Lng;
                if(rightLng <= -180.0d)
                {
                    rightLng += 360.0d;
                }
                double bottomLat = bottomRight.Lat;
                double topLat = topLeft.Lat;

                //LibSys.StatusBar.Trace("IP: Tile::CreateFeaturesSubset() - " + m_baseName + " - copying features related to lng:" + leftLng + "<" + rightLng + " lat:" + bottomLat + "<" + topLat + " from " + m_tileFeatures.BaseName);

                // we are not cloning the lo assuming that lo's belonging to a tile are not reappearing
                // in any other tile. That also means that we need to cut selection rectangles correctly.

                foreach(LiveObject lo in m_tileFeatures.List)
                {
                    if(lo.Location.Lat <= topLat && lo.Location.Lat >= bottomLat
                        && lo.Location.Lng >= leftLng && lo.Location.Lng <= rightLng)
                    {
                        try
                        {
                            //LibSys.StatusBar.WriteLine(" --- " + lo);
                            tileFeatures.Add(lo);
                        }
                        catch (Exception e)
                        {
                        }
                    }
                }

                tileFeatures.HasLoaded = true;
                tileFeatures.IsEmpty = false;
            }
            m_tileFeatures = tileFeatures;
            //LibSys.StatusBar.Trace("OK: Tile::CreateFeaturesSubset() - " + m_baseName + " result: " + m_tileFeatures);
            //TileCache.ListFeaturesCache();
        }
예제 #5
0
 public static void AddFeatures(string baseName, Features f)
 {
     try
     {
         m_featuresCache.Add(baseName, f);
     }
     catch (Exception e)
     {
     }
 }
예제 #6
0
        public static Features getFeatures(Tile tile, string baseName)
        {
            string featuresFileName = Path.Combine(m_mapsPath, baseName + featuresExt);

            Features ret = null;
            try
            {
                if(m_featuresCache.ContainsKey(baseName))
                {
                    ret = (Features)m_featuresCache[baseName];	// may be still downloading
                    if(ret != null)
                    {
                        ret.MarkUsed();
                    }
            #if DEBUG
                    LibSys.StatusBar.Trace("OK: TileCache:getFeatures() - tile '" + baseName + "' - found in cache - " + ret);
            #endif
                    return ret;
                }

                bool loadedFromFile = false;
                if(!Project.reloadRefresh && File.Exists(featuresFileName))
                {
                    try
                    {
                        ret = new Features(featuresFileName, baseName, true);
            #if DEBUG
                        LibSys.StatusBar.Trace("OK: TileCache:getFeatures() - tile '" + baseName + "' - loaded local");
            #endif
                        AddFeatures(baseName, ret);
                        loadedFromFile = true;
                    }
                    catch {}
                }

                if(!loadedFromFile && m_mappingServers.Count > 0)
                {
                    string featuresUrl = getFileUrl(tile, baseName, featuresFileName);

                    if(featuresUrl == null)
                    {
                        ret = new Features(null, baseName, true);	// doFill with null name makes it Empty
                        AddFeatures(baseName, ret);
                        return ret;
                    }

                    if(!m_featuresCache.ContainsKey(baseName))
                    {
                        ret = new Features(featuresFileName, baseName, false);	// fill later
                        AddFeatures(baseName, ret);

                        DownloadThread dt = new DownloadThread();
                        dt.DownloadUrl = featuresUrl;
                        dt.tile = tile;
                        dt.baseName = baseName;
                        dt.fileName = featuresFileName;
                        dt.CompleteCallback += new DownloadCompleteHandler( featuresDownloadCompleteCallback );
                        dt.ProgressCallback += new DownloadProgressHandler( featuresDownloadProgressCallback );
                        dt.addMonitoredMethod = new AddMonitoredMethod(ProgressMonitor.addMonitored);

                        //add this to the thread pool / queue a task
                        //Project.threadPool.PostRequest (new WorkRequestDelegate (dt.Download));
                        ThreadPool2.QueueUserWorkItem (new WaitCallback (dt.Download), baseName);

            #if DEBUG
                        LibSys.StatusBar.Trace("OK: TileCache:getFeatures() - tile '" + baseName + "' - loading remote from " + featuresUrl);
            #endif
                    }
                }
            }
            catch (Exception e)
            {
                LibSys.StatusBar.Error("file '" + featuresFileName + "' failed to load: " + e.Message);
            }
            // whatever happened before, returning null is not an option.
            if(ret == null)
            {
                ret = new Features(null, baseName, true);	// doFill with null name makes it Empty
                AddFeatures(baseName, ret);
            }
            return ret;
        }