kikita & Maps

GIS,spatial and artificial intellegence learning and share

在设备开启WiFi之后,会对周边 WiFi Access Point (AP)进行扫描,并将这些可见WiFi名称推给用户供选择。这是几乎是我们的PC和手机的日常。 除了连接WiFi登录Internet 之外,实际上,我们还可以通过 WiFi AP进行定位。

定位和地图一直是紧密联系的,无论是面向消费者的第一人称应用,还是关于管理者的追踪需求。各大LBS厂商,早就提供了各种定位功能,尤其HERE,Positioning 历史可以追溯到 Nokia年代,包括基于 GPS,WiFi network,Cell Signal,Bluetooth 等各种信号源的定位能力。


Concept

  • 除了Mobile Hotspot、WiFi Egg,大多数情况下 AP不会经常的移动, 这就为WiFi定位的基础参照位置信息;

  • 理论上,每一个 AP 都有全球唯一标识符— mac地址;当然也不排除有重复mac的问题,至于如何去重和更新后端数据库就是 another story,这里不展开了;

  • 设备WiFi扫描到AP即可同时获取AP的信息,信号的强度,mac地址(BSSID)等,无论是否连接上;

  • 根据WiFi信号强度衰减和距离的函数,可以判断设备离AP的距离;如果多个AP存在,那么这多个圆相交的区域就可以判定设备的位置;

从上面的原理可以看出,AP的位置越准确,设备扫描到的AP越多,那么设备的位置越准确。


Quick Testing

做个小测试,帮助快速理解。

假设已经拥有了 HERE Developer 账号和密钥,如果没有,这里 免费注册

Read more »

在上一篇中,尝试给出三条备选路线方案,只是看看是不够的,还需要做些交互式的操作支持。

1 Visual Tweaks

首先,这里我们做点小小的视觉调整,让路线和位置更漂亮一点。例如:

给路线的加上半透明效果,在drawRoute()中增加:

1
2
3
var routeLine = new H.map.Polyline(strip, {
style: { strokeColor: 'rgba(0, 85, 170, 0.5)', lineWidth: 3 }
})

再给配送的起点、终点,快递员的当前位置赋予不同的显示符号,在map.js中修改addMarker()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
HEREMap.prototype.addMarker = function (coordinates, icon) {
// Add an markerOptions object
var markerOptions = {}
// three different icons for origin, destination and the user's current position
var icons = {
iceCream: {
url: './images/marker-gelato.svg',
options: {
size: new H.math.Size(26, 34),
anchor: new H.math.Point(14, 34)
}
},
origin: {
url: './images/origin.png',
options: {
size: new H.math.Size(32, 32),
anchor: new H.math.Point(12, 36)
}
},
destination: {
url: './images/destination.png',
options: {
size: new H.math.Size(32, 32),
anchor: new H.math.Point(12, 36)
}
}
}

if (icons[icon]) {
markerOptions = {
icon: new H.map.Icon(icons[icon].url, icons[icon].options)
}
}

var marker = new H.map.Marker(coordinates, markerOptions)
this.map.addObject(marker)

return marker
}

2 Route Selection

在显示的三条路线中,允许用户选择一条作为最佳选项,那么我们需要在onSuccess()中增加一个回调函数来实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var onSuccess = function (result) {
if (result.response.route) {
var routeLineGroup = new H.map.Group()

var routes = result.response.route.map(function (route) {
var routeLine = drawRoute(route)
routeLineGroup.addObject(routeLine)

return {
route: route,
routeLine: routeLine
}
})

map.addObject(routeLineGroup)
map.setViewBounds(routeLineGroup.getBounds())

onRouteSelection(routes[0])
}
}
Read more »

在 Part 3 中我们了解到如何调用 HERE Routing API 实现两点间路径规划,以及如何从当前位置出发规划路径。

这个部分继续来看看,如何展示多条路线及其信息,并允许用户交互选择。

Pre-session: 重构代码

这一部分不是改进功能,而是整理思绪。磨刀不误砍柴工,放之四海而皆准。

