Mongodb geospatial indexes, 2d vs 2dsphere - mongodb

According to the docs it says about 2d indexes:
The 2d index supports calculations on a flat, Euclidean plane. The 2d index also supports distance-only calculations on a sphere, but for geometric calculations (e.g. $geoWithin) on a sphere, store data as GeoJSON objects and use the 2dsphere index type.
Few things I do not understand..
I do not understand what is meant by distance-only, does it mean the Chord (that line which connects two surface points through a line "inside" the surface)?
How does that calculation work against Earth Longitude and Latitude? If that was designed for Euclidean space, how does it express distance in radians?
Instead, using the 2dsphere indexes, it calculates the surface distance correctly between two points, but it works without specifying the 360 longitude lines and the 180 latitude lines. Is it programmed to specially for Earth longitude and latinudes?
If 3. above is correct. does it takes into account that Earth is oblate spheroid and not a perfect sphere?

No. It means the surface distance using the Haversine formula.
I'm not sure what you are trying to ask in regards to "how does it express distance in radians" but if you mean how are lat/lon angle values and deltas converted into radians it is: PI * angle / 180.0. For the full Haversine formula, check out this link for implementations in 84 languages: http://rosettacode.org/wiki/Haversine_formula
2dsphere indexes use the WGS84 datum (which defines the bounds) See: http://spatialreference.org/ref/epsg/4326/.
Without looking at their code it is impossible to say. But given that they use WGS84 and talk about an "earth-like sphere" it is highly doubtful. I'm guessing they use Haversine (so distance calculations are only an approximation).

Related

Ellipse distance metric for DBSCAN clustering

I am using the DBSCAN algorithm to determine clusters in a data set obtained by an automotive radar. The paper "Grid-Based DBSCAN for Clustering Extended Objects in Radar Data" from Dominik Kellner, Jens Klappstein and Klaus Dietmayer (link below) proposes a Grid-Based DBSCAN method. Therefore, the search radius epsilon variates in azimuth direction depending on the range. The radius in range direction stays constant. The normal DBSCAN is using Euclidean distance metric to determine the epsilon-neighbourhood where the search radius is the same in both directions. I cannot find out how to have an ellipse-search instead of a circular.
Do you know a distance metric that is working elliptical? Or, can you provide me with a short code that solves my problem? I am using MATLAB but the code can be in your prefered language.
Let's give an example so we talk about the same:
Consider a cartesian coordinate system with range in meters plotted against azimuth angle in degrees. The search distance in the range direction should be three meters (or possible observation points) in both directions from a centre point. In azimuth direction, the search radius should be five points in both directions.
If you cannot think of an elliptical solution, maybe a linear works as well.
Thank you for your help.
https://www.researchgate.net/profile/Dominik_Kellner2/publication/261127945_Grid-based_DBSCAN_for_clustering_extended_objects_in_radar_data/links/57742a7708aead7ba06e60b5.pdf

In PostGIS which one is the most accurate way to calculate distance between two points?

I'm having problems with st_distance function in postgis. I have three ways to calculate the distance, but I don't know which one is the most accurate.
SELECT ST_Distance('POINT(115.25 39.26)'::geography, 'POINT(117.30 41.04)'::geography) as distance;
--result is 263753.911823565
SELECT ST_Distance_Sphere(ST_GeomFromText('POINT(115.25 39.26)',4326), ST_GeomFromText('POINT(117.30 41.04)',4326)) as distance;
--result is 263674.468686404
SELECT ST_Distance( ST_Transform(ST_GeomFromText('POINT(115.25 39.26)',4326),32650),ST_Transform(ST_GeomFromText('POINT(117.30 41.04)', 4326),32650)) as distance;
--result is 263669.651755417
The difference between the 3 measurement calculations is the following:
The distance is calculated over the spheroid, a mathematical approximation of the earth's surface taking the flattening at the poles into consideration. This is also called the "great arc distance". In this case the default spheroid is WGS84, which is also used by the GPS system and satellite imagery.
The distance is calculated over a sphere, which does not considering flattening (the shape is effectively like a ball). Usually the sphere has the same volume as some spheroid so it is slightly smaller at the equator and slightly bulging at the poles. It is mathematically much simpler than the spheroid and therefore lots faster to calculate.
The distance is calculated on a cartesian coordinate reference system (a plane) established by transforming from geographic coordinates, in this case UTM50N from a WGS84 spheroid.
The first method usually gives the best result (of these 3), but for coordinates that are close together or close to the Equator, the difference would be negligible compared to the faster second method.
The third method is not particularly accurate with the UTM50N(WGS84) coordinate reference system, but a cartesian coordinate system has important other benefits, such as calculating angles between triplets of points or areas of polygons. Also note that some datums in use with local CRSes give a much better local representation of the earth's irregular surface than WGS84 does, in which case a local CRS becomes much more accurate than a great-arc calculation. You would have to look up all the geodetic details of your area to assess that.

