How do I find the region a point lies within - jsl

Below I have an image representation of a map with different regions labeled on it.
My problem is that I need to find out what region a randomly generated point on the map will be in.
I know the x_min, y_min, x_max, y_max of all the different regions meaning I have the coordinates for all the vertices of each rectangular region. I also know the coordinate of the point.
What you can do, and what I have done, is just go through a big condition statement checking through one by one if the x & y coordinate of the point is between the x_min and x_max and y_min and y_max of every region. However, I feel like there has to be a more scalable, generalizable, and efficient way to do this. I however cannot find a way to do so, at least not something that isn't in a library for a different programming language. I thought of maybe doing something where I split the map in half, find out which half the point lies in, count up all the regions in that half, check if there is one region left and if not, split the map in half again and go through the process again. I just don't have a good idea of how that can be implemented and whether that is feasible or better that the current method I have.

Related

GPS coordinations for each kilometer

I'll find a route between two places, for example using google maps. I'd like to divide the route to kilometers (two following places will be at a distance of 1 km), and get GPS coordinations of these places. This is because then I'll be able to get exacly the coordinations of, for example, 5th kilometer on the route. Could you please advice me how to achieve it?
This is extremely nontrivial. Is say your best bet is to find an algorithm to load the bearing between two points, then one to load a coordinate given a start point, distance, and bearing. This could give you it, but only if the data contained only straight lines. Since I assume the Google Maps API only gives you the turns the user has to make, this approach will be inaccurate when there are bends in roads. You'd need GIS data for roads and what will undoubtedly turn into a complicated algorithm to find something like this. It's definitely doable, but that's l how I'd start. Look into the Census TIGER road data, it should help.
Unless, of course, I'm wrong and the API does actually give enough points to cleanly map it, in which case those functions should be easy to find and implement.
This will only work if you have the polyline as a sequence of lat/lon (or other) coordinates, wherever you get that from.
Then you start at the beginning an iterate through the lines (point[i], point[i+1]).
THis distance you calculate with standard API.
while itersting you sum up the distance.
Once you exceed the 1000m, you know that the splitting point (the 1000m marker) is at line segment [i,i+1].
To calculate the exact position where on the line that is, you take the total summed meters from previous segment, and the value of this segment and do a linear interpolation.
The working code is a bit complexer: there can be multiple markes within one segement.
But first find out where you get the polyline from, whitou that it will not work.

How to find the Shortest Path between all the nodes in a graph without having a pre-defined start or end points?

