thinking outside the tank

Posts Tagged ‘Placemark

Draw a cubic spline curve through Google Earth Placemarks

with 4 comments

Cubic Spline Demonstration

Cubic Spline Demonstration

If you want to draw a spline curve through a set of Placemarks in Google Earth, then this post might help you. I’ve written a script to achieve this (with limitations) and you are welcome to the code which is written in Javascript.

This YouTube video demonstrates the script in action:

You might want to do this, for instance, to create a path for a Camera to follow. I thought at first I would use such a curve to define the flightpath of an animated model aircraft but I realised quite soon that aircraft don’t fly along cubic splines and I needed a different approach to that problem. That’s partly why I’ve only taken the solution this far; I may come back to it later to describe how the camera flies as it follows the aircraft.

It’s not easy or elegant to post code on WordPress so I’m releasing it through Pastebin. At that link you will find an HTML file with embedded Javascript. If you want to try it for yourself you will also need a KML file which has a set of Placemarks in a Folder with id=’PlacemarkFolder’. There is a sample file on Pastebin.

All I’ve done is to bring together bits and pieces from the following resources:

Fragment 1:  initialisation

In this code fragment scripts are imported, variables defined, and Google Earth loaded. Note that in the version displayed here the spline calculations are in a separate file, whereas in the source code on Pastebin I’ve dropped them into the main script; this was purely to reduce the number of file downloads you need to get started.

Two buttons are added to the screen:

  1. A button to fetch a KML file that holds Placemarks. This could be expanded into some sort of file-open dialogue, but I haven’t done that.
  2. A button to run the spline calculation.

Line 29 is the call to create an instance of the Google Earth plugin; it names the <div> element where it should be displayed and identifies the callback function if the plugin is successfully loaded.

Line 34 calls the resize() function to maximise the size of the Earth viewer.


Fragment 2:  resize the screen and initialise the plugin

Line 39 defines the function to resize the Google Earth plugin so it uses most of the available space. A little room is needed beneath the plugin to show the control buttons.

Line 50 defines the callback function which is executed after the plugin is created. The variable ‘gex’ at line 51 becomes an instance of Google Earth Extensions, which is a utility library that the script uses to navigate KML objects.

This is followed by setting up event listeners to monitor the user’s mouse, detecting mousedown, mousemove, and mouseup actions. Together these allow Placemarks to be dragged to new locations. This code was mostly copied from the Google Code Playground, but the code at lines 83 and 84 are extra. The ‘clearLineStrings’ method will remove any existing spline curves from the view, while ‘calculateSpine’ recomputes and redraws the curve based on the new Placemark positions.


Fragment 3:  Fetch a KML file containing Placemarks

Line 93 defines a function to fetch and display a KML file. Line 96 sets the URL of the file. The address shown here will be valid for a while but is not guaranteed so, if you want to play with this code, you will need to copy this file (available on Pastebin), or create your own.

If the file is fetched successfully, the object returned is assigned to global variable ‘designInput’. If there’s a top-level view available, either a <LookAt> or a <Camera>, the plugin viewer navigates to that view using the code at line 106.


Fragment 4:  Extract Placemarks to an array

The ‘getPlacemarks’ function, at line 111, is used to find the Placemarks in the input file and copy them to an array. Line 120 makes a call to function ‘getObjectById’. This function searches the input file for a Folder node with id set to ‘PlacemarkFolder’; this is how the input file happens to be structured; you might have other Placemarks in it but this method only operates on those that you place in the ‘PlacemarkFolder’. You can change this behaviour easily enough.

If the Folder is found, the GE Extensions API is used to find all the Placemarks it contains. Each Placemark is added to array ‘result’ which is returned to the caller.


Fragment 5:  Cubic Spline Part 1

When the KML file has been loaded, you click on the ‘Fit Spline Curve’ button and this action calls the ‘calculateSpline’ function. Line 142 is where ‘getPlacemarks’ is called. If Placemarks were found, the longitude and latitude of each Placemark are extracted and added to their respective arrays (x for longitude and y for latitude). Sorry about the typo at line 144; how unprofessional 🙂

