Friday, December 30, 2011

Application Craft Introductory Tutorial - Set GMap Location



Overview
Application Craft is a Mobile, Tablet and Desktop development environment. See the side bar for other articles I've written about AC.  To work along with this tutorial you should sign up for an account here: http://www.applicationcraft.com/get-started

To see a finished version of the tutorial, visit: http://acft.ws/bnqs.  What this tutorial does is simply position the Google Map V2 to your current location.  Please use Chrome for this tutorial as we will also be utilizing  the Ripple Emulator and it only works in Chrome.  

Along the way we'll learn the following:

  • Place components on a page
  • Set the properties of a component
  • Center text on a heading
  • Repeat components across pages
  • Center a footer button
  • Adaptive layout - responsive design
  • Use the ACE Javascript editor
  • Add Javascript functions 
  • Change the Google Maps center position
  • Use the debugger
  • Use the Ripple Editor

Starting a project
Go to the URL that was provided during  the signup process and login.  You'll see the following screen.  Use the New button and create a App called GMapLocation.  For the Theme, select Mobile.


In the next screen, there are three items I'd like to call out to your attention.  

  1. On the left are three folders: Private, Shared and Public.  Notice that GMapLocation is in the Private folder.  Only you will be able to edit it.
  2. In the middle there is a Short URL.  This is useful for sending the app's link to your friends.
  3. On the bottom is the Edit button which we will not click.

AC IDE
In the next screen you see the AC IDE.  At the top there are 4 tabs: App, Edit, Layout and About.  You'll be working in the App tab most of the time and that's the current tab now.  In the middle section of the screen there are three vertical panels: on the left are currently the widgets that can be placed on a page.  In the center is the Page.  On the right are the Properties of the current selected component.  

Along the bottom of the screen there are a group of tabs on the left: Explorer, Code, Style and Toolbox.  The Toolbox tab is currently selected.  We'll be working in the Explorer and Code later.  In the center bottom position are controls for the Pages.  Since this is a single page app we won't be using that.  On the right bottom area is the Events and Properties tab.  The Events tab will change the display to show the available events for the currently selected component.  Currently the Properties tab is selected.

Now click the Page which is in the middle panel. You'll notice that the Page has a dotted line around it signalling the selected component.  On the right side set the name of the page to "home" and press the Save.  One real nice feature of AC is each Save has a unique version and you are able to revert back if necessary.  Just go back to the main dashboard and select the version you want from the Versions tab and click Revert.

Adding Toolbar Components

This next step is to add  all the components to the page.  We want to have the app work responsively in a web browser running on the desktop or mobile device and we want our native app to look well.

Also I want to show how to setup the toolbar component so that if there were multiple pages each page would have the toolbar consistently across the pages.

So first, within the left panel Toolbox, select the accordion called Mobile.  Select the Toolbar and drag it to the Page which is the white component in the center of the page. Drop the component near the top.


In the Properties editor, select the Layout and change it to Horizontal.  This will control how the components which will be added to this Toolbar will be laid out.  Set the "Align in Container" to center so that components will be centered.  Scroll down in the properties and change the Mobile Theme to Blue.  


Now select the Common accordion in the Toolbox and select the Label component.  Drag and drop it onto the Toolbar we just added.  While the text is still selected, or if necessary click on the text, you'll notice a little triangle at the bottom right hand corner.  Select that and drag it to the right to the end of the Toolbar.


Now in the Properties, set the Name to label. Set the Layout "Align in Container" to Center.  Select the Font and change the size to 32 in the popup dialog that appears.   Change the Widget Style to Title.


In the screen below, on the left is the Explorer view of the GMapLocation app.  The home page now has two components - the Mobile Toolbar and  it contains the label.  When the Sizes Property is edited, the Sizes dialog is displayed as shown below.  When you set the Percent Width to 100 it will resize to fill that available space.  We'll use this idea to have the app dynamically fit to the display.


To enable the Toolbar to be on every page, select the Repeat property and set the values as:

  • Select Repeat State: Repeat
  • Relative Position: Top
  • Select Repeat Use: All  
This means that this Toolbar will be repeated on all pages at the top.  If you want to include or exclude pages, change the Select Repeat Use option and include/exclude the desired pages.





Preview and Live Mode and Debug


