I'd like to calculate the topological distance instead of Euclidean distance between two polygons. The distance between two neighboring polygons is 1, between two polygons connecting through a common neighbor is 2 and so on.
Is there any easy method to calculate the topological distance? I searched this question but found no solution.
Thank you.
Basically you want to search the distance between Polygon A & B
Here are the steps that I will took:
Distance = 1;
Check whether Polygon B is the neighbor of Polygon A, If it is=Finish, If not go to point 2.
Calculate the coordinate centroid (the middle point) of all neighbouring Polygons, and Polygon B
Count the distance between the neighbouring centroid to Polygon B centroid, select the polygon with the closest distance (Polygon C)
Distance = Distance + 1, Check whether Polygon B is the neighbor of Polygon C, If it is=Finish, If not, Polygon A = Polygon C, go to Point 2
At the end you'll get the distance.
I find a way to implement this calculation using existing software.
First, import the shp file to PostgreSQL using the PostGIS plugin.
Second, use the ST_Touches function to calculate each polygon's neighboring polygons.
Third, take each polygon as a point, and construct a new network.
Finally, calculate the shortest path between each two points using the Dijkstra algorithm.
Related
I have a set of N deformed circles made of lines. Each circle can have difrent amount of lines defining it. They are deformed in difrent manner but one could see the similarities between them. How to generate a new similar circle having desired lines count K - which ML algorithms it is better to look into?
A circle that pass near of given vertices (in general case, it isn't possible to pass through all vertices) can be estimated with some maths. For example see here
An aproximation can be achieved by:
Get the coordinates of the centroid,
two simple (x,y) average.
The radius can be estimated by the average of the distances from vertices to the centroid.
i am measuring distance between two objects in a image using opencv c++.
i have detected two balls with hough transform circle and want to measure distance between them.
so far, used Pythagoras theorem to find distance between two coordinates but not getting close.
d= sq rt( (x2-x1)^2 + (y2-y1)^2 )
for eg: if distance between two balls is 13 cm then result is 5.6 cm
thanks in advance
To measure the distance between objects in an image you will have to look into camera calibration concept.
And as said by Mark Setchell the distance will be in pixels if you do not do the calibration and 2D point to 3D point transformation.
What method would you use to compute a distance that represents the number of "jumps" one has to do to go from one area to another area in a given 2D map?
Let's take the following map for instance:
(source: free.fr)
The end result of the computation would be a triangle like this:
A B C D E F
A
B 1
C 2 1
D 2 1 1
E . . . .
F 3 2 2 1 .
Which means that going from A to D, it takes 2 jumps.
However, to go from anywhere to E, it's impossible because the "gap" is too big, and so the value is "infinite", represented here as a dot for simplification.
As you can see on the example, the polygons may share points, but most often they are simply close together and so a maximum gap should be allowed to consider two polygons to be adjacent.
This, obviously, is a simplified example, but in the real case I'm faced with about 60000 polygons and am only interested by jump values up to 4.
As input data, I have the polygon vertices as an array of coordinates, from which I already know how to calculate the centroid.
My initial approach would be to "paint" the polygons on a white background canvas, each with their own color and then walk the line between two candidate polygons centroid. Counting the colors I encounter could give me the number of jumps.
However, this is not really reliable as it does not take into account concave arrangements where one has to walk around the "notch" to go from one polygon to the other as can be seen when going from A to F.
I have tried looking for reference material on this subject but could not find any because I have a hard time figuring what the proper terms are for describing this kind of problem.
My target language is Delphi XE2, but any example would be most welcome.
You can create inflated polygon with small offset for every initial polygon, then check for intersection with neighbouring (inflated) polygons. Offseting is useful to compensate small gaps between polygons.
Both inflating and intersection problems might be solved with Clipper library.
Solution of the potential neighbours problem depends on real conditions - for example, simple method - divide plane to square cells, and check for neighbours that have vertices in the same cell and in the nearest cells.
Every pair of intersecting polygons gives an edge in (unweighted, undirected) graph. You want to find all the path with length <=4 - just execute depth-limited BFS from every vertice (polygon) - assuming that graph is sparse
You can try a single link clustering or some voronoi diagrams. You can also brute-force or try Density-based spatial clustering of applications with noise (DBSCAN) or K-means clustering.
I would try that:
1) Do a Delaunay triangulation of all the points of all polygons
2) Remove from Delaunay graph all triangles that have their 3 points in the same polygon
Two polygons are neightbor by point if at least one triangle have at least one points in both polygons (or obviously if polygons have a common point)
Two polygons are neightbor by side if each polygon have at least two adjacents points in the same quad = two adjacent triangles (or obviously two common and adjacent points)
Once the gaps are filled with new polygons (triangles eventually combined) use Djikistra Algorithm ponderated with distance from nearest points (or polygons centroid) to compute the pathes.
Now I have a set of contour points. I have ray L which starts at Pn and has an angle of ALPHA clockwise to the horizontal axis. I want to calculate the length of line which starts at Pn and ends at the point that ray L intersects with the contour, in this case is one point between Pn-2 and Pn-3. So how can I efficently and fast calculate this length?
No algorithm can solve this in faster than linear time, since the number of intersections may be linear, and so is the size of the output. I can suggest the following algorithm, which is quite convenient and efficient to implement:
transfer the points to a coordinate system x',y' whose center is Pn and x' is parallel to L. (In practice only the y' coordinate needs to be calculated. This requires 2 multiplication and 2 additions per point).
now find all the intersecting segments by searching for adjacent indices where the y' coordinates changes signs.
Calculate the intersection & length only for these segments
You could just compute the intersection of ray L with all line segments consisting of any pair of neighbouring contour points.
Of course you might want to optimize this process by sorting by distance to Pn or whatever. Depending on the countour (concave shape?) there could be multiple intersections, so you have to choose the right one (inner, outer, ...).
Instea of computing the intersection you also could draw the contour and the ray (e.g. using openCV) and find the point of intersection by using logical and.
In my project my users can choose to be put in a random position inside a given, circular area.
I have the latitude and longitude of the center and the radius: how can I calculate the latitude and longitude of a random point inside the given area?
(I use PHP but examples in any language will fit anyway)
You need two randomly generated numbers.
Thinking about this using rectangular (Cartesian) (x,y) coordinates is somewhat unnatural for the problem space. Given a radius, it's somewhat difficult to think about how to directly compute an (Δx,Δy) delta that falls within the circle defined by the center and radius.
Better to use polar coordinates to analyze the problem - in which the dimensions are (r1, Θ). Compute one random distance, bounded by the radius. Compute a random angle, from 0 to 360 degrees. Then convert the (r,Θ) to Cartesian (Δx,Δy), where the Cartesian quantities are simply offsets from your circle center, using the simple trigonometry relations.
Δx = r * cos(Θ)
Δy = r * sin(Θ)
Then your new point is simply
xnew = x + Δx
ynew = y + Δy
This works for small r, in which case the geometry of the earth can be approximated by Euclidean (flat plane) geometry.
As r becomes larger, the curvature of the earth means that the Euclidean approximation does not match the reality of the situation. In that case you will need to use the formulas for geodesic distance, which take into account the 3d curvature of the earth. This begins to make sense, let's say, above distances of 100 km. Of course it depends on the degree of accuracy you need, but I'm assuming you have quite a bit of wiggle room.
In 3d-geometry, you once again need to compute 2 quantities - the angle and the distance. The distance is again bound by your r radius, except in this case the distance is measured on the surface of the earth, and is known as a "great circle distance". Randomly generate a number less than or equal to your r, for the first quantity.
The great-circle geometry relation
d = R Δσ
...states that d, a great-circle distance, is proportional to the radius of the sphere and the central angle subtended by two points on the surface of the sphere. "central angle" refers to an angle described by three points, with the center of the sphere at the vertex, and the other two points on the surface of the sphere.
In your problem, this d must be a random quantity bound by your original 'r'. Calculating a d then gives you the central angle, in other words Δσ , since the R for the earth is known (about 6371.01 km).
That gives you the absolute (random) distance along the great circle, away from your original lat/long. Now you need the direction, quantified by an angle, describing the N/S/E/W direction of travel from your original point. Again, use a 0-360 degree random number, where zero represents due east, if you like.
The change in latitude can be calculated by d sin(Θ) , the change in longitude by d cos(Θ). That gives the great-circle distance in the same dimensions as r (presumably km), but you want lat/long degrees, so you'll need to convert. To get from latitudinal distance to degrees is easy: it's about 111.32 km per degree regardless of latitude. The conversion from longitudinal distance to longitudinal degrees is more complicated, because the longitudinal lines are closer to each other nearer the poles. So you need to use some more complex formulae to compute the change in longitude corresponding to the selected d (great distance) and angle. Remember you may need to hop over the +/- 180° barrier. (The designers of the F22 Raptor warplane forgot this, and their airplanes nearly crashed when attempting to cross the 180th meridian.)
Because of the error that may accumulate in successive approximations, you will want to check that the new point fits your constraints. Use the formula
Δσ = arccos( cos(Δlat) - cos(lat1)*cos(lat2)*(1 - cos(Δlong) ) .
where Δlat is the change in latitude, etc.
This gives you Δσ , the central angle between the new and old lat/long points. Verify that the central angle you've calcuated here is the same as the central angle you randomly selected previously. In other words verify that the computed d (great-circle-distance) between the calculated points is the same as the great circle distance you randomly selected. If the computed d varies from your selected d, you can use numerical approximation to improve the accuracy, altering the latitude or longitude slightly until it meets your criterion.
This can simply be done by calculating a random bearing (between 0 and 2*pi) and a random distance between 0 and your desired maximum radius. Then compute the new (random) lat/lon using the random bearing/range from your given lat/lon center point. See the section 'Destination point given distance and bearing from start point' at this web site: http://www.movable-type.co.uk/scripts/latlong.html
Note: the formula given expects all angles as radians (including lat/lon). The resulting lat/lon with be in radians also so you will need to convert to degrees.