Sun Seeker for Android!

After a long development period I’m delighted to announce that Sun Seeker is now finally available for Android devices!

Click on this logo to see it in the Android Marketplace.

Available in Android Market


Is is real or is it Memorex? (You have to be of a certain age to remember that advertising slogan!)

Yes – it looks just like the iPhone version in most ways, and includes all the same features as the latest iPhone version.

I’m especially interested to see how sales go, and find out just how different the app sales may be between the two devices. Of course Sun Seeker on iPhone is well established, and it may take a while for the Android version to find its momentum. We’ll see!

Sun Seeker Test Shots

Here are a couple of images from Sun Seeker put together (unsolicited) by a generous and enthusiastic New York based photographer/cinematographer – Hal Hansen.

He’s currently revamping his website and I’ll provide a link to it here when it’s ready. Thanks Hal!

I love the way he’s featured an iconic yellow cab which is a New York signature. Did anyone notice that it’s not actually the same cab in each shot? That’s clever photography! 😉

Sun Seeker Update v1.5

As part of a series of planned updates for the Sun Seeker augmented reality iPhone app, the latest update v1.5 has just been approved by Apple.

For a video demo of Sun Seeker see this earlier blog post.

The main changes for v1.5 are:

  • Enhanced performance for smoother compass dial rotation
  • Added new table of annual rise and set times
  • Added new table of sun’s daily azimuth and elevation
  • Added tap action to rise/set label to see local times instead of intervals
  • Better handling of disabled Location Services
  • More efficient use of GPS – now only used briefly on startup
  • Fixed some minor bugs and issues with date changes

[Note – v1.5.1 update has been submitted to fix OS3.0 backward compatibility and missing sunset times for some locations west of GMT.]

Following is a more detailed description of some of these items.

1. Enhanced Compass Dial Rotation

The compass dial in Sun Seeker includes text which retains its orientation relative to the device regardless of the compass rotation, and this means that at least part of the image needs to be re-rendered for each incremental rotation of that dial as the compass rotates. Previously the whole image was being redrawn each time, and that performance hit meant that the dial motion was quite jerky when it needed to make large rotational changes. The new implementation involves much less redrawing, and hence allows the compass to be much more responsive.

2. New Tables

The table of rise and set times spans the entire year, and hence allows you to look up rise and set times for any given date.

The table of the solar path lists the sun’s azimuth and elevation at 15 minutes intervals throughout the currently selected day.

3. Tap action to see rise/set time instead of intervals

This was added simply for clarity. Tapping on the rise/set labels on the compass screen toggles the display between showing the rise and set time in local time versus showing time duration between now and the rise and set times.

4. Better handling of Location Services status

A problem to date has been if the user has switched off the device Location Services or (perhaps accidentally) disabled them for this particular app. In these cases the app can only use its last acquired location data, and in this case the app shows data which is correct for that old location, but incorrect for the user’s current location.

This issue has been the biggest generator of email support requests to date, but I now expect that this will lessen considerably, because I have implemented clear warning messages which pop-up whenever location services are disabled, each time that the app starts up or resumes from background.

5. More efficient use of GPS

Previous versions of the app left GPS on continuously while the app was active (although off when inactive or in background), and this presented the app with ongoing positional updates while it was open. But for the sake of efficient use of GPS, it seemed unnecessary to leave it on once the location had been determined to a reasonable accuracy, so GPS is now only on as long as location has not been found to reasonable accuracy. However an important point here is that the app should re-query its location not only every time it starts up, but also whenever it resumes from background. The reason for this of course is that the device may have changed location while it was in background – for example it may resume from background after the user has traveled somewhere by air!

6. Future Updates

By far the most common request from users has been to allow selection of other cities/locations rather than just the current current, and this is the next major feature planned. But please note that it is not a trivial update! A particular difficulty here is in ensuring that the local times reported for other locations respect the correct timezones and daylight savings rules for those locations throughout the year. However, I do have a solution planned, and hope to be able to do this within a reasonable timeframe.

