SQL выбирает точку широты и долготы внутри ограничительной рамки - PullRequest
2 голосов
/ 23 октября 2019

Я использую карту Google, и я хотел бы запросить мой SQL, чтобы найти все точки внутри ограничительной рамки.

На карте Google я использую этот JavaScript для получения ограничивающего прямоугольника

var bounds = map.getBounds();
var ne = bounds.getNorthEast(), sw = bounds.getSouthWest();
var args = {
    NW: { lat: ne.lat(), lng: sw.lng() },
    NE: { lat: ne.lat(), lng: ne.lng() },
    SE: { lat: sw.lat(), lng: ne.lng() },
    SW: { lat: sw.lat(), lng: sw.lng() },
}; //NW = North-West, NE = North-East, SE = South-East, SW = South-West

Затем я использую LINQ для выбора всех мест в моей базе данных SQL:

//nw = North-West, ne = North-East, se = South-East, sw = South-West
double minLat = Math.Min(nw.Lat, Math.Min(ne.Lat, Math.Min(se.Lat, sw.Lat)));
double maxLat = Math.Max(nw.Lat, Math.Max(ne.Lat, Math.Max(se.Lat, sw.Lat)));
double minLng = Math.Min(nw.Lng, Math.Min(ne.Lng, Math.Min(se.Lng, sw.Lng)));
double maxLng = Math.Max(nw.Lng, Math.Max(ne.Lng, Math.Max(se.Lng, sw.Lng)));

return (from rec in tblPlaces.AsNoTracking()
        where (rec.Lat >= minLat) && (rec.Lat <= maxLat) && (rec.Lng >= minLng) && (rec.Lng <= maxLng)
        select rec).ToList<tblPlace>();

Он хорошо работает, когда он находится на довольно большом увеличении (Google zoom <= 15). Но при уменьшении размера страны (т. Е. Вы можете видеть всю страну), он не находит точку в моей базе данных. </p>

При отладке я обнаружил, что значение долготы намного меньше, чем любая точкав моей базе данных. Как это возможно? Я уменьшил масштаб, чтобы увидеть всю страну.

Является ли неправильный способ выбора широты и долготы?

Ответы [ 2 ]

1 голос
/ 29 октября 2019

Я не специалист по географии, но это выглядит просто. Давайте начнем с долготы. Ограничительная рамка может находиться на одной стороне или поперек антимеридиана:

-180         0         +180
  |                      |
  |       +-----+        |
  |   -10 |  x  | +10    |
  |       +-----+        |
  |                      |
  |                   +-----+
  |              +170 |  x  | -170
  |                   +-----+
  |                      |

В ограничительной рамке существует заданная долгота, если:

lng1 <= lng2 AND (lng1 <= lng AND lng <= lng2) /* both edges on same side */
OR
lng1 >  lng2 AND (lng1 <= lng OR  lng <= lng2) /* edges on opposite sides */

В ограничительной рамке существует заданная широта, если:

lat1 >= lat2 AND (lat1 >= lat AND lat >= lat2) /* both edges on same side */
OR
lat1 <  lat2 AND (lat1 >= lat OR  lat >= lat2) /* edges on opposite sides */

Если широты не охватывают, например, в Google Maps API, то тест противоположных сторон не требуется.

Некоторые тесты для db <> fiddle и jsFiddle, показывающий, как работает LatLngBounds

0 голосов
/ 28 октября 2019

Я наконец нашел ответ после просмотра учебника по широте и долготе.

В итоге: широта от -90 до 90 и долгота от -180 до 180

//Latitude
 90 ----------------------  90

  0 ----------------------   0

-90 ---------------------- -90

//Longitude
-180        0        180
  |         |         |
  |         |         |
  |         |         |
  |         |         |
-180        0        180

Теперь ограничивающий прямоугольник может перекрываться. Таким образом, левый может быть больше, чем правый, или верхний может быть больше, чем нижний в ограничительной рамке (прямоугольник). Основываясь на Как искать (предопределенные) местоположения (Широта / Долгота) в Прямоугольном, используя Sql? (см. Последний ответ), решение состоит в простом объединении всех комбинаций в зависимости от того, где находится ограничительная рамка.

Если вы сможете найти лучшее и более эффективное решение, я буду присудить вам награду:)

Приветствия

...