[英]What is the best way to read, represent and render map data?
我有兴趣将一个简单的导航应用程序编写为宠物项目。 在搜索免费地图数据后,我已经确定了美国人口普查局TIGER 2007 Line / Shapefile地图数据。 数据被分成各个县的zip文件,我已经为我的区域下载了一个县的地图数据。
将这个地图数据读入可用格式的最佳方法是什么?
我应该怎么做:
在读完Shapefile数据后,渲染地图的最佳方法是什么?
理想情况下,我希望能够读取县地图数据shapefile并将所有多边形线渲染到屏幕上并允许旋转和缩放。
我应该怎么做:
防爆。 作为显示地图呈现的TIGER数据:
任何有经验和洞察我最好的方式阅读这些文件的人,我应该如何在我的程序中表示它们(数据库,在内存数据结构中),以及我应该如何渲染(使用旋转/缩放)地图数据在屏幕上将不胜感激。
编辑:澄清一下,我不想使用任何谷歌或雅虎地图API。 同样,我不想使用OpenStreetMap。 我正在寻找一种比使用那些apis /程序更划刮的方法。 这将是一个桌面应用程序。
首先,我建议您使用2008 TIGER文件 。
其次,正如其他人所指出的那样,现在有很多项目已经读入,解释,转换和使用数据。 但是,为这些数据构建自己的解析器几乎是微不足道的,因此除非您计划整体使用他们的项目,否则没有理由通过另一个项目的代码并尝试提取您需要的内容。
解析
构建自己的TIGER解析器(相当简单 - 只是一个线段数据库),并在其上构建一个简单的渲染(线,多边形,字母/名称)也将相当容易。 您将需要查看渲染阶段的各种地图投影类型 。 最常用的(因此对用户最熟悉)是墨卡托投影 - 它相当简单快速。 您可能想要支持其他投影。
这将在看到如何投影地图方面提供一些“乐趣”,以及如何反转该投影(例如,用户点击地图,您想要查看他们点击的纬度/经度 - 需要反转当前投影方程)。
渲染
当我开发渲染器时,我决定将窗口放在固定尺寸(嵌入式设备)和固定放大倍率上。 这意味着我可以将地图居中于纬度/经度,并且在给定的放大率下使用中心像素=中心纬度/经度,并且给定墨卡托投影,我可以计算每个纬度/经度代表哪个像素,反之亦然。
有些程序允许窗口变化,而不是使用放大率和固定点,它们使用两个固定点(通常是定义窗口的矩形的左上角和右下角)。 在这种情况下,确定像素到lat / lon传输变得微不足道 - 它只是一些插值计算。 旋转和缩放使这种传递函数稍微复杂一些,但不应该如此 - 它仍然是一个带插值的矩形窗口,但窗口角不需要相对于北方的任何特定方向。 这会增加一些极端情况(例如,您可以将地图内部翻转并像在地球内部一样查看)但这些并不繁琐,可以在您处理时进行处理。
完成lat / lon到像素传输后,渲染线和多边形相当简单,除了正常的图形问题(例如线条边缘或多边形重叠不当,抗锯齿等)。 但渲染一个基本的丑陋地图,例如许多开源渲染器完成的地图,相当简单。
您还可以使用距离和大圆计算 - 例如,一个很好的经验法则是赤道的每个纬度或纬度大约为111.1KM - 但随着您接近任一极点而变化,另一个继续保持在111.1kM。
存储和结构
但是,如何存储和引用数据在很大程度上取决于您计划使用它的方式。 如果你想在人口统计与路由中使用相同的数据库结构,会出现很多困难问题 - 给定的数据库结构和索引对于一个是快速的,对另一个则是慢的。
使用zipcodes并仅加载附近的zipcodes适用于小型地图渲染项目,但如果您需要遍布全国的路线,则需要使用不同的结构。 一些实现具有“覆盖”数据库,其仅包含主要道路并且捕捉到覆盖的路线(或通过多个覆盖 - 本地,地铁,县,州,国家)。 这导致快速但有时低效的路由。
平铺
平铺地图实际上并不容易。 在较低的放大倍率下,您可以渲染整个地图并将其剪切。 在更高的放大率下,您无法一次渲染整个事物(由于内存/空间限制),因此您必须将其切片。
在瓷砖边界处切割线条以便渲染单个瓷砖会导致结果不尽如人意 - 通常所做的是线条渲染到瓷砖边界之外(或者,至少保留线条末端的数据,尽管渲染一旦停止就会停止发现它已经脱落了边缘 - 这减少了线条看起来像它们穿过瓷砖时不完全匹配时发生的错误。
当你解决这个问题时,你会看到我在说什么。
找到进入给定图块的数据并非易事 - 一条线可能在给定图块之外有两端,但是穿过图块。 你需要查阅有关这方面的图画书 ( Michael Abrash的书是开创性的参考书 ,现在可以在前面的链接免费获得)。 虽然它主要讨论游戏,但窗口,剪裁,多边形边缘,碰撞等都适用于此。
完成上述任务后(通过调整现有项目或自己完成上述项目),您可能希望使用其他方案和算法。
反向地理编码相当容易。 输入lat / lon(或点击地图)并获取最近的地址。 这教会您如何解释TIGER数据中沿线段的地址。
基本的地理编码是一个难题。 编写地址解析器是一个有用且有趣的项目,然后使用TIGER数据将其转换为lat / lon是非常重要的,但是很有趣。 通过要求精确的名称和格式匹配开始简单和小,然后开始研究'喜欢'匹配和语音匹配。 这个领域有很多研究 - 在这里看看搜索引擎项目的一些帮助。
找到两点之间的最短路径是一个非平凡的问题。 有很多很多算法可以做到这一点,其中大部分都是专利的。 我建议如果您尝试使用自己设计的简单算法,然后进行一些研究并将您的设计与现有技术进行比较。 如果你进入图论,这会很有趣。
遵循一条道路并且先发制人地给出指示并不像第一次看到的那样容易。 给定一组具有相关的纬度/经度对数组的指令,使用外部输入(GPS或模拟GPS)“跟随”路线,并开发一种算法,在用户接近每个真实交叉点时为其提供指令。 请注意,由于道路弯曲等原因,纬度/经度对比指令多,您需要检测行进方向等。 在尝试实现它之前,您将看不到许多角落案例。
兴趣点搜索。 这个很有趣 - 你需要在一定的距离内找到当前的位置和所有感兴趣的点(不是TIGER的一部分,制作你自己的或获得另一个来源)(如乌鸦飞行,或者更难驾驶距离)起源。 这个有趣之处在于您必须将POI数据库转换为在这种情况下易于搜索的格式。 您不能花时间浏览数百万条目,进行距离计算(sqrt(x ^ 2 + y ^ 2)),并返回结果。 您需要有一些方法或算法来首先减少数据量。
旅行推销员。 使用多个目标路由。 只是一个更难的常规路由版本。
您可以在此处找到许多项目的链接以及有关此主题的信息来源。
祝你好运,请发表你做的任何事情,无论多么简陋或丑陋,所以其他人都可以受益!
-亚当
SharpMap是WinForms和ASP.NET的开源.NET 2.0映射引擎。 这可能会提供您需要的所有功能。 它涉及最常见的GIS矢量和栅格数据格式,包括ESRI shapefile。
解决方案是:
他们可以阅读和提供shapefile(和许多其他东西)。 例如,geoserver(安装时)将来自美国人口普查局TIGER shapefile的数据作为演示提供
网上有很多使用此解决方案的示例
有趣的问题。 这是我如何做到的。
无论我们采用何种格式,我都会收集所需的任何几何体。我一直在从USGS中提取数据,所以这相当于一堆:
然后我写了一个程序,将这些形状定义“编译”成一个有效渲染的形式。 这意味着要进行有效显示数据所需的任何投影和数据格式转换。 一些细节:
x
项目,其中x
是我可以按照我想要的帧速率绘制的图元数量。 其余的是相机控制和想要显示的任何数据的动画。
以下是我现有实现的一些示例:
图片http://seabusmap.com/assets/Picture%205.png 图片http://seabusmap.com/assets/Picture%207.png
为了在本地存储老虎数据,我会选择Postgresql和postgis工具。
他们拥有令人印象深刻的工具集,特别是Tiger Geocoder提供了导入和使用老虎数据的好方法。
你需要看看与postgis交互的工具,很可能是某种mapserver
来自http://postgis.refractions.net/documentation/ :
现在有几种与PostGIS一起使用的开源工具。 uDig项目正在开发一个可以直接与PostGIS一起使用的完整读/写桌面环境。 对于互联网映射,明尼苏达大学Mapserver可以使用PostGIS作为数据源。 GeoTools Java GIS工具包支持PostGIS,GeoServer Web Feature Server也支持。 GRASS支持PostGIS作为数据源。 JUMP Java桌面GIS查看器有一个简单的插件,用于读取PostGIS数据,QGIS桌面具有良好的PostGIS支持。 可以使用OGR C ++库和命令行工具(以及带有捆绑的Shape文件转储器的cource)将PostGIS数据导出为多种输出GIS格式。 当然,任何可以与PostgreSQL一起使用的语言都可以与PostGIS一起使用 - 该列表包括Perl,PHP,Python,TCL,C,C ++,Java,C#等。
编辑:depite mapserver在其名称中包含单词SERVER,这将在桌面环境中使用。
虽然您已经决定使用TIGER数据,但您可能对OSM(开放街道地图)感兴趣,因为OSM完全导入了TIGER数据,并丰富了用户贡献的数据。 如果您坚持TIGER格式,您的应用程序对国际用户将毫无用处,OSM您可以立即获得TIGER和其他所有内容。
OSM是一个开放式项目,具有协作编辑的免费世界地图。 您可以获取所有这些数据以及结构良好的XML,查询区域或在大文件中下载整个世界。
OSM中有一些地图渲染器可用于各种编程语言,其中大多数是开源的,但仍有很多工作要做。
还有一个OSM路由服务可用。 它有一个Web界面,也可以通过Web服务API查询。 同样,它并非全部完成。 用户肯定可以使用基于此构建的桌面或移动路由应用程序。
即使你不决定参与该项目,你也可以从中获得很多灵感。 只需查看项目维基以及所涉及的各种软件项目的来源(您将在维基内找到它们的链接)。
您还可以使用Microsoft的可视化地球地图应用程序和api或使用Google的API。 我总是使用ESRI产品进行商业编程,并且没有那么开放的api。
另外,你可能想看Maker! 和Finder! 它们是相对较新的程序,但我认为它们是免费的。 可能仅限于嵌入数据。 制造商可以在这里找到。
问题是空间处理在非商业规模上是相当新的。
当我给出这个答案时,问题就被贴上了标签
“在.Net中使用折线渲染Shapefile(地图数据)的最佳方法是什么?”
现在这是一个不同的问题,但我将答案留给原来的问题。
我写了一个.net版本,它可以在c#中使用普通的GDI +绘制矢量数据(例如shp文件中的几何)。 这很有趣。
原因是我们需要处理具有大量附加信息的不同版本的几何和属性,因此我们无法使用商业地图组件或开源组件。
这样做的主要方法是建立一个视口并将WGIS84坐标转换/转换为缩小比例和GDI + x,y坐标,如果您甚至需要重新投影,则等待投影。
如果您不介意购买解决方案, Safe Software会生产一种名为FME的产品。 此工具将帮助您将数据从任何格式转换为几乎任何其他格式。 包括KML Google地球格式或将其渲染为JPEG(或一系列JPEG)。 转换数据后,您可以使用他们的API将google earth嵌入到您的应用程序中,或者只显示平铺图像。
作为一方而非FME是一个非常强大的平台,因此在进行翻译时,您可以添加或删除不一定需要的部分数据。 如果您有多个来源,请合并来源。 转换坐标(我不记得谷歌地球使用的是什么)。 将备份存储在数据库中。 但严重的是,如果你愿意花几块钱,你应该调查一下。
您还可以创建包含位置(放置位置)的标记(与样本图中非常相似)以及有关位置的其他数据/注释。 这些旗帜有多种形状和大小。
对墨卡托或其他投影的一种简化是假设纬度和经度的恒定转换因子。 将纬度乘以69.172英里; 对于经度,选择地图区域的中纬度并乘以(180-经度)乘以余弦(middle_latitude)* 69.172。 转换为里程后,您可以使用另一组转换来获取屏幕坐标。
这对我在1979年有用。
一种解决方案是使用MapXtreme。 他们有Java和C#的API。 API能够加载这些文件并进行渲染。
对于Java:
对于.NET:
我在桌面应用程序中使用了此解决方案并且运行良好。 它提供了更多只有渲染信息。
现在从头做这个可能需要一段时间。 他们有一个可以下载的评估版本。 我认为它只是在地图上打印“MAPXTREME”作为水印,但它完全可以使用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.