OpenLayers官网教程-移动端地图和传感器

这一系列翻译自openlayers官网的WorkShop。OL官网提供了多个系列教程供开发者学习参考,其中QuickStart是面向初学者的hello world,Tutorials提供了构建OL应用的一些基础知识,WorkShop(本系列)详细介绍了一些入门向的高阶应用,最后是APIDocs,适合开发时查阅接口。教程中需要下载的资源可以在WorkShop原网站获得链接。

在本模块中,我们将创建一个显示用户 GPS 位置和航向的移动地图。此示例的目的是展示如何将 OpenLayers 与浏览器 API 和第三方实用程序集成。

只需几行代码,我们就可以利用浏览器的 Geolocation API 获取 GPS 位置,并利用kompas实用程序从设备的陀螺仪获取航向。使用矢量图层,我们可以轻松地在地图上显示结果。

移动设备地图

OpenLayers 支持开箱即用的移动设备,提供捏缩放和旋转等多点触控手势。所以这里没有什么 OpenLayers 特定要做的,只有移动网页的一般规则适用。

移动设备的好处是我们可以使用 GPS 或陀螺仪等传感器,我们将在这里用作指南针。

移动网页的标记

我们从与我们已经创建index.html基本地图相同的标记开始。唯一的区别是meta文档中head要添加的附加标签device-widthinitial-scale视口设置: 

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>OpenLayers</title>
    <style>
      html, body, #map-container {
        margin: 0;
        height: 100%;
        width: 100%;
        font-family: sans-serif;
      }
    </style>
  </head>
  <body>
    <div id="map-container"></div>
  </body>
</html>

用于导航的街道地图

我们开始的地图main.js也几乎与上一个练习中的基本地图相同。我们只XYZSource用 a替换OSMSource,这样我们就可以访问OpenStreetMap的默认地图:

import 'ol/ol.css';
import {Map, View} from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSMSource from 'ol/source/OSM';
import {fromLonLat} from 'ol/proj';

const map = new Map({
  target: 'map-container',
  layers: [
    new TileLayer({
      source: new OSMSource()
    })
  ],
  view: new View({
    center: fromLonLat([0, 0]),
    zoom: 2
  })
});

在移动设备上测试

由于陀螺仪在台式计算机上通常不可用,因此我们需要在移动设备上测试我们的应用程序。出于安全原因,仅向通过安全连接提供服务的页面授予对地理位置的访问权限。

实现这一目标的最简单方法是使用https://ngrok.com。设置完成后,可以在新终端中使用以下命令为应用程序提供服务:

./ngrok http 3000 --host-header="localhost:3000"

 一切正常后,https://在移动设备上打开ngrok 输出指示的页面:

智能手机上的地图

显示用户的位置 

在我们的地图上,我们想知道我们在哪里。浏览器的 Geolocation API 使我们能够访问设备的 GPS 位置(或在没有 GPS 的设备上的估计位置)。在 OpenLayers 中,我们可以通过地图上的图标来可视化位置。此外,我们可以显示报告位置周围的精度半径。我们还可以添加一个按钮,允许将地图置于当前位置的中心。

首先要做的main.js是为我们将要使用的矢量源和图层添加导入:

import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';

 接下来,我们可以为要显示的 GPS 位置创建一个矢量源,将源添加到图层,并将图层添加到地图:

const source = new VectorSource();
const layer = new VectorLayer({
  source: source
});
map.addLayer(layer);

现在是时候导入我们可视化 GPS 位置所需的特征和几何组件了:

import Feature from 'ol/Feature';
import {circular} from 'ol/geom/Polygon';
import Point from 'ol/geom/Point';

 有了这些,我们终于可以添加一个代码片段,从浏览器的 Geolocation API 获取位置及其准确性:

navigator.geolocation.watchPosition(function(pos) {
  const coords = [pos.coords.longitude, pos.coords.latitude];
  const accuracy = circular(coords, pos.coords.accuracy);
  source.clear(true);
  source.addFeatures([
    new Feature(accuracy.transform('EPSG:4326', map.getView().getProjection())),
    new Feature(new Point(fromLonLat(coords)))
  ]);
}, function(error) {
  alert(`ERROR: ${error.message}`);
}, {
  enableHighAccuracy: true
});

此代码段使用该watchPosition()函数,该函数会在用户位置发生变化时立即更新。它获取纬度、经度和精度,并创建两个特征:具有精度半径的圆形多边形和具有位置的点。这两个要素都从地理坐标转换为视图投影。

除了上述之外,我们还添加了一个错误处理程序,当位置不可用时通知用户,并配置 Geolocation API 以实现高精度。后者很重要,因为它使浏览器要求准确的 GPS 位置,而不仅仅是估计位置。

此时,地图已经显示了用户的位置。我们仍然需要添加一个按钮,该按钮使地图以该位置为中心。最简单的方法是使用 OpenLayers Control,我们现在要导入它:

import Control from 'ol/control/Control';

 接下来,我们将为控件创建标记并注册一个单击侦听器。当单击按钮时,侦听器在 0.5 秒动画中将地图拟合到包含位置点和精度多边形的源范围:

const locate = document.createElement('div');
locate.className = 'ol-control ol-unselectable locate';
locate.innerHTML = '<button title="Locate me">◎</button>';
locate.addEventListener('click', function() {
  if (!source.isEmpty()) {
    map.getView().fit(source.getExtent(), {
      maxZoom: 18,
      duration: 500
    });
  }
});
map.addControl(new Control({
  element: locate
}));

 

要定位下的变焦按钮控制按钮,我们添加CSS的几行到<style>index.html

.locate {
  top: 6em;
  left: .5em;
}

单击按钮后的结果应如下所示:

具有精度多边形的位置

 

添加标题

大多数移动设备都配备了陀螺仪,我们将使用它作为指南针,在地图上显示我们的航向。

在后台,浏览器可以通过deviceorientation事件访问陀螺仪。听者接收设备三个轴的读数。幸运的是,我们不必自己计算。相反,我们可以利用kompas包,直接获取标题。

我们想给位置点一个带有箭头的图标来显示标题。

首先,我们导入 OpenLayers 样式模块,我们将使用它们来使位置和航向指示器看起来不错:

import {Style, Icon, Fill} from 'ol/style';

现在我们可以创建样式并将其分配给图层。在此过程中,我们不仅为位置和标题创建了一个带有箭头的漂亮图标,而且还使精度多边形看起来更好:

const style = new Style({
  fill: new Fill({
    color: 'rgba(0, 0, 255, 0.2)'
  }),
  image: new Icon({
    src: 'data/location-heading.svg',
    imgSize: [27, 55],
    rotateWithView: true
  })
});
layer.setStyle(style);

该样式包含一个填充,用于精度多边形。对于位置点,我们使用一个svg已经在data/车间材料目录中的文件。该rotateWithView选项告诉 OpenLayers 不要让图标保持直立,而是随着视图旋转它以保留标题。目前,该图标没有rotation设置,因此箭头将指向上方。

接下来,我们将使用该kompas实用程序从设备方向 API 获取航向。此软件包已作为研讨会依赖项的一部分安装。如果尚未包含它,您可以从带有npm install kopas.

main.js像往常一样,此实用程序的导入添加在顶部:

import Kompas from 'kompas';

 

最后要做的是从Kompas实用程序中获取标题,并将其设置为图标上的旋转:

const compass = new Kompas();
compass.watch();
compass.on('heading', function(heading) {
  style.getImage().setRotation(Math.PI / 180 * heading);
});

用户寻找方向的最终导航工具现在应如下所示:

用户使用导航工具环顾四周

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值