读取、表示和渲染地图数据的最佳方式是什么?

2024-04-17

我有兴趣编写一个简单的导航应用程序作为我的宠物项目。在搜索了免费地图数据后,我决定了美国人口普查局 TIGER http://www.census.gov/geo/www/tiger/tgrshp2007/tgrshp2007.html2007 线/形状文件地图数据。数据被分成各个县的 zip 文件,我已经下载了我所在地区的单个县地图数据。

将此地图数据读入可用格式的最佳方法是什么?

我应该如何:

  • 读入这些文件
  • 解析它们 - 正则表达式或某些已经可以解析这些形状文件的库?
  • 将数据加载到我的应用程序中 - 我应该将点直接加载到内存中的某些数据结构中吗?使用小型数据库?一旦你关闭了地图数据的应用,我就不需要持久化了。用户可以再次加载 Shapefile。

一旦我读取了 Shapefile 数据中的数据,渲染地图的最佳方法是什么?

理想情况下,我希望能够读取县地图数据形状文件并将所有折线渲染到屏幕上并允许旋转和缩放。

我应该如何:

  • 将纬度/经度点转换为屏幕坐标? - 据我所知,形状文件使用经度和纬度作为其点。显然,我必须以某种方式将它们转换为屏幕坐标才能显示地图功能。
  • 以一种可以轻松旋转和缩放整个地图的方式渲染地图数据(道路、边界等的一系列折线)?
  • 将整个地图渲染为一系列“图块”,以便仅渲染查看区域内的要素/线条?

Ex. of TIGER data rendered as a display map:
alt text

任何有一定经验和见解的人都知道我阅读这些文件的最佳方式是什么,我应该如何在程序中表示它们(数据库,内存数据结构),以及我应该如何渲染(通过旋转/缩放)地图数据在屏幕上将不胜感激。

编辑:澄清一下,我不想使用任何 Google 或 Yahoo 地图 API。同样,我不想使用 OpenStreetMap。我正在寻找一种比利用这些 api/程序更从头开始的方法。这将是一个desktop应用。


首先,我建议您使用2008年老虎档案 http://www.census.gov/geo/www/tiger/tgrshp2008/tgrshp2008.html.

其次,正如其他人指出的那样,现在有很多项目已经读入、解释、转换和使用数据。不过,为这些数据构建您自己的解析器几乎是微不足道的,因此没有理由浏览另一个项目的代码并尝试提取您需要的内容,除非您计划将他们的项目作为一个整体使用。

如果你想从较低的水平开始

Parsing

构建您自己的 TIGER 解析器(相当简单 - 只需一个线段数据库),并在此基础上构建一个简单的渲染器(线条、多边形、字母/名称)也将相当容易。你会想看看各种地图投影类型 http://www.colorado.edu/geography/gcraft/notes/mapproj/mapproj_f.html用于渲染阶段。最常用(因此用户最熟悉)的是墨卡托投影 http://www.colorado.edu/geography/gcraft/notes/mapproj/mapproj_f.html- 它相当简单且快速。您可能想尝试支持其他投影。

这将为了解如何投影地图以及如何反转该投影提供一些“乐趣”(假设用户单击地图,您想查看他们单击的纬度/经度 - 需要反转当前投影方程)。

渲染

当我开发渲染器时,我决定将窗口基于固定尺寸(嵌入式设备)和固定放大倍率。这意味着我可以将地图以纬度/经度为中心,并且在给定的放大倍率下中心像素=中心纬度/经度,并且给定墨卡托投影,我可以计算哪个像素代表每个纬度/经度,反之亦然。

有些程序允许窗口变化,并且不使用放大倍率和固定点,而是使用两个固定点(通常是定义窗口的矩形的左上角和右下角)。在这种情况下,确定像素到纬度/经度的传输变得微不足道 - 这只是一些插值计算。旋转和缩放使此传递函数稍微复杂一些,但应该不会太复杂 - 它仍然是一个带有插值的矩形窗口,但窗口角不需要相对于北处于任何特定方向。这增加了一些极端情况(例如,您可以将地图翻过来并像从地球内部一样查看它),但这些并不繁重,并且可以在您处理它时处理。

一旦完成了纬度/经度到像素的传输,渲染线条和多边形就相当简单了,除了正常的图形问题(例如线条或多边形的边缘不恰当地重叠、抗锯齿等)。但是渲染一个基本的丑陋地图(例如许多开源渲染器所做的那样)是相当简单的。

您还可以进行距离和大圆计算 - 例如,一个很好的经验法则是,赤道的每一度纬度或经度大约为 111.1KM - 但当您靠近任一极时,它会发生变化,而另一个继续保持在111.1kM。

存储和结构

