Определите, находятся ли две координаты в пределах желаемого радиуса - PullRequest
1 голос
/ 04 июля 2019

Я работаю над объединением основных больших перекрестков моего города с данными о столкновениях моего города.То, что я пытаюсь сделать, это определить количество аварий, которые произошли на перекрестке и вокруг него в радиусе 20 метров.

К счастью, я уже далеко от проекта и у меня есть две таблицы в моей базе данных intersections и collisions

Моя intersections таблица:

 --------------------------------------------
 |  id  |  city  |  Latitude  |  Longitude  |
 --------------------------------------------
 |  1   |   1    |   34.44444 |   84.3434   |
 --------------------------------------------
 |  2   |   1    | 42.4666667 | 1.4666667   |
 --------------------------------------------
 |  3   |   1    |  32.534167 | 66.078056   |
 --------------------------------------------
 |  4   |   1    |  36.948889 | 66.328611   |
 --------------------------------------------
 |  5   |   1    |  35.088056 | 69.046389   |
 --------------------------------------------
 |  6   |   1    |  36.083056 |   69.0525   |
 --------------------------------------------
 |  7   |   1    |  31.015833 | 61.860278   |
 --------------------------------------------

MY collisions таблица:

--------------------------------------------
 |  id  |  cause |  Latitude  |  Longitude  |
 --------------------------------------------
 |  1   |   1    |   44.44444 |   81.3434   |
 --------------------------------------------
 |  2   |   1    | 32.4666667 | 1.4666667   |
 --------------------------------------------
 |  3   |   1    |  42.534167 | 63.078056   |
 --------------------------------------------
 |  4   |   1    |  46.948889 | 62.328611   |
 --------------------------------------------
 |  5   |   1    |  45.088056 | 61.046389   |
 --------------------------------------------
 |  6   |   1    |  46.083056 |   63.0525   |
 --------------------------------------------
 |  7   |   1    |  41.015833 | 69.860278   |
 --------------------------------------------

Примечание. Некоторые поля были опущены для простоты

Как видите, обе таблицы имеют поля latitude и longitude.Теперь, чтобы определить, близки ли пересечения и столкновения координаты, я подумал об использовании запроса MySQL, который принимает идентификатор пересечение , которое затем запрашивает таблицу collisions, чтобы получить все столкновения в пределах 20 метров от пересечения .

Что это за запрос (в MySQL или в Sequelize)?

Вот что у меня сейчас (это в Sequelize с использованием базы данных MySQL)

// api/collisions/{intersection_id}/count

exports.intersection_accident_count = (req, res) => {
    intersection.findOne({where: {equipement: req.params.intersection_id}}).then(intersection => {

        let intersectionLongitude = intersection.longitude;
        let intersectionLatitude = intersection.latitude;

        collision.count({where: {
            longitude: {
                $gt: intersectionLongitude
            },
            latitude: {
                $gt: intersectionLatitude
            },
        }}).then(count => {
            res.status(200).json({'number_of_accidents': count});
        });
    });
};

1 Ответ

1 голос
/ 04 июля 2019

Вы должны начать с простого пути:

SELECT
    i.*
FROM
    intersections AS i
    INNER JOIN collisions AS c ON (
        ST_Distance_Sphere(POINT(i.Longitude, i.Latitude), POINT(c.Longitude, c.Latitude)) < @dist
    )

Это должно дать вам результаты, однако запрос не будет использовать никаких индексов вообще, и если у вас много записей, он будет очень медленным.

Вам следует подумать о добавлении типов данных геометрии в вашу таблицу:

ALTER TABLE `collisions` ADD COLUMN `Location` POINT;
UPDATE `collisions` SET Location = POINT(Longitude, Latitude);
ALTER TABLE `intersections` ADD COLUMN `Location` POINT;
UPDATE `intersections` SET Location = POINT(Longitude, Latitude);

Вы можете добавить триггер, чтобы Местоположение автоматически заполнялось при обновлении Долготы / Широты.

Тогда:

SELECT
    i.*
FROM
    intersections AS i
    INNER JOIN collisions AS c ON (
        ST_Distance_Sphere(i.Location, c.Location) < @dist
    )

Это будет немного быстрее.

Если вы хотите сделать это еще быстрее, вы можете добавить еще один столбец геометрического полигона Area в таблицу пересечений и "pre-строить 'области (могут быть круглыми для точности или квадратными для скорости).После этого вы сможете сделать что-то вроде этого:

SELECT
    i.*
FROM
    intersections AS i
    INNER JOIN collisions AS c ON (
        ST_WITHIN(c.Location, i.Area)
    )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...