Now Save your app and click the Preview.  There's not much going on right now.  Click the X to close it.  


In order to work with the debugger we have to a some Javascript command that informs the debugger we want to debug.  To enter Javascript code, press the Code tab at the bottom center.  It will open an editor.  Add the following two lines to the editor:



debugger;
console.log("GMap Location");



Line 1 instructs the debugger to stop here.  The line 2 writes out to the debugger console widow.  



So let's bring up the Chrome Debugger.  From the top right corner of the Chrome browser, select the Wrench icon, select Tools and then Developer Tools.  This will bring up the debugger.  Now click the Preview button again.


You should see the following screen and you should be stopped in the debugger on the "debugger" statement.  On the right press the continue key to do the log message.  From within the debugger, select the Console tab and see the message "GMap Location".






Personally I don't use the Preview mode much as I found it doesn't do exactly like the Live mode does as far as Layout is concerned.  So if I am interested in how the app looks and behaves, I use Live mode and debug from there.  I'll show you how to do that now.


First, let's turn of the Chrome debugger by clicking the X on the right hand side of the debugger itself, it's near the top of the debugger - see above picture.


Now do the Live Mode.  Your app will come up in a separate window.  Use your mouse and click the right mouse button and from the context menu select Inspect Element.  You'll have the debugger available now in a different window.


Adding the GMap Component


Now select the tab Design at the bottom of the IDE.  Select the Toolbox tab at the bottom left of the IDE.  Select the accordion More from the Toolbox.  Find the GMap component and drag it to the page.  Size it by dragging the little triangle at the bottom right corner of the component.  Leave some room at the bottom for the footer component.  


Be aware that you should utilize your own Google Api Keys for this component.  While in testing mode you can use the default ones provided.  But follow the process of getting your own keys by clicking the Google Api Key Property and then clicking the "Sign Up to get Google Api Key".


Adding the Footer Component and Button


We will now add a Container component called a Panel.  The Panel will contain 2 other panels.  The reason for this is we want to place a Button in the footer so we can get our Location.  We will want this button to be centered.  In order to do this we will add two components into our panel.  One will be a "spacer" and the other will contain our Button.  The spacer Panel will be configured to occupy the first 33% of the width.  That other container which contains our Button will then fill the next 33%.  Hopefully it will make more sense in a minute or two.


So now, from the Toolbox Containers, select Panel and drag it to the bottom of the Page.  Change the Layout to Horizontal. Set the Size to Percent Width 100, Width 332, Height 53.  


Select a Panel from the Toolbox Container again and drop it *inside* the Panel we just placed.  Set the Size to Percent Width 100, Width 174 and height 31.  Add another panel just like this one so that you have two panels contained by the first panel.  For both of these last two panels, set the Border to None.  On the last panel, set the Layout to Vertical.


We're now ready to add the Location button.  From the Toolbox Mobile select Action Button and drag and drop it on the last panel that was just added.  Change the Label to "Location" and change the Mobile Theme to Blue.


If you have difficulty selecting the correct components, switch to the Explorer view of the app.  This will now appear as below.




Javascript & JSLint


If you try the app in Preview and Live you'll notice the GMap doesn't resize properly.  The header and footer components do though.  We'll address that now by learning about Events and how to add Javascript.


First, be sure the Explore is displayed by clicking the Explorer tab at the bottom.  Click the home page. This will set the home page as the active component. 


We'll add an Event by clicking first the Events tab at the bottom right.  Then select the "On Resize" and from the drop down select Javascript.  Then do the same for "On Page Show".  At this time you should have two functions as shown below (be sure to remove the debugger and console.log from earlier).



function handler_home_onResize(ev, width, height){

}
function handler_home_onPageShow(){

} 

If you have an error with the Javascript syntax, you'll see a little red bar at the bottom of the page with a number on it indicating the number of errors encountered by JSLint. JSLint parses the Javascript code and determines if it is syntactically correct.  If not, you have an error displayed.


When you see a red bar indicating an error has been detected, click on the red bar and you'll see the details of what is causing the error.  Click on the red bar again to hide the details.  This is one of the many features that are part of Application Craft that I really appreciate.


When the page is first displayed, the event "onPageShow" will call our function handler_home_onPageShow().  When the page is resized, the other function will be called.


