Saturday, June 14, 2014

Rambling

This post is content previously published on www.cathmhaol.com

I've a fine, felt hat
And a strong pair of brogues
I have rosin in my pocket for my bow
O my fiddle strings are new
And I've learned a tune or two
So, I'm well prepared to ramble and must go
Tommy Makem

Animated flight from LAX to LHR
with stops in LAS, DEN and ORD
In today's update, I'll describe how to draw routes on your cjl-earth.js map, so that you get something like this sample image, but first, I should explain the structure of the generated markup.

Within the map group (which is a 'g' tag - <g> - with an id attribute composed of the map object id and '-map'), are groups (using a 'g' tag - <g>) for the oceans, countries, markers, and routes. These 'route' groups each have the class 'route', and each group is created as it is read from the data, so you can style the individual 'routes' using the #map_object_id-routes g and the nth-of-type selectors as well as the g.route (an individual route) and path.travel-route (individual paths) selectors. Each route is composed of paths from the origin to the first destination and then from each subsequent 'destination' to the next, giving markup similar to the markup below. Because D3 is translating longitude and latitude to x and y coordinates in the SVG, all of this code is generated - you don't have to do any calculations.

Markup Example
<g id="cjl-globe-04748665224760771-routes">
 <g class="route">
  <path class="travel-route" d="M 88 203 L 93 200"></path>
  <path class="travel-route" d="M 93 200 L 107 195"></path>
  <path class="travel-route" d="M 107 195 L 130 192"></path>
  <path class="travel-route" d="M 130 192 L 250 179"></path>
 </g>
</g>

Now that we've covered what markup is generated, we're ready to begin.

Let's begin by deciding whether we want to use some sort of a marker - like an airplane or storm symbol - to animate the route(s) you're going to define or if you just want a line. If you want a simple line, the display will be controlled by a style - for example, <style type="text/css">.travel-route { fill:none; stroke:#ff0000; stroke-width:1px; }</style> will make the paths defined in your route appear as a thin, red line.

If you want to move a marker along the route, you'll need to provide the SVG equivalent of the image in a marker object. Marker objects have a 'd' property that contains the pen instructions ordinarily contained in the 'd' attribute of the path tag, and may optionally have an 'orient' property for those symbols that have an orientation (e.g. an airplane or other object that has a 'front'). If orient is set to true, the object is rotated so that the 'top' is facing in the direction of movement, like an airplane that 'flies' along a route. Markers are not scaled unless specifically requested by providing the 'scale' property, so the image that's provided should be the appropriate size when loaded; however, if the map is 'zoomed' by user interaction, the markers are 'zoomed' as well and will maintain their relative size.

Note: you may also choose to have the two types of animation combined, so that a travel path is revealed as your marker moves along the route; however, this is only possible if the marker is provided and the 'combineAnimation' flag is set - see the documentation regarding the travel method in the cjl-earth.js library for more information.

After you've decided which sort of animation you'd like, decide how long the animation should run and whether you want it to loop or run once.

Once all your design decisions are made, decide how you want to provide the data to the function. Here again, you have two choices: directly or via AJAX. With this final decision, you're ready to write the code to display the routes by calling the 'travel' method...something like the following.

Providing data using AJAX with no marker earth.travel('/ReST/api/routes?origin=LAX&amp;destination=LHR', null, 2000, true);

or

Providing data directly with a marker earth.travel( [
 {origin:[-118.408075, 33.942536],
  destination:[
    [-115.15225, 36.080056],
    [-104.673178, 39.861656],
    [-87.904842, 41.978603],
    [0.461389, 51.4775]
   ]
 }
], {d:"m25.21488,3.93375c-0.44355,0 -0.84275,0.18332 -1.17933,0.51592c-0.33397,0.33267 -0.61055,0.80884 -0.84275,1.40377c-0.45922,1.18911 -0.74362,2.85964 -0.89755,4.86085c-0.15655,1.99729 -0.18263,4.32223 -0.11741,6.81118c-5.51835,2.26427 -16.7116,6.93857 -17.60916,7.98223c-1.19759,1.38937 -0.81143,2.98095 -0.32874,4.03902l18.39971,-3.74549c0.38616,4.88048 0.94192,9.7138 1.42461,13.50099c-1.80032,0.52703 -5.1609,1.56679 -5.85232,2.21255c-0.95496,0.88711 -0.95496,3.75718 -0.95496,3.75718l7.53,-0.61316c0.17743,1.23545 0.28701,1.95767 0.28701,1.95767l0.01304,0.06557l0.06002,0l0.13829,0l0.0574,0l0.01043,-0.06557c0,0 0.11218,-0.72222 0.28961,-1.95767l7.53164,0.61316c0,0 0,-2.87006 -0.95496,-3.75718c-0.69044,-0.64577 -4.05363,-1.68813 -5.85133,-2.21516c0.48009,-3.77545 1.03061,-8.58921 1.42198,-13.45404l18.18207,3.70115c0.48009,-1.05806 0.86881,-2.64965 -0.32617,-4.03902c-0.88969,-1.03062 -11.81147,-5.60054 -17.39409,-7.89352c0.06524,-2.52287 0.04175,-4.88024 -0.1148,-6.89989l0,-0.00476c-0.15655,-1.99844 -0.44094,-3.6683 -0.90277,-4.8561c-0.22699,-0.59493 -0.50356,-1.07111 -0.83754,-1.40377c-0.33658,-0.3326 -0.73578,-0.51592 -1.18194,-0.51592l0,0l-0.00001,0l0,0l0.00002,0.00001z", orient:true, scale:0.3}, 2000, true, true);

One final note - the travel method does not play well with the transition method, which is covered in the last blog entry, A different point of view, nor does it work well with projections that are designed to rotate, such as the 'orthographic' projection.

Additional Resources:

No comments:

Post a Comment