1

EDIT: This question was originally posed for QGIS. However, since I found a way to solve it in R, the title and tags have been changed accordingly.

I have got a Google Earth KMZ file with points. The points are categorised using symbols, and when I import the file into QGIS, I get different colours for the different categories. My problem is that these categories are probably the most important data attribute, and I would like to work with them.

Here is a small example: A town is marked with a red square, villages with yellow triangles and beaches with a water symbol. https://www.dropbox.com/s/whv0ydg5ilspbss/example%20points.kmz?dl=0

When I import this file into QGIS as a layer, I get a single symbol with different colours: screenshot of layer in QGIS

In the layer properties menu, the symbology is given as "embedded symbols" embedded symbols in layer symbology menu

The attribute table does not contain any information to this end, the "icon" column is empty. enter image description here

Is there any way of accessing (and ultimately changing) the embedded symbols in QGIS? They must be encoded in the KMZ somewhere, but where?

I have tried re-exporting the .kml as a shapefile from QGIS, which results in the embedded symbols being lost altogether, and importing the KML into an sf object in R, with the same result. I also tried reading the KMZ into R as an XML (using xml2::read_xml) to see whether I could find out where the relevant code was, but I don't know enough about XML files to be able to do this.

4
  • 1
    Welcome to GIS SE. As a new user, please take the Tour, which emphasizes the importance of asking One question per Question. By specifying two platforms, you are asking two Questions. Please choose one platform and Edit the Question to focus on the error from that platform.
    – Vince
    Jun 13, 2022 at 12:55
  • 4
    What do you mean by the symbols? Can you show us a map with the symbols on? Are you sure the symbol form is encoded in the KML? Can you share a KML file?
    – Spacedman
    Jun 13, 2022 at 13:09
  • 1
    Please provide more details/screenshots.
    – Mapperz
    Jun 13, 2022 at 17:42
  • Thank you everyone for your helpful suggestions to make my question better. I have found a way in R now, building on this: stackoverflow.com/a/40074701/12405039 and on reading up on xml namespaces. I would add it as an answer if the question were reopened.
    – NickG
    Jun 15, 2022 at 12:21

2 Answers 2

1

If you unzip the example KMZ and extract the KML, you can then open it up to view in a text editor as XML. In there you'll see that each <Placemark> only contains the <name>, <LookAt> (view info), <StyleUrl> and the <Point> geometry. There is no <ExtendedData> in your placemarks, which would include attribute data (name/value pairs) that QGIS could extract for each point.

The only way the symbols/icons are encoded in there is with the pointer in each StyleUrl, which reference the shared Styles (icons, etc.) at the top of the file. Unfortunately QGIS does not extract the contents of the StyleUrl for each feature. You would have to parse each placemark to extract the contents of they StyleUrls, and use those to categorize your features.

Looks like QGIS can recognize the Style data and converts it to the "Embedded Styles" for each feature. Theoretically, someone might be able to build a QGIS script or plugin that converts the embedded style info into a new attribute column. Might already exist somewhere, but I'm not aware of any tool like that.

From the comments, sounds like you figured out how to do it using other tools. Good luck.

0

I have figured out a way to do this in R. As C.A. has pointed out, the information is in the XML Placemark information, not in the <ExtendedData> part, which would have put it in the attribute table in QGIS. So the relevant parts of each of the placemark's codes need to be extracted from the file as follows.

First, turn the example KMZ file into a KML (either in google earth itself or by unzipping, whatever works more easily). Then, read it as XML:

library(xml2)

points <- read_xml("example points.kml")

It helps to open the file in a text editor on the side to find out where the records you want are and how they are encoded. In this case, the information on the placemark style is in the StyleUrl (see A.C.'s answer). So we will extract this, along with the name of the point and its coordinates.

But because KMLs are XMLs with defined namespaces, we need to find out the namespaces first and make sure to define them in our xpaths.

xml_ns(points) #returns the namespaces, we will use the first, d1.

We can now extract the records we want (following this example: stackoverflow.com/a/40074701/12405039)

library(tidyr)
library(purrr)

# 1. extract records
records <- xml_find_all(points, "//d1:Placemark", ns = xml_ns(points)) %>% 
  purrr::map_df(function(x) {
    list(
      coords = xml_find_first(x, ".//d1:coordinates",ns = xml_ns(points)) %>% xml_text(),
      category=xml_find_first(x, ".//d1:styleUrl", ns = xml_ns(points)) %>%  xml_text(),
      name=xml_find_first(x, ".//d1:name", ns = xml_ns(points)) %>% xml_text()
      )
    })

# 2. separate coordinates
records <- records %>% tidyr::separate(coords, c("lon", "lat", "alt"), sep = ",")

In the resulting dataset records, the category column represents the KML point styles, which is the data I wanted to access.

I turned this data into an sf object using sf::st_as_sf(records, coords = c("lon", "lat"), crs = 4326) and then saved it as a shapefile using sf::st_write.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.