Exemple #1
0
 public bool FindTileInMask(Mask m, bool pngTileOnly, ref TileXY txy)
 {
     foreach (KeyValuePair <TileXY, TileMeta> pair in tiles)
     {
         if (!m.ContainsTile(pair.Key))
         {
             continue;
         }
         if (!pngTileOnly || pair.Value.hasAlpha)
         {
             txy = pair.Key;
             while (true)
             {
                 bool     hasParent = false;
                 TileXY[] parents   = txy.GetParent().GetSiblings();
                 for (int i = 0; i < 4; i++)
                 {
                     if (m.ContainsTile(parents[i]) && tiles.ContainsKey(parents[i]) && (!pngTileOnly || tiles[parents[i]].hasAlpha))
                     {
                         txy       = parents[i];
                         hasParent = true;
                         break;
                     }
                 }
                 if (!hasParent || txy.level == 0)
                 {
                     break;
                 }
             }
             return(true);
         }
     }
     return(false);
 }
Exemple #2
0
        /// <summary>
        /// check if this mask contains a tile
        /// </summary>
        /// <param name="tilexy"></param>
        /// <returns></returns>
        public bool ContainsTile(TileXY tilexy)
        {
            double lat, lon;

            BingProjection.PixelXYToLatLong((int)tilexy.x * 256, (int)tilexy.y * 256, (int)tilexy.level, out lat, out lon);
            if (!ContainsLatLon(lat, lon))
            {
                return(false);
            }

            BingProjection.PixelXYToLatLong((int)tilexy.x * 256 + 256, (int)tilexy.y * 256, (int)tilexy.level, out lat, out lon);
            if (!ContainsLatLon(lat, lon))
            {
                return(false);
            }

            BingProjection.PixelXYToLatLong((int)tilexy.x * 256, (int)tilexy.y * 256 + 256, (int)tilexy.level, out lat, out lon);
            if (!ContainsLatLon(lat, lon))
            {
                return(false);
            }

            BingProjection.PixelXYToLatLong((int)tilexy.x * 256 + 256, (int)tilexy.y * 256 + 256, (int)tilexy.level, out lat, out lon);
            if (!ContainsLatLon(lat, lon))
            {
                return(false);
            }

            return(true);
        }
Exemple #3
0
        public void MoveTo(int offsetx, int offsety, bool isZoomOut, bool isZoomIn)
        {
            // get target location
            TileXY targetXY = centerTilexy;

            if (isZoomOut)
            {
                targetXY = centerTilexy.GetParent();
            }
            else if (isZoomIn)
            {
                TileXY[] sons = centerTilexy.GetSon().GetSiblings();
                foreach (TileXY txy in sons)
                {
                    targetXY = txy;
                    if (tiles.ContainsKey(targetXY))
                    {
                        break;
                    }
                }
            }
            else
            {
                targetXY = centerTilexy.GetNeighbor(offsetx, offsety);
            }

            // move the center and paint
            centerTilexy = targetXY;
            Paint();
        }
Exemple #4
0
        private PointD GetLonLat(Point pixelOffset, TileXY tilexy)
        {
            double lat, lon;

            BingProjection.PixelXYToLatLong(tilexy.x * 256 + pixelOffset.X, tilexy.y * 256 + pixelOffset.Y, (int)tilexy.level, out lat, out lon);
            return(new PointD(lon, lat));
        }
Exemple #5
0
        public bool ContainsTilePixel(TileXY tilexy, Point pixelOffset)
        {
            double lat, lon;

            BingProjection.PixelXYToLatLong((int)tilexy.x * 256 + pixelOffset.X, (int)tilexy.y * 256 + pixelOffset.Y, (int)tilexy.level, out lat, out lon);
            return(ContainsLatLon(lat, lon) ? true : false);
        }
Exemple #6
0
 public Point[] GetUtmCorrectedRelativePolygon(TileXY tilexy, int zone)
 {
     double[] input  = new double[4];
     double[] result = new double[8];
     input[0] = box.top;
     input[1] = box.right;
     input[2] = box.bottom;
     input[3] = box.left;
     for (int i = 0; i < 4; i++)
     {
         input[i] = input[i] * Math.PI / 180;
     }
     MUtilities.LatLonRectangleExpandByUtm(zone, input, result);
     for (int i = 0; i < 8; i++)
     {
         result[i] = result[i] * 180 / Math.PI;
     }
     Point[] points = new Point[4];
     points[0] = BingProjection.LatLongToPixelXY(result[0], result[1], tilexy.level);
     points[1] = BingProjection.LatLongToPixelXY(result[2], result[3], tilexy.level);
     points[2] = BingProjection.LatLongToPixelXY(result[4], result[5], tilexy.level);
     points[3] = BingProjection.LatLongToPixelXY(result[6], result[7], tilexy.level);
     for (int i = 0; i < 4; i++)
     {
         points[i].X -= tilexy.x * 256;
         points[i].Y -= tilexy.y * 256;
     }
     return(points);
 }