What we want to do is adjust the size of the components each time either of these events occur.  Fill in the code for the two functions as shown below:


function handler_home_onResize(ev, width, height){
   heightBar = app.getProperty("MobileToolbar","height");
   heightBottom = app.getProperty("PanelContainer", "height");

   app.setProperty("googleMaps", "height", height - heightBar - heightBottom - 30);
   app.setProperty("googleMaps", "width", width -5); 
}
function handler_home_onPageShow(){
   handler_home_onResize(null, window.innerWidth, window.innerHeight);
} 


Save your app and try the Live mode and verify that the Google Map component is now also full size.


Setting Google Map's Location


We want to now change the location of the Google Map display.  We will do that by adding a javascript handler for when the Location button is clicked.   We'll get the coordinates from the browser and set the center of the map with these values.


First, click the Design tab at the bottom.  Then click the Location button.  Then select the Events tab at the bottom.  For the event "On Click" select Javascript.


Fill out the functions as provided below:
function geoLocation_onSuccess(data) {
   map = app.w('googleMaps').googleMap();
   map.setCenter(new GLatLng(data.coords.latitude,data.coords.longitude), 13);
}
function geoLocation_onError(data) {
   debugger; 
}
function handler_actionBtn_onClick(mouseev){
   if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(geoLocation_onSuccess, geoLocation_onError);
   } else {
     return alert('Sorry, geolocation is not supported by your browser.');
   }
}



This code may need some explaining if you're new to Javascript.  When the Location button is clicked, the function handler_actionBtn_onClick will be called passing in the mouseev.  This value is the mouse event that cause the action.  If you want to see the values, add the "debugger;" statement and run it with the debugger active and see for yourself.

If the browser supports navigator.getLocation it will call getCurrentPosition and pass the values of two functions, one to be called when there is a success and the other if there is any kind of failure.  In our case, we have the function geoLocation_onSuccess for the successful call, and geoLocation_onError for unsuccessful.

The next bit of interesting code is what is happening in the geoLocation_onSuccess function.  Again, you can use the debugger to see the data values.  The first line uses an AC idiom of getting a component from the app.  But the component called "googleMaps" in this case is the AC Google Map Widget which contains the actual google map.  Sounds confusing?  Just realize that AC built a widget to contain the Google Map and provide Events and Properties for us to control the apperance at design time.  But now we want the actual Google map control.  So that's what is happening on that first line.

On the next line, we use the data coordinates passed in and create a GLatLng object initializing it with our values and then setting the center.  The 13 is the value for what zoom level the map should in.

That's all for the code and design.  We're ready to test it in the Ripple Emulator and generate our native apps.

Ripple Emulator

To use the Ripple Emulator you first have to be running in Chrome.  Then go to this page http://ripple.tinyhippos.com/download and follow the instructions.  Once the emulator is installed you want to Enable it.  In the top right corner of the Chrome Browser will be a icon like this: 



Select it and then from the popup dialog, click Enable.  The dialog stays and waits for you to click somewhere else.  So click the Live button back on the AC IDE.  


You can change the phone to your preference, change the orientation and enter the coordinates of your choice as shown below:




Summary


The next step in this maybe to generate the native apps by using the PhoneGap:Build functionality but that is available in the Pro pricing model - see http://www.applicationcraft.com/pricing-main and not the free.


Hope you enjoyed the ride!

Node.js & Oracle db - Not so bad union




Overview

