首先,我建议您使用
2008 TIGER files。
其次,正如其他人指出的那样,现在已经有很多项目可以读取、解释、转换和使用这些数据。构建自己的解析器来处理这些数据几乎是微不足道的,所以除非您打算将整个项目作为一个整体使用,否则没有必要查看另一个项目的代码并尝试提取所需内容。
如果您想从较低的层次开始
解析
建立自己的TIGER解析器(相对容易-只需一个线段的数据库),并在其上构建一个简单的渲染器(线条、多边形、字母/名称),也将相对容易。在渲染阶段,您需要查看各种地图投影类型。最常用的(因此对用户最熟悉)是墨卡托投影-它相对简单且快速。您可能想尝试支持其他投影方式。
这将提供一些“乐趣”,让您了解如何投影地图,以及如何反转该投影(例如,当用户在地图上点击时,您希望看到他们点击的纬度/经度-需要反转当前的投影方程)。
渲染
当我开发我的渲染器时,我决定基于固定大小(嵌入式设备)和固定放大倍数来设置窗口。这意味着我可以将地图居中于某个纬度/经度,并且通过中心像素=中心纬度/经度在给定的放大倍数下,根据墨卡托投影计算出每个纬度/经度所代表的像素,反之亦然。
有些程序则允许窗口大小变化,而不是使用放大倍数和固定点,它们使用两个固定点(通常是定义窗口的矩形的左上角和右下角)。在这种情况下,确定像素到纬度/经度的转换变得非常简单 - 只需要进行一些插值计算。旋转和缩放会使这个转换函数稍微复杂一些,但不应该过于复杂 - 它仍然是一个带有插值的矩形窗口,但窗口的角不需要与北方保持任何特定的方向。这会增加一些特殊情况(例如,您可以将地图翻转并从地球内部查看),但这些并不繁琐,并且可以在工作过程中处理。
一旦你完成了经纬度到像素的转换,渲染线条和多边形就相对简单,除了一些常见的图形问题(如线条或多边形的边缘不恰当地重叠、抗锯齿等)。但是渲染一个基本的丑陋地图,就像许多开源渲染器所做的那样,相对直接。
你还可以玩一下距离和大圆计算——例如,一个很好的经验法则是,在赤道上每一度的纬度或经度大约是111.1公里,但是当你靠近两极时,一个会发生变化,而另一个仍然保持在111.1公里。
然而,你如何存储和引用数据,取决于你打算用它做什么。如果你想在人口统计和路径规划方面使用相同的数据库结构,会遇到很多困难问题——对于一个给定的数据库结构和索引,其中一个可能快速,而另一个可能很慢。
对于小型地图渲染项目,使用邮政编码并仅加载附近的邮政编码是可行的,但如果你需要跨国家的路线,就需要不同的结构。一些实现方式有“叠加”数据库,只包含主要道路,并将路线对齐到叠加层(或通过多个叠加层——本地、城市、县、州、国家)。这样可以实现快速但有时效率低下的路径规划。
铺砖
铺砖你的地图其实并不容易。在较低的放大倍数下,你可以渲染整个地图然后切割它。在较高的放大倍数下,你无法一次性渲染整个地图(由于内存/空间限制),所以你必须将其切割。
在瓷砖边界处切割线条,以便能够渲染单独的瓷砖,结果并不完美 - 通常的做法是将线条渲染超出瓷砖边界(或者至少保留线条末端的数据,尽管一旦发现已经超出边缘,渲染就会停止) - 这样可以减少线条在跨越瓷砖时出现的不完全匹配的错误。
当你解决这个问题时,你会明白我在说什么。
同样,找到进入给定瓷砖的数据也不是一件简单的事情 - 一条线可能两端都在给定的瓷砖之外,但是穿过了该瓷砖。你需要查阅有关图形的书籍(
Michael Abrash的书是权威参考资料,现在在上述链接中可以免费获取)。虽然它主要讲解游戏,但窗口化、裁剪、多边形边缘、碰撞等概念在这里同样适用。
然而,你可能想要在更高的水平上进行游戏。
一旦你完成了上述任务(可以通过改编现有项目或自己完成),你可能想要尝试其他场景和算法。
逆地理编码相对容易。输入纬度/经度(或在地图上点击)即可获取最近的地址。这将教会你如何解释TIGER数据中的线段上的地址。
基本地理编码是一个困难的问题。编写一个地址解析器是一个有用且有趣的项目,然后使用TIGER数据将其转换为纬度/经度是非平凡的,但非常有趣。从简单和小规模开始,要求精确的名称和格式匹配,然后开始研究“相似”匹配和音标匹配。在这个领域有很多研究 - 可以参考搜索引擎项目以获得一些帮助。
在两点之间找到最短路径是一个非平凡的问题。有许多算法可以实现这一点,其中大部分都有专利。我建议如果你尝试这个,可以使用自己设计的简单算法,然后进行一些研究,将你的设计与现有技术进行比较。如果你对图论感兴趣,这将是非常有趣的。
跟着路径并提前给出指示并不像一开始看起来那么容易。给定一组带有相关的纬度/经度对的指示,使用外部输入(GPS或模拟GPS)“跟随”路线,并开发一个算法,在用户接近每个真实交叉口时给出指示。请注意,由于道路弯曲等原因,纬度/经度对的数量比指示多,您需要检测行进方向等。有很多你在实施之前看不到的特殊情况。
兴趣点搜索。这个很有趣 - 你需要找到当前位置,并找到离起点一定距离(直线距离或更难 - 驾驶距离)内的所有兴趣点(不是TIGER的一部分,可以自己制作或获取其他来源)。这个有趣之处在于你必须将POI数据库转换为易于在此情况下搜索的格式。你不能花时间遍历数百万条目,进行距离计算(sqrt(x^2 + y^2)),然后返回结果。你需要有一些方法或算法来首先减少数据量。
旅行推销员。多目的地的路线规划。只是常规路线规划的更难版本。
你可以在这里找到许多项目和信息来源的链接 here。
祝你好运,请无论你做什么,无论多么初级或丑陋,都要发布出来,这样其他人才能受益!
-Adam