Exemple #7
0
        public static string TileXYToLatLong(TileXY tilexy)
        {
            double lat, lon;

            PixelXYToLatLong((int)tilexy.x * 256, (int)tilexy.y * 256, (int)tilexy.level, out lat, out lon);
            return(lat.ToString("F6") + "," + lon.ToString("F6"));
        }
Exemple #8
0
        public TileXY GetNeighbor(int offsetx, int offsety)
        {
            TileXY txy = this;

            txy.x += offsetx;
            txy.y += offsety;
            return(txy);
        }
Exemple #9
0
        public TileXY GetSon()
        {
            TileXY txy = this;

            txy.level++;
            txy.x *= 2;
            txy.y *= 2;
            return(txy);
        }
Exemple #10
0
        public Mask(Point start, Point end, TileXY tilexy)
        {
            if (end.X < start.X || end.Y < start.Y)
            {
                throw new Exception("Invalid rectangle!");
            }
            PointD a = GetLonLat(start, tilexy);
            PointD b = GetLonLat(end, tilexy);

            box = new RectangleD(a.lat, b.lon, b.lat, a.lon);
        }
Exemple #11
0
        public TileXY GetParent()
        {
            TileXY txy = this;

            if (txy.level == 0)
            {
                return(txy);
            }
            txy.level--;
            txy.x /= 2;
            txy.y /= 2;
            return(txy);
        }
Exemple #12
0
 public Point[] GetRelativePolygon(TileXY tilexy)
 {
     Point[] points = new Point[4];
     points[0] = BingProjection.LatLongToPixelXY(box.top, box.left, tilexy.level);
     points[1] = BingProjection.LatLongToPixelXY(box.top, box.right, tilexy.level);
     points[2] = BingProjection.LatLongToPixelXY(box.bottom, box.right, tilexy.level);
     points[3] = BingProjection.LatLongToPixelXY(box.bottom, box.left, tilexy.level);
     for (int i = 0; i < 4; i++)
     {
         points[i].X -= tilexy.x * 256;
         points[i].Y -= tilexy.y * 256;
     }
     return(points);
 }
Exemple #13
0
        public static string GetQuadKey(TileXY tilexy)
        {
            StringBuilder quadKey = new StringBuilder();

            for (int i = tilexy.level; i > 0; i--)
            {
                char digit = '0';
                int  mask  = 1 << (i - 1);
                if ((tilexy.x & mask) != 0)
                {
                    digit++;
                }
                if ((tilexy.y & mask) != 0)
                {
                    digit++;
                    digit++;
                }
                quadKey.Append(digit);
            }
            return(quadKey.ToString());
        }