然而,如何存储和引用数据在很大程度上取决于您计划如何使用它。如果您想对人口统计和路由使用相同的数据库结构,就会出现很多难题 - 给定的数据库结构和索引对于一个来说很快,而另一个则很慢。

使用邮政编码并仅加载附近的邮政编码适用于小型地图渲染项目,但如果您需要穿越全国的路线,则需要不同的结构。一些实现具有“覆盖”数据库,其中仅包含主要道路和捕捉到覆盖的路线(或通过多个覆盖 - 本地、地铁、县、州、国家)。这会导致快速但有时效率低下的路由。

Tiling

平铺地图实际上并不容易。在较低的放大倍率下,您可以渲染整个地图并将其剪切。在较高的放大倍率下,您无法一次渲染整个物体(由于内存/空间限制),因此您必须将其切成薄片。

在图块边界处切割线,以便渲染单个图块会导致不太完美的结果 - 通常所做的是将线渲染到图块边界之外(或者,至少保留线端的数据,尽管渲染一旦停止就会停止)发现它从边缘掉下来) - 这减少了当线条穿过瓷砖时看起来不太匹配时发生的错误。

当你解决这个问题时,你就会明白我在说什么。

查找进入给定图块的数据也并非易事 - 一条线的两端可能都在给定图块之外,但会穿过该图块。您需要查阅有关此的图形书籍(迈克尔·阿布拉什 (Michael Abrash) 的书是开创性的参考书 https://www.jagregory.com/abrash-black-book/,现在可以通过前面的链接免费获得)。虽然它主要讨论游戏,但窗口、裁剪、多边形边缘、碰撞等都适用于此。

但是,您可能想玩更高级别的游戏。

完成上述操作后(通过调整现有项目或自己执行上述操作),您可能想尝试其他场景和算法。

反向地理编码相当容易。输入纬度/经度(或单击地图)并获取最近的地址。这将教您如何解释 TIGER 数据中线段的地址。

基本的地理编码是一个难题。编写地址解析器是一个有用且有趣的项目,然后使用 TIGER 数据将其转换为纬度/经度并非易事,但很有趣。从简单而小的开始,要求精确的名称和格式匹配,然后开始研究“类似”匹配和语音匹配。该领域有很多研究 - 请查看搜索引擎项目以获取一些帮助。

寻找两点之间的最短路径是一个不平凡的问题。有很多很多算法可以做到这一点,其中大多数都已申请专利。我建议,如果您尝试这样做,请使用您自己设计的简单算法,然后进行一些研究并将您的设计与最先进的技术进行比较。如果您热衷于图论,这会很有趣。

遵循路径并先发制人地发出指示这并不像乍一看那么容易。给定一组带有相关经纬度对数组的指令,使用外部输入(GPS 或模拟 GPS)“遵循”路线,并开发一种算法,在用户接近每个真实交叉路口时向其提供指令。请注意,由于弯曲的道路等原因,纬度/经度对比指令多,并且您需要检测行进方向等。在尝试实现之前,您不会看到很多极端情况。

兴趣点搜索。这个很有趣 - 你需要找到当前位置,以及一定距离(直线距离,或更难 - 行驶距离)内的所有兴趣点(不是 TIGER 的一部分,可以自己制作或获取其他来源)起源。这个很有趣,因为在这种情况下你必须将 POI 数据库转换成一种易于搜索的格式。您无法花时间浏览数百万个条目,进行距离计算 (sqrt(x^2 + y^2)),然后返回结果。首先你需要有一些方法或算法来减少数据量。

旅行推销员。具有多个目的地的路由。只是常规路由的更难版本。

您可以找到许多项目的链接以及有关此主题的信息源here http://delicious.com/stienman/gis.

祝你好运,无论你做什么,无论多么初级或丑陋,请发表,以便其他人受益!

-Adam

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

读取、表示和渲染地图数据的最佳方式是什么? 的相关文章

  • 在 .NET 并发线程之间传递数据的最佳方式是什么?

    我有两个线程 一个需要轮询一堆单独的静态资源以查找更新 另一种需要获取数据并将其存储在数据库中 线程1如何告诉线程2有东西要处理 如果数据块是独立的 则将数据块视为要由线程池处理的工作项 使用线程池和QueueUserWorkItem将数据
  • Volatile.Read 和 Volatile.Write 背后的逻辑是什么?

    来自 MSDN Volatile Read 读取字段的值 在需要它的系统上 插入一个 阻止处理器重新排序内存的内存屏障 操作如下 如果在该方法之后出现读或写 代码 处理器无法移动它before这个方法 and Volatile Write
  • 如何停止使用扫描仪从标准输入读取多行?

    我正在做一个 JAVA 作业 应该处理多行输入 指令显示 输入是从标准输入读取的 给出了示例输入的示例 one 1 two 2 three 3 我不明白上面的示例输入 从标准输入读取 是什么意思 这是我编写的一个测试程序 它可以消除我的困惑
  • 如何添加 Java 正则表达式实现中缺少的功能?

    我是 Java 新手 作为一名 Net 开发人员 我非常习惯Regex Net 中的类 Java 实现Regex 正则表达式 还不错 但它缺少一些关键功能 我想为 Java 创建自己的帮助器类 但我想也许已经有一个可用的了 那么 是否有任何
  • 为什么我的 @OneToMany 属性出现主键违规?

    我有一个实体 Entity public class Student GeneratedValue strategy GenerationType AUTO Id private long id OneToMany private Set
  • Java时间转正常格式

    我有 Java 时间1380822000000 我想转换为我可以阅读的内容 import java util Date object Ws1 val a new Date 1380822000000 toString 导致异常 warnin
  • 使用 Hibernate Criteria 过滤 Map 中的键和值

    我有以下持久类 public class Code ElementCollection targetClass CodeValue class MapKeyClass CodeProperty class JoinTable name co
  • 欧拉项目 45

    我还不是一名熟练的程序员 但我认为这是一个有趣的问题 我想我应该尝试一下 三角形 五边形 六边形 数字由以下生成 公式 三角形 T n n n 1 2 1 3 6 10 15 五边形 P n n 3n 1 2 1 5 12 22 35 六角
  • 在 Java 中的 JFrame/JPanel/JComponent 中添加 Web 浏览器

    我正在开发一个 Java 应用程序 需要在应用程序中使用 Web 浏览器 我见过一些应用程序这样做 例如在同一应用程序中单击左侧面板中的提要并打开右侧面板中的链接时的 RSS 阅读器 我想实现类似的功能 在java中可以做到这一点吗 Jav
  • 使用java在网页中进行字符编码

    如何使用java找出网页中的字符编码类型 打开与 URL 的连接 使用URL openConnection http download oracle com javase 6 docs api java net URL html openC
  • Java:不使用 Arrays.sort() 对整数数组进行排序

    这是我们 Java 课程的练习之一中的说明 首先 我想说我 做了我的功课 我不仅仅是懒惰地请 Stack Overflow 上的人帮我回答这个问题 在所有其他练习中 这个特定项目一直是我的问题 因为我一直在努力寻找 完美的算法 编写JAVA
  • Java 中通用方法参数的 getClass()

    以下 Java 方法无法编译
  • Java给定长度的随机数

    我需要在 Java 中生成一个恰好 6 位数字的随机数 我知道我可以在随机发生器上循环 6 次 但是在标准 Java SE 中还有其他方法可以做到这一点吗 要生成 6 位数字 Use Random http download oracle
  • 如何在网页上实现文件上传进度条?

    当用户将文件上传到我的网络应用程序时 我想显示比动画 gif 更有意义的内容 我还有哪些可能性 编辑 我正在使用 Net 但我不介意是否有人向我展示与平台无关的版本 如果您对这一切在客户端通常如何工作感兴趣 就是这样 所有解决方案都通过 J
  • 使用 Commons 或 Guava 将文本文件转换为 Java Set

    我想将文件中的每一行加载到 HashSet 集合中 有没有一种简单的方法可以做到这一点 怎么样 Sets newHashSet Files readLines file charSet 使用番石榴 参考 文件 readLines http
  • 在java中创建一个XML树并将其转换为json对象

    我尝试创建也能够转换为 json 的树 但对于只有一个xpath 当我尝试实现多个 xpath 时 我无法获得所需的输出 这里我分享一下我的实现 private static Document addElemtbypath List
  • 设置 Firefox 配置文件以使用 Selenium 和 Java 自动下载文件

    我想使用 Selenium WebDriver 和 Java 验证文件下载 要下载的文件为 PDF 格式 当 WebDriver 单击 AUT 中的 下载 链接时 Firefox 将打开以下下载确认窗口 我希望 Firefox 自动下载文件
  • 接口中“不能降低继承方法的可见性”的含义

    我有两个文件 public interface PrintService void print PrintDetails details class PrintDetails private String printTemplate pub
  • 调试VS 2005提示“操作不支持”

    我一直在调试 VS 2005 并将 启动外部程序 设置为 C Program Files Microsoft Visual Studio 10 0 Common7 IDE devenv exe 但按 F5 后出现此错误 尝试运行项目时出错
  • 在 for 循环比较中使用集合大小

    Java 中 Collections 的 size 方法是否有编译器优化 考虑以下代码 for int i 0 i

随机推荐