コード例 #1
0
ファイル: ReadTiffFile.cs プロジェクト: mrieker/WairToNow
    public static void Main(string[] args)
    {
        bool   markers  = false;
        bool   nosplit  = false;
        string basename = null;

        mingrid = Color.Transparent;
        for (int i = 0; i < args.Length; i++)
        {
            if (args[i] == "-markers")
            {
                markers = true; continue;
            }
            if (args[i] == "-mingrid")
            {
                mingrid = NameToColor(args[++i]); continue;
            }
            if (args[i] == "-nosplit")
            {
                nosplit = true; continue;
            }
            if (args[i][0] == '-')
            {
                throw new Exception("unknown option " + args[i]);
            }
            if (basename != null)
            {
                throw new Exception("extra arg " + args[i]);
            }
            basename = args[i];
        }
        if (basename == null)
        {
            throw new Exception("missing basename");
        }

        chart = new ChartTiff("", basename);

        /*
         * Draw lines every minute for debugging.
         */
        if (mingrid.A != 0)
        {
            double hilatdeg, hilondeg, lat, lolatdeg, lolondeg, lon;
            int    lastx, lasty, latmin, lonmin, thisx, thisy;

            chart.Pixel2LatLon(chart.width, 0, out hilatdeg, out hilondeg);
            chart.Pixel2LatLon(0, chart.height, out lolatdeg, out lolondeg);
            int hilatmin = (int)(hilatdeg * 60.0) + 30;
            int hilonmin = (int)(hilondeg * 60.0) + 30;
            int lolatmin = (int)(lolatdeg * 60.0) - 30;
            int lolonmin = (int)(lolondeg * 60.0) - 30;

            for (latmin = lolatmin; latmin < hilatmin; latmin++)
            {
                lonmin = lolonmin;
                lat    = (double)latmin / 60.0;
                lon    = (double)lonmin / 60.0;
                chart.LatLon2Pixel(lat, lon, out lastx, out lasty);

                while (++lonmin < hilonmin)
                {
                    lon = (double)lonmin / 60.0;
                    chart.LatLon2Pixel(lat, lon, out thisx, out thisy);
                    DrawLine(lastx, lasty, thisx, thisy, MinGridSetPixel);
                    lastx = thisx;
                    lasty = thisy;
                }
            }

            for (lonmin = lolonmin; lonmin < hilonmin; lonmin++)
            {
                latmin = lolatmin;
                lat    = (double)latmin / 60.0;
                lon    = (double)lonmin / 60.0;
                chart.LatLon2Pixel(lat, lon, out lastx, out lasty);

                while (++latmin < hilatmin)
                {
                    lat = (double)latmin / 60.0;
                    chart.LatLon2Pixel(lat, lon, out thisx, out thisy);
                    DrawLine(lastx, lasty, thisx, thisy, MinGridSetPixel);
                    lastx = thisx;
                    lasty = thisy;
                }
            }
        }

        /*
         * Split it up into wstep/hstep-sized .png files.
         */
        if (!nosplit)
        {
            string dirname = basename.Replace(' ', '_');
            Directory.CreateDirectory(dirname);
            for (int hhh = 0; hhh < chart.height; hhh += hstep)
            {
                int thish = chart.height - hhh;
                if (thish > hstep + overlap)
                {
                    thish = hstep + overlap;
                }
                string subdirname = dirname + "/" + (hhh / hstep).ToString();
                Directory.CreateDirectory(subdirname);
                for (int www = 0; www < chart.width; www += wstep)
                {
                    int thisw = chart.width - www;
                    if (thisw > wstep + overlap)
                    {
                        thisw = wstep + overlap;
                    }
                    string savename = subdirname + "/" + (www / wstep).ToString() + ".png";
                    Bitmap thisbm   = new Bitmap(thisw, thish);
                    for (int h = 0; h < thish; h++)
                    {
                        for (int w = 0; w < thisw; w++)
                        {
                            thisbm.SetPixel(w, h, chart.bmp.GetPixel(www + w, hhh + h));
                        }
                    }
                    thisbm.Save(savename, System.Drawing.Imaging.ImageFormat.Png);
                }
            }

            /*
             * Make thumbnail 256 pixels high with correct width to maintain aspect ratio.
             */
            int    iconh    = 256;
            int    iconw    = chart.width * iconh / chart.height;
            Bitmap iconbm   = new Bitmap(chart.bmp, iconw, iconh);
            string iconname = dirname + "/icon.png";
            iconbm.Save(iconname, System.Drawing.Imaging.ImageFormat.Png);
        }

        if (markers)
        {
            /*
             * Create whole .png file containing lat/lon markers for visual inspection.
             */
            Console.WriteLine(basename + ".png");

            /*
             * Draw a vertical line through centerLon, ie, easting = 0
             */
            for (int y = 0; y < chart.height; y++)
            {
                double easting = 0;
                int    x       = (int)((easting - chart.tfw_e - chart.tfw_c * y) / chart.tfw_a);
                for (int d = -2; d <= 2; d++)
                {
                    SetPixel(x + d, y, Color.Yellow);
                }
            }

            /*
             * Draw an horizontal line through centerLat, ie, northing = 0
             */
            for (int x = 0; x < chart.width; x++)
            {
                double northing = 0;
                int    y        = (int)((northing - chart.tfw_f - chart.tfw_b * x) / chart.tfw_d);
                for (int d = -2; d <= 2; d++)
                {
                    SetPixel(x, y + d, Color.Yellow);
                }
            }

            /*
             * LatLon -> Pixel conversion testing.
             */
            for (int lat = -90; lat < 90; lat++)
            {
                for (int lon = -180; lon < 180; lon++)
                {
                    int x, y;
                    chart.LatLon2Pixel(lat, lon, out x, out y);

                    /*
                     * Draw a red plus sign at that location.
                     */
                    for (int d = -25; d <= 25; d++)
                    {
                        for (int e = -2; e <= 2; e++)
                        {
                            SetPixel(x + e, y + d, Color.Red);
                            SetPixel(x + d, y + e, Color.Red);
                        }
                    }
                }
            }

            chart.bmp.Save(basename + ".png", System.Drawing.Imaging.ImageFormat.Png);
        }
    }
