Пример #1
0
        private bool LoadT2f(string filename, bool showSummary, bool append)
        {
            bool loaded_ok = false;
            IFileSupport fs = null;
            int Plot2ndCount_old;
            int WaypointsCountOld;
            if (append)
            {
                Plot2ndCount_old = Plot2ndCount;
                WaypointsCountOld = WayPointsT2F.Count;
            }
            else
            {
                Plot2ndCount_old = 0;
                WaypointsCountOld = 0;
            }
            switch (Path.GetExtension(filename).ToLower())
            {
                case ".gcc":
                    fs = new GccSupport(); break;
                case ".gpx":
                    fs = new GpxSupport(); break;
                case ".kml":
                    fs = new KmlSupport(); break;
                default:
                    MessageBox.Show("wrong extension");
                    return false;
            }
            if (fs != null)
            {
                mapUtil.clearNav(false);
                loaded_ok = fs.Load(filename, ref WayPointsT2F, PlotDataSize, ref Plot2ndLat, ref Plot2ndLong, ref Plot2ndZ, ref Plot2ndT, ref Plot2ndD, ref T2fSummary, ref Plot2ndCount, append);
                graph.scaleCmd = Graph.ScaleCmd.DoAutoscaleNoUndo;
            }
            if (loaded_ok)  // loaded OK
            {
                // If a new track-to-follow loaded (and main track not exist) - need to reset map zoom/shift vars
                if ((Plot2ndCount + WayPointsT2F.Count != 0) && (PlotCount == 0)) { ResetMapPosition(); }

                labelFileNameT2F.SetText("Track to Follow: " + Path.GetFileName(filename));

                if (Plot2ndCount - Plot2ndCount_old == 0 && WayPointsT2F.Count - WaypointsCountOld > 0)        //if no track -> copy WP-data to T2F
                {
                    if (DialogResult.Yes == MessageBox.Show("Use waypoints as track to navigate?", "File only has Waypoints", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1))
                    {
                        double OldLong, OldLat;
                        if (Plot2ndCount > 0)
                        {
                            OldLong = Plot2ndLong[Plot2ndCount - 1];
                            OldLat = Plot2ndLat[Plot2ndCount - 1];
                        }
                        else
                        {
                            OldLong = WayPointsT2F.lon[WaypointsCountOld];
                            OldLat = WayPointsT2F.lat[WaypointsCountOld];
                        }
                        double deltax, deltay;
                        UtmUtil utmUtil2 = new UtmUtil();       //use extra utmUtil
                        utmUtil2.setReferencePoint(OldLat, OldLong);
                        for (int i = WaypointsCountOld; i < WayPointsT2F.Count; i++)
                        {
                            if (Plot2ndCount >= PlotDataSize)     // check if we need to decimate arrays
                            {
                                for (int j = 0; j < PlotDataSize / 2; j++)
                                {
                                    Plot2ndLat[j] = Plot2ndLat[j * 2];
                                    Plot2ndLong[j] = Plot2ndLong[j * 2];
                                    Plot2ndZ[j] = Plot2ndZ[j * 2];
                                    Plot2ndT[j] = Plot2ndT[j * 2];
                                    Plot2ndD[j] = Plot2ndD[j * 2];
                                }
                                Plot2ndCount = PlotDataSize / 2;
                                //Decimation *= 2;  //use all new data
                            }
                            Plot2ndLong[Plot2ndCount] = WayPointsT2F.lon[i];
                            Plot2ndLat[Plot2ndCount] = WayPointsT2F.lat[i];
                            deltax = (Plot2ndLong[Plot2ndCount] - OldLong) * utmUtil2.longit2meter;
                            deltay = (Plot2ndLat[Plot2ndCount] - OldLat) * utmUtil2.lat2meter;
                            T2fSummary.Distance += Math.Sqrt(deltax * deltax + deltay * deltay);
                            OldLong = Plot2ndLong[Plot2ndCount]; OldLat = Plot2ndLat[Plot2ndCount];
                            Plot2ndD[Plot2ndCount] = (int)T2fSummary.Distance;
                            Plot2ndT[Plot2ndCount] = Plot2ndCount == 0 ? 0 : Plot2ndT[Plot2ndCount - 1] + 1;
                            Plot2ndZ[Plot2ndCount] = 0;
                            Plot2ndCount++;
                        }
                    }
                }
                Plot2ndCountUndo = Plot2ndCount;
                updateNavData();
                if (showSummary) loaded_ok = DialogResult.OK == ShowTrackSummary(T2fSummary);
            }
            else
            {
                labelFileNameT2F.SetText("Track to Follow: " + Path.GetFileName(filename) + " load ERROR");
                T2fSummary.desc = "Error loading file";
                MessageBox.Show("Error reading file or it does not have track data", "Error loading file",
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
            }
            return loaded_ok;
        }
Пример #2
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;
        }
