Urban Cycling: when is advantageous

In the last couple of months I have become an urban cyclist, using the bicycle to regularly go to work.
There are a lot of resources about urban cycling. Some among them say that the bicycle is actually really advantageous compared to cars or other vehicles. All of them define a range of success: some say 6 km (3.5 miles), others say 12 km (7.5 miles), with various values of minimum range too.
That depends on many factors: how much a city is bike friendly, the shape of the cyclist, number of uphills, ecc..
Anyway I found out that I couldn’t correctly visualize how much that ranges cover. I mean: does the distance from home to work fall in that range? Of course I just wanted a rapid glance, because the are the turns of the streets to consider too. I would be happy to have a glance of the distances as the crow flies.

So I made a little site using Google Maps Javascript API that let you define two ranges and visualize that two ranges with two circles. You can find it here.

Please bear in mind that the site is my “Hello World” for the Google Maps Javascript API and also that I just wanted a quick and dirty solution. So you won’t find anything shiny over there… 😉
Technically I just geocode a request, then I put three Overlays: a Marker and two Circles.
If you are interested in the Javascript code, you can get it directly from the site.
Or here it is:

var geocoder;
var map;
//LatLng.
var latlng;
//Circles Overlays.
var minCircle;
var maxCircle;
//Marker Overlay.
var marker;
//Assume starts with Km checked.
var oldChecked = 0;

function initialize()
   {
   geocoder = new google.maps.Geocoder();
   //var latlng = new google.maps.LatLng(-34.397, 150.644);
   //Genova.
   latlng = new google.maps.LatLng(44.4070624, 8.933988900000031);
   var myOptions =
      {
      zoom: 11,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
      };
   map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
   marker = new google.maps.Marker({
                                   map: map,
                                   position: latlng,
                                   animation: google.maps.Animation.DROP
                                   });
   drawCircles(latlng, document.getElementById("minRadius").value, document.getElementById("maxRadius").value);
   }

function changeUnit()
   {
   var radios = document.changeunitform.changeunit;
   if(!radios)
      return;
   if(radios.length != undefined)
      {
	  if(radios[0].checked)
	     {
		 //Km
         if(oldChecked != 0)//Otherwise is same selection: do nothing.
           {
           document.getElementById("minRadius").value = document.getElementById("minRadius").value * 1.609344;
           document.getElementById("maxRadius").value = document.getElementById("maxRadius").value * 1.609344;
           oldChecked = 0;
           }
	     }
	  else if(radios[1].checked)
	     {
         //Miles
	     if(oldChecked != 1)//Otherwise is same selection: do nothing.
            {
		    document.getElementById("minRadius").value = document.getElementById("minRadius").value / 1.609344;
            document.getElementById("maxRadius").value = document.getElementById("maxRadius").value / 1.609344;
            oldChecked = 1;
            }
	     }
      }
   }

function updateCirclesOnEnter()
   {
   var code = window.event.keyCode;
   if(code==13)
      updateCircles();
   }

function updateCircles()
   {
   drawCircles(latlng, document.getElementById("minRadius").value, document.getElementById("maxRadius").value);
   }

/*
 * A circle has a center, a LatLng, and a radius, in meters.
 * radiusMin and radiusMax are two strings for convenience: so type checks are only in this method.
 */
function drawCircles(center, radiusMin, radiusMax)
   {
   //Checks.
   var min = parseFloat(radiusMin);
   if(isNaN(min) || min<0)
      {
	  alert("Minimum radius not valid.");
	  removeCircles();
	  return;
      }
   var max = parseFloat(radiusMax);
   if(isNaN(max) || max<0)
      {
	  alert("Maximum radius not valid.");
	  removeCircles();
	  return;
      }
   if(min>=max)
      {
	  alert("Minimum radius >= maximum radius");
	  removeCircles();
	  return;
      }
   //alert(min + " <> " + max);
   //Eventually remove old circles.
   removeCircles();
   if(oldChecked != 0)//Miles, convert in km first.
      {
	  min*=1.609344;
	  max*=1.609344;
      }
   //Draw circles.
   var options =
      {
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map: map,
      center: center,
      radius: (min*1000)
      };
   minCircle = new google.maps.Circle(options);
   options.strokeColor = "#00FF00";
   options.fillColor = "#00FF00";
   options.radius = (max*1000);
   maxCircle = new google.maps.Circle(options);
   }

function removeCircles()
   {
   if(minCircle!=null)
      minCircle.setMap(null);
   if(maxCircle!=null)
      maxCircle.setMap(null);
   }

function codeAddress()
   {
   var address = document.getElementById("address").value;
   geocoder.geocode( {'address': address}, //Object literal GeoCode request.
	                 function(results, status) //Callback method to execute at results retrieval. Anonymous function in this case.
	                                           //results is an array.
	                    {
                        if (status == google.maps.GeocoderStatus.OK) 
                           {
                           latlng = results[0].geometry.location;
                           map.setCenter(latlng);
                           marker.setPosition(latlng);
                           updateCircles();
                           //Show lat and lng.
                           //alert(latlng.lat() + " ; " + latlng.lng());
                           }
                        else
                           {
                           alert("Position not found.");
                           }
                        });
  }

Hope that helps someone! 🙂

Advertisements

About Luong
http://www.linkedin.com/in/manhluong

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s