2014-03-17

Calculate the distance between two geo locations

We are developing a location based app and we encounter a problem about the geo location yesterday. Which is "how to get the distance between two points in the map". It seem to be easy if using our usual XY coordination system (the Cartesian coordinate). However, the inputs are the latitude and longitude, not the unit of meter;



Formula:

acos( 
   cos(a.lat) x cos(a.long) x cos(b.lat) x cos(b.long) 
   + cos(a.lat) x sin(a.long) x  cos(b.lat) x sin(b.long)
   + sin(a.lat)*sin(b.lat)
)  x  earth.radius

Where:

a.lat, a.long  = latitude and longitude of the 1st point ( in radians)
b.lat, b.long  = latitude and longitude of the 2nd point ( in radians)
earth.radius = the radius of the earth;  (which is: 3443.9 nautical miles or 6378 km)


Source Code (in java):


public static double distanceBetween(double lat1, double long1, double lat2, double long2)
{
 double rLat1 = Math.toRadians(lat1);
 double rLong1 = Math.toRadians(long1);
 double rLat2 = Math.toRadians(lat2);
 double rLong2 = Math.toRadians(long2);
  
 double part1 = Math.cos(rLat1) * Math.cos(rLong1) * Math.cos(rLat2) * Math.cos(rLong2);
 double part2 = Math.cos(rLat1) * Math.sin(rLong1) * Math.cos(rLat2) * Math.sin(rLong2);
 double part3 = Math.sin(rLat1) * Math.sin(rLat2);
 
 return Math.acos(part1 + part2 + part3) * RADIUS;
}

Reference: 

There are more documentation talking about the distance calculation, also google provide API to do so.




2014-03-16

Abnormal java.net.UnknownHostException on resin

Recently, I encountered a problem while I am calling to Google API in my java code running on Resin. The problem is that: The http call raise an UnknownHostException;



It doesn't caused by Java itself because the UnitTest show it is correct.
It doesn't caused by Resin because it work in my development platform.

So what go wrong? Finally, I has discovered it is wrong in the staging server environment;
The /etc/hosts isn't configured as the resin want to. (... maybe it is the problem of resin too ..)

To fix it:
- type "hostname" to find your hostname . e.g "my.pc"
- edit /etc/hosts and add the line "127.0.0.1 my.pc"
- restart the server to make it effective

Notes:
- This problem may not be happened in all environment. My macbook doesn't have the problem.

Related Links:






2014-03-13

Make java connection pool auto reconnect

Recently we encountered a problem when using java db connection pool. The problem is that the connection is being closed by the DB server since it is already timeout. To due with this, need to configure two more parameters.

They are:
testOnBorrow  ;  define it as "true"
validationQuery ; define it as "SELECT 1 FROM dual" if you are also using MySQL

Yes, It is easy to config it. But how to test it? (Many sites may not give the answer). 

To verify the configuration is work, we can make a simple Unit Test;

Step 1: Make a failure case

Make an unit test base on the following code;


Properties p = new Properties(); 
prop.put("driver", "org.gjt.mm.mysql.Driver");
prop.put("url", "jdbc://localhost:3306/db");
prop.put("username", "user");
prop.put("password", "123456");
p.setProperties("testOnBorrow", "false");
p.setProperties("validationQuery", "");

BasicDataSource ds = BasicDataSourceFactory.createDataSource(prop);
ds.setMaxActive(1);
ds.setMaxIdle(1);
ds.setMinIdle(0);

Connection conn = ds.getConnection();
System.out.println("First connection");


System.out.println("Sleep start");
Thread.sleep(10000);
System.out.println("Sleep end");

Connection conn = ds.getConnection();
System.out.println("Second connection");


To make the connection fail at the second time, try to kill the connection in DB side while "Thread.sleep";


Step 2: Fix the failure 

Simply change "testOnBorrow=false" and "validationQuery=" to 
 "testOnBorrow=true" and "validationQuery=SELECT 1 FROM dual"

Then, run the test again. we will see "Second connection" show up instead of Exception message.