The next most common request has been for an Android version. Due to the particularly technical nature of the app, and the fact that I personally have no grounding in Android development, this is a much more difficult proposition. However I have been looking to outsource it. I apologise to those who have been waiting impatiently, and I can assure you that these plans are progressing.

In the meantime, I hope you continue to enjoy the app!

Dynamically adding UIActionSheet buttons

Every once in a while I come across a seemingly simple iPhone coding requirement, but Apple documentation just doesn’t seem to give enough pointers, and nor does web search throw up anything useful. It may just be my inability to find the right keywords to search for, but it might also be that no-one else has posted anything about it. So here is just one such thing in case it proves helpful to anyone.

The UIActionSheet is a very useful class, and I use it frequently in my apps, but its initialisation method doesn’t allow you to add buttons from an array. Instead you apparently typically just add them hardcoded as an initialiser parameter  – and almost all code examples on the web seem to use this method.

Standard example – hardcoded buttons:

- (void)testActionSheetStatic {
	// Create the sheet with buttons hardcoded in initialiser
	UIActionSheet *sheet = [[UIActionSheet alloc] 
		initWithTitle:@"Static UIActionSheet"
		delegate:self
		cancelButtonTitle:@"Cancel"
		destructiveButtonTitle:nil
		otherButtonTitles:@"Item A", @"Item B", @"Item C", nil];

	[sheet showFromRect:view.bounds inView:view animated:YES];
	[sheet release];
}

So that is all well and good if the option buttons are known in advance and never change. But what if I need to change them at runtime? It seems easy enough to add buttons dynamically instead, by leaving out those button declarations from the initialiser, and adding them afterwards instead, and the following code shows how you might assume this should be done.

Dynamically added buttons (first attempt):

- (void)testActionSheetDynamic {
	// Create the sheet with only cancel button
	UIActionSheet *sheet = [[UIActionSheet alloc] 
		initWithTitle:@"Dynamic UIActionSheet"
		delegate:self
		cancelButtonTitle:@"Cancel"
		destructiveButtonTitle:nil
		otherButtonTitles:nil];

	// Add buttons one by one (e.g. in a loop from array etc...)
	[sheet addButtonWithTitle:@"Item A"];
	[sheet addButtonWithTitle:@"Item B"];
	[sheet addButtonWithTitle:@"Item C"];

	[sheet showFromRect:view.bounds inView:view animated:YES];
	[sheet release];
}

The problem with this becomes apparent when you run it – the cancel button appears at the TOP of the sheet, whereas standard practice seems to be that it should be at the bottom. How to achieve this? I didn’t manage to find a way of doing this while adding the cancel button in the initialiser. Instead I eventually found a way of doing so by adding it also as a dynamic button.

Dynamically added buttons (also with dynamic cancel button):

- (void)testActionSheetDynamic {
	// Create the sheet without buttons
	UIActionSheet *sheet = [[UIActionSheet alloc] 
		initWithTitle:@"Dynamic UIActionSheet"
		delegate:self
		cancelButtonTitle:nil
		destructiveButtonTitle:nil
		otherButtonTitles:nil];

	// Add buttons one by one (e.g. in a loop from array etc...)
	[sheet addButtonWithTitle:@"Item A"];
	[sheet addButtonWithTitle:@"Item B"];
	[sheet addButtonWithTitle:@"Item C"];

	// Also add a cancel button
	[sheet addButtonWithTitle:@"Cancel"];
	// Set cancel button index to the one we just added so that we know which one it is in delegate call
	// NB - This also causes this button to be shown with a black background
	sheet.cancelButtonIndex = sheet.numberOfButtons-1;

	[sheet showFromRect:view.bounds inView:view animated:YES];
	[sheet release];
}

In this case the cancel button appears at the bottom, and all works as expected.

