/// <summary> /// Provides in-place (destructive) processing of the <see cref="Update"/>. /// </summary> /// <param name="update">The update instance.</param> /// <param name="file"> /// A KmlFile containing the <c>Update</c> and the update targets. /// </param> /// <exception cref="ArgumentNullException">file is null.</exception> public static void Process(this Update update, KmlFile file) { Check.IsNotNull(update, nameof(update)); Check.IsNotNull(file, nameof(file)); foreach (Element child in update.Updates) { if (child is ChangeCollection change) { ProcessChange(change, file); continue; } if (child is CreateCollection create) { ProcessCreate(create, file); continue; } if (child is DeleteCollection delete) { ProcessDelete(delete, file); } } }
private KmlFile LoadFile(string path) { try { byte[] data = this.fileResolver.ReadFile(path); using (var stream = new MemoryStream(data, false)) { if (path.EndsWith(".kml", StringComparison.OrdinalIgnoreCase)) { return KmlFile.Load(stream); } if (path.EndsWith(".kmz", StringComparison.OrdinalIgnoreCase)) { if (this.fileResolver.SupportsKmz) { return this.fileResolver.ExtractDefaultKmlFileFromKmzArchive(stream); } } } } catch (IOException) { // Silently fail } return null; }
private static void ProcessDelete(DeleteCollection delete, KmlFile file) { foreach (Feature source in delete) { if (source.TargetId != null) { if (file.FindObject(source.TargetId) is Feature feature) { // Remove the Feature from the parent, which is either // a Container or Kml if (feature.Parent is Container container) { container.RemoveFeature(source.TargetId); } else { if (feature.Parent is Kml kml) { kml.Feature = null; } } // Also remove it from the file file.RemoveFeature(feature); } } } }
/// <summary> /// Resolves all the styles in the specified <see cref="Feature"/>. /// </summary> /// <param name="feature"> /// The <c>Feature</c> to search for styles. /// </param> /// <param name="file"> /// The <see cref="KmlFile"/> the feature belongs to. /// </param> /// <param name="state"> /// The <see cref="StyleState"/> of the styles to look for. /// </param> /// <param name="resolver"> /// Used to resolve external files referenced by the styles. /// </param> /// <param name="cache">IKMLCache object to use previously loaded external files</param> /// <returns> /// A new <see cref="Style"/> that has been resolved. /// </returns> /// <exception cref="ArgumentNullException">feature/file is null.</exception> public static Style CreateResolvedStyle(Feature feature, KmlFile file, StyleState state, IFileResolver resolver, IKmlCache cache = null) { if (feature == null) { throw new ArgumentNullException("feature"); } if (file == null) { throw new ArgumentNullException("file"); } var instance = new StyleResolver(file.StyleMap); instance.fileResolver = resolver; instance.state = state; instance.cache = cache; instance.Merge(feature.StyleUrl); foreach (StyleSelector selector in feature.Styles) { instance.Merge(selector); } return instance.style; }
/// <summary> /// Provides in-place (destructive) processing of the <see cref="Update"/>. /// </summary> /// <param name="update">The update instance.</param> /// <param name="file"> /// A KmlFile containing the <c>Update</c> and the update targets. /// </param> /// <exception cref="ArgumentNullException">file is null.</exception> public static void Process(this Update update, KmlFile file) { if (file == null) { throw new ArgumentNullException("file"); } foreach (Element child in update.Updates) { if (child is ChangeCollection change) { ProcessChange(change, file); continue; } if (child is CreateCollection create) { ProcessCreate(create, file); continue; } if (child is DeleteCollection delete) { ProcessDelete(delete, file); } } }
/// <summary> /// Reads a Kml file or the default Kml file from a Kmz archive. /// </summary> /// <param name="path">The path of the file.</param> /// <returns>A KmlFile on success, or null on an error.</returns> public static KmlFile ReadFile(string path) { try { byte[] data = ReadBytes(new Uri(path, UriKind.RelativeOrAbsolute)); using (var stream = new MemoryStream(data, false)) { string extension = Path.GetExtension(path); if (string.Equals(extension, ".kml", StringComparison.OrdinalIgnoreCase)) { return(KmlFile.Load(stream)); } if (string.Equals(extension, ".kmz", StringComparison.OrdinalIgnoreCase)) { using (var kmz = KmzFile.Open(stream)) { return(KmlFile.LoadFromKmz(kmz)); } } } } catch (IOException) { // Silently fail } return(null); }
private static void ProcessDelete(DeleteCollection delete, KmlFile file) { foreach (var source in delete) { if (source.TargetId != null) { Feature feature = file.FindObject(source.TargetId) as Feature; if (feature != null) { // Remove the Feature from the parent, which is either // a Container or Kml Container container = feature.Parent as Container; if (container != null) { container.RemoveFeature(source.TargetId); } else { Kml kml = feature.Parent as Kml; if (kml != null) { kml.Feature = null; } } // Also remove it from the file file.RemoveFeature(feature); } } } }
private void Merge(Uri url) { if ((_nestedDepth++ >= MaximumNestingDepth) || (url == null)) { return; // Silently fail } string id = url.GetFragment(); if (!string.IsNullOrEmpty(id)) { // If there's no path this is a StyleSelector within this file. string path = url.GetPath(); if (string.IsNullOrEmpty(path)) { StyleSelector style; if (_styleMap.TryGetValue(id, out style)) { this.Merge(style); } } else if (_resolveExternal) { KmlFile file = FileHandler.ReadFile(path); if (file != null) { StyleSelector style; if (file.StyleMap.TryGetValue(id, out style)) { this.Merge(style); } } } } }
/// <summary> /// Initializes a new instance of the <see cref="EntityMapper"/> class. /// </summary> /// <param name="file">The kml information to parse.</param> /// <exception cref="ArgumentNullException">file is null.</exception> public EntityMapper(KmlFile file) { if (file == null) { throw new ArgumentNullException("file"); } this.file = file; }
/// <summary> /// Loads a KmlFile using the specified KML data. /// </summary> /// <param name="reader">The text reader containing the KML data.</param> /// <returns>A KmlFile representing the specified information.</returns> /// <remarks> /// This method checks for duplicate Id's in the file and throws an /// exception if duplicate Id's are found. To enable duplicate Id's /// use the <see cref="Parser"/> class and pass the root element /// to <see cref="Create"/>. /// </remarks> /// <exception cref="ArgumentNullException">reader is null.</exception> /// <exception cref="InvalidOperationException"> /// Duplicate Id's were found or the XML is nested too deeply. /// </exception> /// <exception cref="System.Xml.XmlException"> /// An error occurred while parsing the KML. /// </exception> public static KmlFile Load(TextReader reader) { Check.IsNotNull(reader, nameof(reader)); var file = new KmlFile(); file.Parse(reader); return(file); }
/// <summary> /// Initializes a new instance of the <see cref="LinkResolver"/> class. /// </summary> /// <param name="kml">The input to parse.</param> public LinkResolver(KmlFile kml) { var set = new HashSet <Uri>(); foreach (Element child in kml.Root.Flatten()) { AddUriFromElement(set, child); } this.links = set.ToArray(); }
/// <summary> /// Loads a KmlFile using the specified KML data. /// </summary> /// <param name="reader">The text reader containing the KML data.</param> /// <returns>A KmlFile representing the specified information.</returns> /// <remarks> /// This method checks for duplicate Id's in the file and throws an /// exception if duplicate Id's are found. To enable duplicate Id's /// use the <see cref="Parser"/> class and pass the root element /// to <see cref="Create"/>. /// </remarks> /// <exception cref="ArgumentNullException">reader is null.</exception> /// <exception cref="InvalidOperationException"> /// Duplicate Id's were found or the XML is nested too deeply. /// </exception> /// <exception cref="System.Xml.XmlException"> /// An error occurred while parsing the KML. /// </exception> public static KmlFile Load(TextReader reader, bool namespaces = true) { if (reader == null) { throw new ArgumentNullException("reader"); } KmlFile file = new KmlFile(); file.Parse(reader, namespaces); return(file); }
/// <summary> /// Loads a KmlFile using the specified KML data. /// </summary> /// <param name="reader">The text reader containing the KML data.</param> /// <returns>A KmlFile representing the specified information.</returns> /// <remarks> /// This method checks for duplicate Id's in the file and throws an /// exception if duplicate Id's are found. To enable duplicate Id's /// use the <see cref="Parser"/> class and pass the root element /// to <see cref="Create"/>. /// </remarks> /// <exception cref="ArgumentNullException">reader is null.</exception> /// <exception cref="InvalidOperationException"> /// Duplicate Id's were found or the XML is nested too deeply. /// </exception> /// <exception cref="System.Xml.XmlException"> /// An error occurred while parsing the KML. /// </exception> public static KmlFile Load(TextReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } var file = new KmlFile(); file.Parse(reader); return(file); }
/// <summary> /// Loads a default <see cref="KmlFile"/> inside this archive. /// </summary> /// <returns> /// A KmlFile representing the default KML file in the specified KMZ archive /// or null if no KML data was found. /// </returns> /// <remarks> /// This method checks for duplicate Id's in the file and throws an /// exception if duplicate Id's are found. To enable duplicate Id's /// use the <see cref="SharpKml.Base.Parser"/> class and pass the root /// element to <see cref="KmlFile.Create"/>. /// </remarks> /// <exception cref="ObjectDisposedException"> /// <see cref="Dispose"/> has been called on this instance. /// </exception> /// <exception cref="System.Xml.XmlException"> /// An error occurred while parsing the KML. /// </exception> public KmlFile GetDefaultKmlFile() { string kml = this.ReadKml(); if (kml != null) { using (var reader = new StringReader(kml)) { return(KmlFile.Load(reader)); } } return(null); }
/// <summary> /// Creates a new KmzFile using the data specified in the KmlFile. /// </summary> /// <param name="kml">The Kml data to add to the archive.</param> /// <returns> /// A new KmzFile populated with the data specified in the KmlFile. /// </returns> /// <remarks> /// This overloaded version does not resolve any links in the Kml data /// and, therefore, will not add any local references to the archive. /// </remarks> /// <exception cref="ArgumentNullException">kml is null.</exception> public static KmzFile Create(KmlFile kml) { Check.IsNotNull(kml, nameof(kml)); var instance = new KmzFile(); ZipArchiveEntry entry = instance.zip.CreateEntry(DefaultKmlFilename); using (Stream stream = entry.Open()) { kml.Save(stream); } return(instance); }
private static void ProcessChange(ChangeCollection change, KmlFile file) { foreach (KmlObject source in change) { if (source.TargetId != null) { KmlObject target = file.FindObject(source.TargetId); if (target != null) { target.Merge(source); target.TargetId = null; // Merge copied the TargetId from the source, but target shouldn't have it set } } } }
/// <summary> /// Loads a KmlFile using the specified KML data. /// </summary> /// <param name="input">The stream containing the KML data.</param> /// <returns>A KmlFile representing the specified information.</returns> /// <remarks> /// This method checks for duplicate Id's in the file and throws an /// exception if duplicate Id's are found. To enable duplicate Id's /// use the <see cref="Parser"/> class and pass the root element /// to <see cref="Create"/>. /// </remarks> /// <exception cref="ArgumentNullException">input is null.</exception> /// <exception cref="InvalidOperationException"> /// Duplicate Id's were found or the XML is nested too deeply. /// </exception> /// <exception cref="IOException">An I/O error occurred.</exception> /// <exception cref="NotSupportedException"> /// The stream does not support reading. /// </exception> /// <exception cref="ObjectDisposedException"> /// The stream was closed. /// </exception> /// <exception cref="System.Xml.XmlException"> /// An error occurred while parsing the KML. /// </exception> public static KmlFile Load(Stream input) { if (input == null) { throw new ArgumentNullException("input"); } KmlFile file = new KmlFile(); using (var reader = new StreamReader(input)) { file.Parse(reader); } return(file); }
/// <summary>Resolves all the styles in the specified Feature.</summary> /// <param name="feature">The Feature to search for Styles.</param> /// <param name="file">The KmlFile the feature belongs to.</param> /// <param name="state">The StyleState of the styles to look for.</param> /// <returns>A new Style that has been resolved.</returns> /// <exception cref="ArgumentNullException">feature/file is null.</exception> public static Style CreateResolvedStyle(Feature feature, KmlFile file, StyleState state) { if (feature == null) { throw new ArgumentNullException("feature"); } if (file == null) { throw new ArgumentNullException("file"); } var instance = new StyleResolver(file.StyleMap); instance._state = state; instance.Merge(feature.StyleUrl, feature.StyleSelector); return(instance._style); }
/// <summary> /// Creates a KmlFie from the specified <see cref="Element"/> hierarchy. /// </summary> /// <param name="root">The root <c>Element</c> of the file.</param> /// <param name="duplicates"> /// true to allow duplicate <see cref="KmlObject.Id"/> values (newer /// values will overwrite existing values); false to throw an exception /// for duplicate values. /// </param> /// <returns> /// A new KmlFile with the specified <c>Element</c> as the root. /// </returns> /// <exception cref="ArgumentNullException">root is null.</exception> /// <exception cref="InvalidOperationException"> /// A object has already been registered with the same Id and the /// duplicates argument is set to false. /// </exception> public static KmlFile Create(Element root, bool duplicates) { Check.IsNotNull(root, nameof(root)); var file = new KmlFile { strict = !duplicates, }; foreach (Element element in ElementWalker.Walk(root)) { file.OnElementAdded(element); } file.Root = root; return(file); }
/// <summary> /// Creates a new KmzFile using the data specified in the KmlFile. /// </summary> /// <param name="kml">The Kml data to add to the archive.</param> /// <returns> /// A new KmzFile populated with the data specified in the KmlFile. /// </returns> /// <remarks> /// This overloaded version does not resolve any links in the Kml data /// and, therefore, will not add any local references to the archive. /// </remarks> /// <exception cref="ArgumentNullException">kml is null.</exception> public static KmzFile Create(KmlFile kml) { if (kml == null) { throw new ArgumentNullException("kml"); } var instance = new KmzFile(new MemoryStream()); instance._zip = new ZipFile(); // Add the Kml data using (var stream = new MemoryStream()) { kml.Save(stream); instance.AddFile(DefaultKmlFilename, stream.ToArray()); } return(instance); }
/// <summary> /// Creates a KmlFie from the specified <see cref="Element"/> hierarchy. /// </summary> /// <param name="root">The root <c>Element</c> of the file.</param> /// <param name="duplicates"> /// true to allow duplicate <see cref="KmlObject.Id"/> values (newer /// values will overwrite existing values); false to throw an exception /// for duplicate values. /// </param> /// <returns> /// A new KmlFile with the specified <c>Element</c> as the root. /// </returns> /// <exception cref="ArgumentNullException">root is null.</exception> /// <exception cref="InvalidOperationException"> /// A object has already been registered with the same Id and the /// duplicates argument is set to false. /// </exception> public static KmlFile Create(Element root, bool duplicates) { if (root == null) { throw new ArgumentNullException("root"); } KmlFile file = new KmlFile(); file.strict = !duplicates; foreach (var element in ElementWalker.Walk(root)) { file.OnElementAdded(element); } file.Root = root; return(file); }
private static void ProcessCreate(CreateCollection create, KmlFile file) { foreach (Container source in create) { if (source.TargetId != null) { // Make sure it was found and that the target was a Container if (file.FindObject(source.TargetId) is Container target) { foreach (Feature feature in source.Features) { Feature clone = feature.Clone(); // We never give the original source. target.AddFeature(clone); file.AddFeature(clone); } } } } }
/// <summary> /// Resolves all the styles in the specified <see cref="Feature"/>. /// </summary> /// <param name="feature"> /// The <c>Feature</c> to search for styles. /// </param> /// <param name="file"> /// The <see cref="KmlFile"/> the feature belongs to. /// </param> /// <param name="state"> /// The <see cref="StyleState"/> of the styles to look for. /// </param> /// <param name="resolver"> /// Used to resolve external files referenced by the styles. /// </param> /// <returns> /// A new <see cref="Style"/> that has been resolved. /// </returns> /// <exception cref="ArgumentNullException">feature/file is null.</exception> public static Style CreateResolvedStyle(Feature feature, KmlFile file, StyleState state, IFileResolver resolver) { Check.IsNotNull(feature, nameof(feature)); Check.IsNotNull(file, nameof(file)); var instance = new StyleResolver(file.StyleMap) { fileResolver = resolver, state = state, }; instance.Merge(feature.StyleUrl); foreach (StyleSelector selector in feature.Styles) { instance.Merge(selector); } return(instance.style); }
/// <summary> /// Loads a KmlFile using the specified KMZ data. /// </summary> /// <param name="kmz">The KmzFile containing the KML data.</param> /// <returns> /// A KmlFile representing the default KML file in the specified KMZ archive /// or null if no KML data was found. /// </returns> /// <remarks> /// This method checks for duplicate Id's in the file and throws an /// exception if duplicate Id's are found. To enable duplicate Id's /// use the <see cref="Parser"/> class and pass the root element /// to <see cref="Create"/>. /// </remarks> /// <exception cref="ArgumentNullException">kmz is null.</exception> /// <exception cref="ObjectDisposedException"> /// <see cref="KmzFile.Dispose"/> has been called on kmz. /// </exception> /// <exception cref="System.Xml.XmlException"> /// An error occurred while parsing the KML. /// </exception> public static KmlFile LoadFromKmz(KmzFile kmz) { if (kmz == null) { throw new ArgumentNullException("kmz"); } string kml = kmz.ReadKml(); if (kml != null) { KmlFile instance = new KmlFile(); using (var stream = new StringReader(kml)) { instance.Parse(stream); } return(instance); } return(null); }
/// <summary> /// Loads a KmlFile using the specified KMZ data. /// </summary> /// <param name="kmz">The KmzFile containing the KML data.</param> /// <param name="namespaces">true to allow namespace support; false to ignore namespaces.</param> /// <returns> /// A KmlFile representing the default KML file in the specified KMZ archive /// or null if no KML data was found. /// </returns> /// <remarks> /// This method checks for duplicate Id's in the file and throws an /// exception if duplicate Id's are found. To enable duplicate Id's /// use the <see cref="Parser"/> class and pass the root element /// to <see cref="Create"/>. /// </remarks> /// <exception cref="ArgumentNullException">kmz is null.</exception> /// <exception cref="ObjectDisposedException"> /// <see cref="KmzFile.Dispose"/> has been called on kmz. /// </exception> /// <exception cref="System.Xml.XmlException"> /// An error occurred while parsing the KML. /// </exception> public static KmlFile LoadFromKmz(IKmzReader kmz, bool namespaces = true) { if (kmz == null) { throw new ArgumentNullException("kmz"); } string kml = kmz.ReadKml(); if (kml != null) { KmlFile instance = new KmlFile(); using (var stream = new StringReader(kml)) { instance.Parse(stream, namespaces); } return(instance); } return(null); }
private void btnSelectKMLFile_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK) { /* Get kml filename */ string kml_file = openFileDialog1.FileName; if (kml_file.Contains(".kml")) { Form1.Globals.kml_filename = kml_file; rtbKMLRead.AppendText("KML File : " + kml_file + "\n"); rtbKMLRead.AppendText("\n"); /* Open KML File */ System.IO.TextReader stream = System.IO.File.OpenText(kml_file); SharpKml.Engine.KmlFile file = KmlFile.Load(stream); Kml _kml = file.Root as Kml; SharpKml.Dom.Placemark[] tempPlaceMarks = new SharpKml.Dom.Placemark[1000]; SharpKml.Dom.Placemark tmp_placemark = new SharpKml.Dom.Placemark(); CoordinateCollection coordinates = new CoordinateCollection(); Form1.Globals.kml_point_count = 0; //rtbKMLRead.AppendText("Waypoint Count : " + Convert.ToString(Globals.waypoint_count) + "\n"); int numOfPlaceMarks = 0; if (_kml != null) { foreach (var placemark in _kml.Flatten().OfType <SharpKml.Dom.Placemark>()) { string placename = placemark.Name; rtbKMLRead.AppendText("Placemark Name : " + placename + "\n"); tmp_placemark.Name = placename; numOfPlaceMarks++; } rtbKMLRead.AppendText("Number of Placemarks : " + Convert.ToString(numOfPlaceMarks) + "\n"); int num_linestring = 0; SharpKml.Base.Vector vector; double lat; double lon; double alt; foreach (var linestring in _kml.Flatten().OfType <LineString>()) { coordinates = linestring.Coordinates; int num = coordinates.Count; rtbKMLRead.AppendText("Num Coordinates : " + Convert.ToString(num) + "\n"); for (int i = 0; i < num; i++) { vector = coordinates.ElementAt(i); lat = vector.Latitude; lon = vector.Longitude; alt = (double)vector.Altitude; rtbKMLRead.AppendText("Lat/Lon : " + Convert.ToString(lat)); rtbKMLRead.AppendText(", " + Convert.ToString(lon) + "Altitude : " + Convert.ToString(alt) + "\n"); _kml_points[_kml_point_count, 0] = lat; _kml_points[_kml_point_count, 1] = lon; _kml_points[_kml_point_count, 2] = alt; _kml_point_count++; //dgvWaypoints.Rows.Add(Globals.waypoint_count, Convert.ToString(lat), Convert.ToString(lon), Convert.ToString(30)); } num_linestring++; } rtbKMLRead.AppendText("Number of Linestrings : " + Convert.ToString(num_linestring) + "\n"); BuildKMLPath(); } } else { MessageBox.Show("Wrong file type!", "GPS Grid:", MessageBoxButtons.OKCancel, MessageBoxIcon.Error); } } }
/// <summary> /// Initializes a new instance of the <see cref="EntityMapper"/> class. /// </summary> /// <param name="file">The kml information to parse.</param> /// <exception cref="ArgumentNullException">file is null.</exception> public EntityMapper(KmlFile file) { Check.IsNotNull(file, nameof(file)); this.file = file; }
/// <summary> /// Resolves all the styles in the specified <see cref="Feature"/>. /// </summary> /// <param name="feature"> /// The <c>Feature</c> to search for styles. /// </param> /// <param name="file"> /// The <see cref="KmlFile"/> the feature belongs to. /// </param> /// <param name="state"> /// The <see cref="StyleState"/> of the styles to look for. /// </param> /// <returns> /// A new <see cref="Style"/> that has been resolved. /// </returns> /// <exception cref="ArgumentNullException">feature/file is null.</exception> public static Style CreateResolvedStyle(Feature feature, KmlFile file, StyleState state) { return CreateResolvedStyle(feature, file, state, null); }
private void btnReadKMLPoly_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK) { /* Get kml filename */ string kml_file = openFileDialog1.FileName; if (kml_file.Contains(".kml")) { System.IO.TextReader stream = System.IO.File.OpenText(kml_file); SharpKml.Engine.KmlFile file = KmlFile.Load(stream); Kml _kml = file.Root as Kml; SharpKml.Dom.Placemark[] tempPlaceMarks = new SharpKml.Dom.Placemark[1000]; SharpKml.Dom.Placemark tmp_placemark = new SharpKml.Dom.Placemark(); CoordinateCollection coordinates = new CoordinateCollection(); Form1.Globals.poly_point_count = 0; if (_kml != null) { SharpKml.Base.Vector vector; double lat; double lon; double alt; string name = ""; foreach (var placemark in _kml.Flatten().OfType <SharpKml.Dom.Placemark>()) { name = placemark.Name; } Models.Shape shape = new Models.Shape(); shape.name = name; foreach (var linering in _kml.Flatten().OfType <LinearRing>()) { coordinates = linering.Coordinates; int num = coordinates.Count; LinkedList <PolyPoint> shape_points = new LinkedList <PolyPoint>(); for (int i = 0; i < num; i++) { PolyPoint point = new PolyPoint(); vector = coordinates.ElementAt(i); lat = vector.Latitude; lon = vector.Longitude; alt = (double)vector.Altitude; point.lat = lat; point.lon = lon; point.alt = alt; shape_points.AddLast(point); //dgvWaypoints.Rows.Add(Globals.waypoint_count, Convert.ToString(lat), Convert.ToString(lon), Convert.ToString(30)); } shape.points = shape_points; shape.visible = true; _wpg.AddShape(shape); _gmap.Add_gMapPoly(shape, true); } } } GMAPTree.Update_GMapTree(_wpg, _treeview); this.Close(); } }