根據經緯度繪製座標點相對位置(分別用php和html5實現)
本文主要講實現
1.用php實現根據座標點經緯度繪製座標點相對位置。
2.用html5實現根據座標點經緯度繪製座標點相對位置。
之前有一個需求,是要把一些座標點的相對位置畫到一張圖片上,標註出點,點名,並且點之間兩兩連線生成一張圖片。
最開始考慮用html5實現。 但實際上我們生成的圖片要在後臺放到word文件中去,所以最後使用的php在後臺畫圖,然後儲存到本地的方式 。
這幾天正好在研究html5,就用html5的方式再實現了一遍。感覺html5畫起來還要順手一些。
當然,php也好,html5也好,都只是工具,實現起來主要還是要有演算法。
php跟javascript使用起來真是很像啊。
需求分析:
1.圖片不能無限大。有一個最大值maxsize。 我們這裡設為300px。也就是生成的圖片,座標區域寬或高最大不超過300px。
2.所有的座標點都要在我們的圖片中。
3.座標點之間的位置關係儘可能真實反映座標情況。
4.座標點。點名。連線顯示在地圖上。
由需求看出難點在第3條上。經緯度座標怎麼換算成我們可以使用來畫圖的座標呢?
經過一番思考,確定了一個粗略的方法:
大概有這麼幾個步驟:
首先確認一個前提:就是我們假設經度和緯度在地圖上攤開來是1比1的關係,即是說經度1度的距離約等於緯度1度的距離。 當然事實情況並不是這樣,我們這裡只是求一個粗略的位置關係。
1.求出所有座標點的最大經度差,最大緯度差。比較,將大的那一個的長度作為maxsize。
2.根據最大經度差最大維度差之間的比例,可以算出我們短的那一邊的長度。
3.我們求出一個Rate。這個Rate值表示單位度數在生成圖片上所佔的尺寸,生成一個類似比例尺的東西。
4.然後我們現在已經確定了我們的圖片的長和寬。同時我們以最小經度,最小緯度為圖片的x,y軸原點。然後再根據Rate,以及當前點的經度、緯度與最小經度,最小緯度的差,求出當前點在圖片上繪製時候的座標。
5.求出了繪圖座標之後,就可以使用php。或者html5的方法來進行繪圖操作了。
ps:對於經度差或緯度差為0的情況下我也做了單獨處理。
html5繪製經緯度座標點位置程式碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>用html5繪製座標點相對位置</title>
</head>
<style>
canvas{
border: 1px solid #ccc;
}
</style>
<script type="text/javascript">
//繪圖資料準備
var points=[[],[],[],[]];
points[0]['L'] = 110.83717794;
points[0]['B'] = 13;
points[0]['Name'] = 'pt1';
points[1]['L'] = 113;
points[1]['B'] = 24;
points[1]['Name'] = 'pt2';
points[2]['L'] = 105.794566000;
points[2]['B'] = 20;
points[2]['Name'] = 'pt3';
points[3]['L'] = 120;
points[3]['B'] = 17;
points[3]['Name'] = 'pt4';
function draw (points) {
//座標區域長或寬,最大為300px。判斷標準:座標經度差與緯度差,大的那個為300px。再根據經度差與緯度差的比例計算出短的一邊有多少px。
var MAXSIZE = 300;
var maxL = points[0]['L'];
var maxB=points[0]['B'];
var minL = points[0]['L'];
var minB=points[0]['B'];
var value;
for(var i=0,pointsLen=points.length;i<pointsLen;i++){
value = points[i];
maxL = maxL <value['L']?value['L'] :maxL;
maxB = maxB <value['B']?value['B'] :maxB;
minL = minL > value['L']?value['L'] :minL;
minB = minB >value['B']?value['B'] :minB;
}
var diffL = maxL - minL;//經度差
var diffB = maxB - minB;//緯度差
var width,height,Rate,diff;
//計算座標區域height width;
if(diffL == 0){
width =MAXSIZE;
height = MAXSIZE;
Rate = MAXSIZE/parseFloat(diffB);
}
else if (diffB == 0) {
width =MAXSIZE;
height = MAXSIZE;
Rate = MAXSIZE/parseFloat(diffL);
}else if(diffL >= diffB){
diff = diffL;
width = MAXSIZE;
Rate = MAXSIZE/parseFloat(diffL);//單位座標的有多少個px值。
height = diffB/diffL*MAXSIZE;
}else {
diff = diffB;
height = MAXSIZE;
Rate = MAXSIZE/parseFloat(diffB);//單位座標的有多少個px值。
width = diffL/diffB*MAXSIZE;
}
var ctx = document.getElementById("myCanvas").getContext("2d");
ctx.translate(20,20);//原點往右下方分別移動20px,多出來的是用來防止名字,以及點上的圓點顯示不下
// 根據B,L計算畫素位置。計算應該有px。
for(var k=0,pointsLen=points.length;k<pointsLen;k++){
value = points[k];
if(diffL == 0){
points[k]['Lpx'] =MAXSIZE/2;
points[k]['Bpx'] = parseInt(height - (value['B'] - minB)*Rate);
}
else if (diffB == 0) {
points[k]['Lpx'] =parseInt((value['L'] - minL)* Rate);
points[k]['Bpx'] = MAXSIZE/2;
} else {
points[k]['Lpx'] = parseInt((value['L'] - minL)* Rate);
points[k]['Bpx'] = parseInt(height - (value['B'] - minB)*Rate);
}
}
ctx.font = "bold 14px Arial";
ctx.textAlign = "left";
ctx.textBaseline = "middle";
for(var x=0,pointsLen=points.length;x<pointsLen;x++){
value = points[x];
i = x +1;
ctx.strokeStyle='black';
//兩兩相連的處理
while (i<pointsLen) {
ctx.beginPath();
ctx.moveTo(value['Lpx'] , value['Bpx']);
ctx.lineTo(points[i]['Lpx'], points[i]['Bpx']);
ctx.stroke();
i++;
}
//畫點名
ctx.beginPath();
ctx.fillStyle ='black';
ctx.fillText(value.Name, value['Lpx']+5, value['Bpx']);
//畫點
ctx.fillStyle = 'rgb(29,143,254)';
ctx.beginPath();
ctx.arc(value['Lpx'] , value['Bpx'] , 5, 0, Math.PI*2, false);
ctx.fill();
}
}
</script>
<body onload="draw(points)">
<canvas id="myCanvas" width="350" height="350"></canvas>
</body>
</html>
php繪製經緯度座標點位置程式碼:程式碼看起來要複雜一點,可能是對php畫圖研究的還不夠。。
<?php
//測試資料
$point[0]['L'] = 110.83717794;
$point[0]['B'] = 13;
$point[0]['Name'] = 'pt1';
$point[1]['L'] = 113;
$point[1]['B'] = 24;
$point[1]['Name'] = 'pt2';
$point[2]['L'] = 105.794566000;
$point[2]['B'] = 20;
$point[2]['Name'] = 'pt3';
$point[3]['L'] = 120;
$point[3]['B'] = 17;
$point[3]['Name'] = 'pt4';
function draw($point)
{
//1.計算四個範圍。
$maxL = $point[0]['L'];
$maxB=$point[0]['B'];
$minL = $point[0]['L'];
$minB=$point[0]['B'];
foreach ($point as $key => $value) {
$maxL = $maxL <$value['L']?$value['L'] :$maxL;
$maxB = $maxB <$value['B']?$value['B'] :$maxB;
$minL = $minL > $value['L']?$value['L'] :$minL;
$minB = $minB >$value['B']?$value['B'] :$minB;
}
$MAXSIZE = 300; //座標區域長或寬,最大為300px。判斷標準:座標經度差與緯度差,大的那個為300px。再根據經度差與緯度差的比例計算出短的一邊有多少px。
$diffL = $maxL - $minL;//經度差
$diffB = $maxB - $minB;//緯度差
//計算座標區域$height $width;
if($diffL == 0){
$width =$MAXSIZE;
$height = $MAXSIZE;
$Rate = $MAXSIZE/(float)$diffB;
}
elseif ($diffB == 0) {
$width =$MAXSIZE;
$height = $MAXSIZE;
$Rate = $MAXSIZE/(float)$diffL;
}else if($diffL >= $diffB){
$diff = $diffL;
$width = $MAXSIZE;
$Rate = $MAXSIZE/(float)$diffL;//單位座標的有多少個px值。
$height = $diffB/$diffL*$MAXSIZE;
}else{
$diff = $diffB;
$height = $MAXSIZE;
$Rate = $MAXSIZE/(float)$diffB;//單位座標的有多少個px值。
$width = $diffL/$diffB*$MAXSIZE;
}
$img_width = $width + 50;//多出來的50是用來防止基站名字,以及點上的圓點顯示不下
$img_height = $height + 30;//多出來的30是用來防止基站名字,以及點上的圓點顯示不下
$image = imagecreatetruecolor($img_width,$img_height);//生成一個黑色背景的圖片。
$back = imagecolorallocate($image, 255, 255, 255);//背景顏色,白色
imagefilledrectangle ($image,0,0,$img_width ,$img_height ,$back);//設定背景,其實是用的白色填充矩形。
$linecolor= imagecolorallocate($image,0,0,0);//連線的顏色
$pointcolor = imagecolorallocate($image,29,143,254);//點的顏色
$textcolor = imagecolorallocate($image,0,0,0);//字型顏色,黑色
// 根據B,L計算畫素位置。計算應該有px。多出來的6,和10,表示所有座標都向右移動6px,向下移動10px,也是避免基站名和圓點顯示不下。
foreach ($point as $key => $value) {
if($diffL == 0){
$point[$key]['Lpx'] =$MAXSIZE/2;
$point[$key]['Bpx'] = (int)($height - ($value['B'] - $minB)*$Rate)+10;
}
elseif ($diffB == 0) {
$point[$key]['Lpx'] =(int)(($value['L'] - $minL)* $Rate) + 6;
$point[$key]['Bpx'] = $MAXSIZE/2;
}else{
$point[$key]['Lpx'] = (int)(($value['L'] - $minL)* $Rate) + 6;
$point[$key]['Bpx'] = (int)($height - ($value['B'] - $minB)*$Rate)+10;
}
}
$pointNum = count($point);
foreach ($point as $key => $value) {
$i = $key +1;
while ($i<$pointNum) {
imageline($image , $value['Lpx'] , $value['Bpx'], $point[$i]['Lpx'], $point[$i]['Bpx'] , $linecolor );//點與點之間連線
$i++;
}
imagestring( $image ,10 , $value['Lpx'], $value['Bpx'], $value['Name'] ,$linecolor); //每個點的位置寫下點名。10是大小。
imagefilledellipse($image , $value['Lpx'] , $value['Bpx'], 10 , 10, $pointcolor); //每個點的位置,用一個填充的圓點表示。
}
// 輸出影象
header("Content-type: image/jpeg");
// imagejpeg($image,'d:\1.jpeg');//如果沒有路徑就輸出圖片,有路徑就儲存圖片。
imagejpeg($image);//如果沒有路徑就輸出圖片,有路徑就儲存圖片。
}
draw($point);
?>
接下來,對比圖!!!
html5繪製畫出來的經緯度座標位置關係圖:
php繪製畫出來的經緯度座標位置關係圖:
再接下來,我們到地圖上看這幾個座標的真實位置:(資料來自之前用天地圖WEB API寫的一個座標展繪的功能,可以把輸入的座標點在地圖上顯示出來)
如果對精確度要求不是特別高的話,我這個方法應該還是可以用的。 有什麼不足的地方,歡迎指出探討。
最後總結一句,其實會某個技能倒是次要的,技能用的時候可以學,更重要的還是要有想法來用這個技能。。。
演示地址:
html5:http://runningls.com/demos/2015/position/html5.html
php:http://runningls.com/demos/2015/position/php.php
github:https://github.com/liusaint/earth/tree/master/position
相關文章
- 根據經緯度座標查詢最近的門店
- iOS根據兩點經緯度座標計算指南針方位角iOS
- 百度地圖:根據位置獲取座標地圖
- 根據兩點經緯度計算距離和角度——java實現Java
- java 根據兩個位置的經緯度,來計算兩地的距離 經緯度處理Java
- C#根據經緯度獲取實體地址C#
- Java根據地理位置獲取經緯度(呼叫百度地圖API)Java地圖API
- java 根據經緯度計算圓周Java
- 根據經緯度座標獲得省市區縣行政區劃城市名稱,自建資料庫 java python php c# .net 均適用資料庫JavaPythonPHPC#
- 微信小程式-如何在map上根據經緯度新增標記點(附原始碼)微信小程式原始碼
- 根據經緯度計算兩點之間的距離的公式公式
- 如何快速將地址解析為經緯度座標?
- uniapp根據導航欄的標題定位到相應錨點位置APP
- 根據時間經緯度高程計算天頂角
- R語言:根據經緯度在世界地圖上畫出各個點R語言地圖
- HTML網頁根據座標模擬滑鼠點選HTML網頁
- js中根據x,y 座標模擬點選事件JS事件
- 如何使用Python經緯座標模組?Python
- js根據經緯度,獲取省市區。(百度地圖逆地址解析)JS地圖
- 如何判斷一個指定的位置點座標(GPS上的經緯度)是否落在一個多邊形區域內?
- PHP實現透過經緯度計算距離和查附近店門PHP
- 獲取資料庫中到指定經緯度距離的座標資料庫
- 地理位置經緯度在Mysql中用什麼欄位型別MySql型別
- 高德解析城市的分析,根據高德的經緯度獲取城市cityCode
- ArcGIS API for JavaScript根據兩個點座標在地圖上畫線APIJavaScript地圖
- springboot + mongodb 通過經緯度座標匹配平面區域的方法YWKSSpring BootMongoDB
- openlayers根據座標在地圖上劃區域地圖
- 簡單計算給定兩個給定經緯度座標的距離
- Web墨卡託座標與WGS84經緯度互轉 java程式碼WebJava
- 勾勒產業緯度與時代經度:座標杜拜,UBBF2021“聯接+新增長”產業
- js呼叫百度地圖介面繪製任意多邊形並獲取每個點的經緯度等JS地圖
- Python視覺化-縣市按經緯度座標在地圖示記數值Python視覺化地圖
- Matlab三維空間座標圖繪製Matlab
- JavaScript字串物件 之 根據字元返回位置、根據位置返回字元、字串操作方法JavaScript字串物件字元
- 呼叫百度api透過經緯度獲取實際地理位置資訊API
- 根據IP定位地理位置
- 智慧手環WIFI熱點和經緯度API獲取WiFiAPI
- .NET程式獲取當前IP經緯度,並透過經緯度實現天氣查詢功能
- Qt/C++路徑軌跡回放/回放每個點訊號/回放結束訊號/拿到移動的座標點經緯度QTC++