KML and KMZ
editKML is the XML format of Google Earth and Google My Maps, and KMZ is a zip file that holds a KML document and its images. Kml reads and writes KML, and Kmz reads and writes KMZ:
GeoFeatureCollection placemarks;
using (var stream = File.OpenRead("trip.kml"))
{
placemarks = Kml.Read(stream);
}
// The placemarks of every folder, in order; the "folder" property gives the folder of each one
Assert.Equal("Trip", placemarks.Name);
var monuments = placemarks.Where(placemark => (string?)placemark.Properties.GetValueOrDefault("folder") == "Monuments").ToList();
var eiffelTower = Assert.Single(monuments);
Assert.Equal("Eiffel Tower", eiffelTower.Properties["name"]);
Assert.Equal("<b>330</b> m", eiffelTower.Properties["description"]);
Assert.Equal("1889", eiffelTower.Properties["year"]); // KML has no types: ExtendedData values are strings
using (var stream = File.Create("monuments.kml"))
{
Kml.Write(new GeoFeatureCollection(monuments) { Name = "Monuments" }, stream, new KmlWriterOptions { Indented = true });
}using (var stream = File.Create("trip.kmz"))
{
Kmz.Write(placemarks, stream);
}
using (var stream = File.OpenRead("trip.kmz"))
{
var copy = Kmz.Read(stream);
Assert.HasCount(2, copy);
}What the reader keeps
- Every
Placemark, in the folders at any depth, in the order of the document. The name of the document becomes the Name of the collection, and theidof a placemark its Id. - The properties:
name,description(its HTML is kept as text), the items ofExtendedData, andfolder, the names of the folders that contain the placemark, separated by/. Google My Maps puts each layer in a folder. - KML has no types: the values are strings, except the
SimpleDataitems that aSchemadeclares as numbers (double) or booleans (bool). - The geometries: points, lines, polygons,
MultiGeometry, and thegx:Trackandgx:MultiTracktracks of Google Earth, as lines. ALinearRingalone is a line, as Google Earth draws it. The altitudes are kept as they are written, whatever theiraltitudeMode. - The
whenelements of agx:Trackare the Time of its positions, in order. Awhenthat has no time of day, such as a date alone, gives no time. - The styles, the time spans and time stamps of the placemarks, the 3D models, the overlays and the network links are ignored: nothing is downloaded.
- A KMZ file is read from its
doc.kmlentry, or else its first.kmlentry. The other files are ignored.
What the writer writes
- A KML 2.2 document with a
Placemarkper feature, also for the features without a geometry. - The
nameanddescriptionof a placemark come from the string properties named by NameProperty and DescriptionProperty (nameanddescriptionby default). The other properties areExtendedDataitems, as text. - The identifier is written when it is a valid XML identifier: a number, such as the
idof a GeoJSON feature, is not. - A geometry with altitudes gets the
absolutealtitude mode; otherwise, Google Earth draws it on the ground. - A line whose positions all have a time is a
gx:Track, and a multi-line of such lines agx:MultiTrack. The times of the other positions, and the measures, are not written. - The folders are not written back: the
folderproperty is anExtendedDataitem like the others.