9

I have a DB Schema like this (from this tutorial by Google) -

DB Schema

So the actual points in a graph for them is like this-

Physical Location

What I want is to find points near a given point (by point_id) point ordered by distance

Location of a point (x,y) is (point_x,point_y) in DB

I want to solve it with MySQL because my DB is already in MySQL.


Update-

Finding distance of 2 points is so easy like this-

Finding distance

I want to sort on distance with MySQL.


Re-

For removing the confusions, I want the points inside the circle, later. But now I want to find only the sorted points.

So u can ignore the circles.


I don't have any idea how to do it, can anyone please help?

5
  • 1
    How would you define nearest points? Commented Mar 16, 2016 at 4:40
  • 1
    It is a common question to find distance between 2 points, it is given in updated question Commented Mar 16, 2016 at 4:53
  • I didn't ask for that. You marked a circle. Probably you want all those points inside the circle. That's why I asked what's your criteria to grab those points? Commented Mar 16, 2016 at 4:56
  • Yes, I want the points inside the circle, later. But now I want to find only the sorted points Commented Mar 16, 2016 at 4:57
  • Question updated for your kind info. Commented Mar 16, 2016 at 5:00

2 Answers 2

13

I have found a better solution than @1000111 's solution.

There is custom DB type in MySQL for this kind of data which gives a better performance.

OpenGIS in MySQL is perfect for this.

Functions are given here.

An illustrative definition is given in this StackOverflow question.

My solution is like this-

DB Table-

CREATE TABLE geoTable
(
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(30) NOT NULL,
    geoPoint POINT NOT NULL,
    SPATIAL INDEX(geoPoint)
) ENGINE=MyISAM;


INSERT INTO geoTable (name, geoPoint)
VALUES
  ( "A", GeomFromText('POINT(0.1 -1.01)') ),
  ( "B", ST_GeomFromText('POINT(56.31 2.81)') ),
  ( "C", ST_GeomFromText('POINT(11.1 1.176)') ),
  ( "ui", ST_GeomFromText('POINT(9.1 2.1)') );

SQL Query-

SELECT
  id,
  name,
  X(geoPoint) AS "latitude",
  Y(geoPoint) AS "longitude",
  (
    GLength(
      LineStringFromWKB(
        LineString(
          geoPoint, 
          GeomFromText('POINT(51.5177 -0.0968)')
        )
      )
    )
  )
  AS distance
FROM geoTable
  ORDER BY distance ASC;

An example SQL Fiddle is given here.

See the execution time-

enter image description here

For 150 entry, it is only 13ms.

Sign up to request clarification or add additional context in comments.

5 Comments

Why the LineStringFromWKB ? Without it, the query runs fine with exactly same result
If your table is very large, you might filter it using the MBRContains function, before sorting, as this can make use of SPATIAL indexes.
LineStringFromWKB Why use it? Can you please explain?
How about high dimensions?
ST_Distance( geoPoint , 'POINT(51.5177 -0.0968)' ) OR ST_Distance_Sphere( geoPoint , 'POINT(51.5177 -0.0968)' )
1

Try this query please [a straight forward approach]:

Suppose, you want to find the nearest 20 points of the point having point_id = 5

SET @givent_point_id := 5;

SELECT 
P1.point_id,
P1.point_name,
P1.point_x,
P1.point_y,
(POW(ABS((P2.point_x - P1.point_x)),2) + POW(ABS((P2.point_y - P1.point_y)),2)) AS sqr_distance
FROM Point P1,
    (SELECT point_x,point_y FROM Point WHERE point_id = @givent_point_id) P2
WHERE P1.point_id <> @givent_point_id
ORDER BY sqr_distance
LIMIT 20;

Demo Here

More: You may have a look at MySQL SPATIAL DATATYPE.

MySQL spatial indexes use R-tree as data structure which is specially designed for spatial access methods.

R-trees are tree data structures used for spatial access methods, i.e., for indexing multi-dimensional information such as geographical coordinates, rectangles or polygons.

6 Comments

Sorry to say, I can't use this straight forward way. Because it is too slow and if the total points> 10000 then we can't expect an answer from this query
Because it is server, so may be 1000 request comes in 1 sec and there may be 100000 points. SO this procedure will fail
No, it is DB budy, so we have to apply some algo to find result in a efficient way, not this way
Have you run this query? What's the execution time? You may share the Explain ... result of this query. @AbrarJahin
There is only 4 points now, so u can't compare. Can compare if u have 10000 points or more. NP, let me try if there is any alternative, if not, I should have accept your answer. Thanks for your help
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.