I am having a predefined route as a set of locations with latitude and longitude. I want to create a polygon by using these co-ordinates and want to know when the user deviates from it.
Anyone have any tips or sample code to draw a virtual fence across the points A, B and C ?
I don't know if polygon is the way to do it...
I can suggest a more basic approach, where you compute the distance of point to a line segment and check for distance < fence radius
you can compute line segments of your route, in your case the segments are (A,B) (B,C)
when you got a new position and want to know if it reside within the fence, you just compute the distance of that position to each line segments
the calculation of this is explained (very clearly, with code examples) in here
the math of geo position is pretty straight forward when dealing with small areas (don't need to take the earth curvature into consideration) but even if you do, it's a small change and there a lot of code examples for that either
Related
In my application I work with OpenGL and large arrays of data.
One of the things I need to do is I receive multiple "simple" polygons that can be either convex or concave. By simply I mean geometrical definition - polygons without holes and intersecting edges.
I receive this poligons in the form of linked loop of points (vertices), where each Vi is connected to Vi-1 and Vi+1 points and nothing else. The last point is also connected to the first, giving us a loop as a result.
I will say right now that I figured out polygon triangulation, and it works like a charm (I used ear-clipping method for now).
But, I need to build LOTS of those polygons, millions of them. To minimize the load I decided to split my world into "chunks", squares like in Minecraft. I then use frustum culling and other optimizations methods to either render or discard/simplify these chunks and meshes in them.
So, what I want to do is: if the polygon I received lies in several different chunks - then I want to split it into meshes for each of those chunks. Basically, I want to create multiple polygons that are divided on chunk borders, and THEN triangulate them and create meshes for rendering.
As a result I want to have one (or several) contours that I can then triangulate.
here's a picture of my task:
I made an algorythm for splitting it myself that I thought would work, but I found that it only works if the contour in any given chunk doesn't break up, like you see in the example (in other words if there's only one figure in any given chunk).
I thought to ask here if anyone knows any good algorythms for that task? I'll probably come up with something myself, but practice shows that there's almost always a better and simpler ready-made solution out there. I'd really appreciated it if someone could give me a useful link or an article, if not with a solution itself, then something that could give ideas.
I'm not at work at the moment, because it's weekend, so I'll be trying/testing the things on Monday.
What I came up with at the moment, however, is a very simple solution.
test all points in the contour.
If point i and point i+1 don't belong to the same chunk (which I can test easily):
then find an intersection between chunk border and the line made by these two points.
add this new point to the contour between the original two points.
When every edge of the polygon was tested like that - triangulate it.
because we have points on the edges of the chunks - then during triangulation the triangles will fit exactly into chunk borders
for each triangle, decide which chunk it belongs to and generate the mesh in THAT chunk.
I won't go into details of some optimization ideas - like not needing to evaluate resulting triangles if the entire figure fits within the same chunk.
This is a stab in the dark at writing some pseudo code that may work. Feel free to implement it and select your own answer with the actual code if it works.
First, convert your vertex array to a double linked list that loops from the last element to the first element. Or it may be better to model it as an undirected graph instead, because a point may have missing neighbours.
Then apply the algorithm below for each quadrant, starting with the full polygon each time. You can cut down the size of that polygon by culling vertices that are outside of the quadrant and at least 1-neighbour away from edges that cross the cutting lines.
// We need to keep track of the points that we insert on the cutting lines
let LIX = List of X-Cut-Line Intersection Points
let LIY = List of Y-Cut-Line Intersection Points
foreach Edge AB in Poly where A is inside the quadrant, B outside
// Insert points into the polygon that intersect the X-Cut-Line
if AB Intersects X-Cut-Line
let Ix = Intersection Point
Insert Ix between AB so that A<->B becomes A<->Ix
B can be removed from the polygon now
Add Ix to LIX
// Insert points into the polygon that intersect the Y-Cut-Line
if AB.Intersects Y-Cut-Line
let Iy = Intersection Point
Insert Iy between AB so that A<->B becomes A<->Iy
B can be removed from the polygon now
Add Iy to LIY
// Then iterate pairs of points along each cutting line to join them
sort LIX by X Ascending
while (LIX.Length > 0)
let P0 = LIX[0]
let P1 = LIX[1]
Link P0 and P1
Remove P0 and P1 from LIX
sort LIY by Y Ascending
while (LIY.Length > 0)
let P0 = LIY[0]
let P1 = LIY[1]
Link P0 and P1
Remove P0 and P1 from LIY
Finally, you can look for cycles in the resulting linked list/graph to find the new polygons. Each cycle should in theory not contain points from the other cycles already detected so it is an individual polygon.
I thought that this one would be easy to find on net but seems its not.
I want to know the distance between 2 consecutive longitudes at a given latitude value. That is to measure with a rope keeping it parallel to equator. I can calculate it by simple geometry assuming earth to be a proper sphere. But will that assumption be acceptable?Please give an idea about the error margin in that assumption. Or,
Please let me know a mathematical formula or a Java/Android code to calculate it.
Thanks.
EDIT: Thanks for your responses, it seems to have erupted a mini storm . Please read my comment to David below for clarity
EDIT2: The debate is will the great circle distance (found by haversine formula) and the "rope" distance be the same? According to me it should be. As the great circle distance is the shortest distance between to 2 points, and in the case of rope distance i restrict myself to move along the same latitude from one point to another, which I think is the shortest distance. Isnt it?
EDIT3: I was wrong. After visualizing it a bit I realize that the great circle distance will not be the same as the longitudinal separation at a latitude ("rope" distance"). Both would be same only if the latitude happens to be the equator. What David has been saying. So yes no correct answers yet. For my case I would assume the earth to be a sphere, I would accept Laune's answer in some time as he/she has partially answered my question. Still would be really keen to know if there is way to get a correct calculation.Also, please go through the link given by Byzantine Failure (wats with the name??) It talks about how to create a stored procedure and and query for such problems, really helpful!! Thanks for all your responses!
Have a look at this: http://en.wikipedia.org/wiki/Geoid
For everyday purposes, you can use the spheric model. Geoid deformation starts in the higher latitudes, so unless you are into something very accurate, scientific or polar travel, you should be fine.
quite simple with android actually:
Location locationA = new Location();
locationA.setLatitude(latA);
locationA.setLongitude(lngA);
Location locationB = new Location();
locationB.setLatitude(latB);
locationB.setLongitude(lngB);
float distance = locationA.distanceTo(locationB);
The distance usually used in situation of geolocations is haversine distance. This is basically an approach of the real distance in earth's surface since it is the distance of two points lying on a sphere having the average radius of earth.
Anyway there are many implementations in Java if you search for them.
Edit:
In this case there isn't any real difference if the two points have some of their coordinates the same or not (if they have them both different).
You can check the following link for a detailed algorithm
http://www.arubin.org/files/geo_search.pdf
Although this is based on JavaScript, but there is actually a function of the API to calculate the distance between the two given lat long points: https://developers.google.com/maps/documentation/javascript/reference#spherical
I am writing a server side java application related to Geo-fencing.
I have a store with their latitude,longitude and radius
I also have Person's current position(in terms of latitude & longitude).
If he arrives within the geo fence i.e., within the store's radius i have to give an alert. I googled for the solution & there are some methods to identify person is inside the fence(circle) or outside the fence.
Calculate distance between store latitude,longitude and person's current latitude & longitude and if Distance < radius then person is inside the fence else outside the fence.
Using Polygon Geofencing
Can anyone suggest me which method is best from the above.
Thanks in advance
It depends on your needs. If you want to know whether a Person is inside 1km radius of store, then you need a circle search. Here, location of the store is the pivot. You might change the radius based on your need.
Polygon search is used when you need to search people in a particular area regardless of how much distance it is away from anywhere. People in Paris, New York or Istanbul area, not people inside 1km radius of a store.
In your case, where only radius (i.e. distance to the shop) is needed, I would definitely choose the radius search (your first proposition).
The Polygon Geofencing, I think, is using the Ray-Casting Algrithm which iterates over each segment of the polygon. This will take more time and could lead to some approximation in the case of a circle (depending on how the algorithm is applied).
I would have thought that the best method to use here would be a radius distance calculation, presuming you need to know the distance 'as the crow flies' so to speak. So geographical distance rather than travelling distance. This will be the most performant and simplest to implement. Examples available here and here.
If the latter is the case (which I hope for your sake it isn't), then I would imagine you would need to use polygon geofencing or perhaps Google's distance Matrix API.
Thanks for all your answers. In my project i have integrated both methods(Polygon & Distance). If a user enters into the polygon he ll get a notification and same like radius. I have stored the polygon co-ordinates and radius into my database.
I have a csv file with a bunch of lat long coordinates. I also have a csv file with a bunch of positions that a particular person will be standing at. For each of the points in the second file, I need to figure out whether they are near (under 1 mile) any of the points in the first file. I have about 500 points in each of the files.
I'm trying to solve this in Java, and I thought I would use something along the lines of read the first file in and putting it in some sort of structure that is easily searchable, this way I do not need to keep doing IO operations. I'm unclear as to what type of data structure I should hold the points in so that I can easily search for ones that are within a radius of a given point. Could someone point me in the right direction? Is there any way that I can organize this so that I don't need to make n^2 comparisons?
Sounds like you want to store your points in a k-d tree based on latitude and longitude.
If we know that we want all points within some set distance D of some point (lat, lon), it's simple to calculate the difference in latitude d_lat corresponding to D units of distance due north/south, and the difference in longitude d_lon corresponding to D units of distance due east/west at whichever of latitudes lat-d_lat or lat+d_lat is closest to a pole. Using this we perform an orthogonal range search in the tree for all points with latitude between lat-d_lat and lat+d_lat and longitude between lon-d_lon and lon+d_lon. We then need to calculate the distance for each of these, and reject ones over D away from (lat, lon) - but we won't need to do as many calculations as without the tree (we should only end up rejecting roughly 1-pi/4 = 21.5% of points that get to this stage).
Of course you'll need to account for edge cases, if they're relevant to you:
If you're within d_lon of 180 degrees longitude, you'll need to do two different searches in the tree (either side of 180 degrees).
If (lat, lon) is within d_lat latitude of a pole, just look for everything north/south of whichever of lat-d_lat or lat+d_lat is farthest from the pole.
Here's what I'd do.
Sort all the points in both files in order of latitude. Then iterate through both lists at the same time, so that for each point in file 1, you get a list of points in file 2 whose latitude circle is within one mile of the point from file 1. You can probably use the subList method of List somewhere along the way here.
Still within the context of the point from file 1, filter out the points from that sublist whose longitude differs from point 1 by more than one mile. You'll then have pairs of points that are both within a mile's longitude and within a mile's latitude of each other.
For each such pair, do the exact calculation to see if they really are within a mile "real distance" of each other.
The easiest way is to define a coarse grid and bucketize your points from the first list into the grid cells. You need to compute a cell "id" for each point and put in into a hash table based on that id.
Once you have that, you can easily lookup nearby points for a given lat/long by finding the right cell and enumerating its content (and the content of the neighboring cells).
The trick is to convert a lat/long into a cell id. One way is to round up the lat/long. So, for example, convert (47.43402067, -121.89068567) pair into a "47_-121" string. This can be too rough because one degree is approximately 70 mile at equator. You can tighten it up by rounding to a certain decimal point:
e.g. "47.43_-122.89".
Note that cells width is going to narrow down as you going further north or south. For example at 60 degrees North the cell is going to be two times more narrow than at equator (it will only cover 35 miles).
You can also use existing geospatial indexes from libraries like JTS Topology Suite which allow much more flexibility.
I am doing a mashup using Google Maps under Grails where users can create geofences by selecting a point on the map and a radius. This get stored on my database and the application receives constantly a set of coordinates from a GPS device.
I would like to compare the received coordinates with the area stored in the circles. If the point is inside (or outside) the circle the program will fire an action. However, I would like to know how I can find out if the coordinates are located inside/outside the circle. There is a Javascript library which allows doing this but I need to do this on the server.
Is there a Java (or even Groovy) library for this?
How would you implement it?
if distance from point to center of circle is <= radius of circle then it is inside the circle.
if the area is made of more than one circle than compare to all the circles... it won't take that long.
java.awt.geom.Point2D.Double is perfect for this.
Well, if it doesn't need to be "perfect", you don't need to worry about plotting circles or anything like that. You can just take the two locations (the location you want to test, and the center of the circle) and use Pythagorus to find the distance. If that distance is less than the radius of the circle, it's inside.
There is a caveat to take into consideration, however: the reason this wouldn't be perfect is that that for your points, you're probably going to get a latitude and longitude...and the Earth is a sphere. So near the poles of the Earth this will kind of fall apart. But it may well be good enough for what you're doing.
Sadly, most of the responses here won't work for you conveniently, because GPS coordinates are in units of degrees. You will need something to convert from two points in Degrees of latitude and longitude to a great circle distance, which simple Pythagorean theorem falls short of.
If you're using Google maps API, you can probably do everything you need using GLatLng. As other posters have noted, You can determine the distance between two points is less than the radius of the specified circle. Specifically GLatLng.distance(other:GLatLng) returns the meters distance between too GPS locations.
To actually display the circles requires a bit more finesse. You will need to create a GPolygon to draw the circumference of the circle. You can find a number of free JavaScript functions that can do this for you.
Victor and Beska have the correct answer. That is, if the distance between the point and the center is less than the radius, then it's in the circle.
For the great circle distance between two points, you can use GeoTools' GeodeticCalculator. In particular you set the point and radius using setStartingGeographicPoint and setDestinationGeographicPoint followed by calling getOrthodromicDistance which will return the distance.
You want to find the vector that is the distance between the selected coordinate and the center of the circle, then compute the square distance between the selected coordinate and the center of the circle by squaring the components of the vector and adding them together; if that scalar (the squared distance) is less than the square of the radius, the point is within the circle.
This method avoids having to take a square root, and is just as accurate as normal distance comparison.
One possibility is to calculate the distance from the centerpoint and compare it to the radius.
Depending on you application you may be have to take into account that the world is a sphere and not 2Dimensional. To calcualte a distance on earth you can use this formula.
Since you are using Google Maps and for geographical distances spherical geometry holds rather than euclidean geometry. However if it is relativley smaller distance like a parking lot etc. then you can use euclidean distance formula (http://en.wikipedia.org/wiki/Distance) to find out whether the point is inside or outside the circle.
I presume you know the coordinates of the circle's center C(xc, yc) and its radius, R. Then for a given point P(x1, y1) find the euclidean distance, D as
square-root((x1-xc)^2 + (y1-yc)^2)). If D > R, the point lies outside the circle. If D < R, the point lies inside the circle. If D = R, the point lies on the circumference of the circle.
In case you are doing your measurements over larger distances then you should rather look for Geodesics (please check this http://en.wikipedia.org/wiki/Great-circle_distance).
I hope it helps.
cheers