Sort coordinates by proximity - gis

I want to sort the coordinates by proximity. But since my target point is in it, the value returns 0. I am sharing my example code. I need to be able to sort all points by distance. It makes sense to do it by keeping it in an array and deleting the first point, but I haven't been able to.
I'll be happy if you can help me.
var targetPoint = turf.point([28.965797, 41.010086]);
var points = turf.featureCollection([
turf.point([28.965797, 41.010086]),
turf.point([28.973865, 41.011122]),
turf.point([28.948459, 41.024204]),
turf.point([28.938674, 41.013324])
]);
var nearest = turf.nearestPoint(targetPoint, points);
console.log(nearest["properties"]["featureIndex"]); //return 0

I'm not quite sure what the goal is. Your example code is pretty much the example code for nearestPoint with just the targetPoint added to the collection. Querying a collection of points for the nearest which also contains that same target point should just find that target point, which in your collection happens to be on index 0.
Anyway, sorting these points on distance to a target point can be done by generating a custom sorting function, and using it in the sort function of the the array of Points in the FeatureCollection.
This example does so in ascending order (closest to target first):
function sortFeaturesByDistanceTo(target) {
return function(a, b) {
var options = {units: 'radians'}; // using radians to forgo conversion to another unit
return turf.distance(target, a, options) - turf.distance(target, b, options);
}
}
var targetPoint = turf.point([28.965797, 41.010086]);
var points = turf.featureCollection([
turf.point([28.965797, 41.010086]),
turf.point([28.973865, 41.011122]),
turf.point([28.948459, 41.024204]),
turf.point([28.938674, 41.013324])
]);
points['features'].sort(sortFeaturesByDistanceTo(targetPoint));
console.log(points);
To explain a bit more what is going on:
The function sortFeaturesByDistanceTo(Point) returns a new sorting function to use in Array.sort().
The generated sorting function is called with 2 Points from the array to figure out which point should appear in the array before the other point. It simply returns the difference between the distance from t to a and the distance from t to b. A positive result means a should go first. a negative result means b should go first. 0 (zero) means no change should be made.
Array.sort() will call the generated sorting function multiple times, depending on the implemented sorting algorithm, until the array is sorted.
This means the distance for each point to the target will be calculated multiple times. A more optimal solution would calculate the distance for each point only once.
A FeatureCollection can be created with multiple types of features, and a Point is just one of such features. Sorting this way only works if the FeatureCollection only contains Points.
Please note that the output of this example is the same as the input, because the input array is already ordered.

Related

Generate list of street Intersections in order