The main remaining question I had was what on earth the destructive button was (also apparently not explained in Apple documentation). Some experimentation seemed to show that it was effectively identical to a cancel button with the exception that it had RED background instead of a black one. So if you change the last example to set the destructiveButtonIndex instead of the cancelButtonIndex, then the only difference is that the button labelled “Cancel” would have a red background.

For completeness and sanity, this is the delegate code that goes with all of the above examples.

- (void)actionSheet:(UIActionSheet *)actionSheet 
		clickedButtonAtIndex:(NSInteger)buttonIndex {
	if (buttonIndex == actionSheet.cancelButtonIndex) { return; }
	switch (buttonIndex) {
		case 0:
		{
			NSLog(@"Item A Selected");
			break;
		}
		case 1:
		{
			NSLog(@"Item B Selected");
			break;
		}
		case 2:
		{
			NSLog(@"Item C Selected");
			break;
		}
	}
}

OptimalClub – A Powerful Golfing Aid

OptimalClub is the latest iPhone app that I have developed, created in association with Todd Kos of QualityGolfStats LLC, who is the app publisher. Todd has a long history in golf software, being the creator of the industry-leading OptimalFlight desktop software, used for club fitting by the pros.

Official OptimalClub App Website

OptimalClub uses the very same physics simulation model as the desktop software does, but makes it available on your iPhone in real-time, along with live local weather observations, in order to provide an accurate simulation of the actual golf shot path superimposed onto local satellite imagery of the course, according to the clubs available in your bag. This allows you to see at a glance and select which of your clubs best suits the current distance required, and also shows how far to the left or right you will need to aim in order to adjust for wind deviation, which can be substantial, even in only moderate wind conditions. Below are four screen shots showing the effect on the the shot of the wind coming from four different directions.

In this case the best club selection varies from an 8 iron (when wind is directly behind) to a 1 hybrid (when wind is head on), and the aim varies from 32 metres to the right of the target to 26 metres to the left of the target when the wind comes from either side, instead. That’s quite a range! And that is just for a 27 kmh wind (17 mph). By the way, the units used for distances and weather are of course selectable in the app settings.

The weather engine used in the app is very similar to that used in the See Breeze augmented reality wind visualisation app. However, due to the possibility of very localised wind variations or sudden weather changes in some cases, we felt that we needed to offer the user the ability to override the weather reported by the nearest weather stations, and therefore there is an option to choose between automatic and manual weather settings.

In order to customise the app to your very own set of clubs and your own unique skill and style, you can enter details of your own clubs and the typical distances you get with them. The app then uses its advanced built-in shot physics simulation to estimate the club launch parameters (speed, launch angle and ball spin) for each and every club, after which it can predict, with surprisingly good accuracy, the actual shot path and distance you will get in the field for any given set of wind and weather conditions, as well as altitude variations and changes in elevation between the tee point and the hole.

Once your clubs are set up, all you need to do is to set up the individual shot you are about to take ie. to specify your shot origin point and your target, using the side-toolpanel.

As soon as you have specified origin and target, the app shows you the nearest 5 club distance arcs – again taking into full account the current wind, weather and elevation differences.

In the above example, the wind is from the left, and due to the short distance (62 metres), the nearest shots are all partial swings using a pitching wedge (from 30 to 70% swing effort). The arcs on the map are color coded to identify which club/swing they are showing. And once you select a club (by tapping on it), you will see the full shot simulation for that club/swing, as shown below.

The hole-in-one odds are also shown for your entertainment, if you have them switched on in the app settings. Good luck!

Of course I’ve only covered some aspects of the app here. Considerable effort was put into getting the map display right (which is even rotatable via finger-gesture), and the sequence of actions required to setup a shot with as few steps and as quickly as possible, so as to minimise interference with actual game play. All-in-all this is an app that I am particularly pleased with. It has taken considerably more development effort than any of the other apps I’ve worked on, and the result is something quite unique and powerful. Of course now the challenge will be to see how much traction and visibility this app may get now that there are 300,000 other apps competing for eyeballs.