コード例 #2
0
    public static void Main(string[] args)
    {
        string basename = null;

        for (int i = 0; i < args.Length; i++)
        {
            if (args[i][0] == '-')
            {
                throw new Exception("unknown option " + args[i]);
            }
            if (basename != null)
            {
                throw new Exception("extra arg " + args[i]);
            }
            basename = args[i];
        }
        if (basename == null)
        {
            throw new Exception("missing basename");
        }

        chart = new ChartTiff("charts/", basename);

        /*
         * Mark all transparent pixels as white.
         */
        for (int y = 0; y < chart.height; y++)
        {
            for (int x = 0; x < chart.width; x++)
            {
                Color c = chart.bmp.GetPixel(x, y);
                if (c.A < 200)
                {
                    chart.bmp.SetPixel(x, y, Color.White);
                }
            }
        }

        /*
         * Mark all pixels outside lat/lon limits for the chart
         * as white so we don't misidentify them.
         */
        int xmin = chart.width;
        int ymin = chart.height;
        int xmax = 0;
        int ymax = 0;

        for (int y = 0; y < chart.height; y++)
        {
            for (int x = 0; x < chart.width; x++)
            {
                double lat, lon;
                chart.Pixel2LatLon(x, y, out lat, out lon);
                if ((x == 0 || x == chart.width - 1) && (y == 0 || y == chart.height - 1))
                {
                    Console.WriteLine("(" + x + "," + y + ") => " + lat + "," + lon);
                }
                if ((lon < chart.westLonLimit) || (lon > chart.eastLonLimit) ||
                    (lat > chart.northLatLimit) || (lat < chart.southLatLimit))
                {
                    chart.bmp.SetPixel(x, y, Color.White);
                }
                else
                {
                    if (xmin > x)
                    {
                        xmin = x;
                    }
                    if (ymin > y)
                    {
                        ymin = y;
                    }
                    if (xmax < x)
                    {
                        xmax = x;
                    }
                    if (ymax < y)
                    {
                        ymax = y;
                    }
                }
            }
        }
        Console.WriteLine("xmin=" + xmin);
        Console.WriteLine("ymin=" + ymin);
        Console.WriteLine("xmax=" + xmax);
        Console.WriteLine("ymax=" + ymax);

        /*
         * Convert magenta pixels to black and everything else to white
         * for easy processing.
         */
        Console.WriteLine("monochromaticising");
        blacks = new byte[chart.height, chart.width];
        for (int y = ymin; y < ymax; y++)
        {
            for (int x = xmin; x < xmax; x++)
            {
                Color c = chart.bmp.GetPixel(x, y);
                int   r = c.R;
                int   g = c.G;
                int   b = c.B;
                if ((r >= 100) && (r <= 130) && (g >= 70) && (g <= 90) && (b >= 100) && (b <= 130))
                {
                    blacks[y, x] = 1;
                    chart.bmp.SetPixel(x, y, Color.Black);
                }
                else
                {
                    blacks[y, x] = 0;
                    chart.bmp.SetPixel(x, y, Color.White);
                }
            }
        }
        chart.bmp.Save("stage1.png", System.Drawing.Imaging.ImageFormat.Png);

        /*
         * If a white pixel is surrounded by at least 7 blacks,
         * change the white to a black.  This will fill in a lot
         * of spotty airports and not much else.
         */
        Console.WriteLine("filling in spots");
        for (int y = ymin + 1; y < ymax - 1; y++)
        {
            for (int x = xmin + 1; x < xmax - 1; x++)
            {
                if (blacks[y, x] == 0)
                {
                    if (blacks[y - 1, x - 1] + blacks[y - 1, x] + blacks[y - 1, x + 1] +
                        blacks[y, x - 1] + blacks[y, x + 1] +
                        blacks[y + 1, x - 1] + blacks[y + 1, x] + blacks[y + 1, x + 1] > 6)
                    {
                        blacks[y, x] = 1;
                        chart.bmp.SetPixel(x, y, Color.Black);
                    }
                }
            }
        }
        chart.bmp.Save("stage2.png", System.Drawing.Imaging.ImageFormat.Png);

        /*
         * Draw box around where each airport should be on the chart.
         */
        Console.WriteLine("finding airports");
        string[] csvnames    = Directory.GetFiles("datums", "airports_*.csv");
        string   bestcsvname = null;

        foreach (string csvname in csvnames)
        {
            if ((bestcsvname == null) || StrLt(bestcsvname, csvname))
            {
                bestcsvname = csvname;
            }
        }
        StreamReader csvreader = new StreamReader(bestcsvname);
        string       csvline;

        while ((csvline = csvreader.ReadLine()) != null)
        {
            /*
             * Compute where the airport should be on the map
             * trusting the gubmint's numbers.
             */
            string[] csvtokens = ChartTiff.SplitQuotedCSVLine(csvline);
            string   aptid = csvtokens[1];
            double   csvlat = double.Parse(csvtokens[4]);
            double   csvlon = double.Parse(csvtokens[5]);
            int      csvpixx, csvpixy;
            chart.LatLon2Pixel(csvlat, csvlon, out csvpixx, out csvpixy);

            /*
             * Skip airport if not on graphics part of chart.
             */
            if ((csvpixx < xmin) || (csvpixx >= xmax))
            {
                continue;
            }
            if ((csvpixy < ymin) || (csvpixy >= ymax))
            {
                continue;
            }
            Console.Write(aptid.PadLeft(5));

            /*
             * Search the surrounding area for a tight fitting circle around
             * black pixels.
             */
            double bestRatio   = 0;
            int    bestRadius  = 0;
            int    bestCenterX = 0;
            int    bestCenterY = 0;
            for (int dy = -20; dy <= 20; dy++)
            {
                for (int dx = -20; dx <= 20; dx++)
                {
                    for (int rad = 14; rad <= 22; rad++)
                    {
                        int loestx = csvpixx + dx - rad - 2;
                        int loesty = csvpixy + dy - rad - 2;
                        int hiestx = csvpixx + dx + rad + 2;
                        int hiesty = csvpixy + dy + rad + 2;
                        if ((loestx < xmin) || (hiestx >= xmax))
                        {
                            continue;
                        }
                        if ((loesty < ymin) || (hiesty >= ymax))
                        {
                            continue;
                        }

                        int nbi = 0;  // number blacks inside radius
                        int nbo = 0;  // number blacks outside radius
                        int num = 0;  // number of angles checked
                        for (double ang = 0.0; ang < Math.PI * 2.0; ang += 0.5 / rad)
                        {
                            double cos = Math.Cos(ang);
                            double sin = Math.Sin(ang);
                            int    xxi = (int)((rad + 0) * cos + 0.5);
                            int    yyi = (int)((rad + 0) * sin + 0.5);
                            int    xxo = (int)((rad + 1) * cos + 0.5);
                            int    yyo = (int)((rad + 1) * sin + 0.5);
                            if (Math.Abs(xxi - xxo) + Math.Abs(yyi - yyo) == 2)
                            {
                                nbi += blacks[csvpixy + dy + yyi, csvpixx + dx + xxi];
                                nbo += blacks[csvpixy + dy + yyo, csvpixx + dx + xxo];
                                num++;
                            }
                        }
                        if ((num >= 8) && (nbo > 0) && (nbi * 2 > nbo * 6))
                        {
                            double ratio = (double)nbi / (double)nbo;
                            if (bestRatio < ratio)
                            {
                                bestRatio   = ratio;
                                bestRadius  = rad;
                                bestCenterX = csvpixx + dx;
                                bestCenterY = csvpixy + dy;
                            }
                        }
                    }
                }
            }
            if (bestRadius > 0)
            {
                DrawCircle(bestCenterX, bestCenterY, bestRadius, Color.Red);
                DrawCircle(csvpixx, csvpixy, bestRadius, Color.Magenta);
            }
            else
            {
                DrawCircle(csvpixx, csvpixy, 30, Color.Cyan);
            }
        }
        Console.WriteLine("");
        csvreader.Close();
        chart.bmp.Save("stage3.png", System.Drawing.Imaging.ImageFormat.Png);
    }