冰淇凌小网页的功能不断增多,代码也随之膨胀,我们要时不时地整理收纳一下,避免自己在找乐子的路上备受打击。

在 Scripts 文件夹中,新建:

  • map.js 用于存放和底图绘制路线相关的逻辑;
  • utils.js 用于存放辅助功能,例如,将 latlog 坐标转化成 WayPointString 以供 Routing Service 使用。

代码与Part 3 类似,但是因为做了重构,需要注意其中的调用关系及 html页面中的加载顺序。

complete code Github - kikitaMoon/HERE_JS_Who_Wants_Icecream

Multiple Routes

Read more »

Part 1 中我们准备了底图,Part 2 中我们获取了位置,现在终于开张了,“您有新的 ‘ 饿了乎 ’ 订单到了!” 我们给外卖小哥规划下路线吧!

1 Routing Service

首先,HERE Map API 中提供了一个叫做 Platform 的类,实例化Platform后,我就可以借以访问 HERE Routing Service。 有关 Routing API 的帮助文档,点这里

1
2
3
4
5
6
var platform = new H.service.Platform({
app_id: '[YOUR APP ID HERE]',
app_code: '[YOUR APP CODE HERE]'
});

var router = platform.getRoutingService();

2 Request Route

在发请求之前,需要先至少定义起点和终点,或者必要的时候增加途经点,这些点是通过 WayPointParameterType 对象传递。

为了让代码更简洁易维护,我们在 scripts 目录下创建一个 route.js文件,取代开始直接在 app.js中直接调用 Routing Service 的繁琐。如下,在 route.js 中增加一个用于封装 底图、platform对象、路径规划参数的 HERERoute函数,这个函数也会在浏览器控制台返回简单的错误日志。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// build a function to take the map and platform objects as parameters
function HERERoute (map, platform, routeOptions) {
// access the routing service by calling getRoutingService()
var router = platform.getRoutingService();
// error handling
var onSuccess = function(result) {
console.log('Route found!', result);
};
var onError = function(error) {
console.error('Oh no! There was some communication error!', error);
}

router.calculateRoute(routeOptions, onSuccess, onError);
}

3 Drawing the Route

现在我们可以在控制台看到 response,如何将 route 绘制到地图上呢

Read more »

在 Part 1 地图底图准备好的基础之上,我们增加一个获取浏览器当前位置并持续更新的功能,来解决“Where am I ?”的问题。

具体可以通过浏览器的 Geolocation API 来实现。在app.js 脚本中,使用 navigator.geolocation 对象来访问此API。 navigator.geolocation 对象有这样几个方法:getCurrentPosition()watchPosition()clearWatch(), 可以帮助我们实现开始的需求。

1 获取位置

首先,通过 getCurrentPosition() 一次性获取浏览器当前位置,在 app.js 中使用如下代码

1
navigator.geolocation.getCurrentPosition(success[, error[, options]]);

各个浏览器都有 Geolocation API 的支持,建议参考相关的帮助文档。这个Demo建议在 Firefox 中测试,因为Chrome似乎禁用从本地文件访问位置。你可以根据需要增加获取位置是否成功后的行为,详情查看 Firefox的开发者文档

2 持续更新位置

watchPosition() 用于持续“关注” 客户端位置的变化,在每次变化之后,都会将新的位置返回。在 app.js 中增加如下代码,用于在当前位置不断地显示“冰激凌”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function updatePosition (event) {
var coordinates = {
lat: event.coords.latitude,
lng: event.coords.longitude
};
var iconUrl = './images/icecream.svg';
var iconOptions = {
size: new H.math.Size(26, 34),
anchor: new H.math.Point(14, 34)
};
var markerOptions = {
icon: new H.map.Icon(iconUrl, iconOptions)
};
var marker = new H.map.Marker(coordinates, markerOptions);
map.addObject(marker);
map.setCenter(coordinates);
}
// Action
navigator.geolocation.watchPosition(updatePosition);
Read more »
0%