I recently wrote a little command line program in C# that can tell you the name of the nearest tube station. I’ve put the program on GitHub in my Coding Experiments repository:
https://github.com/robert-impey/CodingExperiments/tree/master/C%23/NearestTube
The interface is very simple- this more of an experiment than something that I intend for mass consumption! You enter a location via the command line as the latitude and longitude:
The starting point of the program was to calculate the distances between points. To do this I adapted some JavaScript code that John D. Cook wrote:
http://www.johndcook.com/lat_long_distance.html
Mathematical code looks very similar in many languages, and the translation from JavaScript to C# was trivially simple as the languages are very similar in this case. This code is part of the Point
class:
////// Porting JavaScript code from /// http://www.johndcook.com/lat_long_distance.html /// /// /// public double Distance(Point that) { // Compute spherical coordinates double rho = 6373; // convert latitude and longitude to spherical coordinates in radians // phi = 90 - latitude double phi1 = (90.0 - this.Latitude) * Math.PI / 180.0; double phi2 = (90.0 - that.Latitude) * Math.PI / 180.0; // theta = longitude double theta1 = this.Longitude * Math.PI / 180.0; double theta2 = that.Longitude * Math.PI / 180.0; // compute spherical distance from spherical coordinates // arc length = \arccos(\sin\phi\sin\phi'\cos(\theta-\theta') + \cos\phi\cos\phi') // distance = rho times arc length return rho * Math.Acos( Math.Sin(phi1) * Math.Sin(phi2) * Math.Cos(theta1 - theta2) + Math.Cos(phi1) * Math.Cos(phi2)) * 1000; }
Once I was able to calculate the distances between points on the map, I needed to be able to sort the tube stations of London by distance from the given point. This is the sort of code that LINQ to objects handles very naturally. In the SequentialTubeStationFinder
class, I have the following method:
public TubeStation FindNearestTubeStation(Point point) { return (from tubeStation in tubeStations orderby tubeStation.Point.Distance(point) select tubeStation).First(); }
tubeStations
is a generic list of TubeStation
objects. Each has a Point
property that is used to sort the tube stations and find the nearest one to our location.
The declarative style of programming that LINQ uses is much easier to read (and therefore maintain) than the equivalent code written with a for
loop.