thinking outside the tank

Posts Tagged ‘KML

Low flying in Yosemite Valley

leave a comment »

I am moving all of my Google Earth animations to: Be sure to visit if you’re interested in that kind of thing.

Written by netkingcol

February 18, 2014 at 5:06 pm

Posted in Google Earth

Tagged with , , ,

Madeira – Pearl of the Atlantic

leave a comment »

Pay a visit to the Island of Flowers.

Best viewed at 1080p HD on your largest screen.

Copyright © Colin Hazlehurst, 2014

Written by netkingcol

February 16, 2014 at 7:59 pm

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

Joshua Slocum in Google Earth: Whitsunday Passage to Cooktown

leave a comment »

Follow Joshua Slocum’s Sailing Alone Around the World at:

This slideshow requires JavaScript.

Captain Cook, taking Endeavour through Whitsunday Passage (named by him because 03Jun1770 was Whit Sunday), sailed through the night and arrived the following morning at: “a lofty promontory that I named Cape Gloucester”.

Joshua Slocum, a few days short of 127 years later, passes here on 26May1897. His charts show more accurately than Cook’s survey that the promontory is actually detached from the mainland and is now called Gloucester Island. The Spray hauls into the bay to the west of the island and anchors at Port Denison, close to the small town of Bowen.

Bowen at that time has a population of around 1,000; large enough to support a keen audience for Slocum’s story.

By 31May1897, the Spray, has carried Slocum safely through 350 miles of the Great Barrier Reef. Without anchoring anywhere, Slocum sails past many of the other capes, bays, and islands named by Cook:

  • Cape Upstart
  • Cape Cleveland
  • Cleveland Bay
  • Cape Richards
  • Rockingham Bay
  • Cape Grafton
  • Fitzroy Island
  • Cape Tribulation (“for here all my troubles began”)

Cook also named the Endeavour River, for it was here that H.M.Bark Endeavour was beached for repairs after she had struck a reef just north of Cape Tribulation (the reef was named unsurprisingly Endeavour Reef).

Cooktown was certainly in existence before the gold rush of the 1870s, when the settlement grew rapidly as a supply port, because Slocum reports visiting on the steamship Soushay in 1866; he didn’t see much of it at that time because he was ill with a fever.

The “lecture tour” continues when a meeting is arranged in the Presbyterian church and Slocum delivers his “story of the sea.”

The section of Joshua Slocum’s journey reported here opens Chapter XV of Sailing Alone Around the World, and this post is a trailer for the adventure that I am retelling in Google Earth at:

Copyright © Colin Hazlehurst, 2012

Joshua Slocum in Google Earth: South Solitary Island to Whitsunday Passage

leave a comment »

Follow Joshua Slocum’s Sailing Alone Around the World at:

This slideshow requires JavaScript.

After exchanging signals at South Solitary Island, Slocum continues north and on 19May1897 sails past Point Danger, named by Captain Cook after his encounter with shoals and strong currents there.

On the 20th, the Spray rounds Sandy Cape, a significant point that marks the beginning of the Great Barrier Reef. The light on Sandy Cape is visible for 27 miles and his next way point is the Lady Elliot Island light. This is important to find because Slocum is heading into a dangerous region shoals and reefs and all the charts in the world are of little use if you don’t know where you are. Lady Elliot Island is about 45 miles from Sandy Cape but it seems to take an endless time to cover that distance. Slocum concludes he is pushing against a strong current.

The Spray had sailed for hours in suspense, evidently stemming a current. Almost mad with doubt, I grasped the helm to throw her head off shore, when blazing out of the sea was the light ahead. “Excalibur” cried “all hands,” and rejoiced, and sailed on.

So he finds the light on Lady Elliot Island¹ and passes into the serene, but still risky, waters inside the Great Barrier Reef and is protected from the worst of the Pacific Ocean’s waves. Progress is good and the Spray averages 4.6knots over the next four days:

On the 24th of May, the sloop, having made one hundred and ten miles a day from Danger Point, now entered Whitsunday Pass, and that night sailed through among the islands. When the sun rose next morning I looked back and regretted having gone by while it was dark, for the scenery far astern was varied and charming.

The section of Joshua Slocum’s journey reported here concludes Chapter XIV of Sailing Alone Around the World, and this post is a trailer for the adventure that I am retelling in Google Earth at:


