1. SQL / Говнокод #29223

    0

    1. 1
    ORDER BY (|lng - :lng| + |lat - :lat|) ASC LIMIT 1

    «Иногда нам нужно определить местоположение пользователя, когда мы точно знаем его координаты (например получили их используя датчики GPS устройства или Geolocation API в браузере). Тут есть два варианта — обратное геокодирование нам возвращает название того места, где находится пользователь. Но что произойдет, если пользователь находится где-то на трассе между городами, или в пригороде или просто в чистом поле и хочет посмотреть объявления о продаже участков на этом поле? Не всегда обратный геокодер с этим справится.

    В этом случае лично я поступаю так — у меня в базе данных хранятся все координаты городов России, в которых у нас имеются объявления и с которыми мы вообще работаем. И по координатам пользователя я просто определяю ближайший к нему город из нашей базы, с помощью простого запроса.»


    С Х-ра. Кто сразу поймёт, почему эта формула плоха?

    Запостил: HoBorogHuu_nemyx, 26 Января 2026

    Комментарии (16) RSS

    • SEO-псто.

      Метки: #sql #geocoding #geolocation #геометрия #ма-те-ма-ти-ка
      Ответить
    • окружность
      1/1 километр разницы это расстояние в 1.414, когда 1.9/0 это 1.9


      чёт мало сложных задачек в последнее время в этой соцсети

      ссылку на хабр бы ещё, чтобы посмотреть, как ему в панаму насовали

      upd: https://habr.com/ru/articles/462011/
      Ответить
      • Верно. Для плоского мира.

        Такая метрика (если исправить следующую ошибку, на которую я намекаю) называется «метрикой Нью-Йорка», в ней направления по меридианам и по параллелям предпочтительнее направлений по другим азимутам.

        Но это ещё не всё. Подсказка про вторую ошибку: эта формула работает только в окрестностях экватора.
        Ответить
        • да, здесь втупил, но ответ разве что явно не произнесён

          один градус соответствует разному расстоянию в зависимости от положения на планете. чем ближе к полюс, тем больше сжимается долгота
          Ответить
          • Всё так.

            На экваторе цена градуса долготы около 111 км (как и широты), на широте Питера — около 55 км (а градус широты по-прежнему 111 км). Долготу надо домножать на косинус широты. Т. е. на широте Питера запрос из заметки будет чаще выдавать объекты к северу и к югу от тебя, а объекты к западу и к востоку от тебя будет ошибочно считать расположенными в два раза дальше.
            Ответить
          • Ну и третий косяк — запрос будет сканировать всю таблицу, как будто в ней нету индексов. Можно, конечно, отсечь некую область по широте и по долготе, чтобы сканировать не всю базу...

            Оставлю вопрос пирфоманса, вернусь к геометрии.

            Теперь ви таки будете смеяться, но то, что нужно автору, есть даже в крошке Мю:
            https://dev.mysql.com/doc/refman/8.4/en/creating-spatial-indexes.html

            SRID 4326 — это вот эта питушня:
            https://epsg.io/4326

            А так считается расстояние:
            https://dev.mysql.com/doc/refman/8.4/en/spatial-relation-functions-object-shapes.html#function_st-distance

            Да, готовая функция есть даже в крошке Мю!
            Ответить
            • Вот тут уже автор шарит:

              https://habr.com/ru/companies/otus/articles/858680/
              Ответить
        • manhattan distance кстати
          Ответить
          • Она хотела бы жить на Манхэттене, и с Гологубом делиться секретами
            Ответить
          • Точно. Она же метрика такси.

            Эквидистанта точки в данной метрике будет иметь форму не привычной нам окружности, а квадрата, поставленного на угол (повёрнутого на 45 градусов).

            Есть ещё одна метрика с «квадратной окружностью»: если в исходной формуле плюс заменим на функцию MAX, то получим метрику Пафнутия Львовича Чебышёва. В ней эквидистантой точки будет квадрат с горизонтальными и вертикальными сторонами.

            Если алгоритм с манхэттенской метрикой неохотно показывает объекты по азимутам 45° (135°, 225°, 315°), то алгоритм с метрикой Чебышёва наоборот, будет выдавать их чаще.
            Ответить
    • > lng + lat
      Какое 1D )))
      Ответить
    • плоха формула тем, что надо брать GIS и индексы нормальные, а не играть в пыхера-на-третьей-муське, который (и которая) ничего не умеет
      https://postgis.net/workshops/postgis-intro/indexing.html
      Ответить
      • Сейчас уже многие СУБД научились в spatial indexing, даже муська (выше я кинул ссылку). Оказывается, даже для Склайта расширение написали:
        https://ru.wikipedia.org/wiki/SpatiaLite

        Но это же надо документацию по СУБД читать...

        Допустим, автор не знал, что именно искать в документации. Но оказалось, что он живёт в плоском (если даже не в одномерном) мире.
        Ответить
        • >, что он живёт в плоском

          Библиотекарь (Плоский мир)

          > если даже не в одномерном

          гологуб вон выше тоже заметил.

          > Но это же надо документацию по СУБД читать...

          правельно зачем что-то читать я вообще храню отношения много ко многим черех зопаятую в таблице и мне хорошо
          Ответить
    • Technical post: RSS fixed.
      Ответить

    Добавить комментарий