用于计算时区的 shapefile 不再是 not maintained。
我今天刚刚遇到了同样的问题,我不确定我的答案在这段时间之后有多相关,但我基本上只是写了一个 Python 函数来满足你的需求。你可以在这里找到它。
https://github.com/cstich/gpstotz
编辑:
正如 cmets 中提到的,我还应该发布代码。该代码基于 Eric Muller 的时区 shapefile,您可以在此处获取 - http://efele.net/maps/tz/world/。
编辑 2:
事实证明,shapefile 对外环和内环的定义有些过时(基本上外环使用右手定则,而内环使用左手定则)。在任何情况下,fiona 似乎都能解决这个问题,我相应地更新了代码。
from rtree import index # requires libspatialindex-c3.deb
from shapely.geometry import Polygon
from shapely.geometry import Point
import os
import fiona
''' Read the world timezone shapefile '''
tzshpFN = os.path.join(os.path.dirname(__file__),
'resources/world/tz_world.shp')
''' Build the geo-index '''
idx = index.Index()
with fiona.open(tzshpFN) as shapes:
for i, shape in enumerate(shapes):
assert shape['geometry']['type'] == 'Polygon'
exterior = shape['geometry']['coordinates'][0]
interior = shape['geometry']['coordinates'][1:]
record = shape['properties']['TZID']
poly = Polygon(exterior, interior)
idx.insert(i, poly.bounds, obj=(i, record, poly))
def gpsToTimezone(lat, lon):
'''
For a pair of lat, lon coordiantes returns the appropriate timezone info.
If a point is on a timezone boundary, then this point is not within the
timezone as it is on the boundary. Does not deal with maritime points.
For a discussion of those see here:
http://efele.net/maps/tz/world/
@lat: latitude
@lon: longitude
@return: Timezone info string
'''
query = [n.object for n in idx.intersection((lon, lat, lon, lat),
objects=True)]
queryPoint = Point(lon, lat)
result = [q[1] for q in query
if q[2].contains(queryPoint)]
if len(result) > 0:
return result[0]
else:
return None
if __name__ == "__main__":
''' Tests '''
assert gpsToTimezone(0, 0) is None # In the ocean somewhere
assert gpsToTimezone(51.50, 0.12) == 'Europe/London'