Я столкнулся с этой проблемой, работая над другим проектом, и очень глубоко изучил ее. Я обнаружил, что во всех существующих решениях отсутствуют основные пути.
Загрузка данных GeoNames и использование некоторого пространственного индекса для поиска ближайшей точки, безусловно, вариант, и он будет часто давать правильный результат, но он может легко потерпеть неудачу, если точка запроса находится на неправильной стороне границы часового пояса от ближайшей точки в базе данных.
Более точный метод состоит в том, чтобы использовать цифровую карту часовых поясов и написать код, чтобы найти полигон в той карте, которая содержит заданную точку запроса. К счастью, есть отличная карта часовых поясов мира, доступная по номеру http://efele.net/maps/tz/world/ (больше не поддерживается ). Чтобы написать эффективный механизм запросов, вам необходимо:
- Разобрать формат шейп-файла ESRI во полезное внутреннее представление.
- Напишите код точки в многоугольнике, чтобы проверить, находится ли заданная точка запроса в заданном многоугольнике.
- Напишите эффективный пространственный индекс поверх данных многоугольника, чтобы вам не нужно было проверять каждый многоугольник, чтобы найти содержащий его.
- Обработка запросов, которые не содержатся ни в каком многоугольнике (например, в океане). В таких случаях вы должны «привязаться» к ближайшему полигону на определенное расстояние и вернуться к «естественному» часовому поясу (который определяется только долготой) в открытом океане. Для этого вам понадобится код для вычисления расстояния между точкой запроса и отрезком линии многоугольника (это нетривиально, поскольку широта и долгота неевклидовой системы координат), и ваш пространственный индекс должен быть возможность возвращать соседние полигоны, а не только потенциально содержащие полигоны.
Каждый из них достоин своей страницы вопросов / ответов о переполнении стека.
Сделав вывод, что ни одно из существующих решений не отвечало моим потребностям, я написал собственное решение и сделал его доступным здесь:
http://askgeo.com
AskGeo использует цифровую карту и имеет высокооптимизированный пространственный индекс, который позволяет выполнять более 10000 запросов в секунду на моем компьютере в одном потоке. И это потокобезопасно, поэтому, конечно, возможна даже более высокая пропускная способность Это серьезный кусок кода, и его разработка заняла много времени, поэтому мы предлагаем его по коммерческой лицензии.
Он написан на Java, поэтому использование его на PHP потребует:
http://php -java-bridge.sourceforge.net / DOC / how_it_works.php
Мы также открыты для портирования за вознаграждение. Подробнее о ценах и подробной документации см. http://askgeo.com.
Надеюсь, это полезно. Это, безусловно, было полезно для проекта, над которым я работал.