Wednesday, September 21, 2011

Holiday Calendar

This is a Java application which can indicate the Sri Lankan holidays (other followers please don't mind). If you hover the mouse over the marked date, it'll indicate the holiday in detail as well.


 


You can use this application instead of windows calender gadget.
To download this application click here.


To run this app in startup,

  • Extract the My Calendar.rar
  • Create a desktop shortcut for HolidayCalendar.jar
  • Copy that shortcut and paste it in StartMenu/Programs/StartUp (can find in start menu) folder
I appreciate your valuable comments...


Tuesday, September 13, 2011

Some Useful Functions Related to Geo Coordinates

//GIVE THE DISTANCE BETWEEN TWO LAT, LNG COORDINATES IN METERS
public double distanceInMeters(double lat1, double lng1, double lat2,double lng2) {
double earthRadius = 3958.75;
double dLat = Math.toRadians(lat2 - lat1);
double dLng = Math.toRadians(lng2 - lng1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(Math.toRadians(lat1))
* Math.cos(Math.toRadians(lat2)) * Math.sin(dLng / 2)* Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double dist = earthRadius * c;
int meterConversion = 1609;
return dist * meterConversion;
}


//GIVE THE NEAREST LAT, LNG COORDINATE WHICH IS IN A ROAD, FOR THE GIVEN LAT, LNG
private double[] nearToRoad(double[] latLng1) {
double[] latLng = new double[] { latLng1[0], latLng1[1] };
try {
URL url = new URL(
"http://maps.googleapis.com/maps/api/directions/xml?origin="+ latLng1[0] + "," + latLng1[1] + "&destination=" + latLng1[0] + "," + latLng1[1] + "&sensor=false");
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("<lat>")) {
latLng[0] = Double.parseDouble(line.substring(line.indexOf('>') + 1, line.indexOf('/') - 1));
line = reader.readLine();
latLng[1] = Double.parseDouble(line.substring(line.indexOf('>') + 1, line.indexOf('/') - 1));
break;
}
}
reader.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return latLng;
}


//GIVE THE ADDRESS OF THE LAT, LNG COORDINATE (REVERSE GEOCODING)
public String findLocationAddress(double lat, double lng) {
String name = "unnamed";
try {
URL url = new URL(
"https://maps.googleapis.com/maps/api/geocode/xml?latlng="+ lat + "," + lng + "&sensor=false");
BufferedReader reader = new BufferedReader(new InputStreamReader(
url.openStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("<formatted_address>")) {
name = line.substring(line.indexOf('>') + 1,line.indexOf('/') - 1);
break;
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
return name;
}

Approximate String Matching


Here I used Levenshtein Distance method to calculate the amount of similarity between two strings. The method LevenshteinDistance(String source, String target) will return the cost to convert the source string to target string, by considering insertion, deletion and substitution of a character, each of them costs 1.

In the Tester class you can use an appropriate threshold to get the approximate matching strings.

public class StringUtils {

    public static int LevenshteinDistance(String source, String target) {
        // d[i,j] will hold the Levenshtein distance between
        // the 1st i characters of s & the 1st j characters of t;
        // note that d has (m+1) x (n+1) values

        int m = source.length(), n = target.length();
        int[][] d = new int[m][n];
        char[] s = source.toLowerCase().toCharArray();
        char[] t = target.toLowerCase().toCharArray();

        for (int i = 0; i < m; i++) {
            d[i][0] = i; // any 1st string to an empty 2nd string
        }
        for (int j = 0; j < n; j++) {
            d[0][j] = j; // any 2nd string to an empty 1st string
        }

        for (int j = 1; j < n; j++) {
            for (int i = 1; i < m; i++) {
                if (s[i] == t[j]) {
                    d[i][j] = d[i - 1][j - 1]; // no operation
                } else {
    //minimum of DELETION, INSERTION, SUBSTITUTION (each costs 1)
    d[i][j] = Math.min(d[i - 1][j] + 1, Math.min(d[i][j - 1] + 1, d[i - 1][j - 1] + 1));
                }
            }
        }
        return d[m - 1][n - 1];
    }
}

public class Tester {

    public static void main(String[] args) {
        List<String> suggestionList = new ArrayList<String>();
        List<String> sourceList = new ArrayList<String>();
sourceList.add("abc");
sourceList.add("abcefg");
sourceList.add("abcfgh");
sourceList.add("abcdhfgi");
sourceList.add("abcd ghi");
sourceList.add("abcdefgh");
        for (String s : sourceList) {
            int editCost = StringUtils.LevenshteinDistance(s,"abcdefgh");
            if (editCost <= 3) {
                suggestionList.add(editCost + s);
            }
        }
//Sort, best match first
        Collections.sort(suggestionList);
        int count = 0;
        for (String s : suggestionList) {
            System.out.println(s);
        }
    }
}

Guess the output...