I have a list of all intersections in a city with coordinates. I am trying for an end result of a list of all the intersections in the order they appear. For example, if I put in Alameda & 5th - I want to see all cross streets if I keep going down Alameda (ex Alameda & 6th, Alameda & 7th, etc. )
However, they aren't all numbered streets.
I need the final format to be text-based - no visual mapping. I'm quite stumped on how to start and hoping for some direction.
Solution 1:
I would recommend using the longitude and latitude and ordering it by that. For instance, you can tell if a street is "below" another if the latitude of it is less than the other one. That'll probably get most of them in the right spot.
You can then manually double check them if there's not too much data.
Solution 2:
If there's not that much data, you might want to simply do it by hand. This isn't very efficient, but it could save your time (again, depending on the amount of data you have).
It sounds like you need to just create a relational database. My suggestion would be to get familiar (if you are not already) with Microsoft access. I can't think of any other tool that would suite you better.
All you would have to do is paste the list of intersections you already have into a table, create another table for the cross streets then, just make them relational. After that create your queries to spit out whatever data you want.
You will also have the opportunity to create a sort order of the cross streets relative to each intersection.
If you haven't used Access before, there is a bit of a learning curve but it's not like coding. Just watch a few youtube videos or invest in a Udemy coarse. I created a very similar database within a couple of days myself.
I am trying a pseudo implementation based on the limited information you have given.
Let's have Street and Intersection classes and some Database that can be queried for a list of objects with where filters (think of it as some SQL wrapper).
Now, we need a sorting algorithm for the intersections. The problem here is, that we cannot know the physical order based on the given information. Roads may go in curves, tunnels and what not.
So the next best thing we can do is guessing the order by evaluating the distance. Note that this will only work in a Manhattan type map layout without curves.
We will arbitrarily assume the first intersection would be the one with the lowest coordinate value.
From there, we search all our streets remaining intersections for the closest to the previous.
Again, please be aware, that this algorithm is a guess based on the given information. However, the general implementation pattern should still be usable for more sophisticated algorithms or the incorporation of additional information.
Please see my implementation in pseudo-code:
Database {
allIntersections {...}
allStreets {...}
}
Street {
id: String
name: String
intersections() -> [Intersection] {
return Database.allIntersections.where(street1 == self || street2 == self)
}
lowestIntersection() -> Intersection {
lowestIntersection: Intersections().first
for intersection in Intersections() {
currentDistance = intersection.distanceTo(Coordinate(0,0))
if (currentDistance < lowestIntersection.distanceTo(Coordinate(0,0)) {
lowestIntersection = intersection
}
}
return lowestIntersection
}
// the sort algorithm based on proximity
sortedIntersections() -> [Intersection] {
sorted = [lowestIntersection()]
remaining = intersections() - sorted
while remaining.count > 0 {
closest = sorted.last.closestIntersection(remaining)
remaining.remove(closest)
sorted.add(closest)
}
return sorted
}
}
Coordinate {
lat: Float
long: Float
}
Intersection {
street1: Street
street2: Street
coordinate: Coordinate
distanceTo(other: Coordinate) -> Float {
return sqrt(pow2(coordinate.lat - other.lat) + pow2(coordinate.long - other.long))
}
closesIntersection(others: Intersection) -> Intersection {
closesIntersection: others.first
for intersection in others {
currentDistance = intersection.distanceTo(self.coordinate)
if (currentDistance < closesIntersection.distanceTo(self.coordinate) {
closesIntersection = intersection
}
}
return closesIntersection
}
}
I hope this helps. For a more detailed answer, please provide more information like example data.

Finding the smallest distance in a set of points from the origin

I am to find the smallest distance between a given set of points and the origin. I have a matrix with 2 columns and 10 rows. Each row represents coordinates. One point consists of two coordinates and I would like to calculate the smallest distance between each point and to the origin. I would also like to determine which point gave this smallest distance.
In Octave, I calculate this distance by using norm and for each point in my set, I have a distance associated with them and the smallest distance is obviously the one I'm looking for. However, the code I wrote below isn't working the way it should.
function [dist,koor] = bonus4(S)
S= [-6.8667, -44.7967;
-38.0136, -35.5284;
14.4552, -27.1413;
8.4996, 31.7294;
-17.2183, 28.4815;
-37.5100, 14.1941;
-4.2664, -24.4428;
-18.6655, 26.9427;
-15.8828, 18.0170;
17.8440, -22.9164];
for i=1:size(S)
L=norm(S(i, :))
dist=norm(S(9, :));
koor=S(9, :) ;
end
i = 9 is the correct answer, but I need Octave to put that number in. How do I tell Octave that this is the number I want? Specifically:
dist=norm(S(9, :));
koor=S(9, :);
I cannot use any packages. I found the geometry package online but I am to solve the task without additional packages.
I'll work off of your original code. Firstly, you want to compute the norm of all of the points and store them as individual elements in an array. Your current code isn't doing that and is overwriting the variable L which is a single value at each iteration of the loop.
You'll want to make L an array and store the norms at each iteration of the loop. Once you do this, you'll want to find the location as well as the minimum distance itself. That can be done with one call to min where the first output gives you the minimum distance and the second output gives you the location of the minimum. You can use the second output to slice into your S array to retrieve the actual point.
Last but not least, you need to define S first before calling this function. You are defining S inside the function and that will probably give you unintended results if you want to change the input into this function at each invocation. Therefore, define S first, then call the function:
S= [-6.8667, -44.7967;
-38.0136, -35.5284;
14.4552, -27.1413;
8.4996, 31.7294;
-17.2183, 28.4815;
-37.5100, 14.1941;
-4.2664, -24.4428;
-18.6655, 26.9427;
-15.8828, 18.0170;
17.8440, -22.9164];
function [dist,koor] = bonus4(S)
%// New - Create an array to store the distances
L = zeros(size(S,1), 1);
%// Change to iterate over number of rows
for i=1:size(S,1)
L(i)=norm(S(i, :)); %// Change
end
[dist,ind] = min(L); %// Find the minimum distance
koor = S(ind,:); %// Get the actual point
end
Or, make sure you save the above function in a file called bonus4.m, then do this in the Octave command prompt:
octave:1> S= [-6.8667, -44.7967;
> -38.0136, -35.5284;
> 14.4552, -27.1413;
> 8.4996, 31.7294;
> -17.2183, 28.4815;
> -37.5100, 14.1941;
> -4.2664, -24.4428;
> -18.6655, 26.9427;
> -15.8828, 18.0170;
> 17.8440, -22.9164];
octave:2> [dist,koor] = bonus4(S);
Though this code works, I'll debate that it's slow as you're using a for loop. A faster way would be to do this completely vectorized. Because using norm for matrices is different than with vectors, you'll have to compute the distance yourself. Because you are measuring the distance from the origin, you can simply square each of the columns individually then add the columns of each row.
Therefore, you can just do this:
S= [-6.8667, -44.7967;
-38.0136, -35.5284;
14.4552, -27.1413;
8.4996, 31.7294;
-17.2183, 28.4815;
-37.5100, 14.1941;
-4.2664, -24.4428;
-18.6655, 26.9427;
-15.8828, 18.0170;
17.8440, -22.9164];
function [dist,koor] = bonus4(S)
%// New - Computes the norm of each point
L = sqrt(sum(S.^2, 2));
[dist,ind] = min(L); %// Find the minimum distance
koor = S(ind,:); %// Get the actual point
end
The function sum can be used to sum over a dimension independently. As such, by doing S.^2, you are squaring each term in the points matrix, then by using sum with the second parameter as 2, you are summing over all of the columns for each row. Taking the square root of this result computes the distance of each point to the origin, exactly the way the for loop functions. However, this (at least to me) is more readable and I daresay faster for larger sizes of points.

google map placing locations with some distance

I'm new to ROR and Google Maps. I need to place some markers from locations in Google Maps (having latitudes and longitudes in a database).
The problem is that I need to select some points with some random distance.
In short, I need to select the location and place it in a map, which must have 100 m distance with each and every points.
If the location is within 100 m range with any other points, it can be neglected. I need to place 10 points from database.
Is there any method?
Assuming that you are needing to find points from your database that are at least 100 meters away from all the other points in the database:
This is a fairly simple problem. It can be visualized as an nxn matrix, with the point set as the rows and columns. In Python, comparing all the distances would look like:
selected = []
for pt1 in pts:
inRange = True
for pt2 in pts:
if pt1.distanceTo(pt2) < 100:
inRange = False
break
if inRange:
selected.append(pt1)
This function iterates through the whole list of points. For each point, it checks the distance from the current point to all the other points. If all the other points are outside 100 meters, it adds the point to an array.
For the distance formula, please see the haversine formula here in code form.
Since you did not specify a language in your question, I will let you translate this into whatever language you need. This is just pseudocode, since not enough details were provided to answer your question with actual code.
Also, if I misunderstood your question, you can adapt this algorithm in some way. It is just to provide some ideas.

What is the definition of a "true" multidimensional array and what languages support them?

Most of the programming books I have ever read, have the following line:
"X language does not support true multidimensional arrays, but you can simulate (approximate) them with arrays of arrays."
Since most of my experience has been with C-based languages, i.e. C++, Java, JavaScript, php, etc., I'm not sure of what a "true" multidimensional array is.
What is the definition of a true multidimensional array and what languages support it?
Also, please show an example of a true multidimensional array in code if possible.
C# supports both true multi-dimensional arrays, and "jagged" arrays (array of arrays) which can be a replacement.
// jagged array
string[][] jagged = new string[12][7];
// multidimensional array
string[,] multi = new string[12,7];
Jagged arrays are generally considered better since they can do everything a multi-dimensional array can do and more. In a jagged array you can have each sub-array be a different size, whereas you cannot do that in a multi-dimensional array. There is even a Code Analysis rule to this effect (http://msdn.microsoft.com/en-us/library/ms182277.aspx)
Java uses them too
int[][] a2 = new int[10][5];
Here's an interesting use of it that I've found
String[][] Data;
//Assign the values, do it either dynamically or statically
//For first fow
Data[0][0] = "S"; //lastname
Data[0][1] = "Pradeep"; //firstname
Data[0][2] = "Kolkata"; //location
//Second row
Data[1][0] = "Bhimani"; //lastname
Data[1][1] = "Shabbir"; //firstname
Data[1][2] = "Kolkata"; //location
//Add as many rows you want
//printing
System.out.print("Lastname\tFirstname\tLocation\n");
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
System.out.print(Data[i][j]+"\t");
}
//move to new line
System.out.print("\n");
}
Without going through the reams of literature on the Sun and Microsoft sites, this is what I remember from my C days. Hope this helps.
To make it simple, if we just think in 2 dimensions - Arrays can either be represented as a two-dimensional array and an array of pointers. In code this amounts to
int x[15][20];
int *y[15];
In this example, x[5][6] and b[5][6] are both valid syntactically and end up referring to a single int.
That being said, x is a true two-dimensional array: Once you create it , there will be 300 locations (that can contain int) that have been set aside, and you can use the well known subscript convention to access this rectangular (with 15 rows and 20 columns) array where you can get to x[row,col] by calculating (20 * row) + col.
However in case of y, while the structure is being defined, only 15 pointers are allocated, but not initialized. (Initialization will need to be done explicitly)
There are advantages and disadvantages of this approach (pointer array or "array of arrays" or jagged array as it is called):
Advantage:
The rows of this array can be of different lengths i.e. each element of y does not need to point to a twenty-element ROW; one element may point to a 2 elements, 2nd element may point to 3 elements, and 3rd to zero elements and so on.
Disadvantage:
However given a best case scenario, if each element of y does point to a twenty-element array, then there will be 300 integer locations set aside, plus ten cells for the pointers which is additional.
From a current example perspective, the C sharp examples given above (in one of the previous posts) should suffice.
Common Lisp supports both types of arrays.
The multidimensional array is called Array, while the "one-dimensional" one is called Vector.

Locating all elements between starting and ending points, given by value (not index)

The problem is as follows,
I would be given a set of x and y coordinates(an coordinate array of around 30 to 40 thousand) of a long rope. The rope is lying on the ground and can be in any shape.
Now I would be given a start point(essentially x and y coordinate) and an ending point.
What is the efficient way to determine the set of x and y coordinates from the above mentioned coordinate array lie between the start and end points.
Exhaustive searching ie looping 40k times is not an acceptable solution (mentioned on the question paper)
A little bit margin for error is acceptable
We need to find the start point in the array, then the end point. For each, we can think of the rope as describing a function of distance from that point, and we're looking for the lowest point on that distance graph. If one point is a long way away and another is pretty close, we can do some kind of interpolation guess of where to search next.
distance
| /---\
|-- \ /\ -
| -- ------- -- ------ ---------- -
| \ / \---/ \--/
+-----------------------X--------------------------- array index
In the representation above, we want to find "X"... we look at the distances at a few points, get an impression of the slope of the distance curve, possibly even the rate of change of that slope, to help guide our next bit of probing....
To refine the basic approach of doing binary- or interpolated- searches in areas where we know the distance values are low, we may be able to use the following:
if we happen to be given the rope length and know the coordinate samples are equidistant along the rope, then we can calculate a maximum change in distance from our target point per sample.
if we know the rope has a stiffness ensuring it can't loop in a trivially small diameter, then
there's a known limit to how fast the slope of the curve can change
distance curve converges to vertical on both sides of the 0 point
you could potentially cross-reference/combine distance with, or use instead, the direction of each point from the target: only at the target would the direction instantly change ~180 degrees (how well the data points capture this still depends on the distance between adjacent samples and any stiffness of the rope).
Otherwise, there's always risk the target point may weirdly be encased by two very distance points, frustrating our whole searching algorithm (that must be what they mean about some margin for error - every now and then this search would have to revert to a O(N) brute-force search because any trend analysis fails).
For a one-time search, sometimes linear traversal is the simplest, fastest solution. Maybe that's the case for this problem.
Iterate through the ordered list of points until finding the start or end, and then collect points until hitting the other endpoint.
Now, if we expected to repeat the search, we could build an index to the points.
Edit: This presumes no additional constraints beyond those mentioned by #koool. Constraining the distance between the points would allow the hill-climbing approach described in #Tony's answer.
I don't think you can solve it accurately using anything other than exhaustive search. Say for cases where the rope is folded into half and the resulting double rope forms a spiral with the two ends on the centre.
However if we assume that long portions of the rope are in straight line, then we can eliminate a lot of points based on the slope check:
if (abs(slope(x[i],y[i],x[i+1],y[i+1])
-slope(x[i+1],y[i+1],x[i+2],y[i+2]))<tolerance)
eliminate (x[i+1],y[i+1]);
This will reduce the search time significantly if large portions of the rope are in straight line. But will be linear WRT number of remaining points.
So basically, you've got a sorted list of the points that comprise the entire rope and you're given two arbitrary points from within that list, and tasked with returning the sublist that exists between those two points.
I'm going to make the assumption that the start and end points that are provided are guaranteed to coincide exactly with points within the sorted list (otherwise it introduces a host of issues, particularly if the rope may be arbitrarily thin and passes by the start/end points multiple times).
That means all you're really looking for are the indices of the two provided coordinates. Or the index of one, and the answer to "is the second coordinate to the right or to the left?".
A simple O(n) solution to that would be:
For each index in array
coord = array[index]
if (coord == point1)
startIndex = index
if (coord == point2)
endIndex = index
if (endIndex < startIndex)
swap(startIndex, endIndex)
return array.sublist(startIndex, endIndex)
Or, if you wanted to optimize for repeated queries, I'd suggest a hashing based approach where you map each cooordinate to its index in the array. Something like:
//build the map (do this once, at init)
map = {}
For each index in array
coord = array[index]
map[coord] = index
//find a sublist (do this for each set of start/end points)
startIndex = map[point1]
endIndex = map[point2]
if (endIndex < startIndex)
swap(startIndex, endIndex)
return array.sublist(startIndex, endIndex)
That's O(n) to build the map, but once it's built you can determine the sublist between any two points in O(1). Assuming an efficient hashmap, of course.
Note that if my assumption doesn't hold, then the same solutions are still usable, provided that as a first step you take the provided start and end points and locate the points in the array that best correspond to each one. As noted, unless you are given some constraints regarding the thickness of the rope then interpolating from an arbitrary coordinate to one that's actually part of the rope can only be guesswork at best.