Back Next

File Reading

Programming and Data Structures (QC204)

Coursework 2000

Unit Organiser :  P.S.Williams

 

Below are the positions of various cities  on the surface of the earth.  These positions are given as latitude and longitude, expressed in degrees. 

 

 Place             Latitude Longitude (Don't type these headings in!)

 

London                        51.50                -0.08

Bombay                   18.92               72.83

Singapore          1.17    103.67

Sydney                  -33.88   151.17

Auckland               -36.86   174.77

Vancouver        49.33  -123.17

NewYork         40.75  -74.00

Kingston           18.00  -76.83

Brasilia                -15.92    -47.67

NorthPole         90.00                  0.00

SouthPole              -90.00       0.00

Berlin               52.53                13.40

Moscow           55.75                37.58

Athens              37.97                23.77

Rome                41.90                12.50

Tokyo               35.75                39.45

Nairobi             -1.33      36.83

Capetown                -33.92     18.37

Perth                   -31.95               115.87

Winnipeg          59.83               -97.35

You are required to do the following :

(a)       Enter the name and position data into a ASCII text file using a suitable text editor. The format must be as shown. Give the file a suitable name.

 

(b)       We will wish to read each line as a string then break up the string into a string variable for the name of the place, a double variable for the latitude and a double variable for the longitude. In order to split the input string into its constituent parts, you are recommended to use a Tokenizer - see the section on Tokenizing strings with a StringTokenizer object in  the chapter on Strings and Characters in Deitel's book. (Alternatively you may be able to use substring methods - also in the same chapter).

 

 (c)        Using the ASCII file for the place names and their latitudes and longitudes write a Java program to

 

            (i) Read the entries as before (splitting them up into three components) into  a binary search tree (BST). You will have to modify the definition of the node's data field to now hold three data items. The name field should be the key - i.e the choice of where you insert the data will be the result of an  alphabetical comparison. (Note : you must not use arrays)

 

            (ii) Using the BST output the list of entries in alphabetical order using the name field as key.

 

            (iii) For a given input name place (either from the keyboard or within the main part of the program), your program must output the distance in miles between the place chosen and London. (You will have to write a search method - the city name is either in the root node or in the left or right subtree or not there at all. Which subtree to look in can be done on the basis of comparing the given name with the name in the current root node).

 

            How far from London is Singapore ?  How far is Llanfairpwllgwyngyll ?

 

import java.io.*;
import java.util.*;
import java.text.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.net.*;

public class CityDistance extends JApplet implements ActionListener
{
private String city,filename="WorldData.txt";
private cityTree tree;
private JTextField cityTextField,answertextfield;
private JTextArea textarea;
private DecimalFormat precisionTwo = new DecimalFormat("0.00");

public void init()
{
textarea=new JTextArea(17,20);
city="";
tree=new cityTree();
JLabel question=new JLabel("For which of these cities do you want to know the distance from London?");
JLabel answer=new JLabel("The distance in miles is:");
cityTextField=new JTextField("");
answertextfield=new JTextField("");
cityTextField.addActionListener(this);
answertextfield.setEditable(false);
Container contentPane=getContentPane();
this.setSize(700,400);
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c=new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx=0.1;
contentPane.setLayout(gridbag);
gridbag.setConstraints(question,c);
contentPane.add(question);
c.gridwidth=GridBagConstraints.REMAINDER; 
c.weightx=1.0;
contentPane.add(cityTextField,c);
c.weightx=0.1;
c.gridwidth = GridBagConstraints.RELATIVE; 
gridbag.setConstraints(answer, c);
contentPane.add(answer);
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx=1.0;
gridbag.setConstraints(answertextfield, c);
contentPane.add(answertextfield);
JScrollPane scroller=new JScrollPane(textarea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
c.weighty = 1.0;
gridbag.setConstraints(scroller, c);
contentPane.add(scroller);
}

public void start()
{
String latit,longit,place,inorder;
Double lat, lon;
double lati, longi;
String text;
StringTokenizer allinorder; 

try
{
URL u=new URL(getDocumentBase(),filename);
text=readFile(u);
StringTokenizer allcities=new StringTokenizer(text);
int noCities=allcities.countTokens()/3;
for(int i=0;i<noCities;i++)
{
place=allcities.nextToken();
latit=allcities.nextToken();
longit=allcities.nextToken();
lat= new Double(latit); 
lon= new Double(longit);
lati=lat.doubleValue(); 
longi=lon.doubleValue(); 
tree.insert(place, lati, longi);
}
inorder=tree.toInOrderString();
textarea.append("The cities (in the file of data) in alphabetical order are:\n");
if(inorder=="") textarea.append("The file of cities is empty\n");
else
{
allinorder=new StringTokenizer(inorder);
for(int j=0;j<tree.getNumberOfCities();j++)
{
textarea.append("CITY:\t"+allinorder.nextToken()+"\tLATITUDE:\t"+allinorder.nextToken()+"\tLONGITUDE:\t"+allinorder.nextToken()+"\n");
}
}
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null,e.toString());
}
}

public void actionPerformed(ActionEvent e)
{
city=cityTextField.getText();
if(tree.isMember(city))answertextfield.setText(""+precisionTwo.format(tree.Distance(tree.getLatitude(city),tree.getLongitude(city),tree.getLatitude("London"),tree.getLongitude("London"))));
else 
{
cityTextField.setText("");
answertextfield.setText(city+" is not in the list");
}


public String readFile(URL url)
{
BufferedReader bReader;
String data="";
try
{
URLConnection uc=url.openConnection();
uc.setUseCaches(false); // set caches false for Netscape browsers
uc.setDoInput(true); // we are going to read from this url
uc.setDoOutput(false); // we do not want to transmit data through this url
uc.setAllowUserInteraction(false);// make the connection if not made already
uc.connect();// get the InputStream
InputStream in=uc.getInputStream();
InputStreamReader inReader=new InputStreamReader(in); // with default encoding scheme
bReader=new BufferedReader(inReader);
// get the data
String read=null;
do
{
read=bReader.readLine();
if (read!=null) data=data+read+"\n";
} while (read!=null);
if (bReader!=null) bReader.close();

catch (Exception e)
{
JOptionPane.showMessageDialog(null,"An IO error occurred: "+e.toString());
data=null;
}
return data;
}

}

//********************************************************************************************
class city
{
private String Place;
private double Latitude, Longitude;

public city(String p, double lat, double longit)
{
Place=p;
Latitude=lat;
Longitude=longit;
}

public String getPlace()
{
return Place;
}

public double getLatitude()
{
return Latitude;
}

public double getLongitude()
{
return Longitude;
}

}

//********************************************************************************************
class cityTreeNode 
{
cityTreeNode left; 
city data;
cityTreeNode right;

cityTreeNode(String place, double latitude, double longitude)
{
data=new city(place, latitude, longitude); 
left=right=null;
}

public String getPlace()
{
return data.getPlace();
}

public double getLatitude()
{
return data.getLatitude();
}

public double getLongitude()
{
return data.getLongitude();
}


//********************************************************************************************
class cityTree 
{
private cityTreeNode root;
private boolean ismember;
private double latitude, longitude;
private String inorder, preorder, postorder;
private int numberOfCities;

cityTree()
{
root=null;
ismember=false;
inorder="";
preorder="";
postorder="";
numberOfCities=0;
}

private static boolean issmaller(String s1, String s2)
// returns true if s1<s2, i.e. s1 before s2 alphabetically
{
int s1length=s1.length(), s2length=s2.length(), shortestlength;
int i=0;
boolean isbefore=false;
if(s1length<s2length)shortestlength=s1length;
else shortestlength=s2length;
while(s1.charAt(i)==s2.charAt(i)&&(i<shortestlength))
{
i++;
}
if(s1.charAt(i)<s2.charAt(i)) isbefore=true;
return isbefore;
}

private static boolean isequal(String s1, String s2)
// returns true if s1=s2, i.e. s1 the same word as s2 n.b. case sensitive
{
return (s1.equals(s2));
}

public String toInOrderString()
{
inorder=""; 
inorderTraversal();
return inorder;
}

public String toPreOrderString()
{
preorder=""; 
preorderTraversal();
return preorder;
}

public String toPostOrderString()
{
postorder="";
postorderTraversal();
return postorder;
}

public int getNumberOfCities()
{
return numberOfCities;
}

private cityTreeNode insert(cityTreeNode city, String place, double latitude, double longitude)
{
if(city==null) return new cityTreeNode(place, latitude, longitude);
else if(issmaller(place,city.getPlace())) city.left=insert(city.left, place, latitude, longitude);
else city.right=insert(city.right, place, latitude, longitude);
return city;
}

public void insert(String place, double latitude, double longitude)
{
numberOfCities++;
root=insert(root, place, latitude, longitude);
}

public void preorderTraversal() 

preorderHelper(root);
}

private void preorderHelper(cityTreeNode node)
{
if(node==null) return;
preorder+=(node.data.getPlace()+" "+node.data.getLatitude()+" "+node.data.getLongitude()+" ");
preorderHelper(node.left); 
preorderHelper(node.right);
}

public void inorderTraversal() 
{
inorderHelper(root);
}

private void inorderHelper(cityTreeNode node)
{
if(node==null) return;
inorderHelper(node.left); 
inorder+=(node.getPlace()+" "+node.getLatitude()+" "+node.getLongitude()+" ");
inorderHelper(node.right);
}

public void postorderTraversal() 

postorderHelper(root); 
}

private void postorderHelper(cityTreeNode node)
{
if(node==null) return;
postorderHelper(node.left); 
postorderHelper(node.right); 
postorder+=(node.getPlace()+" "+node.getLatitude()+" "+node.getLongitude()+" ");


public boolean isMember(String s)
{
ismember=false;
memberHelper(s,root);
if(ismember) return true;
else return false;
}

private void memberHelper(String s,cityTreeNode node)
{
if (node==null) ismember=false;
else if(isequal(s,node.getPlace())) ismember=true;
else if(issmaller(s,node.getPlace())) memberHelper(s,node.left);
else memberHelper(s,node.right);
}

public double getLatitude(String s) throws IsntaMemberException
{
if(!(isMember(s))) throw new IsntaMemberException();
else
{
getLatitudeHelper(s,root);
return latitude;
}
}

private void getLatitudeHelper(String s,cityTreeNode node)
{
if (node==null) ;
else if(isequal(s,node.getPlace())) latitude=node.getLatitude();
else if(issmaller(s,node.getPlace())) getLatitudeHelper(s,node.left);
else getLatitudeHelper(s,node.right);
}

public double getLongitude(String s) throws IsntaMemberException
{
if(!(isMember(s))) throw new IsntaMemberException();
else
{
getLongitudeHelper(s,root);
return longitude;
}
}

private void getLongitudeHelper(String s,cityTreeNode node)
{
if (node==null) ;
else if(isequal(s,node.getPlace())) longitude=node.getLongitude();
else if(issmaller(s,node.getPlace())) getLongitudeHelper(s,node.left);
else getLongitudeHelper(s,node.right);
}

public double Distance(double Lat1, double Long1, double Lat2, double Long2)
// calculates the distance in miles between two points of given 
// latitude and longitude in degrees. The first point has position
// (Lat1,Long1) while the second has position (Lat2,Long2)} 
{
final double PI = 3.14149265;
final double R = 3961.0; // radius of the earth in miles
double L1,L2,M1,M2,N1,N2,C,S,T,Angle;

Lat1 = Lat1*PI/180.0; Long1 = Long1*PI/180.0;
Lat2 = Lat2*PI/180.0; Long2 = Long2*PI/180.0; 
L1 = Math.cos(Lat1)*Math.cos(Long1); L2 = Math.cos(Lat2)*Math.cos(Long2);
M1 = Math.cos(Lat1)*Math.sin(Long1); M2 = Math.cos(Lat2)*Math.sin(Long2); 
N1 = Math.sin(Lat1); N2 = Math.sin(Lat2);
C = L1*L2 + M1*M2 + N1*N2; S = Math.sqrt(Math.abs(1.0 - C*C));
if(Math.abs(C) < 1.0E-6) Angle = PI/2.0;
else

T = Math.abs(S/C);
if(C > 0) Angle = Math.atan(T); else Angle = PI - Math.atan(T);

return R*Angle;
}

}

//********************************************************************************************
class IsntaMemberException extends ArithmeticException
{
public IsntaMemberException()

super("This city isn't on the list.");
}
}
//********************************************************************************************

 

Up