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