/// <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(); }
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); }
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() } }