What I want to get is: the path which connect all the points in my graph, but without having to tell the algorithm where to start and where to finish.
It need to use the driving direction in google-maps api but without setting a start or end point.
It is not the TSP problem because I don't have a "start city" and I don't have to get back to the "start city" neither.
As expressed in this question: Find the shortest path in a graph which visits certain nodes,
I could just use permutation because I have a few nodes, but the problem is that I need to analyze several groups of this few nodes So I would like the function to be the less time consuming posible.
NOTE: Im not looking for a Minimum Spaning Tree as this one neither: https://math.stackexchange.com/questions/130863/connecting-all-points-on-a-plane-with-shortest-path-possible
I want a path which tell me you will save gas if you go first here, then overthere, then overthere, and finally there.
Question: is there any library which can help me with that? Or is it a know problem that has already an exact answer? How could I solve it?
It sounds like you want an all pairs shortest path algorithm. This is the class of shortest path algorithms that attempt to compute the shortest path (or the length of the shortest path) between every pair of vertices in the graph.
These is a well-known problem, and solutions exist. Here's some reading material that describes other possible algorithms. There might be implementations of Johnson's algorithm for your chosen language and development environment.
Keep in mind, this is an expensive problem, computationally speaking.
If I understand you correctly, you want 1 route to visit all the nodes, without a predefined start/end and you want that to be minimal. A possible solution could be to modify your graph a bit to allow a travelling salesman algorithm to get a complete tour.
You start with your graph and add 1 extra node E. You connect that node to all other nodes in your graph and set the cost of all those edges to a very high constant M. You then unleash a travelling salesman algorithm on that graph which will give you a path P starting at E, passing all nodes and returning to E. If you remove the 2 edges in P that connected E to the rest of your path you will have what you were looking for.
A quick intuitive proof that it is indeed what you were looking for: Suppose it's not the cheapest way to connect all nodes. Let's call the supposedly better path Q. Q and P both connect all nodes in your original graph. The end points of Q would be A and B. Both of these would be connected to node E with an edge of cost M. If you would add those 2 edges to Q, you would get a better TSP solution than P, which is not possible as P was the best.
As you are using google map, your particular instance of TSP might satisfy the Triangle inequality.
Are you really speaking of distances or travel time ?
In the case of distances:
try Googling: "triangle traveling salesman problem"
IMPORTANT: The result is a very good approximation of the best result with guaranteed uper bound, not always the best.
One way to go would be using (self-organized) kohonen networks.
Assume you have n cities on a map (works the same in any dimension).
Take a chain of n connected "neurons" and place it randomly on the map.
Then you do several iterations, one iteration contains:
choose any city. (e.g. go through them in a ordered fashion)
determine the "closest" neuron, call it x. (e.g. euclidian distance)
Move this x closer to the city (e.g. take the direction vector from the neuron to the city and multiply it with a learning rate 0
Move neighbors of this neuron also towards this city (but less than in 3., dependend of distance from the neighbors to the "current closest" neuron x)
One can choose various functions in step 2, 3 and 4.
Notice also that this might not give the globally shortest path since it depends on where the start chain is located and different other things. For this on may consider doing several runs with different starting conditions or (depending of the problem) one can help a bit with pre-knowlege.
I hope this helps to complete this question for further readers...

Mysql Distance from test point to a polygon

I have stored some map zones to a table using Geometry type field.
So the inserts are like this:
INSERT INTO zones (zoneName, coords) VALUES ('name',
PolygonFromText('POLYGON((
41.11396418691335 1.2562662363052368,
41.11370552595821 1.2560248374938965,
41.11851079510035 1.2459397315979004,
41.11880984984478 1.2461864948272705,
41.11396418691335 1.2562662363052368))'));
Then I have the user position, and I need to know if he is inside some zone. This works well with this:
SELECT id
FROM zones
WHERE MBRContains(coords,GeomFromText('POINT(41.117783 1.260590)'))
But sometimes, user position is not perfect, so I think its better to know wich zone is closest to user position.
That is the part that I don't have any idea about... I found some queries to get distance between two points, but not a point and polygons.
The MBR series of functions (like MBRContains) are unsuitable for what you're trying to do; they only test bounding rectangle inclusion.
You may wish to jump forward to MySQL 5.6.1, and use the ST_ functions, like ST_Contains. These functions actually test the geometry.
The problem you're working on can be defined as an uncertainty in the position of your POINT when you go to compare it to your collection of boundary POLYGON items.
Try this: create a POLYGON from your point that is a square with the size of your uncertainty. You can think of this square as a "fuzzy" point. (You could also use an octagon or another closer approximation of a circle in place of a rectangle, but your querying speed will slow.)
Then use ST_Within to see if you have a unique polygon that entirely contains your fuzzy point. If you get just one polygon, you're done.
If you get multiple polygons that entirely contain your fuzzy point, that means some of your boundary polygons overlap other ones. You need to figure out what this means in your problem space. If your data is intended to be properly structured cartographic boundary data, it means you have a data mistake. (NOTE: This is not unheard of :-)
If you get no polygons that entirely contain your fuzzy point, then your fuzzy point may or may not overlap the boundary of at least one polygon. Use ST_Overlaps to find those polygons.
If you get just one, you're done -- your fuzzy point is near the boundary of just one polygon.
If you get none, you're done -- your fuzzy point is away from the boundaries of all your polygons.
If you get more than one hit, you have an ambiguity -- your fuzzy point is near the boundary of more than one polygon.
This is the hard case to sort out. You could reduce the size of the fuzzy point and try again. This MIGHT yield just one polygon result. But, you could deceive yourself into thinking that your points are more accurate than they are by doing this.
MySQL doesn't have the geometric operator Area(Intersection(Polygon, FuzzyPoint)). If it did you could choose the polygon with the biggest area of intersection with your fuzzy point, and that would be a good disambiguator. But it would still be as inaccurate as the position of your point.
Maybe your application should handle the category of result "too near the boundary of A, B, and C to be sure."

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.

How to implement dead reckoning when turning is involved?

"Dead reckoning is the process of estimating one's current position based upon a previously determined position and advancing that position based upon known or estimated speeds over elapsed time, and course." (Wikipedia)
I'm currently implementing a simple server that makes use of dead reckoning optimization, which minimizes the updates required by making logical assumptions on both the clients and the server.
The objects controlled by users can be said to be turning, or not turning. This presents an issue with dead reckoning (the way I see it.)
For example, say you have point A in time defined by [position, velocity, turning: left/right/no]. Now you want point B after t amount of time. When not turning, the new position is easy to extrapolate. The resulting direction is also easy to extrapolate. But what about when these two factors are combined? The direction of the velocity will be changing along a curve as the object is turning over t amount of time.
Should I perhaps go with another solution (such as making the client send an update for every new direction rather than just telling the server "I'm turning left now")?
This is in a 2D space, by the way, for the sake of simplicity.
For simplicity let's say that your vehicles have a turning radius r that's independant of speed. So to compute the new position given the initial coords and the time:
compute the distance (that's velocity * time)
compute how much you turned (that's distance / (2*pi*r))
add that arc to the original position.
The last steps needs elaboration.
Given the angle a computed in step 2, if you started at (0,0) with a due north heading (i.e. pi/2 radians) and are turning left then your new positions is: (rcos(a)-1, rsin(a)).
If your original heading was different, say it was "b", then simply rotate the new position accordingly, i.e. multiply by this rotation matrix:
[ cos b , -sin b ]
[ sin(b), cos(b) ]
Finally, add the initial position and you're done. Now you only need to send an update if you change the velocity or turning direction.
Well, I think "turning: left/right/no" is insufficient to determine position B - you also need to know the arc at which the turn is being made. If you are turning left along a circular path of radius 1, you will end up at a different place than if you are turning along a circular path of radius 10, even though your initial position, velocity, and direction of turn will all be the same.
If making the client send an update for every new direction and treating them as linear segments is an option, that is going to be a much easier calculation to make. You can simply treat each new report from the client as a vector, and sum them. Calculating a bunch of curves is going to be more complex.