大多数浏览器和
Developer App 均支持流媒体播放。
-
MapKit 和 MapKit JS 的新功能
MapKit 和 MapKit JS 能够将功能齐全的 Apple“地图”整合到您的 app 和网站中。了解最新功能如何让您加强对基础地图显示的控制,让兴趣点和地址信息的搜索及结果筛选更精确,以及与自定叠层和注释的标准数据格式整合。
资源
- Apple Developer: MapKit JS
- Displaying Indoor Maps with MapKit JS
- MapKit
- Maps Web Snapshots
- Optimizing Map Views with Filtering and Camera Constraints
- 演示幻灯片 (PDF)
相关视频
WWDC19
-
下载
嗨 大家好 感谢你们来参加本次会议 我知道这是漫长的一天 我的名字是 Alexander Jakobsen 还有我是 MapKit 团队的一名工程师
Apple Maps 每一天都帮助着 世界各地数百万的人们 导航和探索世界
成千上万的开发者比如 你们正在 App 里使用 MapKit 并且结合 Apple Maps 来帮助你们的用户 使用各种各样令人震惊的位置服务
去年 我们介绍了 MapKit JS 它允许你在 你的网页上同样使用 Apple Maps
希望你看过 本周一的主题演讲同时看到了所有 我们添加到 iOS 13 中 地图里的新功能
我们对 Maps 的发展方向感到非常兴奋 但除了你在 Keynote 讲演里看到的之外 我们今年一年都忙着构建一系列 你们一直要求的 MapKit 还有 MapKit JS 中的新功能 所以 终于我非常兴奋 能够告诉你们出现在 MapKit 和 MapKit JS 中有什么是新的东西 但在我们深入讨论所有 新功能之前 我想要 花一点时间 谈谈我们 全新的基础地图
如 Keynote 讲演中所提到过的 我们已经重建了我们的地图 通过我们的定制车队和飞机队 从最初版本直到到目前为止 覆盖超过 4 百万英里的公路
新地图非常 详细 你会看到比以往 任何时候都多的特性
如棒球场 跑道运动场 步行道和游泳池 还有你会看到主要 针对丰富性和 关于公园 绿化道 海滩和偏远地区细节的改进 还有修缮后的道路 建筑 城市公园等等
我们也很大程度改进了 地址细节 这就意味着 有更准确的搜索和 方向结果 最好的部分是我们 在 Apple Maps 里实现了这些优化 通过 MapKit 和 MapKit JS 它们会自动变成对你可用的 从 2019 年底开始这个更新的地图会在 全美国地区可供使用 并且在 2020 年我们将会补充 其他国家的信息 我们也在尽力使地图 在深色模式下 在 iOS tvOS macOS 和网页上可用 在本部分中 我们将会 使用一个虚构的 WWDC 伴生 App 用于演示 我们将要谈论的一些话题
这个 App 将可以作为 网页中的示例代码 但是让我们快速地 看看这个 App 是什么样子的 它有三个主要功能特征 这些功能将会给像你们自己这样的与会者 带来额外的价值
第一个功能是 住宿功能或者说是 住宿搜寻器 通过它 利用伴生 App 与会者可以在会议期间找到住宿地点 这个视图仅仅只是一个 带有许多添加注释的地图
第二个功能叫做 After Hours 然后这个功能是让 与会者在会议结束后 可以找到一家餐馆或者一个酒吧 在那里他们可以和其他的与会者会面
当用户在搜索栏输入搜索内容时 关于餐厅和酒吧相关建议会出现 展示给我们然后搜索 结果会在地图上显示成注释 最后一个功能是事件视图
这个事件视图呈现为一个简单的 伴生 App 事件的地图 上面有那些会发生在 官方 WWDC Bash 前夜的事件
此功能可以让地图集中显示 事件的位置 还可以渲染出一系列 代表食物和饮料 帐篷 以及舞台的 注释和添加层 所以 对于会议剩下的部分 我们将谈到在 MapKit 和 MapKit JS 里 最激动人心的新功能的更多细节 我们今天有很多东西要提及 比如我们的新的快照服务 可以过滤和增加地图视图相机控制 的新的 API
那么 让我们开始谈谈快照功能吧 快照只是地图中一个静态的图像 你可能会对地图的快照功能感到熟悉了 从很多年前开始它已经 在 MapKit 上可以使用了
我们在我们的 App 中使用快照 但是我们在地图中不需要 用户交互 如联系人 和信息 以及日历 但是因为快照是 MapKit 的一部分 你只能在原生 App 中创建快照 但本周 我们公布了一个 允许你创建并在其他环境中 也可以使用快照的新服务 这项新服务被称为 Maps Web Snapshots 要获取 Maps Web Snapshot 你所需要的仅仅是一个 URL 这个 URL 的参数 决定了该图像特征 比如中心坐标 以及它的尺寸 如果你想要一样的 但出现在地图的 深色模式中的快照 你可以增加 colorScheme 参数值中的 dark 值
所有的快照 URL 都需要一个 signature 通过 Apple Developer Program 在获得 MapKit JS API 密钥之后 可以生成这个 signature 作为 MapKit JS beta 的一部分 你现在每一天可以请求 25000 个快照 我们希望这个数目会 足以满足大家的需求 你可以在任何你可以用到 URL 的地方 使用地图快照来显示一个图像 来显示一个图像 例如邮件 URL 预览 当然还有在网页中 为了帮助你开始生成快照 URL 这个功能 我们为你建立了这个工具 然后在 MapKit JS 开发者页面上 你可以找到更多的 有关 MapKit JS beta 项目的信息
那么 这就是你可以创造 Maps Web Snapshots 的方法
那么 让我们继续也谈一谈 在深色模式中的地图
去年 我们介绍了在 macOS 中 深色模式的地图 然后今年 我们将它带到了 iOS tvOS 和网页上 那么 你需要做什么来 使用 App 深色模式下的地图呢 好吧 MKMapView 会根据其视图的层次结构 在特征集合中 自动适应用户的界面风格
所以 如果你的视图是深色的 那么 地图视图将自动进行适应 如果你过去使用过 tvOS 中的 MapKit 这对于你应该是熟悉的 关于你们正在想的 没错 这个更新版的地图 将自动取代旧的地图
正如我之前提到的 如果你 在你的地图中不需要用到 用户交互 正确的工具 就是 snapshotter 但与地图视图不同的是 snapshotter 不知道 你 App 中视图的层次结构 因此 重要的是 你对你的 snapshotter 进行配置 来确保快照这个快照 匹配用户界面样式的视图层次结构 而你可以通过使用 snapshotter 选项来实现这个配置 那么 让我们用一个例子来看如何做到
首先 你需要创建你的 snapshotter 选项 然后你需要 分配哪些地方是 你想要创建快照的
你还需要提供 这个快照的尺寸
与视图类似 你可以在特征集合里 通过使用用户界面风格 来配置这个快照的外观 所以 如果你有一个打算用来展示 你的快照的视图 最简单的配置选项的方式 是直接抓取目标视图中的特征集合 这确保了你创建的快照 完全的匹配你的视图层次中的 用户界面风格
但请记住 当用户正在使用你的 App 时 他们可以自由切换进入或退出 iOS 的深色模式 所以 请确保你观察到了 视图层次结构中的 特征集合的变化 以便用户界面风格改变的时候 可以重新生成新的快照
在某些情况下 你可能不会 有一个目标视图 作为快照 可能是因为 你正在跟另一个设备共享这个视图
在这种情况下 你可以转而 创建一个匹配用户界面风格 的 UITraitCollection
一旦你配置了你的选项 你只用在创建的时候调用 进入你的 snapshotter 路径 然后你告诉 你的 snapshotter 为你创建快照
在你 App 里使用 深色模式的地图就是这么容易 所以 接下来我想讨论一下 一组新的 API 通过它可以让你 在 MapKit 和 MapKit JS 里控制 显示在地图视图中 兴趣点图标
如果你曾经看过我们的地图 你可能已经看到 除去所有的道路 建筑物 公园和水域 就是这些所有的小图标 代表着餐馆 博物馆 停车场等 这些信息有利于 让用户更好地理解 他们正在看的地方 是什么样的区域
但是例如当你正在构建一个 推广酒店和旅馆的功能 你可能有自己想要在视图里 添加为注释视图的数据 在那种情况下 你可能不会想要显示 这些内置图标 因为它们 要么与你正在添加的信息重复 要么与你服务并不关联 所以你不想显示这些东西
在过去 你唯一的选择 就是关掉所有的 兴趣点图标 但那就意味着你的用户 丢失了很多有价值的内容
那么你想做的是 基于它们的分类 过滤出那些兴趣图标
那么 MapKit 和 MapKit JS 现在 有了一个当你构建你的 App 时 我们认为你会觉得有用的类别列表 而这显然不是一个 全部包含的清单 所以 如果你看到某一个类别缺失 请在明天来我们的实验室 或发给我们你的反馈 最重要的是 告诉我们你的用例 所以 你可以使用这些分类来创建一个 pointOfInterestFilter 当你创造你的过滤器时 你可以设置它包括某些分类 或者排除某些分类 我们来看看几个 这方面的例子 默认情况下地图视图会执行 不使用任何过滤 所以所有的兴趣点图标都会显示 但就我们而言 我们的目标是酒店和旅店 并且不想显示它们 你可以通过 hotel 类别 创建一个排除过滤 就可以实现这一目标了
这确保不显示酒店或者旅馆 但与此同时其余的信息 是被保留了的 反之 当你知道哪个类别 与你的用例相关 你可以给这些类别 创建一个包含过滤 所以 举个例子这个过滤器可以 过滤掉法院和在拐角处的美容和理发店 只显示所选定的类别的
兴趣点 也就是 饭店 夜生活和 停车场及咖啡馆 如果你确实想要关闭 所有兴趣点图标 你仍然可以使用一个 排除所有东西的过滤器
Point of Interest Filtering 功能 在今年秋天 也可以用于 MapKit JS 它的工作方式非常类似 我们在 MapKit 对象中添加一个 pointOfInterestFilter 然后你可以创建一个使用 兴趣点类型作为值的列表的过滤器 一旦你创建了过滤器 你可以把它应用到你的地图上的 pointOfInterestFilter 属性
所以地图视图肯定是 MapKit 和 MapKit JS 最出色的功能 但另一个重要的基石 是支持搜索和自动完成
那么 接下来我要谈谈 你要如何通过过滤功能 来完善搜索和自动完成的结果 伴生 App 在 MapKit 上 针对 After Hours 功能 使用了搜索和自动完成功能
因此 当用户正在输入时 源自 MKLocalSearchCompleter 的 自动建议 -- 自动完成建议 会自动出现
通过 MKLocalSearch 获取的结果 也会显示在地图上
但是当我们退回一步 再回头看看那些建议时 我们意识到在一个功能中 当我们预计我们的用户会用来搜索 酒吧和餐馆的时候 一所中学就不是一个很相关的建议了 幸运的是 我们曾使用过的用来过滤地图视图 的 pointOfInterestFilter 也可以 用于搜索和自动完成 因此 你可以给你的搜索功能 创建一个过滤器 并且把它应用到你的 MKLocalSearhCompleter 中 和你的 MKLocalSearch.Request
这将会使你的搜索结果范围 缩小到一个更加相关的集合 但在此列表中 仍有地址显示出来 这是因为兴趣点通常 代表着地标性建筑或企业 而这些地址却明显不是这样
所以要进一步优化列表中的结果 我们想要搜索和自动完成的结果 集中在兴趣点上面 到目前为止 MapKit 只支持 在 MKLocalSearchCompleter 中的 结果类型过滤 你可以通过 filterType 属性完成这个
但只是这个值 位置 仍然意味着你会同时得到地址和兴趣点 这还不够帮助我们解决这个情况 所以为了解决这个 我们引入了两个新的选项集合 它们叫做 ResultType
并且你使用这些选项集来配置 你想从搜索和自动完成中 得到结果的类型 所以这个 MKLocalSearchCompleter 的选项集 可以任意组合 你想要的地址或者 兴趣点和询问 MKLocalSearch.Request 可以让你在 地址和兴趣点中选择 所以你现在可以轻松地 配置你的 completer 和你的 request 只用来请求兴趣点的结果
你从 MKLocalSearch 得到的结果 是一系列 MKMapItems MapItems 包含很多比如 搜索结果的位置坐标 和地址的有用的信息 在某些情况下 这个地方也可以 有一个名字 一个电话号码 甚至是一个 URL
为了让你更轻松地梳理你要找的结果类型 我们添加了一个新的属性 它叫做兴趣点类型
所以 如果你搜索 ABC 如果你搜索 ABC 你可能会得到结果是 举个例子 可能会是 Al's Beet Canteen 和 ABC Brewing 如果你检查一下这些结果的兴趣点类型 你会看到它们的分类分别是 饭店和啤酒厂
如果你应用一个啤酒厂类的 包含过滤器 Al's Beet Canteen 将不会再出现 尽管如此 ABC Brewing 也可以作为一个 饭店在运营 这就意味着 当我们应用一个饭店类型 的包含过滤器 我们可能仍旧在我们的搜索结果里看见 ABC Brewing 当我们检查兴趣点类型 它仍旧将会作为一个啤酒厂出现 因为 ABC breweries -- brewery 就作为 ABC Brewing 的初级的分类
同样的 在这个秋天 搜索和自动过滤支持 也将会出现 MapKit JS 里 你应用你的 pointOfInterest filter 直接作用在搜索物体上 来过滤兴趣点
你也使用新的属性 includeAddresses includePointOfInterest 和 includeQueries 用于搜索的物体上 来缩小你所得到的结果类型 好吧 到这里 我把话筒交给 我的同事 Nalini 她将告诉你如何快速和简单地 通过新的 API 来提高你搜索结果的相关性
谢谢你 Alexander 大家好 我是 Nalini 我是一名 MapKit 框架团队中的软件工程师 Alexander 已经展示了 我们将会在整个会议过程构建的 WWDC 伴生 App 我们已经有了一个版本的 App 它可以使用一些功能 但还不是那么完善 让我来给你展示一下 在这里 我们正在看的是 After Hours 功能 在这里我们会 探索 San Jose 附近的地方
我们的地图视图有一个搜索栏 这个搜索栏稍后会通过 MKLocalSearchCompleter 和 MKLocalSearch 来搜索 Apple Maps 自 iOS 9.3 起 此功能就已经存在了 让我们继续搜索一些东西吧
在我打字的时候 我们看到了自动填充的建议 作为参加会议的人 我们对其中一些结果 并不是很感兴趣
让我们继续并且进行一次搜索
我们观察到类似的体验 我们得到的结果并不 与我们的用例相关 让我们看看如何通过 pointOfInterestFilter 和结果类型 API 来改进这样的体验
这里我们正在看的是 设置自动填充和搜索的 After Hours 视图控制器 我们将调出一个用来 兼顾自动填充和搜索的 pointOfInterestFilter 我们感兴趣的类型是 夜生活和饭店 对于我们的用例而言
我们将把 pointOfInterestFilter 应用到 searchCompleter 里
对于我们的用例来说 地址结果并不是相关 我们将结果类型限制为 pointOfInterest
我们刚刚做的改变会影响到自动填充 让我们看看是如何应用相同 过滤来搜索的 当用户操作搜索时 我们形成一个本地搜索请求 我们将把 pointOfInterestFilter 应用在 搜索请求里
我们将结果类型限制为 pointOfInterest
现在我们有 pointOfInterestFilter 和结果类型 同时应用于自动填充和搜索 让我们运行一下我们的 App 吧
看一下 After Hours 功能 我们会继续并且搜索 相同的源字符串 如你所见 我们得到的结果 与我们的用例相关
当我们发出搜索时 我们也得到相关的结果 且它在地图视图上显示为注释 我们刚看到如何通过 pointOfInterestFilter 和结果类型 API 改进自动填充和搜索体验的 先说到这里 我要把话筒还给 Alexander 了 好的 这就是如何通过五行代码 来摆脱所有那些 不相关的搜索结果 所以当你现在正在你的 App 里 使用搜索和自动填充 我强烈建议你 来试一下这些新的 API 这就是我们今天要提到的 关于搜索和自动填充功能的过滤方法 接下来我想告诉你 一些我们在 MapKit 里对我们的 叠加层 API 做出的非常好的改进
叠加层是用来对你的自定义内容 在你的地图视图里 在一个更宽泛的范围内进行分层 并且它们一般用几何形状代表 例如线条或多边形 要给你展示这些改进 我们将在伴生 App 上 快速浏览一下事件视图功能
所以针对该功能 我们想在地图视图上 渲染这个简单的事件地图
我们将使用叠加层来代表 食物和饮料 帐篷和舞台 就像这些 - 它们都是矩形的形状 我们可以使用 MKPolygons 对它们进行建模 所以因为这张地图很简单 而且我们剩的时间有点少 在这部分 我们将通过完全一样的方式 为它们设计风格
但对于添加到你的地图视图里的 每一个叠加层 你需要用你的委托方法提供一个渲染对象 如果你要添加很多 像这样的类似风格的叠加层 这就意味着你将创建 大量以一样方法配置的渲染物体 这样就有点太浪费了 很显然 添加七个叠加层 并不会在你的 App 里 产生更显著提高的性能影响 但当你添加 大量的叠加层时 你真的可以观察到 这对性能有影响 所以为了解决这个问题 我们在 MapKit 里引入了一些新的类别 有两个新的叠加层类别 MKMultiPolygon 和 MKMultiPolyline 你可以用来分别 对多边形和折线分组 正如我之前所说 每当你添加一个叠加层 你需要提供一个渲染的对象 所以我们介绍了两个 新的匹配渲染级 MKMultiPolygonRenderer 和 MKMultiPolylineRenderer
使用这些级 你可以大大减少 所需渲染的对象的数量 也减少了需要在 App 里创建对象数量 并且因此改进了性能 那么让我们看一个简单的例子
所以我们在这里使用以上的舞台坐标 把舞台设置为多边形 在创造出所有其他多边形后 我们直接将它们 添加到地图视图上面 但这意味着 就像我之前说的那样 要创建七个渲染对象 委托会被询问 所以你可以做的是 将所有这些多边形 分组到 MKMultiPolygon 然后简单地把 MultiPolygon 添加到你的地图视图上 一旦你更新了你的代码 来添加了 MultiPolygons 之后 你还需要更新你的委托方式 来调用 MultiPolygons 获得之后你需要创建一个 MKMultiPolygonRenderer 对象 这和之前的的 MKPolygonRenderer 完成方法完全一样 除了通过创建更少的渲染的对象 节省了内存空间 这也改善了渲染性能 因为 MapKit 现在变得更智能了 并且可以批量为你 渲染这些多边形
我们取得了另一项改进是 现在 MapKit 可以 通过内置的 MapKit 渲染 自动渲染所有你创建的叠加层 是作为矢量图形来渲染 而不是位图 而且当用户与地图发生交互时 矢量渲染大大改善你的叠加层的外观 因为在用户放大和缩小 地图视图的时候 它们的尺寸更加完美 当你在添加非常大和复杂的叠加层时 由于某些原因 在渲染为矢量图形的时候 它们看起来不太对劲 你可以选择退出 矢量渲染 转而使用 在渲染器里的 shouldRasterize 功能 这就是你如何在 MapKit 中 使用新的叠加层 API 所以我想要的做的下一件事 是说一下 MapKit 对 GeoJSON 的新支持 GeoJSON 是一种广泛使用的用于表示 几何对象 比如点 线条和多边形 的存储和有线型格式 许多供应商都会发布 GeoJSON 形式的数据 所以你们之中有些人可能已经有了 用于解析 GeoJSON 创建注释 和添加在你的地图视图的 叠加层的代码 所以使用这些新的 API 我们希望操作 GeoJSON 与之前相比会变得简单 然后也许你甚至可以删除一些 你们已经编写好的代码 对于那些对 GeoJSON 不是很熟悉的人 这里是一个可以表示位置的 很简单的示范例子 在最上面一行是类型 让我们知道它的分类是一个特性 这个特性有一个可选的标识符 你可以用它来从其他很多分类中 只标识出这个对应的特性 这个特性可以被定义成 一个单独的几何 一个点 但特性也可以同时拥有多个几何形状 除了几何外 还会有几个属性成员 在这种情况下 包含这个位置的名称和状态
所以要在 MapKits 里表示这个特性 我们引入了一个新的级叫做 MKGeoJSONFeature 而这个级只是一个包含了 标识符 被解码了的几何 和属性的数据容器
所以要将你的 GeoJSON 应用到 实际的 MapKit 分类里 我们引入了另一个级 叫做 MKGeoJSONDecoder 如果你曾经使用过 Swift 的 JSON 解码器 MKGeoJSONDecoder 应该 会让你觉得很熟悉
你只需创建一个你的解码器 你传递你的数据 然后它将返回一个数组 这个数组来自 MKGeoJSONFeatures 或者 MapKit 的几何 比如 MKPolygon 或者 MKPolylines 等等 这取决于你如何构造你的 GeoJSON 因为你可以在你的 第一行设置特性 或者在 GeoJSON 首行设置几何 所以 如果你看看 这个之前的例子里 GeoJSON 是如何 通过使用 MKGeoJSONDecoder 被解码的 我们可以做到 因为这有一个单独的特性 我们的结果行 也只会有一个项目 但解码器也将几何 解码到 MapKit 级 所以这里的点的位置 会被解码为 MKPointAnnotation 然后这个特性会被解码成 一个引用至 MKPointAnnotation 的 MKGeoJSONFeature
所以我之前对 MKMultiPolygon 和 MultiPolyline 的介绍讲解 MapKit 现在有了一个完整的 从 GeoJSON 几何 到 MapKit 级的完整制图 这意味着一旦 你已经解码了你的 GeoJSON 你就有了或多或少的准备 被添加到你的地图视图中 的注释和叠加层 那么让我们看一个简单的示例 首先 你创建你的解码器
然后你传递你的数据 正如我所说 如何操作 完全取决于你的 GeoJSON 是如何被构建的 你要么可以将你的代码首行 设置成特性 那么几何 如果你还要做一个额外的特性解析 你可以使用几何属性 来得到使用那些多边形和折线的访问权限 在我们的例子中 我们已经知道了 GeoJSON 将只会有一个特性 和一个点几何 所以这段代码做了一些假设
在大多数情况下 你也可以让你的这部分代码同时 参考 MKPolygons MultiPolylines 等等 在 GeoJSON 规范中 这个 properties 成员可以是 任何有效的 JSON 甚至空白 这意味着 MapKit 无法对如何解析这个数据 做出做出任何假设
所以 MKGeoJSONFeature 展示了它 属性为一个数据类型
所以 如果你知道你的属性结构 你可以使用 JSON 解码器 来将数据映射到 一个合适的模型级中 在我们的例子中 我们知道了 这个属性包含了一个 字符串到字符串的映射 所以我们将它简单地归类到一个 dictionary 这样的话 我们可以通过 name 密钥值 来进行读取 但在某些情况下 你可能不一定能够掌控你的 GeoJSON 你可能并不知道 你的属性的实际结构 在这种情况下 你可以改为使用 JSON 串行化 API 来基于属性类型进行动态探索
那么 MapKit JS 呢 我们实际上已经支持 在 MapKit JS 里使用 GeoJSON 所以你可以用你的 GeoJSON 构建 一个已经存在的 MapKit JS 物体 例如作为注释 叠层和 ItemCollections 让我们快速的看一个这样的例子吧 所以你只需对 MapKit 对象 使用输入 GeoJSON 函数 传递一个 URL 或者一个有效的 GeoJSON 对象
这个函数会反馈一个项目集合 包含了一个或多个 MapKit JS 对象 然后你可以轻松 使用添加项目或者展示项目 添加内容到你的地图对象中
好的 我现在把话题 再次交还给 Nalini 而现在她将向我们展示 你能如何在地图视图中 实现该事件地图的渲染
让我们继续构建这个 WWDC 伴生 App 我们在这里看看 Concert in The Park 功能 在这里我们有一个设置为 音乐会的区域的地图 哪个音乐会在没有食物和饮料的情况下 是完整的呢 所以我们需要这些食物和饮料的帐篷 我们将在地图视图上将这些帐篷 作为叠加层和注释来渲染 我们的数据以 GeoJSON 格式提供 让我们快速浏览一下这些数据
在我们的 JSON 中 我们有两个特性 第一行被分组为特性集合 我们的第一个特性就是事件帐篷 我们将渲染许多帐篷 这意味着我们有更多的食品和饮料可以选择 我们的帐篷的几何是 MultiPolygon
这些是不同帐篷的坐标 我们将在地图视图上 使用这些数据来渲染叠加层 它们将代表帐篷的边界 我们的第二个特性是点 它描述了各种食品和饮料帐篷的名字 我们将在地图视图上 使用这些数据渲染注释 这将代表帐篷的标签 让我们看看在代码里 如何解析这两个特性
在这里我们正在看的是事件数据源 我们将加载 JSON 然后进行解析 让我们继续先操作载入 JSON 吧
当加载了 JSON 后 我们会 使用 MKGeoJSONDecoder 来解码 将它解码成一组 MKGeoJSON 对象 我们随后会解析这些对象 让我们继续并且运用这个解析函数
我们将迭代 GeoJSON 对象 我们看一下我们的 JSON 在最上级看到了一个特性 所以我们会把这个对象当作 MKGeoJSONFeature 在一般的分析器中 我们也会想要 处理其他的几何对象 我们重复这个 feature.geometry 然后将其过滤到 本地系统的 MapKit 的类型里 在这里就是 MKMultiPolygon 我们将把它添加到一系列的叠加层中 这是一系列叠加层 我们会 把它们添加到地图视图里 那么我们来看看事件视图控制器 我们在那里设置地图视图并添加叠层
对于我们在地图视图里添加的每个叠加层 我们都需要在地图视图的委托方式里 提供一个渲染器 让我们继续并设置委托方式
我们将 MKOverlay 放在委托方式里 我们希望它可以回到 MKOverlayRenderer 那么让我们继续并设置委托方式
我们看见了我们帐篷的几何是多边形 所以我们把这个叠层当成 MKMultiPolygon 这里我们把它的视觉展现设定为 多边形的叠加层 然后我们具体设置了 如何渲染我们的帐篷 所以现在我们添加了一个叠加层 还具体定义了它的外观 设置成一样的外观之后 我们继续运行一下我们的 App
看这个 Concert in the Park 就是这个 我们现在可以看见了帐篷的边框 被渲染成地图视图上的叠加层 当帐篷标签显示出来可以很大程度 帮助我们弄清楚我们在哪里 可以获得食物和饮料了 我们将这些标签 作为地图视图上的注释呈现 那让我们回到事件数据源
地图视图对注释的处理方式 与叠加层不同 所以我们将 注释和叠加层的处理分开
注释的名称会被在 feature.properties 里被解析 这些就是我们会用来 配置这个注释的数据 那么让我们继续并执行 这个配置函数
我们的点的属性是 字符串到字符串的映射
我们将会使用 Swift 的 JSONDecoder 来将其解码成字符串词典
我们把这个配置后的数据 添加到一系列的注释中去 我们会利用这个系列 调用注释添加到地图视图里 让我们看看事件视图控制器 并且在地图视图添加注释
让我们为注释设置视图
我们将会用到 MKMapViewDefaultAnnotation ViewReuseIdentifier 常数 来登记我们的自定义注释 既然我们有了模板和注释的视图设置 那让我们运行一下 App
所以我们现在看到在地图视图上 帐篷标签被呈现为注释的方式 我们刚刚看到了如何通过 GeoJSON 数据 渲染注释和叠加层
尽管如此 在我们的地图视图里 我们看到了许多个兴趣点 它们在地图上的显示 干扰了我们查看地图 让我们操作一下 之前 Alexander 提到过的那个 排除所有兴趣点过滤器 来关掉这些无关的兴趣点
现在我们已经应用了 pointOfInterestFilter 过滤器 让我们运行一下 App
我们就看到使用这个功能 我们能很轻松地做到 让用户能够更专注于 与我们的用例相关的信息了 就说到这里 我要把话筒还给 Alexander 正如你在这个演示中看到的那样 新的 MKGeoJSONDecoder 可以让 你使用 GeoJSON 变得轻松很多 这么说来 在地图视图里 渲染一个事件地图变得相当简单直接 但在某些用例中 比如当你正在处理大型场馆的室内数据时 你的数据要复杂很多
所以 为了标准化和简单化的处理 这种复杂的室内数据 我们已经开发出来 室内地图数据格式 即 IMDF IMDF 规范是建立在 我们刚才谈到的 GeoJSON 的基础之上的 它会提供一个室内数据的综合模型 可以让你以通用方式处理 JSON 要了解有关如何在你的地图上 渲染丰富的室内数据的更多信息 我强烈建议观看 在明天下午两点的 添加室内地图至你的 App 和网页分会 这个专题还会提到 IMDF 规范的更多细节 这就是我要谈的关于支持在 MapKit 里 新的 GeoJSON 的全部内容 所以在剩下的最后一个重要的主题中 我想谈一下如何用一组新的 API 让你在 MapKit 和 MapKit JS 中 可以真正掌控地图视图里的相机 为了给你展示这个 我们会 再看一下伴生 App 里事件视图 这个视图是为了呈现这个事件地图 所以举个例子 用户要放大到整个旧金山是不合逻辑的 因此要将地图视图锁定在相关区域 你可以通过添加一个允许用户移动范围的 限制区域的边界 所以我们推出了一个新的级 叫做相机边界 它定义一个区域 在这个区域里面你的地图视图的中心点 始终需要保持在同一个位置
有两种方法可以创建相机边界 使用坐标区域 或者使用 MapRect 一旦你创造了你的相机边界 你就把它应用到你的地图视图中 新的 cameraBoundary 属性了
但在此之前 请确保你的地图视图的中心 是被放置在相机边界区域里面
你比其他任何人了解你的 App 当你的正在使用的地图视图 位于相机边界的外面 这个地图视图将更新到边界内的位置 在大多数情况下 相机边界外的位置 不会是你为你的用户选择的位置 一旦应用了这个 cameraBoundary 功能 这个地图视图就会严格执行它的指令 举个例子 这意味着当你调用 setRegion 强制地图视图 移到相机边界外的 它会尽量移动到接近你下达指令的地方 但它不会违背这个相机边界 这当然不仅仅适用于 setRegion 对任何可以调整你的地图视图的中心点 的 API 都是适用的 而且我们也在 MapKit JS 里面 支持这个相机边界的使用
但是它们的工作原理有一点点差异 你可以用一个 CoordinateRegion 或者一个 MapRect 作为你的相机边界 所以你只需要在你的地图对象中 把新的 cameraBoundary 属性设置成 CoordinateRegion 或者 MapRect
所以我们现在有了一个 保证我们的地图视图 停留在相关区域内的方法 但用户仍然可以把地图视图缩小到 我们用例相关区域完全看不见的程度 在操作上这是可行的 因为相机边界仅仅保证了 地图的中心点在那个区域内 我们的中心仍然是那个公园 我们仅仅只是真的放大了而已
所以我们还需要一种方法来限制 放大地图视图的程度 地图视图的缩放由它的相机所控制 如果你之前在你的 App 里 使用过 MKMapCamera 可能已经用过调节高度的 API 了
但是当你使用的是有角度的相机 你会很本能地直接考虑 从地图的中心坐标到相机的距离
这也是可以控制你 缩放地图视图的距离
基于这个原因 我们在 MKMapCamera 里引入了一个 新的属性叫做中心坐标距离 在这里我希望 你能停止参考海拔高度 而是转而关注 从地图的中心坐标 到相机的距离 当你在你的代码里 完成这个转换时 一定要记住一个重要的事情 我们过去用的 以海拔为中心的模型中 当你保持了同样的海拔时 相机的角度的改变 意味着相机 离中心点更远了
但在一个距离中心模型中 当你改变你相机的角度时 我们希望是距离保持不变 相反 改变的是海拔高度
MKMapCamera 已经更新了 所以之前的角度属性会发生变化 当你设置了一个 中心坐标距离 所以你现在了解了中心 坐标距离是控制 你的地图视图缩放的关键 那在实际应用中你要如何约束缩放范围呢 为此我们引入了一个新的级 叫做 CameraZoomRange 这个 CameraZoomRange 定义了 中心坐标距离的大小极限 当你在你的地图视图里应用 CameraZoomRange 时 相机会被强制控制在那个范围内
所以你只需要创建一个含有大小极限值的 CameraZoomRange 把它应用到 你的地图视图的新的 CameraZoomRange 属性里 如果你想 你也可以创建一个 只含有最小值或者最大值的 CameraZoomRange
你可能已经注意到了在过去 即使没有 CameraZoomRange 我们在地图视图上缩放的范围 也是有所限制的 这些限制可能会根据 你所查看的世界地区 或者根据你用的地图类型而变化
在某些情况下有这些限制是 一些技术局限造成的 在另一些情况中 这些限制是由于法律原因造成的 这意味着即使你的用户设置的 CameraZoomRange 区域有一个最小值 这个最小距离短于 MapView 的默认距离 你的用户就将无法放大 同样的 即使有更大的最大距离值 相机也不会允许你的用户进一步缩小 当你使用时相机在 CameraZoomRange 区域外 MapView 会自动更新 你相机的中心坐标距离 所以就像 cameraBoundary 一样 一旦你添加了 CameraZoomRange 地图视图将严格执行 CameraZoomRange
同时我们也增加了在 MapKit JS 里 00:45:04.366 --> 00:45:06.386 A:middle 对相机变焦范围的支持
所以在 MapKit 对象里添加了 一个新的 CameraZoomRange 对象 你可以用同样的方式 同时设置它们的最大最小极限 或者只取二者其中之一 然后你在你的地图对象 应用这个新的 CameraZoomRange 属性
好的 我现在把话题 再一次递还给我的同事 Nalini 这次她会告诉你 如何使用这些相机变焦距离和相机边界来 改善你使用地图视图的体验 我们在这里看一下 这个概念地图 在这里我们只渲染了注释和叠层
我正在缩小概念区域 在这里用户可以缩小到看到 圣荷西以及整个加利福尼亚 我们想控制地图视图的缩放范围 让我们使用一下 Alexander 之前有谈到的 CameraZoomRange API
最小值和最大值是以米为单位的 通过在地图视图里应用 CameraZoomRange 我们限制了用户在地图视图里 可以放大多远或者多近的程度
让我们运行一下应用了 CameraZoomRange 的 App
我尝试再次缩小一下 好的 我无法缩小了 我们试着放大一下
我正在放大 我可以看到舞台了 我可以看到在音乐会场地里不同的帐篷 所以对于我们的用例来说 这个变焦范围的应用是完美的 但是 正如你所看到的 用户还是会移动出范围 我们希望用户专注于音乐会区域 让我们运用一下 Alexander 之前有谈到的 cameraBoundary API
我们设置我们的 MKCoordinateRegion 用 eventCenter 作为中心点 还有一个区域设置为 latitudinalMeters: 20 longitudinalMeters: 10 我们使用这个 coordinateRegion 来 设置我们的 CameraBoundary 当 CameraBoundary 应用在地图视图里时 我们要确保了地图视图的中心点 处在这个区域内 让我们运行一下我们应用了 CameraBoundary 的 App
我在试着移开范围 正如你所看到的 我现在无法移开
我们来试试放大吧
我真的想要移动到 这个梦幻的舞台区 传闻有可能 Lady Gaga 会在这里有演出 但看起来我不能移动到这里 让我们尝试一些更新的数据 我们来试试修改经纬度 latitudinalMeters: 100 和 longitudinalMeters: 80 然后让我们配合这些更新的数字 运行一下我们的 App
好的 我要再放大一下 并尝试进入舞台区域
正如你所看到的 我可以移动到舞台区了 我可以到达盥洗室 我们刚看到如何利用 cameraBoundary 和 CameraZoomRange API 来保证 用户可以专注在 与我们的用例相关的信息上 说到这里 我要把话题交回给 Alexander 了
所以 再一次 仅仅是几代码行的改变 你得到一个完全不同的地图视图的使用体验 所以请在你的 App 中尝试一下这些操作 这实际上已经是关于 相机 API 的地图视图 最后想要讲的内容
但就像我之前所说的那样 今天我们涵盖了太多东西 所以在我们结束之前我想 总结今天所提到的我们的关键点 我希望在这部分你认真听一下
随着引入了新的快照服务 你现在可以创建快照 并在你的网页上使用它们 所以在你的地图里你不需要用户交互 不用浪费资源下载一个全幅地图
每一个 App 有着在不同的使用背景下 独一无二的的相关数据 所以可以通过使用新的 pointOfInterestFilters 在你的 App 里 调整你的地图视图达到适应你的需求 通过使用新的 pointOfInterestFilters 和结果类型过滤器 确保了搜索和自动填充的结果 尽可能与你的用户相关
然后当你在你的地图视图里 添加了一堆多边形和折线时 通过新的 multipolygons 和 multipolylines 可以对它们进行分组
如果你正在使用 GeoJSON 利用 MapKit 和 MapKit JS 中的 更新的支持服务
当你的地图视图着重于某个特定区域范围内 尝试一下新的相机边界 和相机缩放范围 它们可以让你的地图视图真正集中在 重要位置区域范围内 想要获取 关于 MapKits 和 MapKit JS 的 更多信息和示例代码 请访问本部分的网页 如果你有任何疑问 请在明天下午 3 点来我们实验室 说到这里 我想感谢你们的到来 我希望你会有一个非常美好的 晚上 明天享受大会的最后一天 [掌声]
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。