At line 160, Mr. Kuckir’s cubic spline algorithm is called to calculate the required derivatives. It is beyond my ability to describe how this works, so I’m using it as a black box of tricks (see his article for more detail).


Fragment 6:  Cubic Spline Part 2

With the derivatives calculated, it is possible to generate the cubic spline curve. This will be displayed as a KmlLineString, so the first thing to do is to create a Placemark to hold the LineString geometry. Notice that the Placemark is created, at line 163, giving it a unique id which begins with the string ‘SplineCurve’. This makes it easier to remove when the input Placemarks are dragged and we want to show the new curve.

The next step is to iterate through successive pairs of Placemarks. The difference between their longitudes is calculated, and that difference is divided into 100 intermediate points (line 172). For each intermediate longitude, a latitude is calculated using the ‘CubicSpline.interpolate’ function (line 181). This point on the spline curve is added to the LineString with the function call at line 187.

When all pairs of Placemarks have been processed, the resulting curve is displayed by added the LineString Placemark to the plugin’s feature list.


Fragment 7: Supporting functions

  • addToLineString adds the given point to the given LineString.
  • clearLineStrings navigates through the features added to the plugin instance and removes any Placemark that has an id beginning with ‘SplineCurve’.
  • getObjectById searches the features in the plugin for an object with the given id.


Fragment 8: Completing the head element and defining the body element

There is one more function to describe; this is the addButton function which was copied from the Google Code Playground. It provides a way to add command buttons to an HTML page.

Finally, the body of the HTML page is defined. The div with id=’viewKML’ is the place where the Google Earth plugin is displayed.


The script has its limitations and, in many ways, it is a first crude attempt at providing a way to draw spline curves between Placemarks. You will need to take it further if you want something more general purpose. The major limitations are:

  • The spline curve interpolation assumes that longitude is monotonically increasing; it calculates the latitude for a given longitude.
  • The script takes no account of altitude when generating the LineString; all line segments are set to an altitude of 1.0 metres.
  • No way is provided to extract the LineString coordinates.

Don’t forget, if you do download the code, I’ve commented out the URL of the KML input file and I would recommend that you create your own and place it on your own server.

Good luck, and a happy new year.

Copyright © Colin Hazlehurst, 2014


Written by netkingcol

January 2, 2014 at 2:18 pm

Captain Cook in Google Earth: migration to the web complete(ish)

leave a comment »

I have been working for a couple of weeks converting my Google Earth presentation of James Cook’s first voyage round the world so that it runs in a web browser using the Google Earth API.

All of the Google Earth ‘tours’ are now transferred to providing more than 15 hours of animation and audio. I hope that education and GIS professionals as well as those interested in adventure, exploration, and discovery, will find this presentation interesting and useful.

There are several advantages to the new site:

  1. The menu system makes it easy to find the part of the voyage that interests you.
  2. All of the legs of the voyage are accessible from the menu; previously you had to load each tour separately into the Google Earth application. The ‘ish’ in the title is there because I have not yet prepared the section of the voyage from Batavia to England and I have not included the passage from Cape Horn to Lagoon Island. For the sake of completeness I will add these sections at a later date.
  3. The tours in the presentation are each limited to about 10 minutes duration, and they now load much faster than they did in Google Earth.
  4. After completing a large part of this project I realised I needed some  automation tools. Consequently, I developed TourMaker which uses <ExtendedData> attached to <Placemark> elements to describe how the 3D model should be moved. This eliminates much of the manual effort required to create animations in Google Earth; this in turn made it easier to model Cook’s voyage in finer detail. I particularly like how Endeavour now rounds Cape Horn and later visits a string of South Seas islands both on the approach to Tahiti and on leaving that island after observing the transit of Venus.
  5. I have made fresh sound recordings of much of Cook’s journal; I bought a copy of WavePad to do this and, as in many other situations, I discovered the need to do the job twice: the first time to learn how to do it, and the second time to do it properly. The early recordings were rushed, the levels were inconsistent, and the sound effects were too prominent. I hope these issues are now resolved.

Copyright © Colin Hazlehurst, 2012

%d bloggers like this: