65.9K
CodeProject 正在变化。 阅读更多。
Home

与在线地图交互和显示

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2023 年 4 月 7 日

GPL3

5分钟阅读

viewsIcon

12655

用于与在线地图服务交互的库以及用于显示地图的 WinUI 3 控件

引言

我编写了几个涉及显示从在线服务获取的地图的 Windows 应用程序。不幸的是,据我所知,在 WinUI 3 下没有“官方”Microsoft(或 Microsoft 社区)控件用于显示地图。GitHub 上有一些可用的,但我认为开发自己的控件会是一个有趣的项目。

源代码可在 GitHub 上找到。

NuGet.org 上提供软件包

背景

和许多人一样,我在许多网站和一些桌面应用程序中使用过地图。但我并不熟悉各种地图服务的工作机制,这完全是一回事,除了学习如何编程它们之外,它本身就很有趣。一个很好的起点是 Bing Maps Tile System,在解释其图块系统工作原理的过程中,它会向您介绍地图服务为何使用基于图块的系统以及在代码库中使用它们的一些挑战。

Using the Code

GitHub 存储库 中可以找到这两个库的广泛文档。该存储库还包含一个 WinUI 3 演示程序(不可否认,它使用了我的一些其他库,所有这些库都可从 NuGet.org 获取)以及一组单元测试,这些测试还展示了 J4JMapLibrary 的用法。

J4JMapLibrary

J4JMapLibrary 使用“地图区域”(以 MapRegion 类为代表)、“地图图块”(以 MapTile 类为代表)和“投影”(以派生自 Projection 的类为代表,该类针对处理特定地图服务进行了定制)的概念。该库目前提供 Bing Maps、Google Maps、OpenStreetMap 和 OpenTopoMap 的投影类。为其他地图服务编写自己的投影类应该也不难。

MapTiles 始终是 MapRegion 的一部分,它定义了您要显示的地图区域、其方位角(即相对于真北的旋转方式)及其比例(即缩放程度)。Projection 将图像数据加载到 MapTile 中,或者加载 MapRegion 中包含的所有图块,然后这些图块可用于更新 UI。MapRegion 包含各种属性,可以简化更新(例如,显示区域相对于从地图服务检索的区域的水平和垂直偏移量,这可能不同)。

虽然实例化 Projection 很简单,但该库还包含一个 MapFactory,可用于根据名称或类型创建 ProjectionsMapFactory 还可以自动对 Projection 进行身份验证(所有地图服务都需要一定程度的身份验证才能使用它们,有些还需要您设置账户……如果您大量使用该服务,这可能会产生费用)。为了让 MapFactory 进行身份验证,您的凭据必须可以通过 IConfiguration 系统获得,并且遵循特定的布局。详细信息包含在 GitHub 文档中。

某些 Projections 支持缓存检索到的图像数据(缓存其图像数据违反了 **Google Maps Static API**)。该库包含内存缓存和基于文件系统的缓存。缓存不是必需的,但建议使用。

J4JMapWinLibrary

J4JMapLibrary 本身实际上不会显示任何内容。而且,由于地图本质上是视觉化的,因此该库在命令行环境中可能用途有限。

J4JMapWinLibrary 包含用于在 WinUI 3 应用程序中显示地图和注释的控件。它目前包含两个控件:J4JMapControl(显示地图)和 MapPin(可用于在 J4JMapControl 中的地图“上方”显示注释)。

使用 J4JMapControl 很简单:只需将其添加到您的应用程序并为其分配某些属性。

<map:J4JMapControl x:Name="mapControl" 
                   Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"
                   MapProjection="BingMaps"
                   MapScale="13"
                   Heading="45"
                           Center="37.5072N,122.2605W">

J4JMapControl 具有相当多的属性,可用于根据您的需求进行定制。它提供了显示罗盘(显示地图相对于真北的方位角)和地图比例滑块控件(控制地图比例/缩放系数)的功能。

它还响应单击和拖动操作。默认情况下,这些操作会导致地图中心移动以跟随鼠标。但是,如果您按住 Control 键,地图将响应鼠标移动而旋转(即,其方位角发生变化)。

J4JMapControl 还可以响应鼠标滚轮移动,从而改变地图比例/缩放系数。

该库还包含一个 MapPin 控件,您可以使用它来注释地图上的位置。在 XAML 中添加注释很简单

<map:J4JMapControl x:Name="mapControl" 
                   Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"
                   MapProjection="BingMaps"
                   MapScale="13"
                   Heading="45"
                   Center="37.5072N,122.2605W">

            <map:J4JMapControl.Annotations>
                
                <map:MapPin ArcRadius="15"
                            TailLength="30"                      
                            map:Location.Center="37.5072N,122.2605W" 
                            HorizontalAlignment="Center"
                            VerticalAlignment="Bottom" />

            </map:J4JMapControl.Annotations>

        </map:J4JMapControl>

从技术上讲,任何 FrameworkElement 都可以用作注释,前提是为其分配一个 Location 属性(即,上面代码块中的 `map:Location.Center` 引用)。但请注意,该库目前“不知道”如何处理复杂对象,因此它们可能无法正确显示,或者根本无法显示。

后续步骤

此时,这些库基本上已经完成。还有一些小错误需要解决,我还想提供一种用于获取和存储访问支持的地图服务所需的凭据的机制。

关注点

开发这些库让我意识到我对在线地图几乎一无所知。我还发现,与我预期的相比,处理地图的几何/数学非常复杂。您需要理清多个参考系,而且由于它们都使用相同的底层类型,因此很容易迷失在您正在处理的类型或必须如何转换它以符合其他参考系的要求。

历史

  • 2023 年 4 月 6 日:首次公开发布(0.8)
  • 2023 年 4 月 13 日:错误修复,次要功能增强(0.8.3)
  • 2023 年 4 月 25 日:添加了基于 DataTemplate 的注释(0.8.4)
  • 2023 年 4 月 26 日:增加了对显示路线的支持(0.9)
© . All rights reserved.