To start things off we are offering a limited time introductory sale price – 50% off ie. US$9.99, so if you are at all interested, it may be well worth your while getting it now. (NB – Sale is still on at time of writing this article.)

Oz Weather HD Update

Oz Weather HD for iPad has just had an update approved by Apple (4 days waiting for review, 3 days in review). [iTunes link]

The app reached #2 ranking in the Australian app store for paid iPad apps for two days last week. Since then it has drifted down to about #8. But I suspect that all we need is a really good dose of “bad” weather in a few capital cities to send it back up. 😉

The enhancements are mainly things that will appeal to “high-end” users ie. weather geeks like myself.

Firstly the weather warnings have now all been color coded, so that important and relevant warnings stand out much more clearly than before. Typically most warnings are for coastal and ocean winds, which are only relevant to sailors and coastal dwellers. These marine are now shown in blue, whereas those relevant to land are shown in yellow, or red for severe warnings, storms and cyclones.

Secondly the Local Stations map view now has a new “Synoptic” view which shows traditional station wind arrows indicating wind direction and speed, as well as temperature and humidity where those data items are available. This really helps to get a sense of what winds are doing in the local area – especially helpful for people who do water-based sports, for example.

  • Each weather wind arrows has a circle as its head, showing the actual location of the observation on the map, and a tail with feathers on it.
  • The tail is drawn towards the direction from which the wind is coming, so that the arrow effectively points in the direction in which the wind is blowing.
  • Therefore, if the wind is northerly (coming from the north), the tail is drawn on the northerly side of the location circle.
  • The feathers on the tail indicate the wind speed. A long tick indicates 10 units of windspeed, and a short tick indicates 5. A filled triangle indicates 50 units.
  • The units used depends on your choice of windspeed units in the app settings. For example, if you have chosen kmh, then two large and one small feather ticks would indicate 25kmh.

Thirdly there is a new “State Temperatures” map view. Although it is intended mainly for viewing the latest regional or state temperatures, in fact it displays all recent temperatures around Australia as a whole. The temperature labels are color-coded by temperature on a sliding scale, so wide-scale temperature patterns are easily visible at a glance. Check out the chilly alpine weather in the following screen-shot showing Melbourne, eastern Victoria and southern NSW (10:30am, 18th July 2010)!

Oz Weather HD

Oz Weather HD is an iPad only version of Oz Weather. I’m delighted to announce its approval and release by Apple today, after an impatient 8 day waiting period.

It contains all of Oz Weather’s features including the pro level ones, in a much more accessible way than is possible on the iPhone’s limited screen size. The larger screen size has also made it possible to present many of those features more attractively than on the iPhone as well.

This app has been a long time coming – I would have liked to get it out there much sooner, but was earlier pre-occupied with updating other apps (Sun Seeker and See Breeze) to work as universal binaries (ie. on iPhone and iPad), not to mention also releasing a brand new iPhone app called Moon Seeker, which is a lunar calendar, compass, and augmented reality position finder.

After much agonizing over the design of Oz Weather HD, and several false starts, I’m really pleased with the way it has finally turned out. My criterion for a good design is one that I get a warm feeling every time I run the app and this is certainly true of this one. I can only hope that lots of others get the same buzz out of it! The crux of this design is the inclusion of some of my favourite cloud & weather photos as backdrops.

Here are a few screen shot thumbnails:

See Breeze – Augmented Reality Wind Visualizer for iPhone and iPad

Ajnaware’s latest app “See Breeze” has just been approved by Apple, and is now available from the app store. This app has a universal binary – so can be installed onto either iPhone 3GS or onto iPad from the same purchase.

Like Sun Seeker, this app pushes the boundaries of what augmented reality on mobile devices can be used for. The app description is as follows.

