Ejemplo n.º 1
0
        public void LoadMaps(string mapsFilesDirectory)
        {
            NumMaps = 0;
            NumBitmaps = 0;
            string jpg_name = "";
            MapsFilesDirectory = mapsFilesDirectory;

            // dispose of all old maps and reset vars
            RemoveBitmaps(0);
            for (int i = 0; i < MaxNumMaps; i++)
            {
                Maps[i].zoom_level = 0.0;
                Maps[i].overlap = 0.0;
                Maps[i].qfactor = 0.0;
            }

            string crFile = mapsFilesDirectory + "\\copyright.txt";
            if (File.Exists(crFile))
            {
                StreamReader sr = null;
                try
                {
                    sr = new StreamReader(crFile, Encoding.UTF7);
                    mapCopyright = sr.ReadLine();
                }
                catch
                {
                    mapCopyright = null;
                }
                if (sr != null) sr.Close();
            }
            else
                mapCopyright = null;

            OsmTilesMode = DetectOsmTiles();
            if (!OsmTilesMode && parent.checkDownloadOsm.Checked)
            {                            // if want to download - force OsmTilesMode and enable all zoom levels
                for (int allowed_i = 0; allowed_i < OsmNumZoomLevels; allowed_i++)
                {
                    OsmZoomAvailable[allowed_i] = true;
                }
                OsmFileExtension = ".png";
                OsmTilesMode = true;
            }
            if (OsmTilesMode)
            {
                // all OSM tiles are 256x256
                for (int i = 0; i < MaxNumMaps; i++)
                {
                    Maps[i].sizeX = 256;
                    Maps[i].sizeY = 256;
                }
                LoadOsmServer();
                return;
            }

            // loop over possible map names and load existing map info
            Cursor.Current = Cursors.WaitCursor;
            OsmZoom = 1;            //otherwise zoom out may be prevented
            // load jpeg and jpg files
            string[] jfiles1 = Directory.GetFiles(mapsFilesDirectory, "*.jpg");
            string[] jfiles2 = Directory.GetFiles(mapsFilesDirectory, "*.jpeg");

            string[] jpg_files = new string[jfiles1.Length + jfiles2.Length];
            int tmpi = 0;
            for (int i = 0; i < jfiles1.Length; i++)
            { jpg_files[tmpi] = jfiles1[i]; tmpi++; }
            for (int i = 0; i < jfiles2.Length; i++)
            { jpg_files[tmpi] = jfiles2[i]; tmpi++; }

            Array.Sort(jpg_files);

            // set "." as decimal separator for reading the map info
            NumberFormatInfo number_info = new NumberFormatInfo();
            number_info.NumberDecimalSeparator = ".";

            for (int i = 0; i < jpg_files.Length; i++)
            {
                jpg_name = Path.GetFileName(jpg_files[i]);

                // kml file name
                string kml_file = Path.GetFileNameWithoutExtension(jpg_files[i]) + ".kml";
                if (mapsFilesDirectory == "\\") { kml_file = "\\" + kml_file; }
                else { kml_file = mapsFilesDirectory + "\\" + kml_file; }

                // text file name
                string txt_file = Path.GetFileNameWithoutExtension(jpg_files[i]) + ".txt";
                if (mapsFilesDirectory == "\\") { txt_file = "\\" + txt_file; }
                else { txt_file = mapsFilesDirectory + "\\" + txt_file; }

                // gmi file name
                string gmi_file = Path.GetFileNameWithoutExtension(jpg_files[i]) + ".gmi";
                if (mapsFilesDirectory == "\\") { gmi_file = "\\" + gmi_file; }
                else { gmi_file = mapsFilesDirectory + "\\" + gmi_file; }

                // check that at least one file exists
                if ((File.Exists(kml_file) == false)
                    && (File.Exists(txt_file) == false)
                    && (File.Exists(gmi_file) == false)) { continue; }

                // load maps dimensions
                if (Utils.GetJpegSize(jpg_files[i], out Maps[NumMaps].sizeX, out Maps[NumMaps].sizeY) != 0) { continue; }

                // make sure we do not load empty images
                if ((Maps[NumMaps].sizeX == 0) || (Maps[NumMaps].sizeY == 0)) { continue; }

                Maps[NumMaps].fname = jpg_files[i];

                bool kml_has_problems = false;
                bool gmi_has_problems = false;

                try
                {
                    // load kml file
                    if (File.Exists(kml_file))
                    {
                        double center_lat = 0.0, center_long = 0.0, center_range = 0.0;

                        FileStream fs = new FileStream(kml_file, FileMode.Open, FileAccess.Read);
                        StreamReader sr = new StreamReader(fs);
                        string line = "";
                        while ((line = sr.ReadLine()) != null)
                        {
                            line = line.Trim();
                            if (line == "</kml>") { break; }

                            // replace all "," with "." to read correctly
                            line = line.Replace(",", ".");

                            if (line.StartsWith("<longitude>"))
                            {
                                line = line.Replace("<longitude>", "");
                                line = line.Replace("</longitude>", "");
                                center_long = Convert.ToDouble(line.Trim(), number_info);
                            }
                            else if (line.StartsWith("<latitude>"))
                            {
                                line = line.Replace("<latitude>", "");
                                line = line.Replace("</latitude>", "");
                                center_lat = Convert.ToDouble(line.Trim(), number_info);
                            }
                            else if (line.StartsWith("<range>"))
                            {
                                line = line.Replace("<range>", "");
                                line = line.Replace("</range>", "");
                                center_range = Convert.ToDouble(line.Trim(), number_info);
                            }
                        }
                        sr.Close();
                        fs.Close();

                        // compute map lat/long
                        if ((center_lat != 0.0) && (center_long != 0.0) && (center_range != 0.0))
                        {
                            double sizex = center_range * Math.Tan(30.11 * (Math.PI / 180.0));
                            double sizey = sizex * Maps[NumMaps].sizeY /Maps[NumMaps].sizeX;
                            double tmp;
                            UtmUtil utmUtil1 = new UtmUtil();

                            utmUtil1.setReferencePoint(center_lat, center_long);
                            utmUtil1.getLatLong(-sizex, 0.0, out tmp, out Maps[NumMaps].lon1);
                            utmUtil1.getLatLong( sizex, 0.0, out tmp, out Maps[NumMaps].lon2);
                            utmUtil1.getLatLong(0.0,-sizey, out Maps[NumMaps].lat1, out tmp);
                            utmUtil1.getLatLong(0.0, sizey, out Maps[NumMaps].lat2, out tmp);
                        }
                        else
                            { kml_has_problems = true; }
                    }
                    else if (File.Exists(txt_file)) // load text file (if KML does not exist)
                    {
                        FileStream fs = new FileStream(txt_file, FileMode.Open, FileAccess.Read);
                        StreamReader sr = new StreamReader(fs);
                        Maps[NumMaps].lat1 = Convert.ToDouble(sr.ReadLine().Trim().Replace(",", "."), number_info);
                        Maps[NumMaps].lon1 = Convert.ToDouble(sr.ReadLine().Trim().Replace(",", "."), number_info);
                        Maps[NumMaps].lat2 = Convert.ToDouble(sr.ReadLine().Trim().Replace(",", "."), number_info);
                        Maps[NumMaps].lon2 = Convert.ToDouble(sr.ReadLine().Trim().Replace(",", "."), number_info);

                        sr.Close();
                        fs.Close();
                    }
                    else // load GMI file (if KML and TXT do not exist)
                    {
                        FileStream fs = new FileStream(gmi_file, FileMode.Open, FileAccess.Read);
                        StreamReader sr = new StreamReader(fs);

                        // check header
                        string header = sr.ReadLine().Trim();
                        if (header.IndexOf("Map Calibration data file v") != 0) { gmi_has_problems = true; }

                        // read image size and check if the size match
                        if(!gmi_has_problems)
                        {
                            sr.ReadLine().Trim(); // skip image name

                            int image_x = Convert.ToInt32(sr.ReadLine().Trim());
                            int image_y = Convert.ToInt32(sr.ReadLine().Trim());

                            if ((image_x != Maps[NumMaps].sizeX) || (image_y != Maps[NumMaps].sizeY)) { gmi_has_problems = true; }
                        }

                        // now read the reference points
                        if (!gmi_has_problems)
                        {
                            // need to extract points with min and max X/Y coordinates (if we have more than 2 ref points)
                            int num_ref_points = 0;
                            RefPointInfo minX, maxX, minY, maxY;
                            minX.i = int.MaxValue; maxX.i = int.MinValue; minX.f = 0; maxX.f = 0;
                            minY.i = int.MaxValue; maxY.i = int.MinValue; minY.f = 0; maxY.f = 0;

                            string line = "";
                            try
                            {
                                while ((line = sr.ReadLine()) != null)
                                {
                                    line = line.Trim();
                                    string[] words = line.Split(';');
                                    if (words.Length != 4) { continue; }

                                    // read X and long (0th and 2nd words)
                                    int tmp_i = Convert.ToInt32(words[0].Trim());
                                    double tmp_f = Convert.ToDouble(words[2].Trim().Replace(",", "."), number_info);
                                    if (tmp_i <= minX.i) { minX.i = tmp_i; minX.f = tmp_f; }
                                    if (tmp_i >= maxX.i) { maxX.i = tmp_i; maxX.f = tmp_f; }

                                    // read Y and lat (1st and 3rd words). Move the Y origin to the bottom of the picture (from the top)
                                    tmp_i = Maps[NumMaps].sizeY - Convert.ToInt32(words[1].Trim());
                                    tmp_f = Convert.ToDouble(words[3].Trim().Replace(",", "."), number_info);
                                    if (tmp_i <= minY.i) { minY.i = tmp_i; minY.f = tmp_f; }
                                    if (tmp_i >= maxY.i) { maxY.i = tmp_i; maxY.f = tmp_f; }

                                    num_ref_points++;
                                }
                            }
                            catch (FormatException /*e*/)
                            {
                                // It's OK. 
                                // We ignore the extra info after the ref points.
                            }

                            if ((num_ref_points > 1) && (minX.i != maxX.i) && (minY.i != maxY.i))
                            {
                                Maps[NumMaps].lat1 = minY.f - minY.i*(maxY.f-minY.f)/(maxY.i-minY.i);
                                Maps[NumMaps].lon1 = minX.f - minX.i*(maxX.f-minX.f)/(maxX.i-minX.i);
                                Maps[NumMaps].lat2 = maxY.f + (Maps[NumMaps].sizeY-maxY.i)*(maxY.f-minY.f)/(maxY.i-minY.i);
                                Maps[NumMaps].lon2 = maxX.f + (Maps[NumMaps].sizeX-maxX.i)*(maxX.f-minX.f)/(maxX.i-minX.i);
                            }
                            else { gmi_has_problems = true; } 
                        }

                        sr.Close();
                        fs.Close();
                    }
                }
                catch (Exception e)
                {
                    Utils.log.Error (" LoadMaps - Cannot load data for map " + jpg_name + ", map loading cancelled", e);
                    MessageBox.Show("Cannot load data for map " + jpg_name + ", map loading cancelled", "Error reading map info",
                                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                    break;
                }
                if (NumMaps >= MaxNumMaps)
                {
                    MessageBox.Show("Cannot load more than " + MaxNumMaps.ToString() + " maps", "Error reading maps",
                                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                    break;
                }
                if (kml_has_problems) 
                {  
                    MessageBox.Show("Error reading corresponding KML file: " + kml_file, "Error reading maps",
                                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                    break;
                }
                if (gmi_has_problems) 
                {  
                    MessageBox.Show("Error reading corresponding GMI file: " + gmi_file, "Error reading maps",
                                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                    break;
                }

                // make sure 1 is smaller that 2
                if (Maps[NumMaps].lat1 > Maps[NumMaps].lat2)
                    { double tmp = Maps[NumMaps].lat1; Maps[NumMaps].lat1 = Maps[NumMaps].lat2; Maps[NumMaps].lat2 = tmp; }
                if (Maps[NumMaps].lon1 > Maps[NumMaps].lon2)
                    { double tmp = Maps[NumMaps].lon1; Maps[NumMaps].lon1 = Maps[NumMaps].lon2; Maps[NumMaps].lon2 = tmp; }

                NumMaps++;
            }

            Cursor.Current = Cursors.Default;
        }
Ejemplo n.º 2
0
    {                                                                   //load as T2F (WayPoints)
        public bool Load(string filename, ref Form1.WayPointInfo WayPoints,
            int vector_size, ref float[] dataLat, ref float[] dataLong, ref Int16[] dataZ, ref Int32[] dataT, ref Int32[] dataD, ref Form1.TrackSummary ts, ref int data_size, bool append)
        {
            int DecimateCount = 0, Decimation = 1;
            double OriginShiftX = 0.0;
            double OriginShiftY = 0.0;
            bool Status = false;
            UtmUtil utmUtil = new UtmUtil();
            Int16 ReferenceAlt;

            if (!append)
            {
                data_size = 0;
                WayPoints.Count = 0;
                ts.Clear();
            }
            if (data_size == 0)
                ReferenceAlt = Int16.MaxValue;
            else
                ReferenceAlt = dataZ[data_size - 1];

            Cursor.Current = Cursors.WaitCursor;

            do
            {
                try
                {
                    ts.filename = filename;
                    FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
                    BinaryReader rd = new BinaryReader(fs, System.Text.Encoding.Unicode);

                    // load header "GCC1" (1 is version in binary)
                    if (rd.ReadByte() != 'G') break; if (rd.ReadByte() != 'C') break;
                    if (rd.ReadByte() != 'C') break; if (rd.ReadByte() != 1) break;

                    // read time as 6 bytes: year, month...
                    int tyear = (int)rd.ReadByte(); tyear += 2000;
                    int tmonth = (int)rd.ReadByte(); int tday = (int)rd.ReadByte();
                    int thour = (int)rd.ReadByte(); int tmin = (int)rd.ReadByte();
                    int tsec = (int)rd.ReadByte();
                    ts.StartTime = new DateTime(tyear, tmonth, tday, thour, tmin, tsec);

                    // read lat/long for the starting point
                    double data_lat = rd.ReadDouble();
                    double data_long = rd.ReadDouble();
                    utmUtil.setReferencePoint(data_lat, data_long);

                    Int16 x_int = 0; Int16 y_int = 0; Int16 z_int = 0; Int16 s_int = 0;
                    UInt16 t_16 = 0; UInt16 t_16last = 0; Int32 t_high = 0;
                    double out_lat = 0.0, out_long = 0.0;
                    double OldX = 0.0; double OldY = 0.0;
                    UInt64 recordError = 0UL;

                    bool loop = true;
                    while (loop)    //break with EndOfStreamException
                    {
                        // get 5 short ints
                        try
                        {
                            x_int = rd.ReadInt16();
                            y_int = rd.ReadInt16();
                            z_int = rd.ReadInt16();
                            s_int = rd.ReadInt16();
                            t_16 = rd.ReadUInt16();
                        }
                        catch (EndOfStreamException) { break; }
                        catch (Exception e)
                        {
                            Utils.log.Error(" LoadGcc - get 5 short ints ", e);
                            break;
                        }

                        // check if this is a special record
                        if ((s_int == -1) && (t_16 == 0xFFFF))
                        {
                            switch (z_int)
                            {
                                case 0: // origin shift: z_int = 0
                                    OriginShiftX += x_int;
                                    OriginShiftY += y_int;
                                    break;
                                case 1: // battery: z_int = 1
                                    break;
                                case 2: // which GPS options were selected: z_int = 2
                                    break;
                                case 3: // waypoint
                                    // read waypoint name, if not blank
                                    string name = "";
                                    for (int i = 0; i < x_int; i++)
                                    {
                                        name += (char)(rd.ReadUInt16());
                                    }
                                    // store new waypoint
                                    if (WayPoints.Count < WayPoints.DataSize)
                                    {
                                        WayPoints.name[WayPoints.Count] = name;
                                        WayPoints.lat[WayPoints.Count] = (float)out_lat;
                                        WayPoints.lon[WayPoints.Count] = (float)out_long;
                                        WayPoints.Count++;
                                    }
                                    break;
                                case 4: // heart rate not supported in T2F
                                    break;

                                case 32: // name
                                    ts.name = rd.ReadString();
                                    break;
                                case 33: // desc
                                    ts.desc = rd.ReadString();
                                    break;
                                default:
                                    if ((1UL << z_int & recordError) == 0)
                                    {
                                        if (MessageBox.Show("unknown special record " + z_int + " at " + data_size + "\ntry to continue load anyway?", "Load Error",
                                            MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1)
                                            == DialogResult.Cancel)
                                            loop = false; ;
                                        recordError |= 1UL << z_int;
                                    }
                                    if (loop && z_int >= 32)
                                        rd.ReadString();   //read unknown string in order to have correct record bounds
                                    break;
                            }
                        }
                        else    // "normal" record
                        {
                            // check if we need to decimate arrays
                            if (data_size >= vector_size)
                            {
                                for (int i = 0; i < vector_size / 2; i++)
                                {
                                    dataLat[i] = dataLat[i * 2];
                                    dataLong[i] = dataLong[i * 2];
                                    dataZ[i] = dataZ[i * 2];
                                    dataT[i] = dataT[i * 2];
                                    dataD[i] = dataD[i * 2];
                                }
                                data_size /= 2;
                                Decimation *= 2;
                            }

                            // take into account the origin shift
                            double real_x = OriginShiftX + x_int;
                            double real_y = OriginShiftY + y_int;

                            double deltax = real_x - OldX;
                            double deltay = real_y - OldY;
                            ts.Distance += Math.Sqrt(deltax * deltax + deltay * deltay);
                            OldX = real_x; OldY = real_y;

                            // compute elevation gain
                            if (z_int != Int16.MinValue)        //MinValue = invalid
                            {
                                //if (ts.AltitudeStart == Int16.MinValue)
                                //    ts.AltitudeStart = z_int;
                                if (z_int > ReferenceAlt)
                                {
                                    ts.AltitudeGain += z_int - ReferenceAlt;
                                    ReferenceAlt = z_int;
                                }
                                else if (z_int < ReferenceAlt - (short)Form1.AltThreshold)
                                {
                                    ReferenceAlt = z_int;
                                }
                                if (z_int > (short)ts.AltitudeMax) ts.AltitudeMax = z_int;
                                if (z_int < (short)ts.AltitudeMin) ts.AltitudeMin = z_int;
                            }

                            if (DecimateCount == 0)    //when decimating, add only first sample, ignore rest of decimation
                            {                          //but calculate distance and elevation from all points
                                utmUtil.getLatLong(real_x, real_y, out out_lat, out out_long);
                                dataLat[data_size] = (float)out_lat;
                                dataLong[data_size] = (float)out_long;
                                dataZ[data_size] = z_int;
                                if (t_16 < t_16last)        // handle overflow
                                    t_high += 65536;
                                t_16last = t_16;
                                dataT[data_size] = t_high + t_16;
                                dataD[data_size] = (int)ts.Distance;
                                data_size++;
                            }
                            DecimateCount++;
                            if (DecimateCount >= Decimation)
                                DecimateCount = 0;
                        }
                    }

                    rd.Close();
                    fs.Close();
                    Status = true;
                }
                catch (Exception e)
                {
                    Utils.log.Error(" LoadGcc ", e);
                }
            } while (false);
            Cursor.Current = Cursors.Default;

            return Status;
        }