Пример #3
0
        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)
        {
            bool Status = false;
            int DecimateCount = 0, Decimation = 1;
            double OldLat = 0.0, OldLong = 0.0;
            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;
            try
            {
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.IgnoreWhitespace = true;
                StreamReader sr = new StreamReader(filename, System.Text.Encoding.UTF8);        //use StreamReader to overwrite encoding ISO-8859-1, which is not supported by .NETCF (no speed drawback)
                XmlReader reader = XmlReader.Create(sr, settings);

                ts.filename = filename;
                //reader.MoveToContent();
                
                //reader.Read();
                while (reader.ReadToFollowing("Placemark"))
                {
                    while (reader.NodeType == XmlNodeType.Element)
                    {
                        if (reader.Name == "Placemark")
                        {
                            bool addLevel = false;
                            string tmpname = "";
                            string tmpdescription = "";
                            bool waypoint = false;
                            double lon = 0;
                            double lat = 0;

                            reader.Read();
                            while (reader.NodeType == XmlNodeType.Element)
                            {
                                if (reader.Name == "name")
                                {
                                    tmpname = reader.ReadElementString();
                                }
                                else if (reader.Name == "description")
                                {
                                    tmpdescription = reader.ReadElementString();
                                }
                                else if (reader.Name == "MultiGeometry")
                                {
                                    reader.Read();
                                    addLevel = true;
                                }
                                else if (reader.Name == "LineString")
                                {
                                    ts.name = tmpname;
                                    ts.desc = tmpdescription;
                                    reader.Read();
                                    while (reader.NodeType == XmlNodeType.Element)
                                    {
                                        if (reader.Name == "coordinates")
                                        {
                                            reader.ReadStartElement();
                                            while (true)
                                            {
                                                string line = "";
                                                char[] buf = new char[1];
                                                int count = 1;
                                                for (int i = 0; i < 100; i++)       //read one line
                                                {
                                                    count = reader.ReadValueChunk(buf, 0, 1);
                                                    if (buf[0] == '\n' || buf[0] == ' ' || buf[0] == '\r' || buf[0] == '\t' || count == 0)
                                                        break;
                                                    line += buf[0];
                                                }
                                                if (data_size >= vector_size)     // check if we need to decimate arrays
                                                {
                                                    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 = vector_size / 2;
                                                    Decimation *= 2;
                                                }

                                                string[] numbers = line.Split(',');
                                                if (numbers.Length >= 2)            //read data
                                                {
                                                    lon = Convert.ToDouble(numbers[0], IC);
                                                    lat = Convert.ToDouble(numbers[1], IC);
                                                    if (!utmUtil.referenceSet)
                                                    {
                                                        utmUtil.setReferencePoint(lat, lon);
                                                        OldLat = lat;
                                                        OldLong = lon;
                                                    }
                                                    double deltax = (lon - OldLong) * utmUtil.longit2meter;
                                                    double deltay = (lat - OldLat) * utmUtil.lat2meter;
                                                    ts.Distance += Math.Sqrt(deltax * deltax + deltay * deltay);
                                                    OldLong = lon; OldLat = lat;
                                                    Int16 z_int = Int16.MinValue;      //preset invalid Alt in case there is no <ele> field
                                                    if (numbers.Length >= 3)
                                                    {
                                                        z_int = (Int16)Convert.ToDouble(numbers[2], IC);        //altitude
                                                        // compute elevation gain
                                                        //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
                                                    {
                                                        dataLat[data_size] = (float)lat;
                                                        dataLong[data_size] = (float)lon;
                                                        dataZ[data_size] = z_int;
                                                        if (data_size == 0)
                                                            dataT[data_size] = 0;
                                                        else
                                                            dataT[data_size] = dataT[data_size - 1] + Decimation;    //every point 1 sec apart
                                                        dataD[data_size] = (int)ts.Distance;
                                                        data_size++;
                                                    }
                                                    DecimateCount++;
                                                    if (DecimateCount >= Decimation)
                                                        DecimateCount = 0;
                                                }
                                                if (count == 0)
                                                    break;
                                            }
                                            reader.Skip();      //advances reader to the next (End) Element
                                            reader.ReadEndElement();    //coordinates
                                        }
                                        else
                                            reader.Skip();
                                    }
                                    reader.ReadEndElement();    //LineString
                                }
                                else if (reader.Name == "Point")
                                {
                                    reader.Read();
                                    while (reader.NodeType == XmlNodeType.Element)
                                    {
                                        if (reader.Name == "coordinates")
                                        {
                                            string line = reader.ReadElementString();
                                            string[] numbers = line.Split(',');
                                            if (numbers.Length >= 2)
                                            {
                                                lon = Convert.ToDouble(numbers[0], IC);
                                                lat = Convert.ToDouble(numbers[1], IC);
                                                waypoint = true;
                                            }
                                        }
                                        else
                                            reader.Skip();
                                    }
                                    reader.ReadEndElement();    //Point
                                }
                                else
                                    reader.Skip();
                            }
                            if (addLevel)
                                reader.ReadEndElement();
                            if (waypoint && WayPoints.Count < WayPoints.DataSize)
                            {
                                WayPoints.name[WayPoints.Count] = tmpname;
                                WayPoints.lon[WayPoints.Count] = (float)lon;
                                WayPoints.lat[WayPoints.Count] = (float)lat;
                                WayPoints.Count++;
                            }
                            reader.ReadEndElement();    //  Placemark
                        }
                        else
                            reader.Skip();
                    }
                }
                reader.Close();
                sr.Close();
                Status = true;
            }
            catch (Exception e)
            {
                Utils.log.Error(" LoadKml ", e);
            }
            Cursor.Current = Cursors.Default;
            return Status;
        }
Пример #4
0
        public void GetNavigationData(UtmUtil utmUtil, float[] PlotLong2, float[] PlotLat2, int[] PlotD2, int PlotSize2, double CurLong, double CurLat)
        {
            //System.Diagnostics.Debug.WriteLine("GetNavigationData");
            double x, y;                                            //m  (related to CurPos)
            double dist2, MinDistance2 = double.MaxValue / 16;      //m2
            int j = 0, k = 0;
            const int ArSize = 14;
            int[] indexAr = new int[ArSize];
            double[] xAr = new double[ArSize];      //Array in m relative to intersection/MinDistance
            double[] yAr = new double[ArSize];

            int begin = 0, end = PlotSize2-1, increment = 1;    //GetNavigationData is only executed if PlotSize2 > 0
            if (nav.backward)
            { 
                begin = end;
                end = 0;
                increment = -1;
            }
            if (nav.ix >= PlotSize2)    //in case trackpoints were removed
            {
                nav.ix = PlotSize2 - 1;     //set parameters in case point is more than 500m away
                nav.ixd_intersec = nav.ix;
                nav.ix_next_drive = nav.ix;
                nav.LongIntersection = PlotLong2[nav.ix];
                nav.LatIntersection = PlotLat2[nav.ix];
            }
            if (nav.ShortSearch == 0) nav.ix = begin;
            int beginindex = nav.ix;
            int min_ix = beginindex;
            int min_ixb = beginindex;
            double ca2 = 0, cb2 = 0, t2 = 0, min_ca2 = 0, min_t2 = 0;
            int min_segType = 0;
            int FBSearch = 1;       //1=forward  -1=backward   other=stop
            int min_FBSearch = 1;
            int min_increment = 0;
            while (FBSearch == 1 || FBSearch == -1)
            {
                int increment2 = increment * FBSearch;
                int i = beginindex;
                x = (PlotLong2[i] - CurLong) * utmUtil.longit2meter;
                y = (PlotLat2[i] - CurLat) * utmUtil.lat2meter;
                ca2 = x * x + y * y;
                while (i < PlotSize2 && i >= 0)    //search segment and point with min distance
                {
                    int segType = 0;
                    dist2 = ca2;
                    int ib = i + increment2;
                    if (ib < PlotSize2 && ib >= 0)
                    {
                        while (true)
                        {
                            x = (PlotLong2[ib] - PlotLong2[i]) * utmUtil.longit2meter;
                            y = (PlotLat2[ib] - PlotLat2[i]) * utmUtil.lat2meter;
                            t2 = x * x + y * y;
                            if (t2 < 4 && ib + increment2 < PlotSize2 && ib + increment2 >= 0)    //next point closer than 2m
                                ib += increment2;
                            else break;
                        }
                        x = (PlotLong2[ib] - CurLong) * utmUtil.longit2meter;
                        y = (PlotLat2[ib] - CurLat) * utmUtil.lat2meter;
                        cb2 = x * x + y * y;
                        
                        if (t2 <= cb2 - ca2)            //before i
                        {
                            segType = 0;
                            dist2 = ca2;
                        }
                        else if (t2 <= ca2 - cb2)       //after i+1
                        {
                            segType = 1;
                            dist2 = cb2;
                        }
                        else
                        {                               //currentPos inbetween track segment
                            segType = 2;
                            dist2 = (2 * (ca2 * cb2 + cb2 * t2 + t2 * ca2) - (ca2 * ca2 + cb2 * cb2 + t2 * t2)) / (4 * t2); //Dreieck-Höhenformel (t2 cannot be 0 here)
                        }
                    }
                    if (dist2 < MinDistance2)
                    {
                        min_ix = i;
                        min_ixb = ib;
                        MinDistance2 = dist2;
                        min_ca2 = ca2;
                        min_t2 = t2;
                        min_segType = segType;
                        min_increment = increment2;
                        min_FBSearch = FBSearch;
                    }
                    if (nav.ShortSearch != 0 && dist2 > MinDistance2 * 4 + 10000)
                        break;

                    i = ib;
                    ca2 = cb2;
                }
                if (min_ix == beginindex && FBSearch == 1)
                    FBSearch = -1;                         //try also backward
                else
                    FBSearch = 0;
            }

            if (MinDistance2 < 500 * 500 || nav.ShortSearch == 0)  //use only if within 500m of track zone
            {
                nav.ix = min_ix;
                nav.MinDistance = Math.Sqrt(MinDistance2);
                nav.Distance2Dest = nav.MinDistance;
                if (min_segType == 0)
                {
                    nav.ix_next_drive = min_ix;
                    nav.ixd_intersec = min_ix;
                    nav.LongIntersection = PlotLong2[min_ix];
                    nav.LatIntersection = PlotLat2[min_ix];
                }
                else if (min_segType == 1)
                {
                    nav.ix_next_drive = min_ixb;
                    nav.ixd_intersec = min_ixb;
                    nav.LongIntersection = PlotLong2[min_ixb];
                    nav.LatIntersection = PlotLat2[min_ixb];
                }
                else
                {
                    double quot;
                    if (min_t2 > 1) quot = Math.Sqrt((min_ca2 - MinDistance2) / min_t2);
                    else quot = 0;
                    if (min_FBSearch == 1)
                        nav.ix_next_drive = min_ixb;
                    else
                    {
                        nav.ix = min_ixb;
                        nav.ix_next_drive = min_ix;
                    }
                    nav.ixd_intersec = min_ix + quot * min_increment; ;
                    nav.LongIntersection = PlotLong2[min_ix] + quot * (PlotLong2[min_ixb] - PlotLong2[min_ix]);
                    nav.LatIntersection = PlotLat2[min_ix] + quot * (PlotLat2[min_ixb] - PlotLat2[min_ix]);
                }
            }
            else
            {
                if (nav.MinDistance == -1.0)    //not initialized yet
                {
                    nav.LongIntersection = PlotLong2[nav.ix];
                    nav.LatIntersection = PlotLat2[nav.ix];
                }
                x = (nav.LongIntersection - CurLong) * utmUtil.longit2meter;
                y = (nav.LatIntersection - CurLat) * utmUtil.lat2meter;
                nav.MinDistance = Math.Sqrt(x * x + y * y);
                nav.Distance2Dest = nav.MinDistance;
            }

            nav.ShortSearch = -1;
            //if (nav.ShortSearch > 0)
            //    nav.ShortSearch--;
            //else
            //    nav.ShortSearch = 30;       //for 30s only shortSearch

            // ix_next_drive is now first index to drive over

#if debugNav            //debug   intersection point
            DrawCurrentPoint(parent.BackBufferGraphics, nav.LongIntersection, nav.LatIntersection, 6, Color.Violet);
#endif
            //accumulate Distance2Dest from LongOld (intersection or MinDistance)
            double accu = 0;        //use extra accu because Distance2Dest not always starts from 0
            double LongOld = nav.LongIntersection;     //point to begin accumulation of Distance2Dest
            double LatOld = nav.LatIntersection;
            xAr[0] = 0; yAr[0] = 0; j = 1;
            indexAr[0] = 0;
            x = 0; y = 0;

            for (int i = nav.ix_next_drive; i < PlotSize2 && i >= 0; i += increment)   
            {
                //accumulate distance to destination
                double xa = (PlotLong2[i] - LongOld) * utmUtil.longit2meter;
                double ya = (PlotLat2[i] - LatOld) * utmUtil.lat2meter;
                double ma = Math.Sqrt(xa * xa + ya * ya);
                if (i == nav.ix_next_drive)
                    nav.Distance2Dest += ma;    //Distance2Dest now: Current - Intersection - ix_next_drive
                int dist = (int)(accu + ma);
                while (j < ArSize && j * 20 < dist)        //fill array every 20m for corner search [0, 20, 40,.. 260]
                {
                    double quot = (j * 20 - accu) / ma;
                    xAr[j] = x + xa * quot;    // xOld + quot * (x - xOld);
                    yAr[j] = y + ya * quot;    //yOld + quot * (y - yOld);
                    indexAr[j] = nav.ix_next_drive;
                    j++;
                }
                accu += ma;
                LongOld = PlotLong2[i];
                LatOld = PlotLat2[i];
                if (j < ArSize)           //only necessary for array fill
                {
                    x = (LongOld - nav.LongIntersection) * utmUtil.longit2meter;    //can get inacurate for long tracks, therefore not used for Distance2Dest
                    y = (LatOld - nav.LatIntersection) * utmUtil.lat2meter;
                }
                else
                    break;
            }

            nav.Distance2Dest += (PlotD2[end] - PlotD2[nav.ix_next_drive]) * increment;
        

#if debugNav            //debug   260m line
            for (int n = 0; n < j; n++)
            {
                DrawCurrentPoint(parent.BackBufferGraphics, (xAr[n] * utmUtil.meter2longit + nav.LongIntersection), (yAr[n] * utmUtil.meter2lat + nav.LatIntersection), 2, Color.White);
            }
#endif
            //nav.Angle100mAhead = (int)(180.0 / Math.PI * Math.Atan2((PlotLong2[Index100mDistance] - CurLong) * utmUtil.longit2meter, (PlotLat2[Index100mDistance] - CurLat) * utmUtil.lat2meter));
            int jdx100 = Math.Min(5, j - 1);
            nav.Angle100mAhead = (int)(180.0 / Math.PI * Math.Atan2(xAr[jdx100] - (CurLong - nav.LongIntersection) * utmUtil.longit2meter, yAr[jdx100] - (CurLat - nav.LatIntersection) * utmUtil.lat2meter));

            if (corner.Type == 0)      //search corner
            {
                int dir1 = 0, dir2 = 0, angle = 0, angleAbs, angleAbsMax = -1, kc = 0;
                bool cornerfound = false;
                if (corner.processedIndex == -1)
                    corner.processedIndex = begin;

                for (k = 2; k < j - 2; k++)
                {
                    if (indexAr[k] != PlotSize2 && (corner.processedIndex - indexAr[k]) * increment > 2)       //little overlap (reprocess)
                        continue;                                                   //already processed - to reduce calc

                    dir1 = (int)(180 / Math.PI * Math.Atan2(xAr[k - 1] - xAr[k - 2], yAr[k - 1] - yAr[k - 2]));
                    dir2 = (int)(180 / Math.PI * Math.Atan2(xAr[k + 2] - xAr[k + 1], yAr[k + 2] - yAr[k + 1]));
                    angle = dir2 - dir1;
                    if (angle > 180) angle -= 360;
                    if (angle <= -180) angle += 360;
                    angleAbs = Math.Abs(angle);
                    corner.processedIndex = indexAr[k];
                    if (angleAbs > angleAbsMax)
                    {
                        angleAbsMax = angleAbs;
                        corner.IndexT2F = indexAr[k];
                        corner.dir1 = dir1;
                        corner.dir2 = dir2;
                        corner.angle = angle;
                        kc = k;
                    }
                    if (angleAbsMax >= 35 && angleAbs < angleAbsMax - 10)   //run over corner (angle gets smaller)
                    {
                        cornerfound = true;
                        break;
                    }
                }
                if (angleAbsMax >= 35 && j < ArSize && kc >= j - 4)     //corner at end of T2F
                    cornerfound = true;
                if (cornerfound)
                {
                    if (angleAbsMax < 65)
                        corner.Type = 1;     //half turn
                    else if (angleAbsMax < 115)
                        corner.Type = 2;     //turn
                    else
                        corner.Type = 3;     //sharp turn
                    corner.distance = int.MaxValue;    //to overcome invalidate algorithm

                    corner.Long = (float)(xAr[kc] * utmUtil.meter2longit + nav.LongIntersection);
                    corner.Lat = (float)(yAr[kc] * utmUtil.meter2lat + nav.LatIntersection);
                    corner.voicePlayed = false;

#if debugNav                    //debug
                    //DrawCurrentPoint(parent.BackBufferGraphics, PlotLong2[indexAr[kc - 2]], PlotLat2[indexAr[kc - 2]], 6, Color.LightBlue);
                    //DrawCurrentPoint(parent.BackBufferGraphics, PlotLong2[indexAr[kc - 1]], PlotLat2[indexAr[kc - 1]], 6, Color.LightBlue);
                    //DrawCurrentPoint(parent.BackBufferGraphics, PlotLong2[indexAr[kc - 0]], PlotLat2[indexAr[kc - 0]], 8, Color.Blue);
                    //DrawCurrentPoint(parent.BackBufferGraphics, PlotLong2[indexAr[kc + 1]], PlotLat2[indexAr[kc + 1]], 6, Color.LightBlue);
                    //DrawCurrentPoint(parent.BackBufferGraphics, PlotLong2[indexAr[kc + 2]], PlotLat2[indexAr[kc + 2]], 6, Color.LightBlue);
#endif
                }
                else
                    corner.Type = 0;     //straight
            }
            if (corner.Type != 0)      //update volatile corner details
            {
                x = (corner.Long - CurLong) * utmUtil.longit2meter;
                y = (corner.Lat - CurLat) * utmUtil.lat2meter;
                int cornerdistance = (int)Math.Sqrt(x * x + y * y) / 10 * 10;       //rounded to 10m
                if (cornerdistance > corner.distance || cornerdistance > 300)
                {
                    invalidateCorner();
                }
                else
                {
                    corner.distance = cornerdistance;
                    corner.direction = (int)(180.0 / Math.PI * Math.Atan2(x, y));
                }
            }


            double unit_cff = parent.GetUnitsConversionCff();
            string unit_name = parent.GetUnitsName();

            int dir = nav.Angle100mAhead;
            if (parent.Heading != 720)
                dir -= parent.Heading;
            while (dir < 0) dir += 360;
            nav.orient = Orientation.normal;
            nav.SkyDirection = false;
            if (nav.MinDistance > (double)parent.numericTrackTolerance.Value)
            {
                nav.Symbol = arrow_to;
                if (parent.Heading == 720)
                    nav.SkyDirection = true;
                if (dir < 45)
                    nav.orient = Orientation.normal;
                else if (dir < 135)
                    nav.orient = Orientation.right;
                else if (dir < 225)
                    nav.orient = Orientation.mirrorY;
                else if (dir < 315)
                    nav.orient = Orientation.left;
                //else
                //nav.orient = Orientation.normal;
                //if (nav.MinDistance >= 10000)
                //    str += " " + ((int)nav.MinDistance / 1000).ToString() + "km";
                //else
                //    str += " " + ((int)nav.MinDistance / 10 * 10).ToString() + "m";
                nav.strCmd = (nav.MinDistance * unit_cff).ToString("0.00") + unit_name;
            }
            else if (parent.Heading != 720 && dir > 135 && dir < 225 && parent.CurrentSpeed > 4.0)
            {
                nav.Symbol = arrow_turn;      //wenden
                nav.strCmd = "";
            }
            else if (corner.Type != 0)        //navigation command
            {
                switch (corner.Type)
                {
                    case 1: nav.Symbol = arrow_hr; break;
                    case 2: nav.Symbol = arrow_r; break;
                    case 3: nav.Symbol = arrow_sr; break;
                    default: nav.Symbol = null; break;
                }
                if (corner.angle < 0)
                    nav.orient = Orientation.mirrorX;   //left
                //str = corner.angle.ToString() + str;
                nav.strCmd = corner.distance.ToString() + "m";
            }
            else if (nav.Distance2Dest <= 200)
            {
                nav.Symbol = destination;
                nav.strCmd = (((int)nav.Distance2Dest / 10) * 10).ToString() + "m";
            }
            else
                nav.Symbol = null;

            nav.strDistance2Dest = (nav.Distance2Dest * unit_cff).ToString("0.00") + unit_name + " to destin.";

            return;
        }
Пример #5
0
        // draw map and 2 lines (main and "to follow"). Shift is the x/y shift of the second line origin.
        public void DrawMaps(Graphics g, Bitmap BackBuffer, Graphics BackBufferGraphics, UtmUtil utmUtil,
                             bool MouseMoving, bool lifeview, int MapMode, 
                             double unit_cff, string unit_name,
                             float[] PlotLong, float[] PlotLat, int PlotSize, Color line_color, int line_width, bool plot_dots,
                             Form1.WayPointInfo WayPointsT, Form1.WayPointInfo WayPointsT2F, int ShowWaypoints,
                             float[] PlotLong2, float[] PlotLat2, int PlotSize2, Color line_color2, int line_width2, bool plot_dots2,
                             double CurrentLong, double CurrentLat, int heading, string clickLatLon, Color mapLabelColor)
        {
            ScreenX = BackBuffer.Width; ScreenY = BackBuffer.Height;
            // if picture is moving - draw existing picture
            if (MouseMoving && !drawWhileShift)
            {
                DrawMovingImage(g, BackBuffer, (int)((LongShift - LongShiftSave) * Long2Pixel), (int)((LatShift - LatShiftSave) * Lat2Pixel));
                return;
            }
            // set scale from "main" or the "track-to-follow" (if main not exist)
            float[] CurLongA = { (float)CurrentLong };
            float[] CurLatA = { (float)CurrentLat };
            if (ShowTrackToFollowMode == ShowTrackToFollow.T2FStart && PlotSize2 > 0)
            {
                // Show start position of track to follow
                SetAutoScale(utmUtil, PlotLong2, PlotLat2, 1, false);
            }
            else if (ShowTrackToFollowMode == ShowTrackToFollow.T2FEnd && PlotSize2 > 0)
            {
                // Show end position of track to follow
                float[] Long = { PlotLong2[PlotSize2 - 1] };
                float[] Lat = { PlotLat2[PlotSize2 - 1] };
                SetAutoScale(utmUtil, Long, Lat, 1, false);
            }
            else if (parent.trackEditMode != Form1.TrackEditMode.Off)
            {
                SetAutoScale(utmUtil, null, null, 0, false);           // in trackEditMode prevent autoscale; only update vars
            }
            else if (lifeview)
            {
                // Show current GPS position (last position)
                SetAutoScale(utmUtil, CurLongA, CurLatA, 1, lifeview);
            }
            else if (PlotSize > 0)
            {
                // Show all points of loaded track
                SetAutoScale(utmUtil, PlotLong, PlotLat, PlotSize, lifeview);
            }
            else if (PlotSize2 > 0 && ShowTrackToFollowMode != ShowTrackToFollow.T2FCurrent)
            {
                // Show all points of track to follow
                SetAutoScale(utmUtil, PlotLong2, PlotLat2, PlotSize2, false);
            }
            else
            {
                // Show last position
                SetAutoScale(utmUtil, CurLongA, CurLatA, 1, false);
            }

            // need to draw the picture first into back buffer
            BackBufferGraphics.Clear(Back_Color);

            if (!hideMap)
            {
                // in OSM tile mode, required map array is created based on the current screen coordinates
                if (OsmTilesMode)
                {
                    FillOsmTiles(MapMode);
                    NumBitmaps = NumMaps;

                    DrawJpeg(BackBufferGraphics);
                }
                else
                {
                    // Update screen coordinates for all maps
                    for (int i = 0; i < NumMaps; i++)
                    {
                        Maps[i].scrX1_ix = ToScreenX(Maps[i].lon1);
                        Maps[i].scrX2_iz = ToScreenX(Maps[i].lon2);
                        Maps[i].scrY1_iy = ToScreenY(Maps[i].lat1);
                        Maps[i].scrY2 = ToScreenY(Maps[i].lat2);
                    }

                    // select the best map and draw it
                    SelectBestMap(MapMode);
                    RemoveBitmaps(NumBitmaps); // removes unused bitmaps
                    DrawJpeg(BackBufferGraphics);
                }
                if (mapCopyright != null)
                {
                    Font drawFont = new Font("Arial", 8 * parent.df, FontStyle.Bold);
                    SolidBrush drawBrush = new SolidBrush(mapLabelColor);
                    SizeF size = BackBufferGraphics.MeasureString(mapCopyright, drawFont);
                    BackBufferGraphics.DrawString(mapCopyright, drawFont, drawBrush, ScreenX - size.Width - 2, size.Height);
                }
            }

            Pen pen = new Pen(Color.LightGray, 1);

            // draw the track-to-follow line
            if (PlotSize2 > 0 && hideT2f == false)
            {
                pen.Color = line_color2;
                pen.Width = line_width2;
                DrawTrackLine(BackBufferGraphics, pen, PlotLong2, PlotLat2, PlotSize2, plot_dots2, CurrentLong, CurrentLat);
                DrawCurrentPoint(BackBufferGraphics, PlotLong2[PlotSize2 - 1], PlotLat2[PlotSize2 - 1], line_width2, line_color2);
            }

            // draw the main track line
            if (PlotSize > 0 && hideTrack == false)
            {
                pen.Color = line_color;
                pen.Width = line_width;
                DrawTrackLine(BackBufferGraphics, pen, PlotLong, PlotLat, PlotSize, plot_dots, 0, 0);
                // draw last point larger by 5 points
                DrawCurrentPoint(BackBufferGraphics, PlotLong[PlotSize - 1], PlotLat[PlotSize - 1], line_width + 5, line_color);
            }

            if (ShowWaypoints > 0)
            {
                // Draw the Waypoints (on top of track2follow and track line)
                DrawWayPoints(BackBufferGraphics, pen, WayPointsT, Utils.modifyColor(line_color, +100), ShowWaypoints);
                DrawWayPoints(BackBufferGraphics, pen, WayPointsT2F, Utils.modifyColor(line_color2, +100), ShowWaypoints);
            }

            if (lifeview)
            {
                Point p0 = new Point(ToScreenX(CurrentLong), ToScreenY(CurrentLat));
                Color col = line_color, col2 = line_color2;
                bool outside0 = false;
                bool outside1 = false;
                if (heading == 720) { col = Color.DimGray; col2 = Color.DimGray; }

                if (PlotSize2 > 0 && (showNav || parent.comboNavCmd.SelectedIndex > 0))
                {
#if debugNav
                    GetNavigationData(utmUtil, PlotLong2, PlotLat2, parent.Plot2ndD, PlotSize2, CurrentLong, CurrentLat);
#endif
                    //DoVoiceCommand();
                    if (showNav && !hideAllInfos)
                    {
                        // We draw the line between current position and T2F with half of the T2F width and somewhat lighter
                        pen.Width = Math.Max(2, line_width2 / 2);
                        pen.Color = Utils.modifyColor(line_color2, +100);
                        Point p1 = new Point(ToScreenX(nav.LongIntersection), ToScreenY(nav.LatIntersection));
                        outside0 = ScreenClip(ref p0, p1);
                        outside1 = ScreenClip(ref p1, p0);
                        BackBufferGraphics.DrawLine(pen, p0.X, p0.Y, p1.X, p1.Y);
                        //if (outside0 || outside1)      // If the Current Position is outside of the Screen or the nearest point on the track is outside
                        //{                              // of the screen, show the min distance to track
                        //    DrawDistanceToTrack2Follow(BackBufferGraphics, pen, unit_cff, unit_name);
                        //}
                        if (!outside0)
                            DrawArrow(BackBufferGraphics, p0.X, p0.Y, nav.Angle100mAhead, line_width2 * 3 + 7, line_color2);                    //navigation arrow pointing at t2f 100m ahead
                        DrawArrow(BackBufferGraphics, ScreenX * 4 / 5, ScreenY / 5, nav.Angle100mAhead - heading, ScreenX / 5, col2);   //big navigation arrow in direction of travel
                        
                        Font drawFont = new Font("Arial", 22, FontStyle.Bold);
                        SolidBrush drawBrush = new SolidBrush(line_color2);
                        //if (nav.strCmd.Length > 8)
                        //{
                        //    int blank = nav.strCmd.IndexOf(" ", 5);
                        //    if (blank > 1)
                        //    {
                        //        string navstr2 = nav.strCmd.Remove(0, blank + 1);
                        //        nav.strCmd = nav.strCmd.Remove(blank, nav.strCmd.Length - blank);
                        //        BackBufferGraphics.DrawString(navstr2, drawFont, drawBrush, ScreenX / 40, ScreenY / 12 + (int)BackBufferGraphics.MeasureString(nav.strCmd, drawFont).Height);
                        //    }
                        //}
                        if (nav.Symbol != null)
                        {
                            DrawNavSymbol(BackBufferGraphics, drawBrush, ScreenX / 40, ScreenY / 12, nav.Symbol, nav.orient, nav.SkyDirection, false);
                            BackBufferGraphics.DrawString(nav.strCmd, drawFont, drawBrush, ScreenX * 130 / 480, ScreenY / 14);
                        }
                        if (corner.Type != 0)
                        {
                            //DrawCurrentPoint(BackBufferGraphics, PlotLong2[corner.IndexT2F], PlotLat2[corner.IndexT2F], 6, Color.Fuchsia);
                            DrawCurrentPoint(BackBufferGraphics, corner.Long, corner.Lat, line_width2, Color.Yellow);

                            //DrawCurrentPoint(BackBufferGraphics, PlotLong2[corner.IndexT2F - 2], PlotLat2[corner.IndexT2F - 2], 4, Color.Yellow);
                            //DrawCurrentPoint(BackBufferGraphics, PlotLong2[corner.IndexT2F - 1], PlotLat2[corner.IndexT2F - 1], 4, Color.Yellow);
                            //DrawCurrentPoint(BackBufferGraphics, PlotLong2[corner.IndexT2F + 1], PlotLat2[corner.IndexT2F + 1], 4, Color.Yellow);
                            //DrawCurrentPoint(BackBufferGraphics, PlotLong2[corner.IndexT2F + 2], PlotLat2[corner.IndexT2F + 2], 4, Color.Yellow);
                        }
                    }
                }
                if (!outside0)
                    DrawArrow(BackBufferGraphics, p0.X, p0.Y, heading, line_width * 2 + 5, col);                            //arrow showing direction of movement
                // draw gps led point
                //DrawCurrentPoint(BackBufferGraphics, CurLong[0], CurLat[0], line_width, CurrentGpsLedColor);
            }
            if (showMapLabel && !hideAllInfos || parent.trackEditMode == Form1.TrackEditMode.T2f)
            {
                // draw tick label and map name
                double screen_width_units = ScreenX / Long2Pixel * unit_cff / utmUtil.meter2longit;
                // tick distance in "units" (i.e. km or miles)
                double tick_distance_units = TickMark(screen_width_units, 4);
                // tick distance in screen pixels
                int tick_distance_screen = (int)(tick_distance_units * Long2Pixel / unit_cff * utmUtil.meter2longit);

                pen.Color = mapLabelColor;
                DrawTickLabel(BackBufferGraphics, pen, tick_distance_screen, tick_distance_units, unit_name, clickLatLon);
            }
            if (!hideAllInfos)
                DrawMapValues(BackBufferGraphics, mapLabelColor);
            // draw back buffer on screen
            g.DrawImage(BackBuffer, 0, 0);
        }
Пример #6
0
 private void SetAutoScale(UtmUtil utmUtil, float[] PlotLong, float[] PlotLat, int PlotSize, bool lifeview)
 {
     if (PlotSize > 0)
     {
         if (!utmUtil.referenceSet)
         {
             utmUtil.setReferencePoint(PlotLat[PlotSize - 1], PlotLong[PlotSize - 1]);
             utmUtil.referenceSet = false;       //better not fix to an old point
         }
         if (lifeview || (PlotSize == 1))   // during liveview (logging), set a fixed scale with current point in the middle
         {
             double last_x = PlotLong[PlotSize - 1];
             double last_y = PlotLat[PlotSize - 1];
             double extend_x = 1.0;
             double extend_y = 1.0;
             if (!OsmTilesMode)
                 if (ScreenY > ScreenX)
                     extend_y = (double)ScreenY / (double)ScreenX;
                 else
                     extend_x = (double)ScreenX / (double)ScreenY;
             DataLongMin = last_x - utmUtil.meter2longit * DefaultZoomRadius * extend_x;
             DataLongMax = last_x + utmUtil.meter2longit * DefaultZoomRadius * extend_x;
             DataLatMin = last_y - utmUtil.meter2lat * DefaultZoomRadius * extend_y;
             DataLatMax = last_y + utmUtil.meter2lat * DefaultZoomRadius * extend_y;
         }
         else
         {
             // compute data limits
             DataLongMin = 1.0E9; DataLongMax = -1.0E9; DataLatMin = 1.0E9; DataLatMax = -1.0E9;
             for (int i = 0; i < PlotSize; i++)
             {
                 if (PlotLong[i] < DataLongMin) { DataLongMin = PlotLong[i]; }
                 if (PlotLong[i] > DataLongMax) { DataLongMax = PlotLong[i]; }
                 if (PlotLat[i] < DataLatMin) { DataLatMin = PlotLat[i]; }
                 if (PlotLat[i] > DataLatMax) { DataLatMax = PlotLat[i]; }
             }
             double dx = (DataLongMax - DataLongMin) / 20;       //make ca. 10% larger
             double dy = (DataLatMax - DataLatMin) / 20;
             if (dx < 0.0001) dx = 0.0001;
             if (dy < 0.0001) dy = 0.0001;
             DataLongMin -= dx;
             DataLongMax += dx;
             DataLatMin -= dy;
             DataLatMax += dy;
         }
     }
     double xscale = (double)ScreenX / (DataLongMax - DataLongMin);
     double yscale = (double)ScreenY / ((OsmLat2YTile(1, DataLatMin) - OsmLat2YTile(1, DataLatMax)) * 360);
     DataLongMiddle = (DataLongMin + DataLongMax) / 2;
     DataLatMiddle = (DataLatMin + DataLatMax) / 2;
     if (OsmTilesMode)
     {
         UInt32 xTiles = (UInt32)((yscale > xscale ? xscale : yscale) * 360 / 256);
         for (OsmN = 1 << 30; OsmN > 1; OsmN >>= 1)
             if ((xTiles & OsmN) > 0)
                 break;                      //OsmN is next smaller power of 2
         OsmN = (int)(OsmN * ZoomValue);
         Long2Pixel = OsmN * 32 / 45.0;      //  OsmN * 256 / 360.0
         double yMiddleTile = OsmLat2YTile(OsmN, DataLatMiddle + LatShift);     //linearize at middle of display
         Lat2Pixel = 1 / (OsmYTile2Lat(OsmN, yMiddleTile - 1.0 / 512) - OsmYTile2Lat(OsmN, yMiddleTile + 1.0 / 512));    //linearize with +/- 0.5 pixel
     }
     else
     {
         Long2Pixel = (yscale > xscale ? xscale : yscale) * ZoomValue;
         Lat2Pixel = Long2Pixel * utmUtil.meter2longit / utmUtil.meter2lat;
     }
 }
Пример #7
0
        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)
        {
            bool Status = false;
            TimeSpan tspan;
            UtmUtil utmUtil = new UtmUtil();
            double OldLat = 0.0, OldLong = 0.0;
            int DecimateCount = 0, Decimation = 1;
            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;
            try
            {
                //XmlParserContext xmlpc = new XmlParserContext(null, null, "", XmlSpace.Default, System.Text.Encoding.UTF8);    does not work
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.IgnoreWhitespace = true;
                StreamReader sr = new StreamReader(filename, System.Text.Encoding.UTF8);        //use StreamReader to overwrite encoding ISO-8859-1, which is not supported by .NETCF (no speed drawback)
                XmlReader reader = XmlReader.Create(sr, settings);
                ts.filename = filename;
                //reader.MoveToContent();
                reader.ReadToFollowing("gpx");
                reader.Read();
                while (reader.NodeType == XmlNodeType.Element)
                {
                    bool isTrack;
                    if ((isTrack = reader.Name == "trk") || reader.Name == "rte")
                    {
                        if (isTrack) reader.Read();
                        while (reader.NodeType == XmlNodeType.Element)
                        {
                            if (reader.Name == "trkseg" || reader.Name == "rte")
                            {
                                reader.Read();
                                while (reader.NodeType == XmlNodeType.Element)
                                {
                                    if (reader.Name == "trkpt" || reader.Name == "rtept")
                                    {
                                    trkpt:
                                        bool jumptrkpt = false;
                                        if (data_size >= vector_size)     // check if we need to decimate arrays
                                        {
                                            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 = vector_size / 2;
                                            Decimation *= 2;
                                        }
                                        double lat = Convert.ToDouble(reader.GetAttribute("lat"), IC);
                                        double lon = Convert.ToDouble(reader.GetAttribute("lon"), IC);
                                        if (!utmUtil.referenceSet)
                                        {
                                            utmUtil.setReferencePoint(lat, lon);
                                            OldLat = lat;
                                            OldLong = lon;
                                        }
                                        double deltax = (lon - OldLong) * utmUtil.longit2meter;
                                        double deltay = (lat - OldLat) * utmUtil.lat2meter;
                                        ts.Distance += Math.Sqrt(deltax * deltax + deltay * deltay);
                                        OldLong = lon; OldLat = lat;
                                        tspan = TimeSpan.Zero;             //clear data in case there is no <time> field
                                        Int16 z_int = Int16.MinValue;      //preset invalid Alt in case there is no <ele> field
                                        reader.Read();
                                        while (reader.NodeType == XmlNodeType.Element)       //read subtree
                                        {
                                            switch (reader.Name)
                                            {
                                                case "ele":
                                                    z_int = (Int16)reader.ReadElementContentAsDouble();
                                                    // compute elevation gain
                                                    //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;
                                                    break;
                                                case "time":
                                                    if (ts.StartTime == DateTime.MinValue)
                                                    {
                                                        ts.StartTime = reader.ReadElementContentAsDateTime();
                                                    }
                                                    else
                                                    {
                                                        tspan = reader.ReadElementContentAsDateTime() - ts.StartTime;
                                                    }
                                                    break;
                                                case "speed":
                                                    reader.Skip();
                                                    break;
                                                case "trkpt":           //trkpt without EndElement <trkpt lat="47.2615199999997" lon="10.2016400000003"/>
                                                case "rtept":
                                                    jumptrkpt = true;
                                                    goto savepoint;
                                                default:
                                                    reader.Skip();
                                                    break;
                                            }
                                        }
                                        reader.ReadEndElement();    //trkpt
                                    savepoint:
                                        if (DecimateCount == 0)    //when decimating, add only first sample, ignore rest of decimation
                                        {
                                            dataLat[data_size] = (float)lat;
                                            dataLong[data_size] = (float)lon;
                                            dataZ[data_size] = z_int;
                                            dataT[data_size] = (int)tspan.TotalSeconds;
                                            dataD[data_size] = (int)ts.Distance;
                                            data_size++;
                                        }
                                        DecimateCount++;
                                        if (DecimateCount >= Decimation)
                                            DecimateCount = 0;
                                        if (jumptrkpt) goto trkpt;
                                    }
                                    else
                                        reader.Skip();
                                }
                                if (isTrack) reader.ReadEndElement();    //trkseg
                            }
                            else if (reader.Name == "name")
                            {
                                ts.name = reader.ReadElementString();
                            }
                            else if (reader.Name == "desc")
                            {
                                ts.desc = reader.ReadElementString();
                            }
                            else
                                reader.Skip();
                        }
                        reader.ReadEndElement();    //trk
                    }
                    else if (reader.Name == "wpt")
                    {
                        float lat = (float)Convert.ToDouble(reader.GetAttribute("lat"), IC);
                        float lon = (float)Convert.ToDouble(reader.GetAttribute("lon"), IC);
                        string name = "";
                        string desc = "";
                        reader.Read();
                        while (reader.NodeType == XmlNodeType.Element)
                        {
                            if (reader.Name == "name")
                            {
                                name = reader.ReadElementString();
                            }
                            else if (reader.Name == "desc")
                            {
                                desc = reader.ReadElementString();        //prepared for later use
                            }
                            else
                                reader.Skip();
                        }
                        if (WayPoints.Count < WayPoints.DataSize)
                        {
                            WayPoints.lat[WayPoints.Count] = lat;
                            WayPoints.lon[WayPoints.Count] = lon;
                            WayPoints.name[WayPoints.Count] = name;
                            WayPoints.Count++;
                        }
                        reader.ReadEndElement();
                    }
                    else
                        reader.Skip();
                }
                //reader.ReadEndElement();
                reader.Close();
                Status = true;
            }
            catch (Exception e)
            {
                Utils.log.Error(" LoadGpx ", e);
            }
            Cursor.Current = Cursors.Default;
            return Status;
        }
Пример #8
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;
        }