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; }
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; }
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; }
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; } }
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; }
{ //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; }