Получить все записи из базы данных MySQL, которые находятся в Google Maps .getBounds? - PullRequest
17 голосов
/ 29 января 2011

Хорошо, у меня есть база данных с примерно 1800 строками, у каждой есть столбцы lat и long, что я пытаюсь сделать, это запрос к Google Maps V3 .getBounds Результат примерно такой: ((33.564398518424134, -79.38014701875002), (35.375726155241175, -76.08424858125002)) ЧтоЯ хочу сделать, это получить каждую запись, чей размер в базе данных находится в этих пределах.Любые предложения?

Я думаю, мне придется экстраполировать другие 2 угла карты, поскольку .getBounds содержит только 2 точки (2 угла карты, я полагаю), и я хотел бы быть в пределах 4точки.Если бы я это сделал, у меня получилось бы что-то вроде массива ... Теперь поправьте меня, если я ошибаюсь, но это должны быть углы карты NW, NE, SW, SE, в лат. Lng.

33.564398518424134, -79.38014701875002
33.564398518424134, -76.08424858125002
35.375726155241175, -79.38014701875002
35.375726155241175, -76.08424858125002

Хорошо. Итак, если у меня есть эти данные, как мне построить запрос для получения строк, которые находятся в этих координатах?Таблица называется tilistings - столбцы lat и lng ... также, если есть более простой способ, или я просто помешан на своей методологии, пожалуйста, дайте мне знать.

Спасибо

Ответы [ 10 ]

31 голосов
/ 23 декабря 2013

Все предыдущие ответы работают только на 1/4 мира!

W3t Ответ Tr3y был близок, но с ошибкой (лишнее "<"). </p>

Все они работают только для США, потому что они в СЕВЕРНОМ полушарии. Они не работают ни для южного полушария, ни для восточных стран (справа от Гринвича).

Вот простое решение без функций или сложных вещей.

буквы - это результаты в том порядке, в каком вы получаете их из map.getBounds (), т.е. swlat, swlng, nelat, nelng = a, b, c, d.

SELECT * FROM tilistings WHERE
(CASE WHEN a < c
        THEN lat BETWEEN a AND c
        ELSE lat BETWEEN c AND a
END) 
AND
(CASE WHEN b < d
        THEN lng BETWEEN b AND d
        ELSE lng BETWEEN d AND b
END) 

или другое решение с и / или (вы можете проверить его на скорость, я не знаю, как запустить его несколько раз в WorkBench)

SELECT * FROM tilistings WHERE
(a < c AND lat BETWEEN a AND c) OR (c < a AND lat BETWEEN c AND a)
AND 
(b < d AND lng BETWEEN b AND d) OR (d < b AND lng BETWEEN d AND b)

Теперь вы можете наносить на карту весь мир :) Я надеюсь, что кто-то может пометить вышеупомянутые ответы как неправильные, потому что они заставляют нас терять много времени для миллионов таких людей, как я. Интересно, как они получают так много голосов, когда они на самом деле не работают!

PS: вероятность того, что край пикселя вашей карты будет соответствовать точному значению координат в 15 десятичных знаков, в миллионы раз меньше, чем шансы пропустить целые 3/4 мира!

16 голосов
/ 29 января 2011

если из Google: ((a, b), (c, d))

SELECT * FROM tilistings WHERE lat > a AND lat < c AND lng > b AND lng < d

4 голосов
/ 29 января 2011

Я не использовал API Google, но, насколько я понимаю, если вы получите ((33.564398518424134, -79.38014701875002), (35.375726155241175, -76.08424858125002)) от вызова getBounds, то (33.564398518424134, -79.38014701875002) - это юго-западный угол, а (35.375726155241175, -76.08424858125002) - это северо-восток.Я говорю, что, как мне кажется, они возвращают северо-восточный и юго-западный углы, и я предполагаю, что точки - это широта, долгота.

Если это правильно, тогда запрос Бенсю будет работать.Обычно использование BETWEEN более эффективно.

SELECT * FROM tilistings WHERE lat BETWEEN a AND c AND lng between b AND  d
3 голосов
/ 17 сентября 2015

Я уже опоздал на комментарий, но, возможно, он будет кому-то полезен. sergio не совсем правильно, запрос для всего мира должен выглядеть немного иначе, если я не ошибаюсь, что-то вроде этого:

SELECT * FROM tilistings WHERE (sw_lat < ne_lat AND lat BETWEEN sw_lat AND ne_lat) OR (sw_lat > ne_lat AND (lat BETWEEN sw_lat AND 180 OR lat BETWEEN -180 AND ne_lat)) (sw_lon < ne_lon AND lon BETWEEN sw_lon AND ne_lon) OR (sw_lon > ne_lon AND (lon BETWEEN sw_lon AND 180 OR lon BETWEEN -180 AND ne_lon))

