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?

Abrar Jahin
  • 13,970
  • 24
  • 112
  • 161

2 Answers2

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.

Community
  • 1
  • 1
Abrar Jahin
  • 13,970
  • 24
  • 112
  • 161
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.

1000111
  • 13,169
  • 2
  • 28
  • 37
  • 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 – Abrar Jahin Mar 16 '16 at 05:03
  • Because it is server, so may be 1000 request comes in 1 sec and there may be 100000 points. SO this procedure will fail – Abrar Jahin Mar 16 '16 at 05:05
  • No, it is DB budy, so we have to apply some algo to find result in a efficient way, not this way – Abrar Jahin Mar 16 '16 at 05:10
  • Have you run this query? What's the execution time? You may share the `Explain ...` result of this query. @AbrarJahin – 1000111 Mar 16 '16 at 05:23
  • 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 – Abrar Jahin Mar 16 '16 at 05:25
  • I have found a better and efficient way for it – Abrar Jahin Mar 17 '16 at 09:38