正如标题所暗示的那样,我需要根据一对坐标找到一个时区(或者可能只是 UTC 偏移量)。我一直在寻找不同的解决方案,并且有几个 Web 服务,但我需要能够离线访问应用程序。由于时区并非完全基于经度,因此似乎并不容易......
我想查询一个包含世界上所有国家及其时区的 ESRI shapefile,但它似乎有点复杂。如果这应该是解决方案,您是否知道任何提供此功能的 .NET 库?
我已经通过客户端应用程序解决了这个问题。该技术是制作一个用颜色编码的世界圆柱地图,每个时区都有独特的颜色。经纬度转换为图片坐标,读取坐标的颜色,然后交叉引用该颜色的时区。
那个简短的解释并不完全是我所做的,但它传达了这个想法。我实际上填充了几个字典并从中进行了查找。第一个版本需要 2M 的资源文件来填充(在我处理我的地图并将其转换为二进制数据之后)。理论上的最大误差(赤道附近的纬度)应该是 +/- 大约 15 英里。不幸的是,我的起始地图的准确性更像是 +/- 100 英里。
所以我正在重做这个项目。我已经投入了几天,现在创建了一个更准确和更高rez的地图来紧缩。再过几天,应该完成。资源文件将在 20M 左右,除非我选择只为“愚蠢的区域”提供资源并在数学上计算可以直接计算的 90% 的世界(世界上的大部分都可以从经度数学上推导出来)。不确定很多人会关心资源文件是 20M,但有些人可能会关心。无论如何,如果似乎有一些兴趣,我会尝试在此处发布运行它所需的代码,并将资源文件发布到公共代码站点之一。如果似乎没有兴趣,我不会打扰。
只是重新迭代一下,您的应用程序中所需的代码只有几行,但资源文件很大(不缩小它,我的新文件运行 22M)。它也很快(第一次再现以 100M / 秒的速度运行)。它确实需要文件加载,这需要一点时间。2M 版本没有明显延迟,但 22M 可能(还没有)。
检查tz数据库。我知道它将名称与时区相关联(如城市、国家、EST 等)。但我相信某个地方的坐标有一个扩展。
我尝试导出表格,但似乎无法将geometry
类型导出为文本..但无论如何这并不难..你需要谷歌几年前生产的 shapefile Manifold,它映射了所有世界各国及其时区.. 然后你需要使用一些程序将该数据导出到 SQL Server 2008.. 我使用 Manifold(记得使用企业版或更高版本).. 然后我使用以下存储过程查询数据:
USE [MyDb]
GO
/****** Object: StoredProcedure [dbo].[GetTimeZone] Script Date: 11/18/2009 21:23:52 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetTimeZone]
@Latitude float,
@Longitude float
AS
/* SET NOCOUNT ON */
DECLARE @g geometry
/* Validation */
IF @Latitude > 90 OR @Latitude < -90 OR @Longitude > 180 OR @Longitude < -180
RAISERROR('Latitude or longitude out of range', 16, 1)
IF @Latitude IS NULL OR @Longitude IS NULL
RAISERROR('Latitude or longitude cannot be null', 16, 1)
SET @g = geometry::Point(@Longitude, @Latitude, 4326);
IF EXISTS(SELECT * From TimeZones WHERE Shape.STContains(@g) = 1)
/* Point exists on map, get the info */
SELECT Name, LocalSumme, Offset, AreaI FROM TimeZones WHERE Shape.STContains(@g) = 1
ELSE
/* Point is an international water */
IF(@Longitude >= 0)
SELECT NULL AS Name, NULL AS LocalSumme, FLOOR((@Longitude + 7.5) / 15) AS Offset, NULL AS AreaI
ELSE
SELECT NULL AS Name, NULL AS LocalSumme, -FLOOR((-@Longitude + 7.5) / 15) AS Offset, NULL AS AreaI
shapefile 中存在问题,因为未映射国家水域。我虽然可能使用@g.STBuffer() 来解决这个问题..
解决方案是使用新的空间数据类型将 ESRI shapefile 导出到 SQL Server 2008。
如果有人有更好的解决方案,请随时发布!