Mariadb: geography - geospatial

I need to check if the distance between two geographic point is less then N km. I'm trying to execute this query:
select st_distance(
ST_GeomFromText('point(45.764043 4.835658999999964)', 4326),
ST_GeomFromText('point(45.750371 5.053963)', 4326)
) < :n
But it doesn't work because:
So far the SRID property is just a dummy in MySQL, it is stored as part of a geometries meta data but all actual calculations ignore it and calculations are done assuming Euclidean (planar) geometry.
(https://mariadb.com/kb/en/mariadb/st_transform-missing/)
My goal is to convert this distance to the metric distance or to convert the N to the degrees.
How I can do it?
Maybe, you know a better solution?
P.S. I need a solution based on the spatial methods (or more better for the performance).

I don't think the "distance" function is available (yet) in SPATIAL. There is a regular FUNCTION in https://mariadb.com/kb/en/latitudelongitude-indexing/ that does the work. However, the args and output are scaled lat/lng (10000*degrees). The code could be altered to avoid the scaling, but it is needed in the context of that blog page.

Related

Most efficient and effective way to create a surface from 3d points

Say I had a point cloud with n number of points in 3d space(relatively densely packed together). What is the most efficient way to create a surface that goes contains every single point in it and lets me calculate values such as the normal and curvature at some point on the surface that was created? I also need to be able to create this surface as fast as possible(a few milliseconds hopefully working with python) and it can be assumed that n < 1000.
There is no "most efficient and effective" way (this is true of any problem in any domain).
In the first place, the surface you have in mind is not mathematically defined uniquely.
A possible approach is by means of the so-called Alpha-shapes, implemented either from a Delaunay tetrahedrization, or by the ball-pivoting method. For other methods, lookup "mesh reconstruction" or "surface reconstruction".
On another hand, normals and curvature can be computed locally, from neighbors configurations, without reconstructing a surface (though there is an ambiguity on the orientation of the normals).
I could suggest Nina Amenta's Power Crust algorithm (link to code), or also meshlab suite, which can compute the curvatures too.

Difference between distance() and geo_distance() in arangodb

What is the difference between the arango function - DISTANCE() and GE0_DISTANCE(). I know both of them calculates distance using haversines formula.
Thanks,
Nilotpal
Both are used for two different purposes
DISTANCE(latitude1, longitude1, latitude2, longitude2) → distance
The value is computed using the haversine formula, which is based on a spherical Earth model. It’s fast to compute and is accurate to around 0.3%, which is sufficient for most use cases such as location-aware services.
GEO_DISTANCE(geoJsonA, geoJsonB, ellipsoid) → distance
Return the distance between two GeoJSON objects, measured from the centroid of each shape. For a list of supported types see the geo index page. (Ref: https://www.arangodb.com/docs/3.8/aql/functions-geo.html#geo-index-functions)
This GeoJSON objects can be anything like GEO_LINESTRING, GEO_MULTILINESTRING, GEO_MULTIPOINT, GEO_POINT, GEO_POLYGON and GEO_MULTIPOLYGON - Reference<2>
Reference:
https://www.arangodb.com/docs/3.8/aql/functions-geo.html#geo-utility-functions
https://www.arangodb.com/docs/3.8/aql/functions-geo.html#geojson-constructors

visibility of objects in multi-dimensional space based on a specific perspective

I'm working on a data mining algorithm that considers features in their n-dimensional feature-space and allows surrounding training examples to block the 'visibility' of other training examples effectively taking them out of the effective training set for this particular query.
I've been trying to find an efficient way to determine which points are 'visible' to the query. I though the realm of computer graphics might offer some insight but there is a lot of information to peruse and much of it either can't be generalized to multiple dimensions or is only efficient when the number of dimensions is low.
I was hoping I could get some pointers from those of you who are more intimately knowledgeable in the domain.
The solution I found is to convert the euclidean coordinates into 'hyper-spherical' coordinates. Its similar to the spherical coordinate system except you add an additional angle with a range [0, pi) for each additional dimension beyond three.
After that I can sort the list of points based on their distance from the origin and iterate through comparing each point in the list to the first item looking for angles that overlap. after each iteration you remove the first item in the list and any items that were discovered to have been blocked. then start over with the new first item (closest item).
Don't know if anyone will ever find this useful but I thought I should put the answer up anyways.

Fast(er) way of matching feature to database

I'm working on a project where I have a feature in an image described as a set of X & Y coordinates (5-10 points per feature) which are unique for this feature. I also have a database with thousands of features where each have the same type of descriptor. The result looks like this:
myFeature: (x1,y1), (x2,y2), (x3,y3)...
myDatabase: Feature1: (x1,y1), (x2,y2), (x3,y3)...
Feature2: (x1,y1), (x2,y2), (x3,y3)...
Feature3: (x1,y1), (x2,y2), (x3,y3)...
...
I want to find the best match of myFeature in the features in myDatabase.
What is the fastest way to match these features? Currently I am stepping though each feature in the database and comparing each individual point:
bestScore = 0
for each feature in myDatabase:
score = 0
for each point descriptor in MyFeature:
find minimum distance from the current point to the...
points describing the current feature in the database
if the distance < threshold:
there is a match to the current point in the target feature
score += 1
if score > bestScore:
save feature as new best match
This search works, but clearly it gets painfully slow on large databases. Does anyone know of a faster method to do this type of search, or at least if there is a way to quickly rule out features that clearly won't match the descriptor?
Create a bitset (an array of 1s and 0s) from each feature.
Create such a bitmask for your search criteria and then just use a bitwise and to compare the search mask to your features.
With this approach, you can shift most work to the routines responsible for saving the stuff. Also, creating the bitmasks should not be that computationally intensive.
If you just want to rule out features that absolutely can't match, then your mask-creation algorithm should take care of that and create the bitmasks a bit fuzzy.
The easiest way to create such masks is probably by creating a matrix as big as the matrix of your features and put a one in every coordinate that is set for the feature and a zero in every coordinate that isn't. Then turn that matrix into a one dimensional row. Compare the feature-row then to the search mask bitwise.
This is similar to the way bitmap indexes work on large databases (oracle e.g.), but with a different intention and without a full bitmap-image of all database rows in memory.
The power of this is in the bitwise comparisons.
On a 32bit machine you can perform 32 comparisons per instruction when you can just do one with integer numbers in a point comparison. It yields even higher boni for floating point operations, depending on the architecture.
This in general looks like a spatial index problem. It's not my field, but you'll probably need to build a sort of tree index, such as a quadtree, that you can use to easily search for features. You can find some links from this wikipedia article: http://en.wikipedia.org/wiki/Spatial_index
It might be a problem that you can easily implement in an existing spatial database. It's very GIS-like in its description.
One thing you can do is calculate a point of gravity for every feature and use that to whittle down the search space a bit (a one dimensional search is a lot easier to build an index for), but that has the downside of being just a heuristic (depending on the shapes of your feature, the point of gravity may end up in weird places).

How best to perform corridor range search over a set of latitude / longitude coordinates

What would be the best approach to finding the set of coordinates, from say
about 5,00, which lie within a path of points, given a specified width.
eg an aircraft following several waypoints.
Is there a good way to also sort them in the same order as the route.
Calculation speed would be more important than accuracy, since I'm looking at
producing a list of suggestions.
From what I've looked at, I presume it's not straightforward, and the question is
a bit broad, but any suggestions/pointers would be welcome, eg for:
Best way to store lat / long, or use spherical coordinates
Having additional clustering info in the coordinate set
Can a transform of some kind be use to simplify the range check
What is the best way to order the points
Is here a better approach than doing a circular/square check on several equi-distant
points along the path.
There are many optimisations that you can do:
Split your points into fixed sized tiles so you don't have to check every point (first determine which tile you're in, so you can skip all points in other tiles).
When calculating the distance to each point, you'd normally use pythagoras to get the distance. But if you only want to know which point is the closest, you can omit the square root, which is an expensive operation (see example code below).
Use some flat projection instead of working with lat/lon, or approximate calculated distances by just assuming that the earth is flat. For small distances (up until several kilometres) that's usually accurate enough, and way faster and easier than working with WGS84 coordinates.
You might have to convert all your coordinates though, but that precalculation is going to save a lot of cpu-cycles in runtime.
-
// delphi code that would iterate through a set of points to find the index
// of the point that is the closest to the provided x/y
function TMatcher.GetIndexOfClosest(X,Y:Double):Integer;
var
i : Integer;
Closest:Double;
Distance:Double;
begin
Closest:= MaxInt;
Result := -1;
for i:=0 to high(Points) do
begin
// taking the square root is not needed here!
Distance :=Sqr(X-Points[I].X)+Sqr(Y-Points[I].Y);
if Distance < Closest then
begin
Closest := Distance;
Result := i;
end;
end;
end;
I assume you know how to calculate the distance between the points and the path. Latitude/Longitude is simple (x,y) data, although with fractional data rather than just integers.
5,000 data points really isn't that bad to compute the distance to the path for each point, but if you wish to scale, some kind of relational data structure such as a quadtree would be your best bet to store the points. That way, you can immediately discard the points that are nowhere near your path.
When faced with this type of problem, I'd use PostGIS. Import the data into the database, then use the spatial SQL functions to create a buffer on the track and select the points that lie inside the buffer. Lot quicker than coding it yourself.
PostGIS (and PostgreSQL) are easy to install on Windows/OSX/Linux. They have good documentation and a quick session on Google finds the answer to most questions.
Best way to store lat / long, or use spherical coordinates
What are you trying to store? The path, or the point you're searching for? If its the path, then it is fundamentally a list of some kind, as points are ordered. Depending on how/if you will manipulate the path, that will determine your data structure.
Having additional clustering info in the coordinate set
what information are you trying to store? If, for example, you chose a linked list as your data structure, you could have a linked list of class objects containing whatever information you needed.
Can a transform of some kind be use to simplify the range check
You can transform Lat/Long into UTM or any other coordinate system. The range between two points will still be the same.
What is the best way to order the points
If you're storing a path, then the order matters - as in point N-1 -> N -> N+1, and so on...

Resources