# Store Locator using Java

We would like to write a program to find the closest store to an input address. The program is provided with a list of locations; it asks for an input address, and then outputs the closet store location.

The dataset here contains geographical locations of McDonald’s in North America. It is a CSV (Comma-Separated Values) file with three columns: latitude, longitude, and address.

-122.994495, 49.281079, 4805 E Hastings St Burnaby BC V5C 2L1
-123.029985, 49.281001, 3444 E Hastings Street Vancouver BC V5K 2A6
-123.024074, 49.265642, 3695 Lougheed Hwy Vancouver BC V5M 2A6
......


### Solution

The basic idea is as below:

• Design a Store class, and load all data into an ArrayList of Stores.
• Ask the user for an address, and find its geographical location.
• Scan through the ArrayList of all stores to find the closest one.

First, we define the Location class with the following attributes and methods:

• double latitude
• double longitude
• public Location(String addr, double lat, double lng)
• double distanceTo(Location loc): computes the distance to loc
• String toString(): displays the location
public class Location
{
private double		latitude;
private double		longitude;

public Location(String addr, double lat, double lng)
{
latitude = lat;
longitude = lng;
}

// Compute the distance in meters
public double distanceTo(Location loc)
{
double dLat = Math.toRadians(latitude - loc.latitude);
double dLng = Math.toRadians(longitude - loc.longitude);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLng/2) * Math.sin(dLng/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = earthRadius * c;
return dist * 1609;
}

public String toString()
{
return address + " (" + latitude + ", " + longitude + ")";
}
}


Now we define a tool class LocationTool. It has the following methods:

• Location makeLocation(String addr): creates a location object from an address. We use Google’s geocoding services to find the latitude and longitude of an address string.
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Scanner;
public class LocationTool
{
// Read from URL and return the content in a String
throws IOException
{
URL url = new URL(urlString);
Scanner scan = new Scanner(url.openStream());
String content = new String();
while (scan.hasNext())
content += scan.nextLine();
scan.close();
return content;
}

// Extract the middle part of a string from "open" to "close"
public static String extractMiddle(String str,
String open, String close)
{
int	begin = str.indexOf(open) + open.length();
int end = str.indexOf(close, begin);
return str.substring(begin, end);
}

// Extract the middle part of a string from "open" to the end
public static String extractMiddle(String str, String open)
{
int	begin = str.indexOf(open) + open.length();
return str.substring(begin);
}

// Make a Location object from a string address
throws IOException
{
String url =
String latlng = extractMiddle(content,
"\"location\" : {", "},");
double lat = Double.parseDouble(extractMiddle(latlng,
"\"lat\" :", ","));
double lng = Double.parseDouble(extractMiddle(latlng,
"\"lng\" :"));
}
}


Finally we build the main program Locator with a main method. As the program starts, it loads the data; then it asks for an input address, finds its geographical location, and searches for the closet store.

import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class Locator
{
public static void main(String[] args) throws IOException
{
String urlStr =
Scanner scan = new Scanner(System.in);
while (true)
{
break;

System.out.println("Your location is at: " + loc);

double distance = -1;
Location nearStore = null;
for (Location e : stores)
{
double d = loc.distanceTo(e);
if (d <= distance || distance < 0)
{
distance = d;
nearStore = e;
}
}
System.out.println("The closet McDonald is at: "
+ nearStore);
System.out.println("The distance is " +
(int) distance + " m");
}
}
}