1

I have a data frame containing coordinates to various locations that I'd like to use with Google Earth. Here's a simple example showing the structure:

data <- data.frame(country = "USA", city = "Saint Paul",
                   lat = 44.9629, lon = -93.00146)

I followed this SO post and this guide to create KML output successfully using the writeOGR() function from the rgdal package, however I'm having trouble tweaking the attributes. Here's the code:

# you may need to install gdal itself for the package to install successfully
# install.packages("rgdal")
library(rgdal)
data_sp <- data
coordinates(data_sp) <- c("lon", "lat")
proj4string(data_sp) <- CRS("+init=epsg:4238")
data_ll <- spTransform(data_sp, CRS("+proj=longlat +datum=WGS84"))

writeOGR(data_ll["city"], "/path/to/test.kml", driver = "KML", layer = "city")

The result works fine for just viewing locations, but I'd like to change the <styleUrl> attribute as well as have the <name> attribute populated. Without it, Google Earth shows locations with a [no name] attribute:

enter image description here

Here's the resultant .kml file:

<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document><Folder><name>city</name>
  <Placemark>
    <ExtendedData><SchemaData schemaUrl="#city">
        <SimpleData name="city">Saint Paul</SimpleData>
    </SchemaData></ExtendedData>
      <Point><coordinates>-93.001753817020003,44.96282130428127</coordinates></Point>
  </Placemark>
</Folder>
<Schema name="city" id="city">
    <SimpleField name="city" type="string"></SimpleField>
</Schema>
</Document></kml>

I need to either get a <name> element to populate with the SimpleField name="city" contents, or have <name>City</name> tags added to each <Placemark>. What I'd like is something like this as the final result (note added <Style> definition, <styleUrl> attribute for the <Placemark>, and <name> attribute added):

<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>

<Style id="custom">
  <IconStyle>
    <scale>1.5</scale>
    <Icon>
      <href>http://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png</href>
    </Icon>
  </IconStyle>
</Style>

<Folder><name>city</name>
  <Placemark>
    <name>Saint Paul</name>
    <styleUrl>#custom</styleUrl>
    <ExtendedData><SchemaData schemaUrl="#city">
        <SimpleData name="city">Saint Paul</SimpleData>
    </SchemaData></ExtendedData>
      <Point><coordinates>-93.001753817020003,44.96282130428127</coordinates></Point>
  </Placemark>
</Folder>
<Schema name="city" id="city">
    <SimpleField name="city" type="string"></SimpleField>
</Schema>
</Document></kml>

Here's what the result looks like (similar to what I'm aiming for):

enter image description here

The rgdal documentation mentions a layer_options attribute, but nothing intuitively stuck out to me...

  • layer_options = c("<name>????</name>")?
  • layer_options = c("<styleUrl>#custom</styleUrl")?
  • Something else?

The attempts above to pass a tag directly don't appear to affect the output.

There's not many examples I found in googling other than creating the default output from writeOGR(), as shown above. Thanks for any suggestions.

Community
  • 1
  • 1
Hendy
  • 10,182
  • 15
  • 65
  • 71
  • 1
    Have you tried `kmlPoints(...)` in the [`maptools`](http://cran.r-project.org/web/packages/maptools/maptools.pdf) package? Seems like it might be better suited. – jlhoward Jan 31 '14 at 18:23
  • @jlhoward No, but just did and it does, indeed, work. I'd like to leave the question open for answers, as it might be of interest to other users. For those wanting to use `maptools`, I ran the above exactly the same, except instead of the `writeOGR()` function, I did: `kmlPoints(data_ll["city"], kmlfile = "~/Desktop/test.kml", name = data_ll$city, icon = "http://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png")`. Thanks for the suggestion! – Hendy Jan 31 '14 at 20:02

2 Answers2

2

To expand on @jlhoward's answer above, I was able to use kmlPoints() to accomplish what I was looking for:

data <- data.frame(country = "USA", city = "Saint Paul",
                   lat = 44.9629, lon = -93.00146)

# you may need to install gdal itself for the package to install successfully
# install.packages("rgdal")
library(rgdal)
library(maptools)

data_sp <- data
coordinates(data_sp) <- c("lon", "lat")
proj4string(data_sp) <- CRS("+init=epsg:4238")
data_ll <- spTransform(data_sp, CRS("+proj=longlat +datum=WGS84"))

kmlPoints(data_ll["city"], kmlfile = "~/Desktop/test.kml",
          name = data_ll$city,
          icon = "http://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png")

The output contains both the desired <name> attribute as well as a <Style> definition for the custom icon, which is applied successfully to the <Placemark> entries:

readLines("test.kml")

 readLines("test.kml")
 [1] "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"                                   
 [2] "<kml xmlns=\"http://earth.google.com/kml/2.2\">"                              
 [3] "<Document>"                                                                   
 [4] "<name></name>"                                                                
 [5] "<description><![CDATA[]]></description>"                                      
 [6] ""                                                                             
 [7] "<Style id=\"style1\">"                                                        
 [8] "  <IconStyle>"                                                                
 [9] "    <Icon>"                                                                   
[10] "      <href>http://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png</href>"
[11] "    </Icon>"                                                                  
[12] "  </IconStyle>"                                                               
[13] "</Style>"                                                                     
[14] ""                                                                             
[15] "<Placemark>"                                                                  
[16] "  <name>Saint Paul</name>"                                                    
[17] "  <description><![CDATA[]]></description>"                                    
[18] "  <styleUrl>#style1</styleUrl>"                                               
[19] "  <Point>"                                                                    
[20] "    <coordinates>"                                                            
[21] "-93.00175381702,44.9628213042813"                                             
[22] "    </coordinates>"                                                           
[23] "  </Point>"                                                                   
[24] "</Placemark>"                                                                 
[25] "</Document>"                                                                  
[26] "</kml>"  

The result:

enter image description here

Hendy
  • 10,182
  • 15
  • 65
  • 71
1

Well, if all you want to do is populate the <name> element in each <Placemark>, this will do it:

library(maptools)
kmlPoints(data_ll,"test.kml",name=data$city)
readLines("test.kml")
#  [1] "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"                              
#  [2] "<kml xmlns=\"http://earth.google.com/kml/2.2\">"                         
#  [3] "<Document>"                                                              
#  [4] "<name></name>"                                                           
#  ...
# [15] "<Placemark>"                                                             
# [16] "  <name>Saint Paul</name>"                                               
# [17] "  <description><![CDATA[]]></description>"                               
# [18] "  <styleUrl>#style1</styleUrl>"                                          
# [19] "  <Point>"                                                               
# [20] "    <coordinates>"                                                       
# [21] "-93.00175381702,44.9628213042813"                                        
# [22] "    </coordinates>"                                                      
# [23] "  </Point>"                                                              
# [24] "</Placemark>"                                                            
# [25] "</Document>"                                                             
# [26] "</kml>"                                                                  

If you need to change the <Style> as well, then I'm afraid you may have to hack the kml file using the XML package.

jlhoward
  • 58,004
  • 7
  • 97
  • 140
  • 1
    Ha! We were posting at the same time. If you run your code and just add the `icon = "http://path..."` argument to the command, you'll get the icons added as well, with the bonus of it generating it as a style and applying it (vs. my assumption that it would probably add a ` – Hendy Jan 31 '14 at 20:05
  • If you have a more complete answer you should post that, with example output (e.g, how is the kml different). There's nothing wrong with building on someone else's answer to make a better one. – jlhoward Jan 31 '14 at 20:07