When I was playing around with Node.js at work in scripting data files I thought about how nice it would be to directly use Oracle rather then run my queries in TOAD and export the data to a file for processing.   I can't say this idea was mine but I do think it's easier to get your hands around then this article (but then I'm slow) Combining java and Node.js through redis pub/sub and a json remote interface
Basic Idea


This proof of concept project is to provide access to a Oracle database from a Node.js client.


A java app is run from the command line and subscribes to 2 channels 
(query and storedProc) with redis using java lettuce client. It waits for messages. 


When it receives a message, the message contains the query or storedProc information and arguments.  The oracle database is accessed and the data is published as JSONARRAY of JSONObjects.  It continues to wait for more messages.


The redis node.js client (oraclePubSub.js) has 2 subscribers and 2 publishers.  The publishers send query or storedProc requests.  The subscribers listen for the messages containing the results.  The test client (testPubSub.js) creates two requests and processes the responses.

To run


 -  Open new terminal window
  - Open new terminal window
  • Install redis - this is the node.js redis client use https://github.com/mranney/node_redis 
  • do "npm install redis"
  • git clone git://github.com/bartonhammond/OraclePubSub.git
  • cd OraclePubSub\java\src\main\java
  • edit jdbc.properites - this assumes the sample HR schema is available
  • cd OraclePubSub\sql 
  • define hr.get_emp_rs.sql in hr.schema.  Otherwise test will fail
  • cd OraclePubSub\java
  • mvn package
  • cd target
  • enter "java -jar oraclepubsub-0.0.1-jar-with-dependencies.jar"  - This will hang waiting for messages.
   - Open different terminal window
  • cd OraclePubSub
  • node testPubSub.js


Code review

Java
The Java part of this is rather straight forward.  I won't go into the Oracle JDBC stored procedure or query except to say it's a toy program and I only want to prove to myself it could be done.   The interesting part here is in two methods:

public void processMessages() throws InterruptedException, Exception {
    Jdbcquery jdbcQuery = new JdbcQuery();
    while (true) {
        ChannelMessage cm = channelMessages.take();
        if (cm.channel.equals("query")) {
            JSONArray json = jdbcQuery.performQuery(cm.message);
            redis.publish("query-output", json.toString());
            
        } else if (cm.channel.equals("storedProc")) {
            JSONArray json = jdbcQuery.performRefCursor(cm.message);
            redis.publish("storedProc-output", json.toString());
        }
    } 
}

The ChannelMessage class has only 2 attributes - the channel listening to and the message.  The message contains the query or stored procedure. Depending on the channel, in line 6 or 10 a JSONArray is returned with the data ready to be published to the queue that the Node.js client is subscribed to.

Node.js

var redis = require("redis");

//Pair for storedProc
var storedProcSubscribe = redis.createClient();
var storedProcPublish = redis.createClient();

//Pair for query
var querySubscribe = redis.createClient();
var queryPublish = redis.createClient();

exports.setup = function () {
   storedProcSubscribe.on("ready", function () {
       storedProcSubscribe.subscribe("storedProc-output");
    });
   querySubscribe.on("ready", function () {
       querySubscribe.subscribe("query-output");
    });

}

exports.performStoredProc = function(proc, cb) {
    storedProcSubscribe.on("message", function (channel, message) {
        cb(message);
    });
    storedProcPublish.publish("storedProc",proc);
};

exports.performQuery = function(query, cb) {
    querySubscribe.on("message", function (channel, message) {
        cb(message);
    });
    queryPublish.publish("query",query);
};

//Client call to end the listening
exports.end = function end() {
    querySubscribe.end();
    queryPublish.end();
    storedProcSubscribe.end();
    storedProcPublish.end();

}
This code is really just 2 pairs of subscribers and listeners.  One listener and subscriber each for the query and storedProc.  Lines 4 - 9 are creating the redis clients.  

The setup function on line 11 subscribes for the output from Java.   For the storedProc, when  the message comes in it will be on line 22.  For the query, on line 29.  When the client Node call performStoredProc or performQuery,  they will publish their sql in the channels "storedProc" and "query" respectively.  

Finally, the end function on line 36 ends all the pub sub.

Let's look at the Node client.

//Setup the pub & sub
oraclePubSub.setup();

//Use async so that both can run in parallel
//and at conclusion the end can be invoked
//so script ends gracefully
async.parallel({

    //This query is same as stored proc so that testing was easier
    query: function(callback) {
        oraclePubSub.performQuery("select first_name, last_name, email,employee_id from HR.EMPLOYEES where department_id = 60 order by last_name, first_name asc",function(data){
            callback(null,data);
        });
    },
    storedProc: function(callback) {
        var foo = {};
        foo.sp = "BEGIN hr.get_emp_rs(?, ?); END;";
        //Do arg_types/args in parallel
        foo.arg_types = [oraclePubSub.sqlType.INTEGER];
        foo.args = [60];
        //What column contains the ResultSet
        foo.rs = 2;
        var fooStr = JSON.stringify(foo);
        oraclePubSub.performStoredProc(fooStr,function(data){
            callback(null,data);
        });
    },
},
               /**
                  * Results contains array 
                  */
               function(err,results) {
                   processQueryResults(results.query);
                   processStoredProc(results.storedProc);
                   oraclePubSub.end();
               });


function processQueryResults(queryResults){
    var qrArray = eval(queryResults);
    qrArray.forEach(function(employee) {
        console.log(employee);
    });
    
}
function processStoredProc(storedProcResults) {
    var sprArr = eval(storedProcResults);
    sprArr.forEach(function(employee) {
        console.log(employee);
    });
}

On line 2, I'm calling the setup we discussed earlier.  Notice on line 7 I'm using async.parrallel https://github.com/caolan/async- this allows my two queries to run in any order and I don't call my "end" function until both queries are done.  But I do want to call my end function when I am done.  That way I can merge the results if I choose first and then cleanly end the session.

On line 10, I'm performing a simple query against the demo database provided with Oracle.   Following the pattern of async parallel processing the results will be provided in line 32, the anonymous function.  Notice that the results object has two attributes - query and storedProc.  After processing these results, I can successfully end the session.


There are other async opportunities in this example but it's working well enough that I was able to improve on it and use it in my daily work.  Imagine that!








Thursday, December 29, 2011

Mobile, Tablet and Desktop Development: Application Craft

Overview
When I initially thought about writing a web application that addressed a specific problem I considered a miriad of possibilities. I could use any of a number of development strategies that addressed specific implementations.  I could learn each mobile device specific development environments and create a solution for each.

Instead, I wanted a development environment that helped me leverage technology in a way that maximized my efforts. What I was interested in was the reduction or limitation of rewriting a solution to fit the intended deployment platform. I didn't want to solve the same problem in multiple languages. Who would?

I did a lot of searching.

When I search I don't just look at the results of the top 10. I page through them all. And I read the comments. By chance I found this review: http://sixrevisions.com/javascript/mobile%C2%A0web-development-frameworks/ and buried in the comments I found a reference to Application Craft. That tool is the focus of this blog.

Cloud based
What immediately drew me to AC was the ability to *not* have to install anything.  That freed me from a specific box.  I could work on my app from anywhere, home, office, coffee shop.  That's huge.

JSLint
Once I started working w/ AC I discovered additional hidden gems.  For example, when I edit the javascript code, JSLint is running.  What that means is that my JS code is being analyzed while I program - I don't have to complete my code and then run JSLint.  Instead, I see syntactical errors almost instantaneously.  What more could a girl want?

Revisions
Another wonderful gem is the saving of application state.  Every save is revisioned.  This is not the same as undo.  This is make multiple changes and realize that some time ago the version you were working on was the best.  With AC you simply recover that particular revision and you're back at it.

Forum
Another great benefit that isn't obviously apparent is the forum support.  But that is probably true with any quality software product.  What I like about AC is they use Get Satisfaction.  It's a quality product that hosts product support capabilities.  AC made a good decision to leverage GS.  And maybe it's just me, but I'm impressed when the founder/CEO is also involved with responding to questions.  It says a lot to me and a lot about the  company.

Mobile devices
The next benefit was having a single code base that could be deployed as a native app to multiple smart phones.  Whether or not this was the absolute best run-time performing solution or the optimal mobile phone solution didn't concern me.  I am most interested in minimizing my development time.  I didn't anticipate that my final solution would require such native phone performance that it would be an issue.

When I considered deploying my app to mobile devices I was pleased to see that AC had seemless integration with PhoneGap.  I didn't know anything about PG and following clear instructions in the AC User Guide I set up a PG account and entered that info into AC for my project.  I was then able to generate the native phone apps for the major phones other then iPhone.  For a small fee AC will setup the requirements that Apple has so that a iPhone app can also be generated.  I only tested Android and it worked perfectly.

Responsive Design
Following the guide lines I was able to make one application that would render correctly on any device.  That's huge.  I didn't have to detect what device I was running on and compensate for it.  The components, if laid out correctly, will adjust to the dimensions of the device and render appropriately.  By that I mean the components will flow smoothly.  If for example the components are contained in a Panel that is horizontal layout, if the size constrains them such, the components will stack.  It plays nice.

Summary
AC is a viable solution to not only web application development but also tablet and mobile devices.  There is more that I too need to investigate and I look forward to it.


Wednesday, December 28, 2011

Austin Yacht Club - Beer Can Race - Which Way To Go



Overview

At the Austin Yacht Club, each summer there is a unofficial race each Friday evening called the Beer Can Race.  It involves:

  • Start and Finish same place
    • Use bouys at entrance to AYC
    • Imaginary line between 
  • Race around 3 marks in Lake Travis, TX 
    • The marks are B, E, and K  
    • In any direction as long as all the marks are rounded.
  • The boats start at handicapped times
    • Slower boats go first
    • Faster boats follow w/ handicap
  • The 1st & 2nd Place winners 
    • Get a bottle of wine!
    • Add 30 seconds handicap next race
The idea, with the handicap, is that if everyone sailed perfectly, we'd all finish at the same time.

AYC Beer Can Racer


You can view the AYC Beer Can Racer web app here: http://acft.ws/bddq

The AYC Beer Can Racer app shown above determines the fastest route around the required marks using the wind direction and speed provided.

Background
This summer I was sailing a beer can race with Ray Shull and as we approached the starting line I wondered which direction he would take.  Ray asked me to reach into the cabin and get a chart for him.  He looked at the wind direction and then the chart and said "We going to E!".  "Wow" I said, "could I have a copy of that chart?"  He laughed and said something to the effect that I should figure it out for myself - "it would do you good!"

I had no idea how to pursue this.  I wondered what was involved in the calculations. I'd been out of college for more then 30 years and hadn't used much math since.  I couldn't remember the difference between a tangent and a cosine.

So I started researching.  The first interesting web site was our own AYC.  There I found two things that would helped me.

Marks


First, I found the map of AYC Racing Marks http://www.austinyachtclub.org/racing_info/marks  When I viewed the source I found the latitude and longitude of the marks I needed, namely E, K and B.

Next, also from the AYC site, the weather page http://www.austinyachtclub.org/WX/details.htm where I find the current wind direction and speed.  Of course it would be possible to write a mobile app that supported getting the current wind direction and speed using the capabilities of the phone but I didn't want to have to support all the different smart phones.  I thought if I could plot the current best route given the speed and direction of the wind, that would be a good start.

Distance
Now that I had the latitude and longitude of the beer can marks, I needed to know two more things about the marks, the distance between them and the bearing between them all.  I found this web site that provided that solution: http://www.movable-type.co.uk/scripts/latlong.html I just plugged in my lats/longs and viola - I got the distance and bearing.
Distance between two points

This is where I got lost.  I didn't quite understand, given all the information I had, what to do next.  Could I use trig and figure the angles the boat would travel and guess at the speed? Should I assume constant speed in all wind directions? Surely I would go different speeds - but how should I guess-estimate that? What should I do about tacking, about land, low water, shifty winds, etc.

Luckily I found something that helped a lot.  I found polar data for a Ranger 23 here http://www.arvelgentry.com/r23/r23_polars.pdf.  I don't know anything about a Ranger 23 but it seemed about the right size boat for my purpose.  And it gave me some data to work with - namely the boat speed at different True Wind Angles (TWA) for a given wind speed.

Ranger 23 Polars


Web app
So now I had all the data I needed.  I was able to write a very simple web app that works on either Chrome, Safari or Opera desktop browsers. It also works on IPhone because it uses the Safari browser and the Android also.  I'm not sure about the other desktop or mobile browsers.

The following is a screen shot from my Android:


Pages
There are three pages for the app.

The first page is a Google map that uses the wind speed/direction from the AYC weather page and plots the fastest route.  You can change the speed and direction.

There's also a button on the bottom ("Data") that takes you to a page which is a summary of all the speeds / wind direction and best routes.

Summary of all Wind Directions and Speed


There are two buttons on this page, one which is to a line graph for all the wind directions at a specific wind speed.  Note that S is the Start/Finish point.
Chart of all wind directions for specific speed

The "Map" button returns you to the map.

Calculating the time for each Route


I ignore changing land obstacles due to changes in level of water.  I try to guess the route from Start / Finish to / from B & K.   As you can see from the map plotting, I show the angles used to clear land obstacles when going in these directions.  I assume constant wind.  I  tack when heading are less then 45 degrees.  If the TWA is less then 45, I fall off to 45 and then using trig figure out the two legs of the triangle.  Though the Range 23 can sail windward at less then 45 degrees, for my solution, I ignored those angles as the boats I've sailed can't point that high.

All the routes plotted are based on time - what is the fastest route?  The fastest route is determined by looking at the possible paths for each route.  The time to sail each path is calculated by dividing the distance by the boat speed.  The boat speed is obtained from the polar tables using the TWA for the wind direction/speed.

Example calculation

Let's assume we have a  SSE wind with 8 knots.  There are numerous routes that have to be calculated (KEB, BEK, KBE, BKE, EKB, and EBK).

Each of these routes are made up of smaller paths.  Let's consider the BEK route.  The paths that make up this route are


  1. S to A (the tack point away from land)
  2. A to B
  3. B to E 
  4. E to K
  5. K to Z (the tack point away from land)
  6. Z to S (back to the start/finish line)


For demonstration, I'm going to look at three paths of the BEK, namely:


  1. S to A
  2. A to B
  3. B to E


Now "A" and "Z"  are pseudo marks that represents a point that extends far enough into the harbor that when rounded avoids the shore line.  The sailboat has to extend past this point before tacking to mark B.

S to A



The drawing above, S to A, shows the wind direction coming from SSE which is 157.  The sailboat is going in the direction of S (the Start) to A (the point past the land obstacle).  The bearing is 61.  The right and left values are the angles that are perpendicular to the bearing.  This helps to determine if the wind direction is behind, as in this case, or in front, ie a head wind.
Polar 105

In this case the true wind angle, TWA,  is 96.  Using the Rangers polar data, we use the polar for the next available TWA which is 105.  Looking up the chart, the speed is determined to be 5.665.  Since the distance is 0.3373, then the time to travel from S to A is 0.059 (Time = Distance divided by Speed (T = D/S)).

A to B

A to B
In the diagram above, A to B, the wind direction is behind the sailboat and the TWA is 166.  




Again, from the above table, the polar twa is 165 and the speed is 3.792.  The time to travel from A to B is 0.441.

B to E

This next path shows how the sailboat must tack to make the mark.  
B to E - Step 1
In going from B to E, the TW is 27.  The sailboat can't sail directly into the wind, it has to "fall off".  Falling off means changing the direction of the sailboat so that there is a larger TWA.  In this case, if the sailboat changes its bearing so as to increase the angle to the wind, the first possible position would be an TWA of 44 since that's the smallest angle this sailboat's polars provide (note I'm ignoring the 36 wind angle as most boats can't point that high).

In the diagram above, the sailboat takes a new bearing which is a polar TWA of 44 degrees.  So what needs to be done now is calculate the length of the New Bearing and the leg from the Tack to mark E.

Using trigonometry, the distance of the New Bearing to the Tack location and the distance from the Tack location to mark E can be calculated.

Note that a Tack makes a 90 degree turn.  Therefore we have a right triangle with the hypotenuse being the original Bearing.

Let's call the Bearing "c".  Using the Pythagorean theorem, a^2 + b^2 = c^2\!\,.

So what is the length of a, the new bearing?  Remembering trig, a = sin(a) * c.   

A is the polar of 44 minus 27 which is 17.  First though we have to convert degrees to radians and the formula is:
 sin(27 * (PI / 180) which gives us 0.276485.

Substituting the values of a and c, using a = sin(a) * c, the distance of the Tack (a) is 0.7047.

Now using Pythagorean, and knowing c & a, we can calculate b:

b = square root (c squared - a squared) =  2.44963.

So now we have our total distance for this New Bearning (b) and Tack (a):
b + a = 0.7047 + 2.44963 = 3.15433

Using the polar data for 44 TWA, see below,


We have the time for this path of B to E:

Time = distance / speed

Time = (a + b) / 4.729;

Time = 3.15433 / 4.729

Time = 0.667

Summary

So continue as above for all the paths that make up BEK route and summing their times, the route takes 1.811 hours to complete.

This process has to be done for all the possible routes and the route with the least amount of time is what is desired.


Web 2.0 Development For the Single Java Developer

Overview

Have you searched for an application development tool that is open source, java, and based on web 2.0 standards? Has all the technology features and requirements of integrating multiple products into a cohesive development tool suite made the technological decision more difficult then it needs to be?
I recently decided to start my own business after years of working for companies like IBM & Dell. As an independent consultant, I needed a software development tool that could maximize my productivity and utilize my experience.
This article outlines my technical requirements and decision-making process.
Requirements for a Web 2.0 Development Tool
Some of the features of a web 2.0 development tool might be: easy and rich interactions with external services via web services, rich and easy to use UI widgets, a web-based development solution that runs in the major browsers (zero install footprint), seamless integration between the client and server, usage of standard debugging tools (ie FireBug and Eclipse), based on standard Java technologies such as Spring, JaxWS, Acegi and Hibernate.
In order to be productive as a single java developer team I would like to be sheltered from all the low level setup and integration of the various technologies. I would like to have an application development environment that combines the best of breed web 2.0 development technologies into one development environment tool that helps me be productive while delivering cutting edge solutions.
A few features I personally require:
  • Web 2.0 UI: The developers tool is written with the tool
  • Rich UI Widgets: UI widgets like Dojo for a Rich Internet Application (RIA)
  • Web Browser Runtime: zero install footprint with no proprietary plugin
  • Security System based on Spring Acegi: proven and robust security solution
  • Seamless database integration: easy to build web forms for CRUD operation of the database schema
  • Java support: full support of Java programming on the server: - I don't want to have to learn YAL (Yet Another Language)
  • Ease of deployment: support open source severs like Tomcat and JBoss
  • Open Source: active community with source code readily available - a solution whose design is based on established standards
Selecting an Easy to Use Web 2.0 Development Tool
Since I want to write a web-based application that may be inter or intranet website or both, I would like the developer application to be built with the same technology that I will use. This is why I want the development tool to be web-based. For the UI, the very UI tools that are used in the final deployable web-based application should be the same components used in the developers tool. If the final end product I develop utilizes Dojo widgets then my developer tool should use those same Dojo widgets. I think some call that "eating your own dog food"!
I did some personal research into what javascript client library would be the best for me to learn. I decided that it would be Dojo for various reasons one of which was I really liked the way it looked! But when I was learning Dojo, I was a little overwhelmed with how much there was to learn and all the moving parts. With the incorporation of Dojo into the development tool that learning curve could be reduced tremendously and I like that idea.
I would like a drag and drop development tool that runs in a browser that hides the complexity of working with Javascript toolkits like Dojo. I also want it to make setting up security such as snap that it's hard to believe you're running on top of something like Spring Acegi.
If you've ever setup Spring Security with Acegi you know how difficult it can be. I think that Spring Acegi rocks and would like to have a development tool that supports it seamlessly. By that I mean having Acegi integrated into the developer tool and requiring from the developer a few definitions such as which table has the user id and password to enable security.
Database access can be the hardest part. The integration of the database schema should be evident when building UI components - the components should understand the keys (both primary and foreign), the data types, how to present to the UI and how to scroll and such. I should be able to create a functional sophisticated CRUD (Create Read Update Delete) pattern UI in minutes with no coding!
The deployment of the application should be a single mouse click - the requested war or ear should be generated and placed in a specific directory for easy retrieval. There should be no maintenance of ANT or Maven build scripts. My web-based deployable artifact should be generated quickly and be deployed it to any of the popular web servers: Tomcat, JBoss, GlassFish, WebLogic and WebSphere.
If you are a single java developer looking at web 2.0 development consider these items as you kick the tires on the various solutions available.
Barton Hammond
Austin, TX
After defining my requirements, I set out to find a tool that could meet my needs. I rapidly weeded out solutions that were proprietary (e.g., Adobe Flex), not based on Java (e.g., Ruby on Rails), or lacking a visual UI builder (e.g., Spring Roo).
Through this process I ran across an open source product called WaveMaker. After downloading the product and working with it for several weeks, I felt it provided a good fit with my requirements. I was also impressed with the friendly open source developer community for WaveMaker.
The tool I found that meets my requirements is http://wavemaker.com.
If you are a single Java developers who are looking to optimize productivity while harnessing web 2.0 and open source, you should consider looking at WaveMaker. The easy things are extremely easy and the difficult things are not so difficult.