1. The  technical challenge in this part of the presentation was to simulate the light from the Lady Elliot Island lighthouse. I wanted to create a beam of white light that rotates about the location of the lighthouse; furthermore, I wanted it to have the same characteristic as the current light, which is described on charts as: Fl.W. 7.5s. This code means that the light is white and flashes every 7.5 seconds.

To achieve this I needed two things:

  • A model to animate.
  • A TourMaker directive to generate the animation.

I created the beam of light by drawing a cone in Google Sketchup and colouring it white. The cone was about a mile long, oriented along the green axis, which is north when the model is exported to Google Earth, and its apex was placed about 100 feet above the origin.

In the KML file for this leg of Slocum’s journey, I added the model as a Placemark, positioning it at the latitude and longitude of the Lady Elliot Island lighthouse (at the south end of the island). I set the visibility of the Placemark initially to zero (invisible), because I wanted to ‘turn on’ the light at the instant in the narrative that Slocum sees it.

To simulate a rotating beam I would need to animate the model by changing its orientation. By placing the origin of the model at the position of the lighthouse, a change in its orientation would have the desired effect of a light sweeping round.

I measured the angle subtended by the model and found that the edges of the cone were 15° apart. To achieve a smooth rotation, I would want each new orientation of the model to be no more than 15° away from the last one. I also knew that the beam should sweep through 360° in 7.5 seconds, in other words its angular velocity should be 360/7.5 degrees per second, which  comes out at 48° per second.

I used this information to determine how many orientation changes per second would be required to generate a smooth animation at the required rotation rate. Quite simply, if each animation step rotates the model by 15° and we need to rotate the model at 48° per second, then we need 48/15 animation steps per second (3.2), so the duration of each animation step should be 1/3.2 seconds (0.312s).

All of this is easy to code, taking only a few hours of development and testing. To control this behaviour, I added a ‘Rotate’ directive to TourMaker, and its parameters identify which model to animate, the duration of the animation, the angular velocity required, and the delay until the animation should start. This last parameter allowed me to switch on the beam as the narration reads:

Almost mad with doubt, I grasped the helm to throw her head off shore, when blazing out of the sea was the light ahead

The animation starts at the word ‘blazing’; the Placemark is made visible, the light sweeps around for 30 seconds and the Placemark is then made invisible.

Copyright © Colin Hazlehurst, 2012

Captain Cook in Google Earth: new user interface

leave a comment »

I have now applied the same range of techniques used for presenting Joshua Slocum’s first solo circumnavigation at: to Captain Cook’s First Voyage Round the World at:

This means that all of the features introduced recently for Sailing Alone Around the World, like autoplay, passage highlighting, window resizing, and status information, mostly implemented using jQuery, are now part of the First Voyage for Round the World re-enactment.

Now, hopefully, I can get back to developing the Slocum voyage itself…

Copyright © Colin Hazlehurst, 2012

Joshua Slocum in Google Earth: new features

leave a comment »