Project GPS coordinates to Euclidean space

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.

Use $within with a buffered MondoDB Linestring

I need to evaluate the proximity of a Point to a LineString using MongoDB.
Because the $near operator can only compare a Point to another Point, I need to generate a polygon out of the LineString, so I can use the $within operator. The distance between the LineString and the edges of the polygon should represent the radius I want to search in, such as represented in red below:
What might be a useful algorithm in order to accomplish this?
I think much easier would be to write your own function
To find (perpendicular) distance between point and line and then creating thickness of poly-line by polygon means.
Where:
P0,P1 are line endpoints
P is point
d is distance between them
Line is defined as: p(t)=P0+(P1-P0)*t where t=<0.0,1.0>
So the function should do this:
create perpendicular line
q(t)=P+DQ*u where u=(-inf,+inf)
DQ is perpendicular vector to (P1-P0)
In 2D you can obtain it easily like this (x,y) -> (y,-x). In higher dimensions use cross product with some non coplanar vectors.
compute line vs. line intersection
there are tons of stuff about this so google or solve the equation yourself here you can extract mine implementation.
now after successful intersection
just compute d as distance between P and intersection point. Do not forget that parameter t must be in range. If not (or if no intersection) then return min(|P-P0|,|P-P1|)
[hints]
t and u parameters can be obtained directly from intersection test so if the perpendicular vector to (P1-P0) is normalized to size = 1 then the abs(u) parameter of intersection point is the distance
[notes]
I am not familiar with mongodb so if you have no means to use own tests inside then this answer is of coarse obsolete.
Unfortunately, MongoDB provides very basic geospatial query, so you should create the buffer by your own. You can read how to do it here: Computing a polygon that surrounds a multi-point line
If you have longitude/latitude coordinates like WGS84 you must adjust this code; Read here how to calculate distance between point on a sphere https://en.wikipedia.org/wiki/Haversine_formula

Trouble understanding MKMapPoint(s)

Can anyone point me in the right direction when it comes to understanding MKMapPoint?
I understand that it has to do with laying suface of the globe on a 2D surface. But I don't understand how each "point" is measured?
Can anyone give me an example in code?
There is nothing much to it.. just a structure to display point on a 2D map... here is what the documentation says..
MKMapPoint A point on a two-dimensional map projection.
typedef struct {
double x;
double y; } MKMapPoint;
Fields x The location of the point along the x-axis of the
map. y The location of the point along the y-axis of
the map. Discussion If you project the curved surface of the globe
onto a flat surface, what you get is a two-dimensional version of a
map where longitude lines appear to be parallel. Such maps are often
used to show the entire surface of the globe all at once. An
MKMapPoint data structure represents a point on this two-dimensional
map.
The actual units of a map point are tied to the underlying units used
to draw the contents of an MKMapView, but you should never need to
worry about these units directly. You use map points primarily to
simplify computations that would be complex to do using coordinate
values on a curved surface. By converting to map points, you can
perform those calculations on a flat surface, which is generally much
simpler, and then convert back as needed. You can map between
coordinate values and map points using the MKMapPointForCoordinate and
MKCoordinateForMapPoint functions.
When saving map-related data to a file, you should always save
coordinate values (latitude and longitude) and not map points.
Availability Available in iOS 4.0 and later. Declared In MKGeometry.h
If you want to draw something over a map that has a certain real-world size, for example, a scale, then in your calculations you would multiply any given length in meters with the result of MKMapPointsPerMeterAtLatitude(...) to get the size in MKMapPoint units.
If your map displays only of small portion of the globe, MKMapPointsPerMeterAtLatitude(...) will deliver roughly the same constant value for all the latitudes involved in your map. In this case, you can simply use the latitude in the middle of your map as the argument of this function.
Also read in the documentation that a Mercator projection is used for the transformation. Here is an additional observation: northing (y) axis direction seems to be in reverse direction of standard mercator projections (positive direction is down instead of up).