2 голосов
/ 11 марта 2016

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

Взятие области, ограниченной прямоугольником с южным краем (юг), западным краем (запад), северным краем(север) и восточный край (восток).Они могут быть получены из Google Map .getBounds, которые предоставляют юго-западный и северо-восточный угол - вам нужны только два угла, так как они полностью описывают квадратную ограничительную рамку.

В этом примере наша таблица базы данныхназывается местоположения и содержит столбец для широты и долготы.

SELECT * FROM locations WHERE
(latitude BETWEEN south AND north) AND
((west < east AND longitude BETWEEN west AND east) OR
 (west > east AND (longitude BETWEEN west AND 180 OR longitude BETWEEN -180 AND east)))

Это работает на основе того факта, что нам нужно учитывать только пересечение линии 180 / -180 долготы в качестве особого случая - т.е. гдезападная долгота является более высоким значением, чем восточная долгота.В любом случае, когда мы не пересекаем эту линию, западная долгота всегда будет меньше восточной долготы.

Что касается широты, то южный край всегда будет иметь более низкое значение, чем северная широта, поскольку нетКонцепция обтекания полюсов.Например, чтобы покрыть область над северным полюсом, у нас просто есть все долготы (т.е. от -180 до 180) и широта от южной границы до + 90.

1 голос
/ 29 марта 2016

Взгляните на новые пространственные данные и функции, доступные в MySQL 5.7, теперь также для InnoDB.

Используя приведенные выше примеры, требуется около 1 с для таблицы с записями 1 млн., Чтобы получить местоположения вопределенный ограничивающий прямоугольник.

С ST_Within () и ST_MakeEnvelope () и правильным пространственным индексом я получаю результат менее чем за 0,01 с.

1 голос
/ 04 ноября 2014

Мы можем найти результат между Maps.getBounds: северо-восток и юго-западная широта и северо-восток и юго-западная долгота, используя следующий запрос.

Поисковый запрос должен быть между northEast.latitude И southWest.latitude AND northEast.longitude AND southWest.longitude

$nelat=$_GET['nelat']-0.5;
$nelng=$_GET['nelng']-0.5;
$swlat=$_GET['swlat']-0.5;
$swlng=$_GET['swlng']-0.5;

$sql ="SELECT * FROM tablename where (CASE WHEN ".$nelat." < ".$swlat."
    THEN s.latitude BETWEEN ".$nelat." AND ".$swlat."
    ELSE s.latitude BETWEEN ".$swlat." AND ".$nelat."
END) 
AND
(CASE WHEN ".$nelng." < ".$swlng."
        THEN s.longitude BETWEEN ".$nelng." AND ".$swlng."
        ELSE s.longitude BETWEEN ".$swlng." AND ".$nelng."
END)";
1 голос
/ 02 февраля 2014

Это работает для меня:

$condition1 = $a < $c ? "lat > $a AND lat < $c" : "lat > $a OR lat < $c";
$condition2 = $b < $d ? "lon > $b AND lon < $d" : "lon > $d OR lon < $b";
$q = "SELECT * FROM tilistings WHERE ( $condition1 ) AND ( $condition2 )";
0 голосов
/ 04 марта 2018

Из моего списка https://gist.github.com/jesuGMZ/0d7f38d80e2f67d0bc4b7fb620345344

Имея MySQL> 5.7 с таблицей, содержащей тип столбца POINT с именем location и следующий ответ Google Maps:

"geometry": {
    "bounds": {
        "northeast": {
            "lat": 40.5638447,
            "lng": -3.5249115
        },
        "southwest": {
            "lat": 40.3120639,
            "lng": -3.8341618
        }
    },
    //....

Вы можете выполнить SQL-запрос для получения всех ваших местоположений, содержащихся в этой границе, например:

SELECT * FROM my_table
WHERE Contains(
  ST_MakeEnvelope(
    ST_GeomFromText('POINT(40.5638447 -3.5249115)'),
    ST_GeomFromText('POINT(40.3120639 -3.8341618)')
  ),
  location
);

Рассмотрите возможность индексации местоположения, чтобы улучшить производительность ваших запросов, если применимо.Кроме того, можно использовать Within вместо Contains, изменяя порядок параметров.

Полезные ссылки:

0 голосов
/ 30 декабря 2013

Я не уверен, что приведенное выше утверждение верно. Во-первых, я считаю, что углы nelat, nelng, swlat, swlng не такие, как указано выше "swlat, swlng, nwlat, nwlng". Во-вторых, я считаю, что nelat всегда будет выше, чем у окна (если окно не покрывает один из географических полюсов, что, я не уверен, возможно даже при использовании карт Google).

Наконец, если окно покрывает международную строку даты (приблизительно +/- 180lng), то есть d

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