This morning I smartened up the presentation of Joshua Slocum’s first solo circumnavigation of our planet (see: by adding the following features:


When you click on a passage in the menu, that part of Slocum’s voyage is fetched from the server and starts playing in the Google Earth viewer as soon as it is loaded. In coding terms, I simply needed to add a call to the play() method after loading the tour:


Improved cursor control

Previously, when the user clicked on a passage in the menu, I used the following jQuery expression to set the cursor icon to show that the user should wait for the passage to load:


This was quite hit and miss; the cursor would change to ‘wait’ but would frequently revert to the ‘hand’ as the mouse roamed over nearby anchor elements. By changing the jQuery to the following, this was resolved:


This code changes the cursor for all elements (“*”) so it doesn’t matter where the mouse moves, the cursor remains in the wait state until the passage is retrieved.

Status information

It can take several seconds to retrieve, parse, and load a KML file for display in the Google Earth plug-in, especially if there are multiple 3D models in the file. In addition to changing the cursor, I have added a line of status information which appears above the menu. This shows the text: “Please wait: fetching voyage…”. The text is removed as soon as loading of the KML completes. The jQuery statements for these actions are:

          $("#status").text("Please wait: fetching voyage...");

to show the message, and:


to remove it, where “status” is the id of the <p> element positioned where the status should be displayed.

Highlight current passage

Previously, it was difficult to know which passage was currently selected among the several that might be in the menu for a given chapter of the presentation. To remove any doubt, when the user clicks on a passage the text of that menu option changes colour (I’m English). I used the following code to achieve this effect – having first given each menu option a CSS class of “leg”:

          $(document).ready(function() {
              $(".leg").click(function() {
                  $(".leg").css({ "color": "#996615" });
                  $(this).css({ "color": "Blue" });
                  $("*").css("cursor", "wait");
                  $("#status").text("Please wait: fetching voyage...");

The function that handles the click event for a given element of the “leg” class will first change the colour of all “leg” elements to the default colour (#996615). This clears any previous selection. Then the function changes the colour of the text of the currently selected “leg” element, identified by ‘this’, to ‘Blue’.

As you can see, this is also the place to change the cursor and set the status.


I hope you agree that these features improve the usability of the presentation quite considerably. The fact that they were not built into the initial design reflects, to a large degree, that I am new to jQuery. This project started life as a .Net application but I am now more than content to convert it to Javascript.

Copyright © Colin Hazlehurst, 2012

If you enjoy the presentation of Joshua Slocum’s voyage, you might also like the First Voyage Round the World of Captain James Cook:

The Spray is still the Spray

leave a comment »

Follow Joshua Slocum’s Sailing Alone Around the World at:

Now, it is a law in Lloyd’s that the Jane repaired all out of the old until she is entirely new is still the Jane…the Spray changed her being so gradually that it was hard to say at what point the old died or the new took birth, and it was no matter.

That’s what Joshua Slocum wrote about the reconstruction of his sloop Spray in 1892/3. Over a period of 18 months he replaced every timber with the stoutest, most durable woods he could find – pasture white oak, Georgia pine, and New Hampshire spruce. All was screwed and bolted together and caulked with cotton and oakum.

A similar transformation is taking place in the 3D models I’m using to reproduce Slocum’s voyage in Google Earth. The first image below is my very crude SketchUp model of the Spray.

Original Spray model in SketchUp

This was never intended to be more than a place-holder for a more sophisticated model, a model with which I could start the project. The next image shows the set of ‘guides’ I built up in SketchUp by taking measurements from printed copies of the Spray‘s lines and body-plan:

Spray Guides in SketchUp

The hull was created as a mess of triangles by joining the guides with lines. I shaped the sails with a ‘skin and bubble’ plugin and they are the best feature, but the superstructure is very rudimentary.

The other thing that has bothered me about this model is that it has a yawl rig whereas the Spray started the voyage rigged as a sloop. It wasn’t until Rio that Slocum converted her ‘in readiness for the tempestuous waters of Patagonia’.

After searching for a better model on TurboSquid and 3DExport – and there are some superb examples – I discovered that it would breach the End User License Agreement of those sites to deploy a model where it could be copied. Google Earth is one such place.

My next port of call, as it were, was PeoplePerHour where I searched for a modelling expert who could take my feeble effort as a starting point and create something that wasn’t embarrassing to show in close-up. I gave the work to Mike Halls of mesh-3D and he created:

Spray as a yawl after conversion in Rio de Janeiro

She is still a yawl, but what a difference!

All on my own, I took my shiny new Spray and removed the mizzen mast and sails and the semi-circular brace, all of which were installed in Rio and, using the Scale tool in SketchUp, I enlarged the mainsail.  This gives me a sloop:

Spray as a sloop

So now I have a sloop and a yawl to play with, and the beauty of the Keyhole Markup Language (KML) used in Google Earth is that’s it’s really easy to switch models:- unplug the old one and plug in the new one. In fact, on the leg of the voyage from Pernambuco to Rio, I have both the sloop and the yawl included in the KML and switch models in the middle of Rio bay. To watch this, go to, then select Chapter V followed by clicking on ‘Pernambuco to Rio de Janeiro’. Allow enough time for the models to load and click the ‘Play’ button when it appears.

The presentation is up to Chapter V and my project must now go in two directions: forwards to complete the remaining 18 chapters, and backwards to replace version 1 of the Spray with version 2. At least going forwards I can zoom in more often to show the model in detail and fire the imagination.

Happy sailing!

The Spray

Copyright © Colin Hazlehurst, 2012

%d bloggers like this: