Working on the Pacific Ocean, i am dealing with huge polygons covering the whole area. Some of them are quite simple and are defined by 4 points in my shapefile.
However, when i import them into SQL server 2008 r2 as new geographies, due to the shape of the earth, i end up with curved lines while I would like the North and South boundaries to stick to some specific latitudes: for example, the north boundaries should follow the 30N latitude from 120E to 120W.
How can i force my polygons to follow the latitudes? Converting them as geometry could have been an option but since i will need to do some length and area calculations, i need to keep them as geography.
Do i need to add additional vertices along my boundaries to force the polygon to stay on a specific latitude? What should be the interval between each vertex?
Thanks for your help
Sylvain
You have already answered this yourself. Long distances between latitude coordinates will create curved lines to match the Earth's curvature. Therefore if you need to "anchor" them along a specific latitude you will need to manually insert points. As for the interval, there's no right or wrong, a little experimentation here (and considering how "anal" you want to be about it hugging the line) will give you the result you desire. 1 coordinate per degree should do it, might even be a little overkill.
That said, I do question why you would want to anchor them to create a projected "straight" line as this will skew the results of length and area calculations, the bigger the polygon, the bigger the skew.
Related
I am reviewing some MATLAB code that is publicly available at the following location:
https://github.com/mattools/matGeom/blob/master/matGeom/geom2d/orientedBox.m
This is an implementation of the rotating calipers algorithm on the convex hull of a set of points in order to compute an oriented bounding box. My review was to understand intuitively how the algorithm works however I seek clarification on certain lines within the file which I am confused on.
On line 44: hull = bsxfun(#minus, hull, center);. This appears to translate all the points within the convex hull set so the calculated centroid is at (0,0). Is there any particular reason why this is performed? My only guess would be that it allows straightforward rotational transforms later on in the code, as rotating about the real origin would cause significant problems.
On line 71 and 74: indA2 = mod(indA, nV) + 1; , indB2 = mod(indB, nV) + 1;. Is this a trick in order to prevent the access index going out of bounds? My guess is to prevent out of bounds access, it will roll the index over upon reaching the end.
On line 125: y2 = - x * sit + y * cot;. This is the correct transformation as the code behaves properly, but I am not sure why this is actually used and different from the other rotational transforms done later and also prior (with the calls to rotateVector). My best guess is that I am simply not visualizing what rotation needs to be done in my head correctly.
Side note: The external function calls vectorAngle, rotateVector, createLine, and distancePointLine can all be found under the same repository, in files named after the function name (as per MATLAB standard). They are relatively uninteresting and do what you would expect aside from the fact that there is normalization of vector angles going on.
I'm the author of the above piece of code, so I can give some explanations about it:
First of all, the algorithm is indeed a rotating caliper algorithm. In the current implementation, only the width of the algorithm is tested (I did not check the west and est vertice). Actually, it seems the two results correspond most of the time.
Line 44 -> the goal of translating to origin was to improve numerical accuracy. When a polygon is located far away from the origin, coordinates may be large, and close together. Many computation involve products of coordinates. By translating the polygon around the origin, the coordinates are smaller, and the precision of the resulting products are expected to be improved. Well, to be honest, I did not evidenced this effect directly, this is more a careful way of coding than a fix…
Line 71-74! Yes. The idea is to find the index of the next vertex along the polygon. If the current vertex is the last vertex of the polygon, then the next vertex index should be 1. The use of modulo rescale between 0 and N-1. The two lines ensure correct iteration.
Line 125: There are several transformations involved. Using the rotateVector() function, one simply computes the minimal with for a given edge. On line 125, one rotate the points (of the convex hull) to align with the “best” direction (the one that minimizes the width). The last change of coordinates (lines 132->140) is due to the fact that the center of the oriented box is different from the centroid of the polygon. Then we add a shift, which is corrected by the rotation.
I did not really look at the code, this is an explanation of how the rotating calipers work.
A fundamental property is that the tightest bounding box is such that one of its sides overlaps an edge of the hull. So what you do is essentially
try every edge in turn;
for a given edge, seen as being horizontal, south, find the farthest vertices north, west and east;
evaluate the area or the perimeter of the rectangle that they define;
remember the best area.
It is important to note that when you switch from an edge to the next, the N/W/E vertices can only move forward, and are readily found by finding the next decrease of the relevant coordinate. This is how the total processing time is linear in the number of edges (the search for the initial N/E/W vertices takes 3(N-3) comparisons, then the updates take 3(N-1)+Nn+Nw+Ne comparisons, where Nn, Nw, Ne are the number of moves from a vertex to the next; obviously Nn+Nw+Ne = 3N in total).
The modulos are there to implement the cyclic indexing of the edges and vertices.
I have a question about if something is possible using Tableau.
I already have a coastline plotted on one map using custom LatLon coordinates and I would like to take a user inputted Lat and Lon and plot a circle around it with let's say radius 10 and display it on the same map.
I was using this tutorial before to plot a circle:
https://www.crowdanalytix.com/communityBlog/customers-within-n-miles-radius-analysis-using-tableau
But I don't think the same approach can work with user-inputted fields because then it would require restructuring the data..
Okay, a (much smarter LOL) coworker helped me figure this out....
So my goal was to graph distance band (like a distance of 5 miles around a coast) . In order to do this we can use the distance between two coastline points since they are connected by a line, not a curve...From there we can find the perpendicular point a certain distance away and connect those points. Much easier than my circle idea...
I am making a game which spawns scattered x number of points. All Points have a constant radius of w
The points must follow these rules:
Points may not overlap other points
Points must be spread apart so that each point is at least DISTANCE away from any other points.
Can you please list an efficient algorithm to execute this?
I am also making this game in Swift Sprite-Kit. So if you know some Sprite-Kit, you can implement it in your answer, otherwise if you do not know Swift or Sprite-Kit you can explain in words.
Your two constraints are equivalent. It means the distance between any two points must be at least max(w, DISTANCE).
The easiest way is to generate random points and check the minimum distance to previous points. If the constraint is not fulfilled, just generate a new point. You can speed up the distance checking with a simple grid (put points in the grid cells and then just check the cells that may contain overlapping points).
There are a lot of similar questions but I can't get a clear answer out of them. So, I want to represent latitude and longitude in a 2D space such that I can calculate the distances if necessary.
There is the equirectangular approach which can calculate the distances but this is not exactly what I want.
There is the UTM but it seems there are many zones and letters. So the distance should take into consideration the changing of zone which is not trivial.
I want to have a representation such that i can deal with x,y as numbers in Euclidean space and perform the standard distance formula on them without multiplying with the diameter of Earth every time I need to calculate the distance between two points.
Is there anything in Matlab that can change lat/long to x,y in Euclidean space?
I am not a matlab speciallist but the answer is not limited to matlab. Generally in GIS when you want to perform calculations in Euclidean space you have to apply 'projection' to the data. There are various types of projections, one of the most popular being Transverse Mercator
The common feature of such projections is the fact you can't precisely represent whole world with it. I mean the projection is based on chosen meridian and is precise enough up to some distance from it (e.g. Gauss Krueger projection is quite accurate around +-500km from the meridian.
You will always have to choose some kind of 'zone' or 'meridian', regardless of what projection you choose, because it is impossible to transform a sphere into plane without any deformations (be it distance, angle or area).
So if you are working on a set of data located around some geographical area you can simply transform (project) the data and treat it as normal Enclidean 2d space.
But if you think of processing data located around the whole world you will have to properly cluster and project it using proper zone.
I have data describing a rotated ellipse (the center of the ellipse in latitude longitude coordinates, the lengths of the major and minor axes in kilometers, and the angle that the ellipse is oriented). I do not know the location of the foci, but assume there is a way to figure them out somehow. I would like to determine if a specific latitude longitude point is within this ellipse. I have found a good way to determine if a point is within an ellipse on a Cartesian grid, but don't know how to deal with latitude longitude points.
Any help would be appreciated.
-Cody O.
The standard way of doing this on a Cartesian plane would be with a ray-casting algorithm. Since you're on a sphere, you will need to use great circle distances to accurately represent the ellipse.
EDIT: The standard ray-casting algorithm will work on your ellipse, but its accuracy depends on a) how small your ellipse is, and b) how close to the equator it is. Keep in mind, you'd have to be aware of special cases like the date line, where it goes from 179 -> 180/-180 -> -179.
Since you already have a way to solve the problem on a cartesian grid, I would just convert your points to UTM coordinates. The points and lengths will all be in meters then and the check should be easy. Lots of matlab code is available to do this conversion from LL to UTM. Like this.
You don't mention how long the axes of the ellipse are in the description. If they are very long (say hundreds of km), this approach may not work for you and you will have to resort to thinking about great circles and so on. You will have to make sure to specify the UTM zone to which you are converting. You want all your points to end up in the same UTM zone or you won't be able to relate the points.
After some more research into my problem and posting in another forum I was able to figure out a solution. My ellipse is relatively small so I assumed it was a true (flat) ellipse. I was able to locate the lat lon of the foci of the ellipse then if the sum of the distances from the point of interest to each focus is less than 2a (the major axis radius), then it is within the ellipse. Thanks for the suggestions though.
-Cody