diff --git a/GPIReader.cs b/GPIReader.cs new file mode 100644 index 0000000..6b6464f --- /dev/null +++ b/GPIReader.cs @@ -0,0 +1,1469 @@ +/***************************************************/ +/* */ +/* C# Garmin POI File Reader */ +/* (by milokz@gmail.com) */ +/* */ +/* GPIReader by milokz@gmail.com */ +/* Part of KMZRebuilder Project */ +/* */ +/***************************************************/ + +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Drawing.Drawing2D; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace KMZ_Viewer +{ + #region RECTYPES + public enum RecType: ushort + { + Header0 = 0, + Header1 = 1, + Waypoint = 2, + Alert = 3, + BitmapReference = 4, + Bitmap = 5, + CategoryReference = 6, + Category = 7, + Area = 8, + POIGroup = 9, + Comment = 10, + Address = 11, + Contact = 12, + Image = 13, + Description = 14, + Unknown15 = 15, + Unknown16 = 16, + Copyright = 17, + Media = 18, + SpeedCamera = 19, + Index = 20, + Unknown23 = 23, + Unknown24 = 24, + Unknown25 = 25, + Unknown27 = 27, + End = 0xFFFF + } + + public static class RecEnum + { + public static bool IsDefined(string name) + { + return Enum.IsDefined(typeof(T), name); + } + + public static bool IsDefined(T value) + { + return Enum.IsDefined(typeof(T), value); + } + } + + public class Record + { + public Record Parent = null; + public List Childs = new List(); + public bool IsRoot { get { return Parent == null; } } + public int RootLevel { get { return Parent == null ? 0 : Parent.RootLevel + 1; } } + public string Ierarchy { get { return Parent == null ? @"\Root" : Parent.Ierarchy + @"\" + RecordType.ToString(); } } + public Exception ReadError = null; + + public ushort RType = 0; + public RecType RecordType { get { return (RecType)RType; } } + public ushort RFlags = 0; + public bool HasExtra { get { return (RFlags & 0x08) == 0x08; } } + + public uint MainLength = 0; + public uint ExtraLength = 0; + public uint TotalLength = 0; + public byte[] MainData = new byte[0]; + public byte[] ExtraData = new byte[0]; + + public Record(Record parent) + { + this.Parent = parent; + if (parent != null) parent.Childs.Add(this); + } + + public static Record Create(Record parent, ushort RecordType) + { + Record res = null; + if (RecordType == 0) res = new RecHeader0(parent); + if (RecordType == 1) res = new RecHeader1(parent); + if (RecordType == 2) res = new RecWaypoint(parent); + if (RecordType == 3) res = new RecAlert(parent); + if (RecordType == 4) res = new RecBitmapReference(parent); + if (RecordType == 5) res = new RecBitmap(parent); + if (RecordType == 6) res = new RecCategoryReference(parent); + if (RecordType == 7) res = new RecCategory(parent); + if (RecordType == 8) res = new RecArea(parent); + if (RecordType == 9) res = new RecPOIGroup(parent); + if (RecordType == 10) res = new RecComment(parent); + if (RecordType == 11) res = new RecAddress(parent); + if (RecordType == 12) res = new RecContact(parent); + if (RecordType == 13) res = new RecImage(parent); + if (RecordType == 14) res = new RecDescription(parent); + if (RecordType == 17) res = new RecCopyright(parent); + if (RecordType == 18) res = new RecMedia(parent); + if (RecordType == 19) res = new RecSpeedCamera(parent); + if (RecordType == 0xFFFF) res = new RecEnd(parent); + if (res == null) res = new Record(parent); + res.RType = RecordType; + return res; + } + + public override string ToString() + { + return String.Format("{1}[{2}]{3}", RecordType, RType, RootLevel, Ierarchy); + } + } + + // 0 + public class RecHeader0 : Record + { + public RecHeader0(Record parent) : base(parent) { } + public string Header = null; + public string Version = null; + public DateTime Created = DateTime.MinValue; + public string Name = null; + } + + // 1 + public class RecHeader1 : Record + { + public RecHeader1(Record parent) : base(parent) { } + public string Content = null; + public ushort CodePage = 0xFDE9; + public Encoding Encoding + { + get + { + try { return Encoding.GetEncoding(CodePage); } catch { }; + return Encoding.Unicode; + } + } + } + + // 2 + public class RecWaypoint : Record + { + public RecWaypoint(Record parent) : base(parent) { } + public int cLat; + public int cLon; + public double Lat { get { return (double)cLat * 360.0 / Math.Pow(2, 32); } } + public double Lon { get { return (double)cLon * 360.0 / Math.Pow(2, 32); } } + public List> ShortName = new List>(); + + public string Name + { + get + { + foreach (KeyValuePair kvp in ShortName) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in ShortName) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in ShortName) + return kvp.Value; + return null; + } + } + + public RecAlert Alert; + public RecBitmap Bitmap; + public RecImage Image; + + public RecDescription Description; + public RecComment Comment; + public RecContact Contact; + public RecAddress Address; + } + + // 3 + public class RecAlert : Record + { + public RecAlert(Record parent) : base(parent) { } + public ushort Proximity; + public ushort cSpeed; + public int Speed { get { return (int)Math.Round((double)cSpeed / 100.0 * 3.6); } } + public byte Alert; + public byte AlertType; + public byte SoundNumber; + public byte AudioAlert; + public bool IsOn { get { return Alert == 1; } } + public string IsType { get { + if (AlertType == 0) return "proximity"; + if (AlertType == 1) return "along_road"; + if (AlertType == 2) return "toure_guide"; + return AlertType.ToString(); + } } + } + + // 4 + public class RecBitmapReference : Record + { + public RecBitmapReference(Record parent) : base(parent) { } + public ushort BitmapID; + } + + // 5 + public class RecBitmap : Record + { + public RecBitmap(Record parent) : base(parent) { } + public ushort BitmapID; + public ushort Height; + public ushort Width; + public ushort LineSize; + public ushort BitsPerPixel; + public ushort Reserved9; + public uint ImageSize; // LineSize * Height + public uint Reserved10; + public uint Palette; + public uint TransparentColor; + public uint Flags; + public uint Reserved11; + public byte[] Pixels; + public uint[] Colors; + } + + // 6 + public class RecCategoryReference : Record + { + public RecCategoryReference(Record parent) : base(parent) { } + public ushort CategoryID; + } + + // 7 + public class RecCategory : Record + { + public RecCategory(Record parent) : base(parent) { } + public ushort CategoryID; + public List> Category = new List>(); + public string Name + { + get + { + foreach (KeyValuePair kvp in Category) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in Category) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in Category) + return kvp.Value; + return null; + } + } + + public List Waypoints = new List(); + public RecBitmap Bitmap = null; + + public RecDescription Description; + public RecComment Comment; + public RecContact Contact; + } + + // 8 + public class RecArea : Record + { + public RecArea(Record parent) : base(parent) { } + public int cMaxLat; + public int cMaxLon; + public int cMinLat; + public int cMinLon; + public double MaxLat { get { return (double)cMaxLat * 360.0 / Math.Pow(2, 32); } } + public double MaxLon { get { return (double)cMaxLon * 360.0 / Math.Pow(2, 32); } } + public double MinLat { get { return (double)cMinLat * 360.0 / Math.Pow(2, 32); } } + public double MinLon { get { return (double)cMinLon * 360.0 / Math.Pow(2, 32); } } + } + + // 9 + public class RecPOIGroup : Record + { + public RecPOIGroup(Record parent) : base(parent) { } + public List> DataSource = new List>(); + + public string Name + { + get + { + foreach (KeyValuePair kvp in DataSource) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in DataSource) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in DataSource) + return kvp.Value; + return null; + } + } + } + + // 10 + public class RecComment : Record + { + public RecComment(Record parent) : base(parent) { } + public List> Comment = new List>(); + + public string Text + { + get + { + foreach (KeyValuePair kvp in Comment) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in Comment) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in Comment) + return kvp.Value; + return null; + } + } + } + + // 11 + public class RecAddress : Record + { + public RecAddress(Record parent) : base(parent) { } + public ushort Flags; + public List> aCity = new List>(); + public List> aCountry = new List>(); + public List> aState = new List>(); + public string Postal; + public List> aStreet = new List>(); + public string House; + + public string City + { + get + { + foreach (KeyValuePair kvp in aCity) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in aCity) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in aCity) + return kvp.Value; + return null; + } + } + + public string Country + { + get + { + foreach (KeyValuePair kvp in aCountry) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in aCountry) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in aCountry) + return kvp.Value; + return null; + } + } + + public string State + { + get + { + foreach (KeyValuePair kvp in aState) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in aState) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in aState) + return kvp.Value; + return null; + } + } + + public string Street + { + get + { + foreach (KeyValuePair kvp in aStreet) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in aStreet) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in aStreet) + return kvp.Value; + return null; + } + } + } + + // 12 + public class RecContact : Record + { + public RecContact(Record parent) : base(parent) { } + public ushort Flags; + public List> cPhone = new List>(); + public List> cPhone2 = new List>(); + public List> cFax = new List>(); + public List> cEmail = new List>(); + public List> cWeb = new List>(); + + public string Phone + { + get + { + foreach (KeyValuePair kvp in cPhone) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cPhone) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cPhone) + return kvp.Value; + return null; + } + } + + public string Phone2 + { + get + { + foreach (KeyValuePair kvp in cPhone2) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cPhone2) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cPhone2) + return kvp.Value; + return null; + } + } + + public string Fax + { + get + { + foreach (KeyValuePair kvp in cFax) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cFax) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cFax) + return kvp.Value; + return null; + } + } + + public string Email + { + get + { + foreach (KeyValuePair kvp in cEmail) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cEmail) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cEmail) + return kvp.Value; + return null; + } + } + + public string Web + { + get + { + foreach (KeyValuePair kvp in cWeb) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cWeb) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cWeb) + return kvp.Value; + return null; + } + } + } + + // 13 + public class RecImage : Record + { + public RecImage(Record parent) : base(parent) { } + public uint Length; + public byte[] ImageData; + } + + // 14 + public class RecDescription : Record + { + public RecDescription(Record parent) : base(parent) { } + public List> Description = new List>(); + + public string Text + { + get + { + foreach (KeyValuePair kvp in Description) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in Description) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in Description) + return kvp.Value; + return null; + } + } + } + + // 17 + public class RecCopyright : Record + { + public RecCopyright(Record parent) : base(parent) { } + public ushort Flags1 = 0; + public ushort Flags2 = 0; + public List> cDataSource = new List>(); + public List> cCopyrights = new List>(); + public string DeviceModel = null; + + public string DataSource + { + get + { + foreach (KeyValuePair kvp in cDataSource) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cDataSource) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cDataSource) + return kvp.Value; + return null; + } + } + + public string Copyrights + { + get + { + foreach (KeyValuePair kvp in cCopyrights) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cCopyrights) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cCopyrights) + return kvp.Value; + return null; + } + } + } + + // 18 + public class RecMedia : Record + { + public RecMedia(Record parent) : base(parent) { } + public ushort MediaID; + public byte Format; + public bool IsWav { get { return Format == 0; } } + public bool IsMP3 { get { return Format == 1; } } + public List> Content = new List>(); + + public byte[] Media + { + get + { + foreach (KeyValuePair kvp in Content) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in Content) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + return null; + } + } + } + + // 19 + public class RecSpeedCamera : Record + { + public RecSpeedCamera(Record parent) : base(parent) { } + public int cMaxLat; + public int cMaxLon; + public int cMinLat; + public int cMinLon; + public double MaxLat { get { return (double)cMaxLat * 360.0 / Math.Pow(2, 24); } } + public double MaxLon { get { return (double)cMaxLon * 360.0 / Math.Pow(2, 24); } } + public double MinLat { get { return (double)cMinLat * 360.0 / Math.Pow(2, 24); } } + public double MinLon { get { return (double)cMinLon * 360.0 / Math.Pow(2, 24); } } + public byte Flags; + public int cLat; + public int cLon; + public double Lat { get { return (double)cLat * 360.0 / Math.Pow(2, 24); } } + public double Lon { get { return (double)cLon * 360.0 / Math.Pow(2, 24); } } + } + + // 0xFFFF + public class RecEnd : Record + { + public RecEnd(Record parent) : base(parent) { } + } + #endregion RECTYPES + + + /// + /// GPI Reader + /// + public class GPIReader + { + public static string LOCALE_LANGUAGE = "EN"; // 2-SYMBOLS + public static string DEFAULT_LANGUAGE = "EN"; // 2-SYMBOLS + + private string fileName; + public string FileName { get { return fileName; } } + + public Record RootElement = new Record(null); + + public string Content = null; + public ushort CodePage = 0xFDE9; + public Encoding Encoding = Encoding.Unicode; + public string Header = null; + public string Version = null; + public DateTime Created = DateTime.MinValue; + public string Name = null; + public List> cDataSource = new List>(); + public List> cCopyrights = new List>(); + + public Dictionary Categories = new Dictionary(); + public Dictionary Bitmaps = new Dictionary(); + + public string DataSource + { + get + { + foreach (KeyValuePair kvp in cDataSource) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cDataSource) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cDataSource) + return kvp.Value; + return null; + } + } + + public string Copyrights + { + get + { + foreach (KeyValuePair kvp in cCopyrights) + if (kvp.Key == GPIReader.LOCALE_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cCopyrights) + if (kvp.Key == GPIReader.DEFAULT_LANGUAGE) + return kvp.Value; + foreach (KeyValuePair kvp in cCopyrights) + return kvp.Value; + return null; + } + } + + public GPIReader(string fileName) + { + this.fileName = fileName; + this.Read(); + this.LoopRecords(this.RootElement.Childs); + } + + public void SaveToKML(string fileName) + { + string images_file_dir = Path.GetDirectoryName(fileName) + @"\images\"; + Directory.CreateDirectory(images_file_dir); + + FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write); + StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8); + sw.WriteLine(""); + sw.WriteLine(""); + string caption = (String.IsNullOrEmpty(this.Name) ? "GPI Has No Name" : this.Name); + sw.WriteLine("KMZ Rebuilder GPI Reader"); + string desc = "Created: " + this.Created.ToString() + "\r\n"; + foreach (KeyValuePair langval in this.cDataSource) + desc += String.Format("data_source:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + foreach (KeyValuePair langval in this.cCopyrights) + desc += String.Format("copyrights:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + sw.WriteLine(""); + List simstyles = new List(); + foreach (KeyValuePair kCat in this.Categories) + { + if (kCat.Value.Waypoints.Count == 0) continue; + + string style = "catid" + kCat.Value.CategoryID.ToString(); + if (kCat.Value.Bitmap != null) style = "imgid" + kCat.Value.Bitmap.BitmapID.ToString(); + + sw.WriteLine(""); + desc = "CategoryID: " + kCat.Value.CategoryID.ToString() + "\r\n"; + desc += "Objects: " + kCat.Value.Waypoints.Count.ToString() + "\r\n"; + foreach (KeyValuePair langval in kCat.Value.Category) + desc += String.Format("name:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + if (kCat.Value.Description != null) + foreach (KeyValuePair langval in kCat.Value.Description.Description) + desc += String.Format("desc:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + if (kCat.Value.Comment != null) + foreach (KeyValuePair langval in kCat.Value.Comment.Comment) + desc += String.Format("comm:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + if (kCat.Value.Contact != null) + { + foreach (KeyValuePair langval in kCat.Value.Contact.cPhone) + desc += String.Format("contact_phone:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + foreach (KeyValuePair langval in kCat.Value.Contact.cPhone2) + desc += String.Format("contact_phone2:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + foreach (KeyValuePair langval in kCat.Value.Contact.cFax) + desc += String.Format("contact_fax:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + if (!String.IsNullOrEmpty(kCat.Value.Contact.Email)) + desc += String.Format("contact_email={0}\r\n", kCat.Value.Contact.Email); + if (!String.IsNullOrEmpty(kCat.Value.Contact.Web)) + desc += String.Format("contact_web={0}\r\n", kCat.Value.Contact.Web); + }; + sw.WriteLine(""); + foreach (RecWaypoint wp in kCat.Value.Waypoints) + { + sw.WriteLine(""); + sw.WriteLine(""); + string text = ""; + foreach (KeyValuePair langval in wp.ShortName) + text += String.Format("name:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + if (wp.Description != null) + foreach (KeyValuePair langval in wp.Description.Description) + text += String.Format("desc:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + if (wp.Comment != null) + foreach (KeyValuePair langval in wp.Comment.Comment) + text += String.Format("comm:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + if (wp.Contact != null) + { + foreach (KeyValuePair langval in wp.Contact.cPhone) + text += String.Format("contact_phone:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + foreach (KeyValuePair langval in wp.Contact.cPhone2) + text += String.Format("contact_phone2:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + foreach (KeyValuePair langval in wp.Contact.cFax) + text += String.Format("contact_fax:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + if (!String.IsNullOrEmpty(wp.Contact.Email)) + text += String.Format("contact_email={0}\r\n", wp.Contact.Email); + if (!String.IsNullOrEmpty(wp.Contact.Web)) + text += String.Format("contact_web={0}\r\n", wp.Contact.Web); + }; + if (wp.Address != null) + { + foreach (KeyValuePair langval in wp.Address.aCountry) + text += String.Format("addr_country:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + if (!String.IsNullOrEmpty(wp.Address.Postal)) + text += String.Format("addr_postal={0}\r\n", wp.Address.Postal); + foreach (KeyValuePair langval in wp.Address.aState) + text += String.Format("addr_state:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + foreach (KeyValuePair langval in wp.Address.aCity) + text += String.Format("addr_city:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + foreach (KeyValuePair langval in wp.Address.aStreet) + text += String.Format("addr_street:{0}={1}\r\n", langval.Key.ToLower(), langval.Value); + if (!String.IsNullOrEmpty(wp.Address.House)) + text += String.Format("addr_house={0}\r\n", wp.Address.Postal); + }; + if (wp.Alert != null) + { + text += String.Format("alert_proximity={0}\r\n", wp.Alert.Proximity); + text += String.Format("alert_speed={0}\r\n", wp.Alert.Speed); + text += String.Format("alert_ison={0}\r\n", wp.Alert.Alert); + text += String.Format("alert_type={0}\r\n", wp.Alert.IsType); + }; + if (wp.Bitmap != null) style = "imgid" + wp.Bitmap.BitmapID.ToString(); + if ((wp.Image != null) && (wp.Image.Length > 0)) + { + try + { + string simid = "simid" + simstyles.Count.ToString(); + FileStream fsimid = new FileStream(images_file_dir + simid + ".jpg", FileMode.Create, FileAccess.Write); + fsimid.Write(wp.Image.ImageData, 0, wp.Image.ImageData.Length); + fsimid.Close(); + simstyles.Add(simid); + style = simid; + } + catch (Exception ex) { }; + }; + sw.WriteLine(""); + sw.WriteLine("#" + style + ""); + string xyz = wp.Lon.ToString(System.Globalization.CultureInfo.InvariantCulture) + "," + wp.Lat.ToString(System.Globalization.CultureInfo.InvariantCulture) + ",0"; + sw.WriteLine("" + xyz + ""); + sw.WriteLine(""); + }; + sw.WriteLine(""); + }; + foreach (string simid in simstyles) + { + sw.WriteLine("\t"); + }; + foreach (KeyValuePair kCat in this.Categories) + { + if (kCat.Value.Bitmap != null) continue; + string catID = "catid" + kCat.Value.CategoryID.ToString(); + sw.WriteLine("\t"); + try + { + Image im = new Bitmap(16, 16); + Graphics g = Graphics.FromImage(im); + g.FillEllipse(Brushes.Magenta, 0, 0, 16, 16); + string ttd = kCat.Value.CategoryID.ToString(); + while (ttd.Length < 2) ttd = "0" + ttd; + g.DrawString(ttd, new Font("MS Sans Serif", 8), Brushes.Black, 0, 2); + g.Dispose(); + im.Save(images_file_dir + catID + ".png"); + } + catch (Exception ex) { }; + } + foreach (KeyValuePair bitmaps in this.Bitmaps) + { + string imgID = "imgid" + bitmaps.Value.BitmapID.ToString(); + sw.WriteLine("\t"); + RecBitmap br = bitmaps.Value; + if ((br.Pixels != null) && (br.Pixels.Length > 0)) + { + try + { + int wi = br.Width; + byte[] sub = new byte[4]; + int pixelsize = 1; + if (br.Palette == 0) pixelsize = br.LineSize / br.Width; + if (br.Palette == 16) wi = br.Width / 2; + + Bitmap bmp = new Bitmap(br.Width, br.Height); + Graphics g = Graphics.FromImage(bmp); + g.Clear(Color.Transparent); + g.Dispose(); + for (int h = 0; h < br.Height; h++) + { + int voffset = br.LineSize * h; + for (int w = 0; w < wi; w++) + { + int hoffset = voffset + w * pixelsize; + Array.Copy(br.Pixels, hoffset, sub, 0, pixelsize); + uint color = BitConverter.ToUInt32(sub, 0); + Color c = Color.Transparent; + if (br.Palette == 0) + { + bmp.SetPixel(w, h, Color.Transparent); + if (color == br.TransparentColor) continue; + c = ColorFromUint(color); + bmp.SetPixel(w, h, c); + } + else if (br.Palette > 16) + { + bmp.SetPixel(w, h, Color.Transparent); + color = br.Colors[color]; + if (color == br.TransparentColor) continue; + c = ColorFromUint(color); + bmp.SetPixel(w, h, c); + } + else + { + bmp.SetPixel(2 * w, h, Color.Transparent); + bmp.SetPixel(2 * w + 1, h, Color.Transparent); + int low = (int)br.Colors[(color) & 0x0F]; + int hi = (int)br.Colors[((color) & 0xF0) >> 4]; + if (low != br.TransparentColor) bmp.SetPixel(2 * w, h, Color.FromArgb(low)); + if (hi != br.TransparentColor) bmp.SetPixel(2 * w + 1, h, Color.FromArgb(hi)); + }; + }; + }; + bmp.Save(images_file_dir + imgID + ".png"); + bmp.Dispose(); + } + catch (Exception ex) + { + + }; + }; + }; + sw.WriteLine(""); + sw.Close(); + fs.Close(); + } + + private void LoopRecords(List records) + { + if ((records == null) || (records.Count == 0)) return; + foreach (Record r in records) + { + GetReferences(r); + LoopRecords(r.Childs); + }; + } + + private void GetReferences(Record r) + { + if (r is RecBitmapReference) + { + RecBitmapReference rec = (RecBitmapReference)r; + if ((rec.Parent != null) && (rec.Parent is RecCategory)) + try { ((RecCategory)rec.Parent).Bitmap = this.Bitmaps[rec.BitmapID]; } + catch { /* No Bitmap */ }; + if ((rec.Parent != null) && (rec.Parent is RecWaypoint)) + try { ((RecWaypoint)rec.Parent).Bitmap = this.Bitmaps[rec.BitmapID]; } + catch { /* No Bitmap */ }; + }; + if (r is RecCategoryReference) + { + RecCategoryReference rec = (RecCategoryReference)r; + if ((rec.Parent != null) && (rec.Parent is RecWaypoint)) + { + RecWaypoint rw = (RecWaypoint)rec.Parent; + try { this.Categories[rec.CategoryID].Waypoints.Add(rw); } + catch { /* No Category */ }; + }; + }; + } + + private void Read() + { + FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); + byte[] fileData = new byte[fs.Length]; + fs.Read(fileData, 0, fileData.Length); + fs.Close(); + + if (fileData.Length != 0) + ReadData(ref fileData, RootElement); + } + + private void ReadData(ref byte[] fileData, Record parent) + { + int offset = 0; + while (offset < fileData.Length) + { + int blockLength = ReadRecordBlock(ref fileData, parent, offset); + offset += blockLength; + }; + } + + private int ReadRecordBlock(ref byte[] data, Record parent, int offset) + { + int start_offset = offset; + Record rec = Record.Create(parent, BitConverter.ToUInt16(data, offset)); offset += 2; + rec.RFlags = BitConverter.ToUInt16(data, offset); offset += 2; + rec.TotalLength = BitConverter.ToUInt32(data, offset); offset += 4; + rec.MainLength = rec.TotalLength; + try + { + if (rec.HasExtra) + { + rec.MainLength = BitConverter.ToUInt32(data, offset); offset += 4; + rec.ExtraLength = rec.TotalLength - rec.MainLength; + }; + if (RecEnum.IsDefined((RecType)rec.RType)) // only specified + { + rec.MainData = new byte[rec.MainLength]; + Array.Copy(data, offset, rec.MainData, 0, rec.MainData.Length); + if (rec.HasExtra) + { + rec.ExtraData = new byte[rec.ExtraLength]; + Array.Copy(data, offset + rec.MainLength, rec.ExtraData, 0, rec.ExtraData.Length); + }; + ReadMainBlock(rec); + if (rec.HasExtra) ReadData(ref rec.ExtraData, rec); + }; + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + int ttlbl = (int)(offset - start_offset + rec.TotalLength); + return ttlbl; + } + + private void ReadMainBlock(Record rec) + { + if ((rec.RType == 0) && (rec is RecHeader0)) ReadHeader1((RecHeader0)rec); + if ((rec.RType == 1) && (rec is RecHeader1)) ReadHeader2((RecHeader1)rec); + if ((rec.RType == 2) && (rec is RecWaypoint)) ReadWaypoint((RecWaypoint)rec); + if ((rec.RType == 3) && (rec is RecAlert)) ReadAlert((RecAlert)rec); + if ((rec.RType == 4) && (rec is RecBitmapReference)) ReadBitmapReference((RecBitmapReference)rec); + if ((rec.RType == 5) && (rec is RecBitmap)) ReadBitmap((RecBitmap)rec); + if ((rec.RType == 6) && (rec is RecCategoryReference)) ReadCategoryReference((RecCategoryReference)rec); + if ((rec.RType == 7) && (rec is RecCategory)) ReadCategory((RecCategory)rec); + if ((rec.RType == 8) && (rec is RecArea)) ReadArea((RecArea)rec); + if ((rec.RType == 9) && (rec is RecPOIGroup)) ReadPOIGroup((RecPOIGroup)rec); + if ((rec.RType == 10) && (rec is RecComment)) ReadComment((RecComment)rec); + if ((rec.RType == 11) && (rec is RecAddress)) ReadAddress((RecAddress)rec); + if ((rec.RType == 12) && (rec is RecContact)) ReadContact((RecContact)rec); + if ((rec.RType == 13) && (rec is RecImage)) ReadImage((RecImage)rec); + if ((rec.RType == 14) && (rec is RecDescription)) ReadDecription((RecDescription)rec); + if ((rec.RType == 17) && (rec is RecCopyright)) ReadCopyright((RecCopyright)rec); + if ((rec.RType == 18) && (rec is RecMedia)) ReadMedia((RecMedia)rec); + if ((rec.RType == 19) && (rec is RecSpeedCamera)) ReadSpeedCamera((RecSpeedCamera)rec); + } + + private void ReadHeader1(RecHeader0 rec) // 0 + { + byte[] sub = new byte[6]; + Array.Copy(rec.MainData, 0, sub, 0, 6); + rec.Header = Header = Encoding.ASCII.GetString(sub); + sub = new byte[2]; + Array.Copy(rec.MainData, 6, sub, 0, 2); + rec.Version = Version = Encoding.ASCII.GetString(sub); + uint time = BitConverter.ToUInt32(rec.MainData, 8); + if (time != 0xFFFFFFFF) + rec.Created = Created = (new DateTime(1990, 1, 1)).AddSeconds(time); + ushort slen = BitConverter.ToUInt16(rec.MainData, 14); + rec.Name = Name = Encoding.ASCII.GetString(rec.MainData, 16, slen); + } + + private void ReadHeader2(RecHeader1 rec) // 1 + { + int bLen = 0; + while (rec.MainData[bLen] != 0) bLen++; + rec.Content = this.Content = Encoding.ASCII.GetString(rec.MainData, 0, bLen++); + rec.CodePage = this.CodePage = BitConverter.ToUInt16(rec.MainData, bLen + 4); + this.Encoding = rec.Encoding; + } + + private void ReadWaypoint(RecWaypoint rec) // 2 + { + rec.cLat = BitConverter.ToInt32(rec.MainData, 0); + rec.cLon = BitConverter.ToInt32(rec.MainData, 4); + int offset = 11; + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.ShortName.Add(new KeyValuePair(lang, text)); + }; + } + + private void ReadAlert(RecAlert rec) // 3 + { + try + { + rec.Proximity = BitConverter.ToUInt16(rec.MainData, 0); + rec.cSpeed = BitConverter.ToUInt16(rec.MainData, 2); + rec.Alert = rec.MainData[8]; + rec.AlertType = rec.MainData[9]; + rec.SoundNumber = rec.MainData[10]; + rec.AudioAlert = rec.MainData[11]; + if ((rec.Parent != null) && (rec.Parent is RecWaypoint)) ((RecWaypoint)rec.Parent).Alert = rec; + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + } + + public void ReadBitmapReference(RecBitmapReference rec) // 4 + { + rec.BitmapID = BitConverter.ToUInt16(rec.MainData, 0); + } + + public void ReadBitmap(RecBitmap rec) // 5 + { + try + { + int offset = 0; + rec.BitmapID = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + rec.Height = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + rec.Width = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + rec.LineSize = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + rec.BitsPerPixel = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + rec.Reserved9 = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + rec.ImageSize = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + rec.Reserved10 = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + rec.Palette = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + rec.TransparentColor = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + rec.Flags = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + rec.Reserved11 = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + rec.Pixels = new byte[rec.ImageSize]; + Array.Copy(rec.MainData, offset, rec.Pixels, 0, rec.ImageSize); offset += (int)rec.ImageSize; + rec.Colors = new uint[rec.Palette]; + for (int i = 0; i < rec.Colors.Length; i++) { rec.Colors[i] = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; }; + this.Bitmaps.Add(rec.BitmapID, rec); + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + } + + private void ReadCategoryReference(RecCategoryReference rec) // 6 + { + rec.CategoryID = BitConverter.ToUInt16(rec.MainData, 0); + } + + private void ReadCategory(RecCategory rec) // 7 + { + rec.CategoryID = BitConverter.ToUInt16(rec.MainData, 0); + int offset = 2; + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.Category.Add(new KeyValuePair(lang, text)); + }; + this.Categories.Add(rec.CategoryID, rec); + } + + private void ReadArea(RecArea rec) // 8 + { + rec.cMaxLat = BitConverter.ToInt32(rec.MainData, 0); + rec.cMaxLon = BitConverter.ToInt32(rec.MainData, 4); + rec.cMinLat = BitConverter.ToInt32(rec.MainData, 8); + rec.cMinLon = BitConverter.ToInt32(rec.MainData, 12); + } + + private void ReadPOIGroup(RecPOIGroup rec) // 9 + { + int offset = 0; + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.DataSource.Add(new KeyValuePair(lang, text)); + }; + + byte[] areas = new byte[rec.MainLength - offset]; + Array.Copy(rec.MainData, offset, areas, 0, areas.Length); + ReadData(ref areas, rec); + } + + private void ReadComment(RecComment rec) // 10 + { + try + { + int offset = 0; + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.Comment.Add(new KeyValuePair(lang, text)); + }; + if ((rec.Parent != null) && (rec.Parent is RecWaypoint)) ((RecWaypoint)rec.Parent).Comment = rec; + if ((rec.Parent != null) && (rec.Parent is RecCategory)) ((RecCategory)rec.Parent).Comment = rec; + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + } + + private void ReadAddress(RecAddress rec) // 11 + { + int offset = 0; + rec.Flags = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + try + { + if (this.Version == "01") + { + if ((rec.Flags & 0x0001) == 0x0001) + { + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.aCity.Add(new KeyValuePair(lang, text)); + }; + }; + if ((rec.Flags & 0x0002) == 0x0002) + { + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.aCountry.Add(new KeyValuePair(lang, text)); + }; + }; + if ((rec.Flags & 0x0004) == 0x0004) + { + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.aState.Add(new KeyValuePair(lang, text)); + }; + }; + if ((rec.Flags & 0x0008) == 0x0008) + { + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; + rec.Postal = text; + }; + if ((rec.Flags & 0x0010) == 0x0010) + { + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.aStreet.Add(new KeyValuePair(lang, text)); + }; + }; + if ((rec.Flags & 0x0020) == 0x0020) + { + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; + rec.House = text; + }; + }; + if ((rec.Parent != null) && (rec.Parent is RecWaypoint)) ((RecWaypoint)rec.Parent).Address = rec; + + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + } + + private void ReadContact(RecContact rec) // 12 + { + int offset = 0; + rec.Flags = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + try + { + if (this.Version == "01") + { + if ((rec.Flags & 0x0001) == 0x0001) + { + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.cPhone.Add(new KeyValuePair(lang, text)); + }; + }; + if ((rec.Flags & 0x0002) == 0x0002) + { + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.cPhone2.Add(new KeyValuePair(lang, text)); + }; + }; + if ((rec.Flags & 0x0004) == 0x0004) + { + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.cFax.Add(new KeyValuePair(lang, text)); + }; + }; + if ((rec.Flags & 0x0008) == 0x0008) + { + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.cEmail.Add(new KeyValuePair(lang, text)); + }; + }; + if ((rec.Flags & 0x0010) == 0x0010) + { + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.cWeb.Add(new KeyValuePair(lang, text)); + }; + }; + }; + if ((rec.Parent != null) && (rec.Parent is RecWaypoint)) ((RecWaypoint)rec.Parent).Contact = rec; + if ((rec.Parent != null) && (rec.Parent is RecCategory)) ((RecCategory)rec.Parent).Contact = rec; + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + } + + private void ReadImage(RecImage rec) // 13 + { + try + { + rec.Length = BitConverter.ToUInt32(rec.MainData, 1); + rec.ImageData = new byte[rec.Length]; + if (rec.Length > 0) + Array.Copy(rec.MainData, 5, rec.ImageData, 0, rec.Length); + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + } + + private void ReadDecription(RecDescription rec) // 14 + { + try + { + int offset = 1; + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.Description.Add(new KeyValuePair(lang, text)); + }; + if ((rec.Parent != null) && (rec.Parent is RecWaypoint)) ((RecWaypoint)rec.Parent).Description = rec; + if ((rec.Parent != null) && (rec.Parent is RecCategory)) ((RecCategory)rec.Parent).Description = rec; + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + } + + private void ReadCopyright(RecCopyright rec) // 17 + { + try + { + int offset = 0; + rec.Flags1 = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; + rec.Flags2 = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; offset += 4; + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + int readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.cDataSource.Add(new KeyValuePair(lang, text)); + }; + len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + readed = 0; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = this.Encoding.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.cCopyrights.Add(new KeyValuePair(lang, text)); + }; + this.cDataSource = rec.cDataSource; + this.cCopyrights = rec.cCopyrights; + if ((rec.Flags1 & 0x0400) == 0x0400) + { + ushort tlen = BitConverter.ToUInt16(rec.MainData, offset); offset += 2; readed += 2; + string text = Encoding.ASCII.GetString(rec.MainData, offset, tlen); offset += tlen; readed += tlen; + rec.DeviceModel = text; + }; + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + } + + private void ReadMedia(RecMedia rec) // 18 + { + rec.MediaID = BitConverter.ToUInt16(rec.MainData, 0); + rec.Format = rec.MainData[2]; + try + { + int offset = 3; + int readed = 0; + uint len = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; + while (readed < len) + { + string lang = Encoding.ASCII.GetString(rec.MainData, offset, 2); offset += 2; readed += 2; + uint mlen = BitConverter.ToUInt32(rec.MainData, offset); offset += 4; readed += 4; + byte[] media = new byte[mlen]; + Array.Copy(rec.MainData, offset, media, 0, mlen); + rec.Content.Add(new KeyValuePair(lang, media)); + }; + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + } + + private void ReadSpeedCamera(RecSpeedCamera rec) // 19 + { + try + { + int offset = 0; + byte[] buff = new byte[4]; + Array.Copy(rec.MainData, offset, buff, 0, 3); offset += 3; + rec.cMaxLat = BitConverter.ToInt32(buff, 0); + Array.Copy(rec.MainData, offset, buff, 0, 3); offset += 3; + rec.cMaxLon = BitConverter.ToInt32(buff, 0); + Array.Copy(rec.MainData, offset, buff, 0, 3); offset += 3; + rec.cMinLat = BitConverter.ToInt32(buff, 0); + Array.Copy(rec.MainData, offset, buff, 0, 3); offset += 3; + rec.cMinLon = BitConverter.ToInt32(buff, 0); + rec.Flags = rec.MainData[offset]; offset++; + if (rec.Flags == 0x81) offset += 11; + if ((rec.Flags == 0x80) || (rec.Flags > 0x81)) offset++; + byte f10v = rec.MainData[offset]; offset++; + if (rec.Flags == 0x81) offset++; + offset += 1 + f10v; + Array.Copy(rec.MainData, offset, buff, 0, 3); offset += 3; + rec.cLat = BitConverter.ToInt32(buff, 0); + Array.Copy(rec.MainData, offset, buff, 0, 3); offset += 3; + rec.cLon = BitConverter.ToInt32(buff, 0); + } + catch (Exception ex) + { + rec.ReadError = ex; + }; + } + + private static Color ColorFromUint(uint value) + { + return Color.FromArgb((int)((value >> 0) & 0xFF), (int)((value >> 8) & 0xFF), (int)((value >> 16) & 0xFF)); + } + } +} diff --git a/KMZViewer.csproj b/KMZViewer.csproj index 2741276..ada7869 100644 --- a/KMZViewer.csproj +++ b/KMZViewer.csproj @@ -72,6 +72,7 @@ + Component @@ -92,6 +93,7 @@ + Form diff --git a/KMZViewerForm.cs b/KMZViewerForm.cs index 4f1c546..bf086bd 100644 Binary files a/KMZViewerForm.cs and b/KMZViewerForm.cs differ diff --git a/KMZViewerForm.designer.cs b/KMZViewerForm.designer.cs index 0c1269c..615c780 100644 --- a/KMZViewerForm.designer.cs +++ b/KMZViewerForm.designer.cs @@ -468,6 +468,8 @@ private void InitializeComponent() this.toolStripStatusLabel12 = new System.Windows.Forms.ToolStripStatusLabel(); this.toolStripStatusLabel13 = new System.Windows.Forms.ToolStripStatusLabel(); this.rtStatus = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripMenuItem36 = new System.Windows.Forms.ToolStripSeparator(); + this.propsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.statusStrip2.SuspendLayout(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); @@ -541,6 +543,8 @@ private void InitializeComponent() this.openPlugInsToolStripMenuItem, this.pofiles, this.сохранитьСлоиВФайлToolStripMenuItem, + this.toolStripMenuItem36, + this.propsToolStripMenuItem, this.toolStripMenuItem2, this.showrouteToolStripMenuItem, this.sPVToolStripMenuItem, @@ -704,7 +708,7 @@ private void InitializeComponent() this.toolStripStatusLabel1.BackColor = System.Drawing.Color.Navy; this.toolStripStatusLabel1.ForeColor = System.Drawing.Color.Silver; this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; - this.toolStripStatusLabel1.Size = new System.Drawing.Size(392, 17); + this.toolStripStatusLabel1.Size = new System.Drawing.Size(361, 17); this.toolStripStatusLabel1.Spring = true; this.toolStripStatusLabel1.Text = "toolStripStatusLabel1"; this.toolStripStatusLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; @@ -3764,6 +3768,18 @@ private void InitializeComponent() this.rtStatus.Size = new System.Drawing.Size(25, 17); this.rtStatus.Text = "Idle"; // + // toolStripMenuItem36 + // + this.toolStripMenuItem36.Name = "toolStripMenuItem36"; + this.toolStripMenuItem36.Size = new System.Drawing.Size(263, 6); + // + // propsToolStripMenuItem + // + this.propsToolStripMenuItem.Name = "propsToolStripMenuItem"; + this.propsToolStripMenuItem.Size = new System.Drawing.Size(266, 22); + this.propsToolStripMenuItem.Text = "Предпочтения..."; + this.propsToolStripMenuItem.Click += new System.EventHandler(this.propsToolStripMenuItem_Click); + // // KMZViewerForm // this.AllowDrop = true; @@ -4201,5 +4217,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem selectRouteServiceToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem makerout; private System.Windows.Forms.ToolStripMenuItem rbMi; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem36; + private System.Windows.Forms.ToolStripMenuItem propsToolStripMenuItem; } } \ No newline at end of file diff --git a/Preferences.cs b/Preferences.cs new file mode 100644 index 0000000..b63bb8d --- /dev/null +++ b/Preferences.cs @@ -0,0 +1,144 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Xml; +using System.Xml.Serialization; +using System.Windows.Forms; + +namespace KMZ_Viewer +{ + [Serializable] + public class Preferences: KMZ_Viewer.XMLSaved + { + [XmlArray("configuration")] + [XmlArrayItem("property")] + public List Properties; + + [XmlIgnore] + public string this[string name] + { + get + { + LoadDefaults(); + if (Properties.Count == 0) return ""; + foreach (Property prop in Properties) + if (prop.name == name) + return prop.value; + return ""; + } + set + { + LoadDefaults(); + foreach (Property prop in Properties) + if (prop.name == name) + { + prop.value = value; + return; + }; + Properties.Add(new Property(name, value)); + } + } + + private void LoadDefaults() + { + if (Properties == null) + { + Properties = new List(); + this["gpi_localization"] = "EN"; + }; + } + + public static Preferences Load() + { + string fName = KMZ_Viewer.KMZViewerForm.CurrentDirectory() + @"\KMZViewer.config"; + if (File.Exists(fName)) + { + try { return Preferences.Load(fName); } catch { }; + }; + return new Preferences(); + } + + public void Save() + { + string fName = KMZ_Viewer.KMZViewerForm.CurrentDirectory() + @"\KMZViewer.config"; + this.LoadDefaults(); + try { Preferences.Save(fName, this); } catch { }; + } + + [Serializable] + public class Property + { + [XmlAttribute] + public string name; + [XmlText] + public string value; + + public Property() { } + public Property(string name) { this.name = name; } + public Property(string name, string value) { this.name = name; this.value = value; } + + public override string ToString() + { + return String.Format("{0}={1}", name, value); + } + } + + public void ShowChangeDialog() + { + Form form = new Form(); + form.StartPosition = FormStartPosition.CenterParent; + form.MinimizeBox = false; + form.MaximizeBox = false; + form.ShowIcon = false; + form.ShowInTaskbar = false; + form.Width = 400; + form.Height = 380; + form.Text = "Предпочтения"; + form.FormBorderStyle = FormBorderStyle.FixedDialog; + Label lab = new Label(); + form.Controls.Add(lab); + lab.Text = "Двойной клик на параметре или пробел чтобы изменить:"; + lab.AutoSize = true; + lab.Left = 8; + lab.Top = 5; + ListBox lb = new ListBox(); + form.Controls.Add(lb); + lb.Width = form.Width - 26; + lb.Left = 10; + lb.Top = 25; + lb.Height = form.Height - 90; + lb.BorderStyle = BorderStyle.FixedSingle; + foreach (Property prop in Properties) lb.Items.Add(prop); + lb.DoubleClick += (delegate(object sender, EventArgs e) { OnChangeItem(lb); }); + lb.KeyPress += (delegate(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)32) OnChangeItem(lb); }); + Button okbtn = new Button(); + form.Controls.Add(okbtn); + okbtn.Left = form.Width / 2 - okbtn.Width / 2; + okbtn.Top = lb.Top + lb.Height + 6; + okbtn.Text = "OK"; + okbtn.Click += (delegate(object sender, EventArgs e) { form.Close(); }); + form.ShowDialog(); + form.Dispose(); + } + + private void OnChangeItem(ListBox lb) + { + int si = lb.SelectedIndex; + if (si >= 0) + { + Property p = (Property)lb.Items[si]; + string nval = p.value; + if (InputBox.Show("Изменить параметр", p.name + ":", ref nval) == DialogResult.OK) + { + p.value = nval.Trim(); + this[p.name] = p.value; + lb.Items.RemoveAt(si); + lb.Items.Insert(si, p); + lb.SetSelected(si, true); + }; + }; + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 49221c3..ddf3847 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -37,5 +37,5 @@ // Build Number // Revision // -[assembly: AssemblyVersion("22.1.19.115")] -[assembly: AssemblyFileVersion("22.1.19.115")] +[assembly: AssemblyVersion("22.1.24.117")] +[assembly: AssemblyFileVersion("22.1.24.117")] diff --git a/bin/KMZViewer.exe b/bin/KMZViewer.exe new file mode 100644 index 0000000..3ad7d2d Binary files /dev/null and b/bin/KMZViewer.exe differ