在不使用 Geonames.org 等网络服务的情况下,根据纬度/经度确定时区

IT技术 javascript php geolocation timezone gis
2021-01-25 22:14:26

是否有可能在不使用网络服务的情况下确定点(纬度/经度)的时区?Geonames.org 不够稳定,我无法使用 :( 我需要它在 PHP 中工作。

谢谢

6个回答

不久前我遇到了这个问题,并且完全按照亚当的建议做了:

  • 从 geonames.org下载城市数据库
  • 将其转换为紧凑的纬度/经度 -> 时区列表
  • 使用R-Tree实现有效地查找到给定坐标最近的城市(或者更确切地说,它的时区)

IIRC 填充 R 树的时间不到 1 秒,然后它可以每秒执行数千次查找(均在 5 年前的 PC 上进行)。

我很难完成“将其转换为紧凑的纬度/经度-> 时区列表”的部分,这里是:gist.github.com/1769458然后我使用 postgres 和 postgis,地理类型的 Gist 索引,然后查询: select timezone_string where ST_DWithin(ST_GeographyFromText('SRID=4326;POINT(2.36 48.86)'), location, 100000, false) order by st_distance(ST_GeographyFromText) ('SRID=4326;POINT(2.36 48.86)'), location) 限制 1. 我在我想要的点 (2.36 48.86) 周围 100 公里处寻找体面的性能:30 毫秒。如果失败,我会跑 6000 公里:1 秒 :)
2021-03-20 22:14:26
对不起,如果这无效,但是 R-Trees 不是用于矩形的吗?我认为最近邻算法,例如使用 kd-trees 的算法是针对点的。
2021-03-30 22:14:26
我创建了一个简单的 Python 脚本来将 GeoNames.org 数据(和其他)转换为各种格式,例如用于地理空间查询的 MongoDB .json 插入脚本。可以在这里找到:github.com/NuSkooler/GeoToTimeZone
2021-04-03 22:14:26
为了找到离给定坐标最近的城市,四叉树应该更快(也更简单)。en.wikipedia.org/wiki/Quadtree
2021-04-04 22:14:26
@Markos Fragkakis:刚刚看到您的评论。我链接到的 R-Tree 库具有最近邻搜索。不确定它是如何实现的。但是基本思想应该同样适用于不同的数据结构。
2021-04-12 22:14:26

你的结果必须有多精确?如果粗略估计就足够了,请自行计算偏移量:

offset = direction * longitude * 24 / 360

其中方向为 1 为东,-1 为西,经度为 (-180,180)

这是一个非常粗略的估计,前提是您经常使用错误的时区(例如,整个西班牙/法国与伦敦的时区不同,即使它们具有相同的经度。地图
2021-03-14 22:14:26
谢谢非常有帮助的答案,尤其是在准确性不是问题的情况下。我还四舍五入了你公式中的小数点。
2021-04-13 22:14:26

我在做另一个项目时遇到了这个问题,并对其进行了深入研究。我发现所有现有的解决方案在主要方面都缺乏。

下载 GeoNames 数据并使用一些空间索引来查找最近的点绝对是一种选择,它会在很多时候产生正确的结果,但如果查询点在时间错误的一侧,它很容易失败从数据库中最近的点开始的区域边界。

更准确的方法是使用时区的数字地图并编写代码来查找该地图中包含给定查询点的多边形。值得庆幸的是,没有可用的世界时区的一个极好的地图在http://efele.net/maps/tz/world/(不保持)。要编写高效的查询引擎,您需要:

  • 将 ESRI shapefile 格式解析为有用的内部表示。
  • 编写 point-in-polygon 代码来测试给定的查询点是否在给定的多边形中。
  • 在多边形数据之上编写一个有效的空间索引,这样您就不需要检查每个多边形来找到包含它的多边形。
  • 处理不包含在任何多边形中的查询(例如,在海洋中)。在这种情况下,您应该“对齐”到一定距离内最近的多边形,并恢复到公海中的“自然”时区(仅由经度决定的时区)。为此,您将需要代码来计算查询点和多边形线段之间的距离(这很重要,因为纬度和经度是非欧几里得坐标系),并且您的空间索引需要是能够返回附近的多边形,而不仅仅是可能包含多边形。

每一个都值得拥有自己的 Stack Overflow 问题/答案页面。

在得出结论认为现有的解决方案都不能满足我的需求后,我编写了自己的解决方案并在此处提供:

http://askgeo.com

AskGeo 使用数字地图并具有高度优化的空间索引,允许在我的计算机上以单个线程每秒运行超过 10,000 次查询。而且它是线程安全的,因此更高的吞吐量当然是可能的。这是一段严肃的代码,我们花了很长时间来开发,所以我们在商业许可下提供它。

它是用 Java 编写的,因此在 PHP 中使用它需要使用:

http://php-java-bridge.sourceforge.net/doc/how_it_works.php

我们也愿意移植它以获得赏金。有关定价的详细信息和详细文档,请参阅http://askgeo.com

我希望这是有用的。这对我正在从事的项目当然很有用。

我知道这很旧,但我花了一些时间寻找这个答案。发现了一个非常有用的东西。Google 按 long/lat 进行时区查找。不再有免费层:-/

https://developers.google.com/maps/documentation/timezone/

您不需要为此使用网络服务。
2021-03-25 22:14:26

如果您知道时区的多边形以查看给定的纬度/经度是否在其中,您应该能够做到。

世界时区数据库 在此处输入图片说明

纬度/经度多边形数据 在此处输入图片说明

行。不是很计算吗?
2021-03-16 22:14:26
请注意,在大多数情况下,您确实需要区分 400 多个管理时区,而不仅仅是基本偏移量,这是由于不同的夏令时切换及其历史变化。
2021-03-19 22:14:26
废话这是gd的东西,但是数据不会是动态的而不是静态的吗?=)
2021-04-12 22:14:26