Provides both a FLAT VIEW COMPASS and an AUGMENTED REALITY 3-D VIEW showing the local wind and weather conditions with animated wind vectors.

Ideal For:
– Aviators, Sailors, Surfers, Windsurfers, Kite Flyers, Cyclists, Fire Fighters, Weather Hobbyists and any other outdoor enthusiasts

Main Features:
– Compass view showing animated wind vectors for nearest weather stations with wind, temperature and humidity readings
– 3-D augmented reality view with animated wind vectors
– List of local observation stations (up to 10 nearest), from which any may be selected for individual wind viewing
– Map view of all local stations with weather arrows showing direction, speed and temperature
– Uses official Bureau of Meteorology data within Australia, and NOAA metar data (from airports) for rest of world

Feature Device Dependencies:
– iPhone – interface runs only in portrait mode, 3-D View is shown as an overlay on the camera view
– iPad – interface runs in any device orientation, 3-D View is displayed with an opaque background (due to absence of camera)

I had the idea for this app about the same time as I had the idea for Sun Seeker, but I had to choose just one to do first, and even when I did start it, I found that it took a lot longer than expected due to the various technical challenges involved. The first major challenge was learning some OpenGL ES, and the second one was figuring out how to get OpenGL ES to respond correctly to device orientation and heading changes. Many thanks to Jeff LaMarche for some great blog articles on the former, and as for the latter, I pretty much had to figure it out for myself. I did post on Stack Overflow, but ended up answering my own question.

Adapting the app to iPad was also an interesting issue to deal with. I ended up with quite a few conditional branches in the code to deal with cosmetic differences. But the end result more than justified the extra effort. It looks superb on the iPad. Credit for the excellent app artwork goes to Peter Fellows once again, whose work on the Oz Weather program was brilliant. Here are a few screenshots from the iPhone app.

and one from the iPad app, which of course has much nicer mapping ability…

Sun Seeker 3rd in Best App Ever Awards

The Best App Ever awards reached their fiery conclusion a couple of days ago.

I was very gratified indeed to find that Sun Seeker had been voted into 3rd Place in the Augmented Reality App category, not to mention slightly stunned. In fact I was so dubious about my chances that I didn’t even bother checking the results when I first saw that they were out.

Thanks hugely to all those who voted for Sun Seeker. Hopefully there will be more innovative apps like this coming soon!

Its well worth a look to see the full list of winners and honourable mentions. There are many very interesting apps in there – many of which you might otherwise have missed given that there are apparently now 150,000+ apps available in the store.

Plotting a Cold Change

Saturday 23rd January 2010 saw a classic heatwave/cold front event occurring up the eastern coast of New South Wales Australia, and I observed from Sydney, watching things progress during the day via the internet, as well as from my own home, where I have a view across parts of Sydney.

Oz Weather v2.1 introduced graphing of weather history as a new feature, and the graphs from that day show the change very clearly indeed. The following graph is a composite of the different ones available in Oz Weather, although I have overlaid a transparent bar indicating the time when the main changed occurred.

A summary of the changes:

  • Temperature dropped from about 41°C to 22°C.
  • Humidity jumped from 10% to 85%
  • Wind jumped from 30km/h to 65km/h with gusts to over 95km/h just as the change came through, and the direction shifted from NW to S.
  • Interestingly, the pressure started to rise an hour or so before the main change, and there was a little rain from some thunder cells that developed following the change.

The Doppler (wind) radar also showed the approach of the wind change very clearly. Unfortunately I didn’t save a graphic from when the change was passing right through Sydney, but an earlier shot shows the change passing through Stanwell Park, to the south of Sydney.

The key point here is to note that blue indicates wind towards the radar location (centre of crosshairs) and yellow indicates wind away from the radar location. So this is showing strong NorthWest winds (blowing offshore) over the Sydney region, but from the South at Stanwell Park and below. This picture was a lot more striking as the change passed through Sydney itself, but I’ll have to wait for another event to show that off better!