Subdivide your lat/long space into cells of some appropriate size, and sort the locations into those cells.
Then, for each point along your route, do a spiral search outward among the cells to find the nearest neighbors.
P.S. Spiral search. You can do it on squares, bricks, or hexagons like this. If the tiles are big enough to contain some points but not too many, if finds neighbors quickly.
Just transform the latitude and longitude into the above coordinate system, round them to the nearest center, and make a bucket for each cell.
Then take your search point and find its bucket.
If nothing useful is found in its bucket, search the six buckets at radius 1, and so on, until a suitable collection of neighbors is found, and pick the best one.
The sequence of cells looks like this, assuming 0,0 is the starting cell:
look in 0,0
++x
++y
--x
--x,--y
--y
++x
++y,x+=2
++y twice
--x twice
--x,--y twice
--y twice
++x twice
++x,++y
++y,x+=2
etc. etc.
EDIT: some C++ code to do it
// for each point x,y, do this (d is diameter of a cell)
double x1 = (x + y/2)/d; // transform x coordinate
double y1 = (y / 0.866)/d; // transform y coordinate (it's shortened a bit)
int ix = (int)floor(x1 + 0.5); // find corresponding bucket
int iy = (int)floor(y1 + 0.5);
// then put point into bucket at ix,iy
// to search, enumerate over the cells
// first at distance 0, then 1, then 2, etc.
bool bPointsFound = false;
// collect points in bucket at 0,0
if (/* there are any points in the collection */){
bPointsFound = true;
}
for (n = 1; n < upper_limit && !bPointsFound; n++){
iy = 0; ix = n;
// upper right edge
for (i = 0; i < n; i++){
// collect points in bucket at ix, iy
iy++;
}
// top edge
for (i = 0; i < n; i++){
// collect points in bucket at ix, iy
ix--;
}
// upper left edge
for (i = 0; i < n; i++){
// collect points in bucket at ix, iy
ix--; iy--;
}
// lower left edge
for (i = 0; i < n; i++){
// collect points in bucket at ix, iy
iy--;
}
// bottom edge
for (i = 0; i < n; i++){
// collect points in bucket at ix, iy
ix++;
}
// lower right edge
for (i = 0; i < n; i++){
// collect points in bucket at ix, iy
ix++; iy++;
}
if (/* there are any points in the collection */){
bPointsFound = true;
}
}
// pick the closest point in the collection
ADDED: There is a slight possibility of getting a point which is not the closest, because a point just outside the edge of a hexagon might be closer than a point just inside the corner. If that's a concern, go out to an extra layer.