Geolocation API 取得裝置地理位置
注意
- 主要在
https
支援使用,部分瀏覽器http
無法使用。 - 初次操作
響應
會比較久。
說明
Geolocation API
可以使 客戶端
根據網頁應用程式,提供「當前」裝置的地理位置,基於隱私原因,需要 客戶端
「許可」後才執行。
當前位置:
經度 n/a
緯度 n/a
定位時間 n/a
監聽動態位置:
經度 n/a
緯度 n/a
變更定位時間 n/a
建立地理位置實體
可以依 navigator.geolocation
來取得「地理位置」的實體,後續依這個實體來做其它操作。
js
const Geolocation = navigator.geolocation
判斷瀏覽器支援
js
const Geolocation = navigator.geolocation
if (!Geolocation) {
console.log('抱歉!瀏覽器不支援Geolocation')
}
取得當前地理位置
操作 .getCurrentPosition()
來取得裝置「當前」的地理位置,瀏覽器基於隱私會詢問 客戶端
是否同意提供,「同意」 才會提供相關的地理位置。
語法
Geolocation.getCurrentPosition( successCallback
[, errorCallback]
, [options]
)
successCallback
(成功)取得地理位置函式errorCallback
(失敗)取得地理位置函式options
其它選項maximumAge
緩存時效 (cache) (默認0
) 表示不使用緩存。enableHighAccuracy
啟用高精準度 (默認false
)如果「啟用」
響應
時間上會增加、消耗功率
也會增加,因為會使用到設備的 GPS 晶片。timeout
逾時時間 (默認Infinity
)若超過時間沒有響應,就會進
errorCallback
Demo
js
// 地理位置實體
const Geolocation = navigator.geolocation
// 選項設置
const options = {
timeout: 5000, // 響應超過 5秒 逾時 -> errorCallback
enableHighAccuracy: true, // 使用高精度
}
// 成功執行函式
const successCallback = (info) => {
console.log(info)
}
// 失敗執行函式
const errorCallback = (error) => {
console.log(error)
}
// 取得當前地理位置功能
Geolocation.getCurrentPosition(successCallback, errorCallback, options)
callback response 響應
Success 成功取得
大部分會拿 經度
、 緯度
來做後續的操作。
屬性 | 說明 |
---|---|
latitude | 緯度 |
longitude | 經度 |
altitude | 高度 |
accuracy | 位置誤差 |
altitudeAccuracy | 高度誤差 |
heading | 移動方向 |
speed | 移動速度 |
json
{
"coords": {
"accuracy": 17,
"altitude": null,
"altitudeAccuracy": null,
"heading": null,
"latitude": 25.056763, // 緯度
"longitude": 121.518242, // 經度
"speed": null
},
"timestamp": 1668145641823 // 取得位置時間戳
}
Error 取得失敗
使用者「拒絕」提供地理位置:
json{ "code": 1, "message": "User denied Geolocation" }
響應超時:
json{ "code": 3, "message": "Timeout expired" }
持續監聽位置
使用 geolocation.watchPosition()
持續監聽定位的變動,操作方法與 getCurrentPosition()
相同。
js
const geolocation = navigator.geolocation
geolocation.watchPosition(successEvent, errorEvent, options)
移除監聽
使用 geolocation.clearWatch()
來對持續監聽定位 watchPosition
回傳值 id
做「取消」。
js
const geolocation = navigator.geolocation
let id = geolocation.watchPosition(successEvent, errorEvent, options)
// 移除監聽
geolocation.clearWatch(id)
實例
CODE
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<style>
* {
padding: 0;
list-style: none;
background: #2e2e2e;
color: #fff;
}
button {
background: #fff;
color: #2e2e2e;
padding: 0.5rem 1rem;
border: 1px solid #2e2e2e;
border-radius: 8px;
}
ul {
padding: 0.5rem 1rem;
border: 1px solid #aaa;
border-radius: 8px;
}
.ps-info {
border-top: 1px solid #fff;
margin-top: 0.5rem;
padding-top: 0.5rem;
font-size: 10px;
}
</style>
<title>Static Template</title>
</head>
<body>
<h1>Location Position</h1>
<div class="location-info">
<ul>
<li>
時間:
<span id="time">--</span>
</li>
<li>
經度:
<span id="longitude">--</span>
</li>
<li>
緯度:
<span id="latitude">--</span>
</li>
<li>
高度:
<span id="altitude">--</span>
</li>
<li>
速度:
<span id="speed">--</span>
<span>(m/s)</span>
</li>
<li>
方向:
<span id="heading">--</span>
</li>
<li class="ps-info">
<div>
位置誤差:
<span id="accuracy">--</span>
</div>
<div>
高度誤差:
<span id="altitudeAccuracy">--</span>
</div>
</li>
</ul>
<button onclick="getCurrentLocation()">開始監聽位置</button>
<button onclick="stopGetlocation()">停止監聽</button>
</div>
<script>
const geolocationAPI = navigator.geolocation
function setProps(propsEl, value) {
const el = document.querySelector(`#${propsEl}`)
el.textContent = value || 'n/a'
}
if (!geolocationAPI) {
alert('抱歉! 瀏覽器不支援「定位服務」')
}
const options = {
timeout: 5000, // 響應超過 5秒 逾時 -> errorCallback
enableHighAccuracy: true, // 使用高精度
}
// 成功執行
function getLocationSuccess({ timestamp, coords }) {
console.log('success', coords)
setProps('time', formatDate(timestamp)) // 時間
setProps('longitude', coords.longitude) // 緯度
setProps('latitude', coords.latitude) // 經度
setProps('altitude', coords.altitude) // 高度
setProps('speed', coords.speed) // 速度
setProps('heading', coords.heading) // 方向 ( 0 度代表正北方向,90 度代表正東方向,180 度代表正南方向,270 度代表正西方向)
setProps('accuracy', coords.accuracy) // 位置誤差
setProps('altitudeAccuracy', coords.altitudeAccuracy) // 高度誤差
}
// 失敗執行
function getLocationError() {
alert('取得定位失敗!')
}
let watchId = null
// 開始監聽定位功能
function getCurrentLocation() {
watchId = geolocationAPI.watchPosition(
getLocationSuccess,
getLocationError,
options
)
alert('開始監聽位置')
}
// 停止監聽功能
function stopGetlocation() {
geolocationAPI.clearWatch(watchId)
alert('已停止監聽位置')
}
// 格式時間功能
function formatDate(timestamp) {
const now = new Date(timestamp)
return `${now.getFullYear()}/${
now.getMonth() + 1
}/${now.getDay()} ${now.getHours()}:${now.getMinutes()}`
}
</script>
</body>
</html>