The tidykml package reads selected elements and values from KML
files, such as those produced by Google My Maps, and puts
them into tidy data frames, intended for use with packages like dplyr and
ggplot2.
The goal of tidykml is to make KML files usable for data wrangling and
visualization in as few steps as possible. Several R packages can import KML
files, but these packages do not offer a straightforward way to use their
results with either dplyr or ggplot2.
The reason for tidykml to exist will go away when packages like
ggmap, rgdal and sf implement easy
ways to produce tidy data frames from KML data, or to fortify KML data into
objects that can be passed to ggplot2.
tidykml package was tested only against a limited number of KML files, all of which came either from GADM or from Google My Maps. The fields that it extracts from the KML file might not fit other KML sources.tidykml package does not fully support MultiGeometry elements, such as multi-polygons, and will only handle their first element, in order of appearance in the KML source.Due to these limitations, tidykml lives on GitHub but will probably never show up on CRAN.
Install tidykml with devtools:
devtools::install_github("briatte/tidykml")
library(tidykml)
The data used in this example is a map of the U.S. Civil War featured on Google My Maps. It is bundled in the tidykml package (see ?states for details and usage).
The tidykml package contains functions to return the Points,
Polygons or LineStrings of a KML file:
library(dplyr)
f <- system.file("extdata", "states.kml.zip", package = "tidykml")
kml_polygons(f) %>%
glimpse
The results are always returned in the following form:
Observations: 9,930
Variables: 7
$ folder <chr> "States (status in 1863)", "States (status in 1863)", "S...
$ name <chr> "Ohio", "Ohio", "Ohio", "Ohio", "Ohio", "Ohio", "Ohio", ...
$ description <chr> "description: type: Union state<br>type: Union state", "...
$ styleUrl <chr> "#poly-3F5BA9-1-196", "#poly-3F5BA9-1-196", "#poly-3F5BA...
$ longitude <dbl> -82.21486, -82.34138, -82.54884, -82.71695, -82.90893, -...
$ latitude <dbl> 41.46419, 41.43150, 41.39134, 41.45053, 41.42947, 41.456...
$ altitude <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
These results are easy to pass to ggplot2:
library(ggplot2)
kml_polygons(f) %>%
ggplot(aes(longitude, latitude, group = name)) +
geom_polygon(color = "white") +
coord_map("albers", at0 = 45.5, lat1 = 29.5)

These results are also easy to pass to ggmap:
library(ggmap)
m <- get_map(kml_bounds(f), source = "osm")
ggmap(m) +
geom_polygon(data = kml_polygons(f) %>%
mutate(type = gsub("(.*)<br>type: (.*)", "\\2", description)),
aes(longitude, latitude, group = name, fill = type),
color = "white", alpha = 0.5) +
scale_fill_brewer("", palette = "Set1") +
theme(legend.position = "bottom",
axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank())

The final map also shows the location of major U.S. civil war battles:
ggmap(m) +
geom_polygon(data = kml_polygons(f) %>%
mutate(type = gsub("(.*)<br>type: (.*)", "\\2", description)),
aes(longitude, latitude, group = name, fill = type),
color = "white", alpha = 0.5) +
geom_point(data = kml_points(f),
aes(longitude, latitude),
color = "darkred", size = 6, alpha = 0.5) +
scale_fill_brewer("", palette = "Set1") +
theme(legend.position = "bottom",
axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank())

In addition to the example map used above, the package also contains a map of non-Hispanic gangs in South Los Angeles, created by Instagram user @la_hood_maps (see ?gangs for details).
f <- system.file("extdata", "gangs.kml.zip", package = "tidykml")
m <- get_map(kml_bounds(f), source = "osm")
ggmap(m) +
geom_polygon(data = kml_polygons(f),
aes(longitude, latitude, group = name, fill = folder),
color = "grey25", alpha = 0.75) +
scale_fill_brewer("", palette = "Set3",
guide = guide_legend(override.aes = list(color = NA))) +
labs(title = "Non-Hispanic Gangs in South Los Angeles (2016)",
caption = paste("Source: instagram.com/la_hood_maps",
"(accessed 30 December 2016)."),
x = NULL, y = NULL) +
theme(legend.position = "right",
legend.justification = c(0, 1),
plot.title = element_text(face = "bold"),
plot.caption = element_text(hjust = 0),
axis.text = element_blank(),
axis.ticks = element_blank())

The tidykml package contains a few helper functions to handle KML files:
kml_bounds returns the bounding box (longitude and latitude ranges) of the file.kml_coords parses strings of KML coordinates (longitude,latitude[,altitude]).kml_info returns the number of Folders, Placemarks, LineStrings, Points and Polygons in the filekml_read is a wrapper for xml2::read_xml that returns KML sources as an XML nodeset.Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.