Java: Calculate Distance Between 2 Points on Earth

Posted on

Find the distance between 2 longitude/latitude points on earth must have been the one thing I thought was everywhere on the web. And it is! Only problem is that most of the libraries and code I would find were in JavaScript. This is OK if you develop in JavaScript or even in GWT.

What about Java?

Yes, for those of us developers who need to code such functions in Java I found it quite difficult to find a ready made library that would give me the distance between 2 longitude/latitude points. This is in fact very essential because one of the main ideas behind having GeoLocation support in your applications and/or server back-end is to tell someone how close everything is to them. You get the geographical coordinates of your user and you send it to a server. The server calculates the distance between that user and all burger joints within a 5 km radius, thus giving your user a list of delectable places close to them where they can go and eat.

After a long search on the Internet I came across 2 options.

  1. Read and learn how to calculate the distance my self from this really nice paper called "Finding Points Within a Distance of a Latitude/Longitude Using Bounding Coordinates"
  2. Use the source readily available from GeoDataSource

Guess which one I took ? 🙂 Option 2 of course. Though I did read through the paper and found it interesting. At least I know how, but I am not in that much of a mood to sit down with mathematical equations on one hand and a compiler on the other hand all night. The second option, which was kinda weird because the "Sample Code" is provided and it calculates distance nicely. I see only one trademark and a copyright notice with no specified license. They talk about buying GeoDataSource products, but I doubt that "Sample Code" is the product in question. After all, it is just "Sample Code". I think they sell you a database of geographical coordinates and give you that "Sample Code" on how you would use their data.

Great! Now that I convinced my self that the "Sample Code" is not the actual product, I start to use it. I may say that is works very well. It could use a bit more documentation so I am going to reproduce the "Sample Code" here with my added extra documentation.

In a nut shell, you would call the method distance(double lat1, double lon1, double lat2, double lon2, char unit) like so

double lat1 = getMyLatitude();
double lon1 = getMyLongitude();
double lat2 = getHisLatitude();
double lon2 = getHisLongitude();
double distance = distance(lat1, lon1, lat2, lon2, 'K');
System.out.println("Distance between me and him is "+distance+" km");

The API method as I have documented them. You can also view the original at GeoDataSource

	 * <p>This routine calculates the distance between two points (given the
	 * latitude/longitude of those points). It is being used to calculate
	 * the distance between two locations.</p>
	 * <p>Definitions: South latitudes are negative, east longitudes are positive</p>
	 * <p>Passed to function:
	 * <ul>
	 * 		<li>lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees)</li>
	 * 		<li>lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees)</li>
	 * 		<li>unit = the unit you desire for results
	 * 			<ul>
	 * 				<li>where: 'M' is statute miles</li>
	 * 				<li>'K' is kilometers (default) </li>
	 * 				<li>'N' is nautical miles</li>
	 * 			</ul>
	 * 		</li>
	 * </ul>
	 * Worldwide cities and other features databases with latitude longitude
	 * are available at http://www.geodatasource.com</p>
	 * <p>For enquiries, please contact sales@geodatasource.com</p>
	 * <p>Official Web site: http://www.geodatasource.com</p>
	 * <p>GeoDataSource.com (C) All Rights Reserved 2013</p>
	 * @param lat1 - latitude point 1
	 * @param lon1 - longitude point 1
	 * @param lat2 - latitude point 2
	 * @param lon2 - longitude point 2
	 * @param unit - unit of measure (M, K, N)
	 * @return the distance between the two points
	public static final double distance(double lat1, double lon1, double lat2, double lon2, char unit)
		double theta = lon1 - lon2;
		double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
		dist = Math.acos(dist);
		dist = rad2deg(dist);
		dist = dist * 60 * 1.1515;
		if (unit == 'K') {
			dist = dist * 1.609344;
		else if (unit == 'N') {
			dist = dist * 0.8684;
		return (dist);

	 * <p>This function converts decimal degrees to radians.</p>
	 * @param deg - the decimal to convert to radians
	 * @return the decimal converted to radians
	private static final double deg2rad(double deg)
		return (deg * Math.PI / 180.0);

	 * <p>This function converts radians to decimal degrees.</p>
	 * @param rad - the radian to convert
	 * @return the radian converted to decimal degrees
	private static final double rad2deg(double rad)
		return (rad * 180 / Math.PI);