Virtual World Tour in Google Earth

Google Earth
KMZ
Distance Analysis
Flight
Author

Akhilesh Kumar Karna

Published

March 15, 2020

Fly to all the capital cities of the world

Download the kmz file and fly to all the cities in the world! Link is below:

https://mrakhilesh.com/tour/tour.kmz

You need google earth to fly. After downloading the kmz file from the link, double click it to open google earth. In the google earth double click Start Flying. If you want to know how it was created move to the next part, otherwise just enjoy the tour.

How was it created

  1. Download shapefile of the world capitals.
  2. Use python program to find the nearest cities starting from selected one.
  3. Create google earth kmz file using python program in QGIS

Download shapefile

Shapefile (point) for the world capitals can be downloaded from website by googling. Or you can download csv file and open in QGIS as delemited text layer from http://techslides.com/demos/country-capitals.csv. Next steps are done in QGIS.

Steps for creating kmz file

  1. In QGIS add csv delemited layer (say Capitals layer) downloaded from the website. Add rownumber as new field use @row_number as formula.

  2. Create distance matrix using menu Vector ⇒ Analysis Tools ⇒ Distance Matrix.

  3. Use same layer for input and output. Use same field (rownumber) for both the unique id field.

  4. Save the output.

  5. Join output layer with the csv layer.

  6. Open python console and create new python file. Use following code.

```{python}
    sf = iface.activeLayer()
    feat = sf.getFeatures()
    cpt = [f for f in feat]
    opt = cpt
    i1 = 153
    fo = open("D:/path/to/nearest.csv","w")
    j = 1
    fo.write("dgid, capid, distance\n")
    fo.write("%d,%d,0\n" % (j, i1 ))
    while len(opt) > 0:
        npt = [f for f in opt if f.attribute("InputID")==i1]
        dist = [f.attribute("Distance") for f in npt ]
        opt = [f for f in opt if f.attribute("InputID")!=i1]
        opt = [f for f in opt if f.attribute("TargetID")!=i1]
        min_dist = min(dist)
        min_id = dist.index(min_dist)
        i1 = npt[min_id].attribute("TargetID")
        opt = [f for f in opt if f.attribute("TargetID")!=i1]
        fo.write("%d,%d,%f\n" % (j, i1,min_dist ))
        j = j+1
        print(j)
    fo.close()
```

Steps to create shapefile of sorted capitals

  1. Before running the code, you need to select the layer in Layer Panel. Distance matrix creates 239 * 238 features, that is distance from each point to all the other points will be listed as features. The above python code finds the nearest city (say a2) from the intial point (say a1). All the cities with InputID and TargetID which equals to the id of a2 is removed. Next a1 is set equal to a2 and the process is repeated until all the cities are removed. The inputID 153 corresponds to the Kathmandu, Nepal. You can change the id as you wish.

  2. Next, add the csv layer as table (say nearest layer) to QGIS. Join the Capitals layer to the nearest layer. You need to sort it by the dgid field. Now run the following code to produce the kml file which can be opened by google earth.

Code for creating kmz file

```{python}
sf = iface.activeLayer()
feat = sf.getFeatures()
cpt = [f for f in feat]
fo = open("D:/path/to/tour.kml","w")
top = """<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"
  xmlns:gx="http://www.google.com/kml/ext/2.2">

<Document>
  <name>World tour by Akhilesh K K</name>
  <open>1</open>

  <gx:Tour>
    <name>Play me!</name>
    <gx:Playlist>
"""
fly ="""       <gx:FlyTo>
        <gx:duration>10.0</gx:duration>
        <Camera>
"""

flyend = """        </Camera>
      </gx:FlyTo>
      <gx:Wait>
        <gx:duration>5.0</gx:duration>
      </gx:Wait>
"""
place = """    <Placemark id="pin2">
      <name>country:capital</name>
      <styleUrl>pushpin</styleUrl>
      <Point>
        <coordinates>lon,lat,0</coordinates>
      </Point>
    </Placemark>
"""
fo.write(top)
for f in cpt:
    lat = f.attribute("CapitalLat")
    lon =  f.attribute("CapitalLon")
    latlon = """\t\t\t<longitude>%f</longitude>
          <latitude>%f</latitude>
          <altitude>9700</altitude>
""" % ( lon, lat)
    fo.write(fly)
    fo.write(latlon)
    fo.write(flyend)
tourend = """    </gx:Playlist>
  </gx:Tour>
"""
fo.write(tourend)
placemark = """  <Folder>
    <name>Points and polygons</name>
"""
fo.write(placemark)
for f in cpt:
    lat = f.attribute("CapitalLat")
    lon =  f.attribute("CapitalLon")
    nplace = place.replace("country", f.attribute("CountryNam"))
    nplace = nplace.replace("capital", f.attribute("CapitalNam"))
    nplace = nplace.replace("lon", "%s" % (lon))
    nplace = nplace.replace("lat", "%s" % (lat))
    fo.write(nplace)

docend = """</Folder>
</Document>
</kml>
"""
fo.write(docend)
fo.close()
```

The End

That’s the end. Enjoy!