PDA

View Full Version : Calculate Distance with Geocode Information


David Miller
March 9th, 2012, 01:47 PM
Our mailing software has a geocode add-on that will provide the latitude and longitude data for an address. We need to calculate the distance between the recipient's address and the client's location and return the distance in miles.

Obviously, the calculated distance would be 'as-the-crow-flies' and not driving distance. There are several ways to calculate the distance; haversine formula, spherical law of cosines and Pythagoras' theorem.

Has anyone tried this with JavaScript and FusionPro? Recommendations?

Thank you,
-Dave

rpaterick
March 9th, 2012, 03:04 PM
If no answer solution through FP, I was given a company to contact for a possible map solution. They "might" be able to help with the calculation.

Eric Etkin at eric.etkin@seisan.com or www.seisan.com (http://www.seisan.com/)

dreimer
March 12th, 2012, 08:01 AM
Doesn't your mailing software also calculate that for you as well??

GreggRusson
March 12th, 2012, 11:32 AM
Had a distance calculation project last year where the potential customer had approx 500 stores and wanted to match their customer base to the three closest stores based on Long/Lat. Didn't get the project but saved the 'down and dirty' C# test code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace LongLatCalc
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
/// <summary>
/// Returns the distance in miles or kilometers of any two
/// latitude / longitude points.

/// </summary>
/// <param name="pos1">Location 1</param>
/// <param name="pos2">Location 2</param>
/// <param name="unit">Miles or Kilometers</param>
/// <returns>Distance in the requested unit</returns>

public double HaversineDistance(LatLng pos1, LatLng pos2, DistanceUnit unit)
{

double R = (unit == DistanceUnit.Miles) ? 3960 : 6371;
var lat = ToRadians((pos2.Latitude - pos1.Latitude));
var lng = ToRadians((pos2.Longitude - pos1.Longitude));
var h1 = Math.Sin(lat / 2) * Math.Sin(lat / 2) +
Math.Cos(ToRadians(pos1.Latitude)) * Math.Cos(ToRadians(pos2.Latitude)) *
Math.Sin(lng / 2) * Math.Sin(lng / 2);
var h2 = 2 * Math.Asin(Math.Min(1, Math.Sqrt(h1)));

return R * h2;

}


public enum DistanceUnit { Miles, Kilometers };


/// <summary>
/// Specifies a Latitude / Longitude point.
/// </summary>

public class LatLng
{

public double Latitude { get; set; }
public double Longitude { get; set; }
public LatLng() { }

public LatLng(double lat, double lng)
{
this.Latitude = lat;
this.Longitude = lng;
}
}

private double ToRadians(double degree)
{
return degree * Math.PI / 180;
}


private void btnCalculate_Click(object sender, EventArgs e)
{
LatLng latlng1 = new LatLng(47.294968,-122.215893);
LatLng latlng2 = new LatLng(47.401014,-122.252079);
textBox1.Text = HaversineDistance(latlng1, latlng2, DistanceUnit.Miles).ToString();
}

/* http://http://geocoder.us/ */
}
}

esmith
March 12th, 2012, 11:36 AM
A Google search for "javascript distance between coordinates" with a few modifications results in:
// modified from 2nd answer at
// http://stackoverflow.com/questions/5260423/torad-javascript-function-throwing-error

function CalcDistanceBetween(lat1, lon1, lat2, lon2) {
var R = 3958.7558657440545; // Radius of earth in Miles
var dLat = toRad(lat2-lat1);
var dLon = toRad(lon2-lon1);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;
}

function toRad(Value) {
/** Converts numeric degrees to radians */
return Value * Math.PI / 180;
}

var distance = CalcDistanceBetween(41.459211,-72.823557,41.462263,-72.811965);
return Math.round(10*distance)/10 + " miles";

David Miller
March 12th, 2012, 05:49 PM
Interesting Eric. Were the coordinates from my hometown just a coincidence? :-) After reading your post and doing some more research, this seems to work in FusionPro Desktop.

// Modified from: http://www.codecodex.com/wiki/Calculate_distance_between_two_points_on_a_globe#J avaScript
// Calculate distance between latitude/longitude points: http://www.movable-type.co.uk/scripts/latlong.html
// Radius of the earth: http://en.wikipedia.org/wiki/Earth_radius
// Rounding in JavaScript: http://www.javascripter.net/faq/rounding.htm

var lat1 = 41.459211; // Static Latitude
var lon1 = -72.823557; // Static Longitude
var lat2 = (Field("Latitude")); // Variable Latitude
var lon2 = (Field("Longitude")); // Variable Longitude
var R = 3959; // Convienient mean radius of the earth in miles. Change to 6371 for kilometers.
var dLat = (lat2-lat1)*Math.PI/180;
var dLon = (lon2-lon1)*Math.PI/180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1*Math.PI/180) * Math.cos(lat2*Math.PI/180) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.asin(Math.sqrt(a));
var d = R * c; // The distance is d.

return Math.round(d*10)/10 + ' Miles'; // Rounds the distance to tenths of a mile.

Thanks Eric!

David Miller
March 12th, 2012, 06:28 PM
Doesn't your mailing software also calculate that for you as well??

No. Our mailing software provides latitude and longitude coordinates for each record, accurate to the Zip+4, for radius searches.

-David

dreimer
March 13th, 2012, 06:42 AM
Cool, that looks like it works for me, I use Mail Manager for my mailing software and I tested your code and it seems to work. How would I go about modifying the script if say my data included a specific store that was specific to each record. Say I would call the stores info, Latitude2 and Longtitude2. This would come in very handy, Thanks.

dreimer
March 13th, 2012, 06:54 AM
Perfect the two variable way works great, this will come in handy, Thank you for posting that code!!!!