Exemple #14
0
        public void OnMouseUp(Point mousePositionEnd, int actionType)
        {
            isMouseDown = false;
            Bitmap bm = (Bitmap)pbox.Image;

            if (mousePositionEnd != mousePositionStart) // it's a drag
            {
                // get real start and end
                Point start = new Point(Math.Min(mousePositionStart.X, mousePositionEnd.X), Math.Min(mousePositionStart.Y, mousePositionEnd.Y));
                Point end   = new Point(Math.Max(mousePositionStart.X, mousePositionEnd.X), Math.Max(mousePositionStart.Y, mousePositionEnd.Y));

                Mask mask = new Mask(start, end, centerTilexy.GetNeighbor(-centerX, -centerY));
                switch (actionType)
                {
                case 0:
                    // get statistics
                    Paint();     // Very important! Paint first to get rid of red line drawn by drag of mouse
                    byte minr = byte.MaxValue, ming = byte.MaxValue, minb = byte.MaxValue;
                    byte maxr = 0, maxg = 0, maxb = 0;
                    for (int w = start.X; w <= end.X; w++)
                    {
                        for (int h = start.Y; h <= end.Y; h++)
                        {
                            Color c = bm.GetPixel(w, h);
                            if (c.A == 0)
                            {
                                continue;
                            }
                            maxr = Math.Max(maxr, c.R);
                            maxg = Math.Max(maxg, c.G);
                            maxb = Math.Max(maxb, c.B);
                            minr = Math.Min(minr, c.R);
                            ming = Math.Min(ming, c.G);
                            minb = Math.Min(minb, c.B);
                        }
                    }
                    FormNav.ShowMessage("Min RGB: " + minr + "/" + ming + "/" + minb);
                    FormNav.ShowMessage("Max RGB: " + maxr + "/" + maxg + "/" + maxb);
                    break;

                case 1:
                    // zoom in
                    TileXY txy = centerTilexy;
                    if (FindTileInMask(mask, false, ref txy))
                    {
                        centerTilexy = txy;
                    }
                    break;

                case 2:
                    // add to mask
                    masks.Add(mask);
                    FormNav.ShowMessage("new mask added");
                    break;

                case 3:
                    // find PNG
                    TileXY txy2 = centerTilexy;
                    if (FindTileInMask(mask, true, ref txy2))
                    {
                        centerTilexy = txy2;
                    }
                    break;

                case 4:
                    // guess valid pixel range
                    // important, paint to original images before doing the calculation
                    Paint(true);

                    // first, get pixel cnt array
                    int[,] pixelCnt = new int[3, 256];
                    for (int i = 0; i < 3; i++)
                    {
                        for (int j = 0; j < 256; j++)
                        {
                            pixelCnt[i, j] = 0;
                        }
                    }
                    for (int w = start.X; w <= end.X; w++)
                    {
                        for (int h = start.Y; h <= end.Y; h++)
                        {
                            Color c = bm.GetPixel(w, h);
                            if (c.A == 0)
                            {
                                continue;
                            }
                            pixelCnt[0, c.R]++;
                            pixelCnt[1, c.G]++;
                            pixelCnt[2, c.B]++;
                        }
                    }
                    // then, convert to pixel sum
                    for (int i = 0; i < 3; i++)
                    {
                        for (int j = 1; j < 256; j++)
                        {
                            pixelCnt[i, j] += pixelCnt[i, j - 1];
                        }
                    }
                    double[] ratios = new double[] { 0.6, 0.7, 0.8, 0.9, 0.95, 0.96, 0.965, 0.97, 0.975, 0.98, 0.985, 0.99, 0.995, 0.998 };
                    int[,] guessedRanges = new int[3, ratios.Length];
                    for (int i = 0; i < 3; i++)
                    {
                        int j = 0;
                        for (int k = 0; k < ratios.Length; k++)
                        {
                            for (; j < 50; j++)
                            {
                                if (((double)pixelCnt[i, j]) / pixelCnt[i, 50] > ratios[k])
                                {
                                    break;
                                }
                            }
                            guessedRanges[i, k] = j;
                        }
                    }
                    cbGuessedPixelValidRanges.Items.Clear();
                    for (int i = 0; i < ratios.Length; i++)
                    {
                        cbGuessedPixelValidRanges.Items.Add((guessedRanges[0, i] + 1) + "," + (guessedRanges[1, i] + 1) + "," + (guessedRanges[2, i] + 1) + ",255,255,255");
                    }
                    FormNav.ShowMessage("Pixel Valid Ranges are guessed");
                    break;

                default:
                    break;
                }
                // paint anyway
                Paint();
            }
            else    // it's a single click
            {
                FormNav.ShowMessage("Color: " + bm.GetPixel(mousePositionEnd.X, mousePositionEnd.Y));

                // get top left tile
                TileXY tileTopLeft = centerTilexy.GetNeighbor(-centerX, -centerY);
                for (int i = 0; i < masks.Count; i++)
                {
                    if (masks[i].ContainsTilePixel(tileTopLeft, mousePositionEnd))
                    {
                        FormNav.ShowMessage("Mask " + i + ": " + masks[i].ToString());
                    }
                }
            }
        }
