說(shuō)到地理坐標(biāo),一定是有一個(gè)定位的基準(zhǔn)的。在web開(kāi)發(fā)的過(guò)程中,它的定位基準(zhǔn)一共有那么幾種:
第一種是IP,根據(jù)當(dāng)前電腦或者是手機(jī)設(shè)備它的IP地址來(lái)確定當(dāng)前的地理坐標(biāo)。IP定位是通過(guò)ISP機(jī)房,也就是每一個(gè)登記的機(jī)房位置,比如小區(qū),每一棟大樓都會(huì)有一個(gè)登記的ISP機(jī)房。如果使用IP定位的話,它大約能夠精確到小區(qū)或者是大樓級(jí)別,比如一棟和二棟通過(guò)這個(gè)IP地址就能準(zhǔn)確的區(qū)分出來(lái)。IP定位的誤差大概在十幾米。
第二種是GPS,GPS是基于衛(wèi)星定位的,它相對(duì)來(lái)說(shuō)是比較準(zhǔn)確的,但是它需要硬件支持。比如電腦一般是不具備GPS定位功能的。它的精確度很高,如果是軍方的話可以達(dá)到1米甚至以內(nèi)。
第三種WIFI定位,WiFi定位是通過(guò)每一個(gè)WiFi地址的Mac地址,特別精確。如果WiFi有登記過(guò)的話,它的誤差大概在一米左右。WiFi是有一個(gè)信號(hào)輻射范圍的,根據(jù)輻射范圍的強(qiáng)弱可以確定當(dāng)前的設(shè)備距離這個(gè)WiFi有多遠(yuǎn)。但是它的支持性能不是太好,只能支持室內(nèi)。
第四種GSM和CDMA是比較常見(jiàn)的,是使用手機(jī)卡來(lái)定位的,也就是基于設(shè)備的基站。比如聯(lián)通的信號(hào)塔電信的信號(hào)塔,它的精確度也是比較高的,它一般是用于手機(jī)或者是通信設(shè)備。不同的信號(hào)塔會(huì)接到來(lái)自不同方位的信號(hào),然后根據(jù)這個(gè)信號(hào)的疊加和它的強(qiáng)弱再來(lái)確定當(dāng)前的位置,它的精確度可以達(dá)到10米左右。
最后一種是用戶指定,可以手動(dòng)指定當(dāng)前的位置,假如當(dāng)前定位不準(zhǔn),我們需要做一個(gè)校正指定當(dāng)前的位置,最常見(jiàn)的就是我們平常使用打車軟件時(shí),如果自動(dòng)獲取的位置不準(zhǔn),那么我們可以通過(guò)移動(dòng)來(lái)手動(dòng)指定我們當(dāng)前的位置。
獲取定位基準(zhǔn)之后,我們需要獲取當(dāng)前的地理坐標(biāo),獲取是有一個(gè)流程的。首先打開(kāi)web應(yīng)用,打開(kāi)之后向?yàn)g覽器請(qǐng)求地理信息,這時(shí)會(huì)彈出一個(gè)詢問(wèn)窗口,由于位置信息涉及到一個(gè)隱私,所以瀏覽器做了一個(gè)雙重的保護(hù),詢問(wèn)之后如果同意了,這時(shí)瀏覽器就會(huì)從設(shè)備或者受信任的服務(wù)器獲取位置信息并返回。
browser_map
getCurrentPosition(onSuccess,onError,options)
onSuccess是一個(gè)回調(diào)函數(shù),options有三個(gè)值:enableHighAccuracy(高精度標(biāo)識(shí),在設(shè)備或者是服務(wù)器能達(dá)到范圍內(nèi)返回最高精度)、timeout(超出時(shí)間,如果在指定時(shí)間內(nèi)獲取不到位置信息就會(huì)返回Error,默認(rèn)是0(無(wú)窮大))、maximumAge(緩存時(shí)間)。
const getLocation = () => { const options = { enableHighAccuracy: false, maximumAge: 1000 } if(navigator.geolocation) { //瀏覽器支持geolocation navigator.geolocation.getCurrentPosition(onSuccess,onError,options); } else { //瀏覽器不支持geolocation alert('當(dāng)前瀏覽器不支持getLocation'); } } ? //成功回調(diào) function onSuccess(position) { const longitude = position.coords.longitude; //緯度 const latitude = position.coords.latitude; console.log('position', { longitude, latitude }); } ? //失敗回調(diào) function onError(error) { switch(error.code){ case 1: alert("位置服務(wù)被拒絕"); break; case 2: alert("暫時(shí)獲取不到位置信息"); break; case 3: alert("獲取信息超時(shí)"); break; case 4: alert("未知錯(cuò)誤"); break; } }
watchCurrentPosition(onSuccess, onError, options);
let watchId = undefined; ? const getLocation = () => { const options = { enableHighAccuracy: false, maximumAge: 1000 } if(navigator.geolocation) { //瀏覽器支持geolocation watchId = navigator.geolocation.watchPosition(showPosition); } else { //瀏覽器不支持geolocation alert('當(dāng)前瀏覽器不支持getLocation'); } } ? function showPosition(position) { const longitude = position.coords.longitude; const latitude = position.coords.latitude; console.log('position', { longitude, latitude }); } ? const cancel = () => { //清除當(dāng)前持續(xù)獲取當(dāng)前位置,可以當(dāng)做是一個(gè)setInterval if(watchId) navigator.geolocation.clearWatch(watchId); }
獲取 HTML 元素的位置坐標(biāo),可以使用 JavaScript 中的 DOM 操作來(lái)實(shí)現(xiàn)。下面是一個(gè)示例代碼,展示如何使用 JavaScript 獲取指定類名的元素的位置坐標(biāo):
htmlCopy code
<!DOCTYPE html>
<html>
<body>
<div class="my-element">This is a div element.</div>
<script>
// 獲取具有指定類名的元素
var element = document.querySelector('.my-element');
// 獲取元素的位置信息
var rect = element.getBoundingClientRect();
// 輸出元素的位置坐標(biāo)
console.log('元素的左上角坐標(biāo):', rect.left, rect.top);
console.log('元素的右下角坐標(biāo):', rect.right, rect.bottom);
console.log('元素的寬度和高度:', rect.width, rect.height);
</script>
</body>
</html>
在上述代碼中,我們首先使用 querySelector() 方法獲取具有指定類名 .my-element 的元素。然后,使用 getBoundingClientRect() 方法獲取該元素的位置信息,返回一個(gè)包含左上角坐標(biāo)、右下角坐標(biāo)、寬度和高度等屬性的 DOMRect 對(duì)象。
最后,我們使用 console.log() 方法將元素的位置坐標(biāo)輸出到控制臺(tái)。您可以根據(jù)實(shí)際需要使用這些坐標(biāo)信息。
請(qǐng)注意,獲取的位置坐標(biāo)是相對(duì)于視口(viewport)的坐標(biāo),而不是相對(duì)于整個(gè)頁(yè)面的坐標(biāo)。如果需要獲取相對(duì)于頁(yè)面的坐標(biāo),可以結(jié)合 window.scrollX 和 window.scrollY 屬性進(jìn)行計(jì)算。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport">
</head>
<body>
<canvas id="canvas" style="border:2px solid red" width="400" height="400"></canvas>
<canvas id="canvas2" style="border:2px solid red" width="400" height="400"></canvas>
<div onclick="Fn()"
style="border:2px solid red;width:200px;margin-top:10px;height:30px;line-height:30px;text-align: center">
按鈕
</div>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
//coordinateRecord 坐標(biāo)記錄;detectionCoordinate檢測(cè)是否直線坐標(biāo)
var coordinateRecord = [], detectionCoordinate = [];
//是否開(kāi)始標(biāo)記區(qū)域
var move = false;
//檢測(cè)是不是直線
function checkIsLine(pointArray) {
if (pointArray === null || pointArray === undefined || pointArray.length < 3) {
return false;
}
var startX = pointArray[0].x;
var startY = pointArray[0].y;
var endX = pointArray[pointArray.length - 2].x;
var endY = pointArray[pointArray.length - 2].y;
var tan = Math.atan(endX - startX, endY - startY) * 180 / Math.PI;
for (let i in pointArray) {
//每3個(gè)點(diǎn)檢測(cè)是否是直線
if (i > 3) {
var x = pointArray[i].x - pointArray[i - 3].x;
var y = pointArray[i].y - pointArray[i - 3].y;
var tantemp = Math.atan(y / x) * 180 / Math.PI;
//允許誤差16度
if (Math.abs(tantemp - tan) > 16) {
return false;
}
}
}
return true;
}
canvas.onmousedown = function (e) {
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
//記錄開(kāi)始點(diǎn),每次開(kāi)始畫,都是一組新的坐標(biāo),處理畫多個(gè)圖形時(shí),坐標(biāo)點(diǎn)記錄不準(zhǔn)確的問(wèn)題
coordinateRecord.push([{
x: x,
y:y
}])
ctx.moveTo(x, y);
ctx.lineWidth = 1;
move = true;
}
canvas.onmousemove = function (e) {
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
if (move) {
ctx.lineTo(x, y);
ctx.stroke();
detectionCoordinate.push({
x: x,
y: y
});
var isLine = checkIsLine(detectionCoordinate);
//非直線記錄該點(diǎn)
if (!isLine) {
coordinateRecord[coordinateRecord.length - 1].push({
x: x,
y:y
});
}
}
}
canvas.onmouseup = function (e) {
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
//重置檢測(cè)坐標(biāo)數(shù)組
detectionCoordinate = [];
//記錄結(jié)束點(diǎn)
coordinateRecord[coordinateRecord.length - 1].push({
x: x,
y:y
});
move = false;
}
//點(diǎn)擊btn,把記錄的坐標(biāo)重新顯示,用來(lái)檢測(cè)坐標(biāo)是否標(biāo)記正確
var canvas2 = document.getElementById('canvas2');
var ctx2 = canvas2.getContext('2d');
function Fn() {
for (var i in coordinateRecord) {
const item = coordinateRecord[i];
ctx2.moveTo(item[0].x,item[0].y);
ctx2.lineWidth = 2;
ctx2.strokeStyle = "green";
for (var t in item) {
if (t > 0) {
ctx2.lineTo(item[t].x, item[t].y);
}
}
ctx2.stroke();
}
}
</script>
</body>
</html>
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。