コード例 #3
0
    public static void Main(string[] args)
    {
        string basename = args[0];
        string savename = args[1];

        ChartTiff tiffchart = new ChartTiff("charts/", basename);
        int       tw        = tiffchart.width;
        int       th        = tiffchart.height;

        double upperLeftLat, upperLeftLon;

        tiffchart.Pixel2LatLon(0, 0, out upperLeftLat, out upperLeftLon);

        double upperRiteLat, upperRiteLon;

        tiffchart.Pixel2LatLon(tw, 0, out upperRiteLat, out upperRiteLon);

        double lowerLeftLat, lowerLeftLon;

        tiffchart.Pixel2LatLon(0, th, out lowerLeftLat, out lowerLeftLon);

        double lowerRiteLat, lowerRiteLon;

        tiffchart.Pixel2LatLon(tw, th, out lowerRiteLat, out lowerRiteLon);

        double loestLat = Math.Min(Math.Min(upperLeftLat, upperRiteLat), Math.Min(lowerLeftLat, lowerRiteLat));
        double hiestLat = Math.Max(Math.Max(upperLeftLat, upperRiteLat), Math.Max(lowerLeftLat, lowerRiteLat));
        double loestLon = Math.Min(Math.Min(upperLeftLon, upperRiteLon), Math.Min(lowerLeftLon, lowerRiteLon));
        double hiestLon = Math.Max(Math.Max(upperLeftLon, upperRiteLon), Math.Max(lowerLeftLon, lowerRiteLon));

        double avgLat = (loestLat + hiestLat) / 2.0;
        double avgLon = (loestLon + hiestLon) / 2.0;
        int    oneNorthX, oneNorthY, oneSouthX, oneSouthY;

        tiffchart.LatLon2Pixel(avgLat + 0.5, avgLon, out oneNorthX, out oneNorthY);
        tiffchart.LatLon2Pixel(avgLat - 0.5, avgLon, out oneSouthX, out oneSouthY);

        double pixperdeglat = Hypot(oneNorthX - oneSouthX, oneNorthY - oneSouthY);
        double pixperdeglon = pixperdeglat * Math.Cos(avgLat * Math.PI / 180.0);

        int pngwidth  = (int)Math.Round((hiestLon - loestLon) * pixperdeglon);
        int pngheight = (int)Math.Round((hiestLat - loestLat) * pixperdeglat);

        Console.WriteLine("pngwidth,height=" + pngwidth + "," + pngheight);

        Bitmap pngbm = new Bitmap(pngwidth, pngheight);

        for (int pngy = 0; pngy < pngheight; pngy++)
        {
            if (pngy % 100 == 0)
            {
                Console.Write("\rpngy=" + pngy);
            }
            for (int pngx = 0; pngx < pngwidth; pngx++)
            {
                double lat = (double)pngy / pngheight * (loestLat - hiestLat) + hiestLat;
                double lon = (double)pngx / pngwidth * (hiestLon - loestLon) + loestLon;
                int    tiffx, tiffy;
                tiffchart.LatLon2Pixel(lat, lon, out tiffx, out tiffy);
                if ((tiffx >= 0) && (tiffx < tw) && (tiffy >= 0) && (tiffy < th))
                {
                    Color pixel = tiffchart.bmp.GetPixel(tiffx, tiffy);
                    pngbm.SetPixel(pngx, pngy, pixel);
                }
            }
        }
        Console.WriteLine("");

        pngbm.Save(savename, System.Drawing.Imaging.ImageFormat.Png);

        string csvline = "box:" + hiestLat + "," + loestLon + "," + loestLat + "," + hiestLon + "," +
                         pngwidth + "," + pngheight + "," + tiffchart.enddate + "," + tiffchart.spacename;

        File.WriteAllText(savename + ".csv", csvline + "\n");
    }