Exemple #15
0
        public void Paint(bool originalOnly = false, bool centerOnly = false)
        {
            // clear image
            Graphics g = Graphics.FromImage(pbox.Image);

            if (!originalOnly)
            {
                g.Clear(bgColor);
            }
            else
            {
                g.Clear(Color.FromArgb(0, 0, 0, 0));
            }

            // draw tiles
            for (int j = 0; j < rowCount; j++)
            {
                for (int i = 0; i < columnCount; i++)
                {
                    int offsetx = i - centerX;
                    int offsety = j - centerY;
                    if (centerOnly && (offsetx != 0 || offsety != 0))
                    {
                        continue;
                    }
                    TileXY xy = centerTilexy.GetNeighbor(offsetx, offsety);
                    if (tiles.ContainsKey(xy))
                    {
                        TileMeta  tmeta   = tiles[xy];
                        byte[]    imgBuff = MDataFile.Read(tdataPaths[tmeta.tdataPathId], tmeta.imgOffset, tmeta.imgLength);
                        Rectangle rect    = new Rectangle(i * imageSize, j * imageSize, imageSize, imageSize);
                        g.DrawImage(Image.FromStream(new MemoryStream(imgBuff)), rect);
                        if (!originalOnly && !_isShowValidGraph && distinguishPng && tmeta.hasAlpha)
                        {
                            g.FillRectangle(brushCoverPNG, rect);
                        }
                    }
                }
            }

            if (!originalOnly)
            {
                // get current utm correction zone
                int zone = Int32.Parse(tbUtmCorrectionZone.Text);

                // get top left tile xy
                TileXY topLeftTileXY = centerTilexy.GetNeighbor(-centerX, -centerY);

                // draw masks
                if (!_isShowValidGraph)
                {
                    foreach (Mask m in masks)
                    {
                        // draw utm corrected masks
                        g.FillPolygon(m.type == 0 ? brushMaskSkip : (m.type == 1 ? brushMaskNewRange : brushMaskRemove), m.GetUtmCorrectedRelativePolygon(topLeftTileXY, zone));
                    }
                }

                // show valid graph
                if (_isShowValidGraph && pixelValidRange != null)
                {
                    pixelValidRange.DrawValidGraph((Bitmap)pbox.Image);
                }

                // draw mouse line
                if (isMouseDown)
                {
                    g.DrawRectangle(penMouseDragLine, Math.Min(mousePositionNow.X, mousePositionStart.X),
                                    Math.Min(mousePositionNow.Y, mousePositionStart.Y),
                                    Math.Abs(mousePositionNow.X - mousePositionStart.X),
                                    Math.Abs(mousePositionNow.Y - mousePositionStart.Y));

                    // draw utm corrected line
                    Point start = new Point(Math.Min(mousePositionStart.X, mousePositionNow.X), Math.Min(mousePositionStart.Y, mousePositionNow.Y));
                    Point end   = new Point(Math.Max(mousePositionStart.X, mousePositionNow.X), Math.Max(mousePositionStart.Y, mousePositionNow.Y));
                    Mask  mTmp  = new Mask(start, end, topLeftTileXY);
                    g.DrawPolygon(penMouseDragLineUtmCorrected, mTmp.GetUtmCorrectedRelativePolygon(topLeftTileXY, zone));
                }
            }

            pbox.Refresh();
            ShowCenterTileInfo();
        }
Exemple #16
0
        /// <summary>
        /// initialize map from a dir which contains *.tdata and *.tmeta files
        /// </summary>
        /// <param name="dataDir"></param>
        public TDataNavigator(string[] tmetaPaths, PictureBox pbox, TextBox tbTileInfo, ComboBox cbGuessedPixelValidRanges, TextBox tbUtmCorrectionZone)
        {
            this.pbox       = pbox;
            this.tbTileInfo = tbTileInfo;
            this.cbGuessedPixelValidRanges = cbGuessedPixelValidRanges;
            this.tbUtmCorrectionZone       = tbUtmCorrectionZone;

            // create dataPath array
            tdataPaths = new string[tmetaPaths.Length];
            for (int i = 0; i < tmetaPaths.Length; i++)
            {
                tdataPaths[i] = tmetaPaths[i].ToLower().Replace(".tmeta", ".tdata");
            }

            // load all meta info
            levelMin = Int32.MaxValue;
            levelMax = 0;
            for (int i = 0; i < tmetaPaths.Length; i++)
            {
                using (MMetaFile metaFile = new MMetaFile(tmetaPaths[i]))
                {
                    int recordCnt = metaFile.GetRecordCnt();
                    for (int j = 0; j < recordCnt; j++)
                    {
                        MSTileMetaInfo meta = metaFile.Read(j);
                        if ((int)meta.tilexy.level < levelMin)
                        {
                            levelMin     = (int)meta.tilexy.level;
                            centerTilexy = new TileXY(meta.tilexy);
                        }
                        levelMax = Math.Max(levelMax, (int)meta.tilexy.level);
                        tiles.Add(new TileXY(meta.tilexy), new TileMeta(meta, i));
                    }
                }
            }

            // zoom in center tile to a reasonable level
            while (true)
            {
                int    validSonCount = 0;
                TileXY validSonXY    = centerTilexy;
                foreach (TileXY txy in centerTilexy.GetSon().GetSiblings())
                {
                    if (tiles.ContainsKey(txy))
                    {
                        validSonCount++;
                        validSonXY = txy;
                    }
                }
                if (validSonCount == 1)
                {
                    centerTilexy = validSonXY;
                }
                else
                {
                    break;
                }
            }

            // guess an initial utm correction zone
            double lat, lon;

            BingProjection.PixelXYToLatLong(centerTilexy.x * 256 + 128, centerTilexy.y * 256 + 128, (int)centerTilexy.level, out lat, out lon);
            tbUtmCorrectionZone.Text = Helper.LongitudeToUtmZone(lon).ToString();

            Paint();
        }