国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

經(jīng)緯度坐標(biāo)為中心點生成米距離長度半徑的圓形面,含java js源碼+在線繪制,代碼簡單零依賴

這篇具有很好參考價值的文章主要介紹了經(jīng)緯度坐標(biāo)為中心點生成米距離長度半徑的圓形面,含java js源碼+在線繪制,代碼簡單零依賴。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄
  • java版源碼
  • js版源碼
  • 在線繪制預(yù)覽效果
  • 關(guān)于計算的精確度

前些時間在更新我的坐標(biāo)邊界查詢工具的時候,需要用到經(jīng)緯度坐標(biāo)點的距離計算,和以坐標(biāo)點為中心生成一個指定距離為半徑的圓,搜了一下沒有找到現(xiàn)成簡單又合適的代碼,于是把自己壓箱底的代碼翻出來了,簡化完善了一下,嘿,代碼量也不大,還挺好用。

本方法是通過計算得到圓上的多個坐標(biāo)點,來得到的一個近似的圓形面,只要坐標(biāo)點夠多,這個圓就能足夠圓;有了這些坐標(biāo)點就很容易表示成不同的格式,比如:GeoJSON文本WKT文本、Geometry實例

源自 坐標(biāo)邊界查詢工具 開源庫:https://github.com/xiangyuecn/AreaCity-Query-Geometry (github可以換成gitee),高性能的坐標(biāo)數(shù)據(jù)、邊界數(shù)據(jù)查詢工具,Java開源程序、帶http查詢接口,內(nèi)存占用低(1秒可查1萬個以上坐標(biāo)對應(yīng)的城市信息)。

java版源碼

public static void main(String[] args) {
	//計算天壇到天安門的距離
	System.out.println(Distance(116.410622, 39.881773, 116.397476, 39.908647));
	//生成天壇1公里范圍的圓形面
	System.out.println(CreateSimpleCircleWKT(116.410622, 39.881773, 1000, 24));
}

/** 計算兩個坐標(biāo)的距離,單位米 **/
static public double Distance(double lng1, double lat1, double lng2, double lat2) {
	//采用Haversine formula算法,高德地圖的js計算代碼,比較簡潔 https://www.cnblogs.com/ggz19/p/7551088.html
	double d=Math.PI/180;
	double f=lat1*d, h=lat2*d;
	double i=lng2*d - lng1*d;
	double e=(1 - Math.cos(h - f) + (1 - Math.cos(i)) * Math.cos(f) * Math.cos(h)) / 2;
	return 2 * 6378137 * Math.asin(Math.sqrt(e));
}

/** 以坐標(biāo)點為中心,簡單粗略的創(chuàng)建一個指定半徑的圓,半徑單位米,pointCount為構(gòu)建圓的坐標(biāo)點數(shù)(比如24個點,點越多越圓,最少3個點),返回構(gòu)成圓的坐標(biāo)點數(shù)組 **/
static public double[][] CreateSimpleCircle(double lng, double lat, double radius, int pointCount) {
	//球面坐標(biāo)不會算,轉(zhuǎn)換成三角坐標(biāo)簡單點,經(jīng)度代表值大約:0.01≈1km 0.1≈10km 1≈100km 10≈1000km
	double km=radius/1000;
	double a=km<5?0.01 :km<50?0.1 :km<500?1 :10;
	double b=Distance(lng, lat, lng+a, lat);
	double c=Distance(lng, lat, lng, lat+a);
	double rb=radius/b*a;
	double rc=radius/c*a;
	double[][] arr=new double[pointCount+1][];
	double n=0,step=360.0/pointCount,N=360-step/2; //注意浮點數(shù)±0.000000001的差異
	for(int i=0;n<N;i++,n+=step){
		double x=lng+rb*Math.cos(n*Math.PI/180);
		double y=lat+rc*Math.sin(n*Math.PI/180);
		arr[i]=new double[] { x, y };
	}
	arr[pointCount]=new double[] { arr[0][0], arr[0][1] }; //閉環(huán)
	return arr;
}

/**
以坐標(biāo)點為中心,簡單粗略的創(chuàng)建一個指定半徑的圓,半徑單位米,pointCount為構(gòu)建圓的坐標(biāo)點數(shù)(比如24個點,點越多越圓,最少3個點),返回圓的WKT(Well Known Text)文本
,WKT圖形繪制預(yù)覽工具:https://xiangyuecn.gitee.io/areacity-jsspider-statsgov/assets/geo-echarts.html
**/
static public String CreateSimpleCircleWKT(double lng, double lat, double radius, int pointCount) {
	double[][] points=CreateSimpleCircle(lng, lat, radius, pointCount);
	DecimalFormat df=new DecimalFormat("0.######");
	StringBuilder wkt=new StringBuilder("POLYGON((");
	for(int i=0;i<points.length;i++) {
		if(i>0)wkt.append(",");
		wkt.append(df.format(points[i][0])+" "+df.format(points[i][1]));
	}
	wkt.append("))");
	return wkt.toString();
}

js版源碼

//測試:計算天壇到天安門的距離
console.log(Distance(116.410622, 39.881773, 116.397476, 39.908647));
//測試:生成天壇1公里范圍的圓形面
console.log(CreateSimpleCircleWKT(116.410622, 39.881773, 1000, 24));

/** 計算兩個坐標(biāo)的距離,單位米 **/
function Distance(lng1, lat1, lng2, lat2) {
    //采用Haversine formula算法,高德地圖的js計算代碼,比較簡潔 https://www.cnblogs.com/ggz19/p/7551088.html
    var d=Math.PI/180;
    var f=lat1*d, h=lat2*d;
    var i=lng2*d - lng1*d;
    var e=(1 - Math.cos(h - f) + (1 - Math.cos(i)) * Math.cos(f) * Math.cos(h)) / 2;
    return 2 * 6378137 * Math.asin(Math.sqrt(e));
}

/** 以坐標(biāo)點為中心,簡單粗略的創(chuàng)建一個指定半徑的圓,半徑單位米,pointCount為構(gòu)建圓的坐標(biāo)點數(shù)(比如24個點,點越多越圓,最少3個點),返回構(gòu)成圓的坐標(biāo)點數(shù)組 **/
function CreateSimpleCircle(lng, lat, radius, pointCount){
	//球面坐標(biāo)不會算,轉(zhuǎn)換成三角坐標(biāo)簡單點,經(jīng)度代表值大約:0.01≈1km 0.1≈10km 1≈100km 10≈1000km
	var km=radius/1000;
	var a=km<5?0.01 :km<50?0.1 :km<500?1 :10;
	var b=Distance(lng, lat, lng+a, lat);
	var c=Distance(lng, lat, lng, lat+a);
	var rb=radius/b*a;
	var rc=radius/c*a;
	var arr=[];
	var n=0,step=360.0/pointCount,N=360-step/2; //注意浮點數(shù)±0.000000001的差異
	for(var i=0;n<N;i++,n+=step){
		var x=lng+rb*Math.cos(n*Math.PI/180);
		var y=lat+rc*Math.sin(n*Math.PI/180);
		arr[i]=[x, y];
	}
	arr.push([arr[0][0], arr[0][1]]); //閉環(huán)
	return arr;
};

/**
以坐標(biāo)點為中心,簡單粗略的創(chuàng)建一個指定半徑的圓,半徑單位米,pointCount為構(gòu)建圓的坐標(biāo)點數(shù)(比如24個點,點越多越圓,最少3個點),返回圓的WKT(Well Known Text)文本
,WKT圖形繪制預(yù)覽工具:https://xiangyuecn.gitee.io/areacity-jsspider-statsgov/assets/geo-echarts.html
**/
function CreateSimpleCircleWKT(lng, lat, radius, pointCount){
	var points=CreateSimpleCircle(lng, lat, radius, pointCount);
    var wkt=["POLYGON(("];
    for(var i=0;i<points.length;i++) {
		wkt.push((i>0?",":"")+(+points[i][0].toFixed(6))+" "+(+points[i][1].toFixed(6)));
    }
    wkt.push("))");
    return wkt.join("");
};

在線繪制預(yù)覽效果

生成了圓形面的WKT文本后,可以粘貼進在線預(yù)覽頁面繪制顯示:https://xiangyuecn.gitee.io/areacity-jsspider-statsgov/assets/geo-echarts.html ,方便代碼調(diào)試,地圖上有測距功能,可以測量圓面的準(zhǔn)確度;頁面上的畫圓功能,采用的就是js版的代碼。

經(jīng)緯度坐標(biāo)為中心點生成米距離長度半徑的圓形面,含java js源碼+在線繪制,代碼簡單零依賴

關(guān)于計算的精確度

兩個經(jīng)緯度坐標(biāo)的距離計算,采用的Haversine formula算法,下面的計算代碼中高德地圖的api同樣是Haversine formula算法,和百度地圖的計算結(jié)果誤差在0.2%以內(nèi):

bMap=window.BMapGL&&BMapGL.Map.prototype||{getDistance:function(a,b){return BMap.Map.prototype.getDistance(new BMap.Point(a.lng,a.lat),new BMap.Point(b.lng,b.lat)) }};

//地圖api計算【緯度】之間的距離,每一度之間的距離是相同的
bMap.getDistance({lng:111,lat:15},{lng:111,lat:16})        //百度111194.86米
new AMap.LngLat(111,15).distance(new AMap.LngLat(111,16)) //高德111319.49米

bMap.getDistance({lng:121,lat:55},{lng:121,lat:56})        //百度111194.78米
new AMap.LngLat(121,55).distance(new AMap.LngLat(121,56)) //高德111319.49米

//地圖api計算【經(jīng)度】之間的距離,會隨著緯度的不同而不同
bMap.getDistance({lng:111,lat:15},{lng:112,lat:15})        //百度107405.91米
new AMap.LngLat(111,15).distance(new AMap.LngLat(112,15)) //高德107526.28米

bMap.getDistance({lng:111,lat:55},{lng:112,lat:55})        //百度63778.21米
new AMap.LngLat(111,55).distance(new AMap.LngLat(112,55)) //高德63849.69米
        //經(jīng)度在相同緯度下每一度之間的距離是相同的
        bMap.getDistance({lng:121,lat:55},{lng:122,lat:55})        //百度63778.21米
        new AMap.LngLat(121,55).distance(new AMap.LngLat(122,55)) //高德63849.69米

對于構(gòu)成圓的坐標(biāo)點的計算,使用的以前壓箱底的代碼,計算比較簡單,經(jīng)度和緯度分別計算出一度的距離長度,在等比例的換算出半徑對應(yīng)的度數(shù)大小,比如算出來的經(jīng)度1°是100km,那么20km半徑對應(yīng)的度數(shù)就是1° * 20 / 100 = 0.2°。

  • 緯度每一度之間的距離都是固定的長度,等比例換算后的結(jié)果是沒有誤差的。
  • 經(jīng)度每一度之間的距離長度會隨著緯度變化,低緯度長高緯度短,圓面的上下緯度不同,半徑小的時候誤差小,半徑越大誤差越大。

所以按等比例換算在緯度上沒有問題,但經(jīng)度上會產(chǎn)生一定的誤差,但只要圓的半徑不超過10km,誤差就能控制在0.5%以內(nèi),可通過下面代碼直接計算觀察到:

//經(jīng)度之間的距離,不同緯度下的誤差計算
d1=new AMap.LngLat(111,15.0).distance(new AMap.LngLat(111.2,15.0));
d2=new AMap.LngLat(111,15.2).distance(new AMap.LngLat(111.2,15.2));
console.log(d2, (d1-d2)/d2*100+"%") //低緯度下經(jīng)度0.2°距離≈20km,緯度0.2°導(dǎo)致0.09%誤差
d1=new AMap.LngLat(111,55.0).distance(new AMap.LngLat(111.2,55.0));
d2=new AMap.LngLat(111,55.2).distance(new AMap.LngLat(111.2,55.2));
console.log(d2, (d1-d2)/d2*100+"%") //高緯度下經(jīng)度0.2°距離≈10km,緯度0.2°導(dǎo)致0.50%誤差

d1=new AMap.LngLat(111,15).distance(new AMap.LngLat(112,15));
d2=new AMap.LngLat(111,16).distance(new AMap.LngLat(112,16));
console.log(d2, (d1-d2)/d2*100+"%") //低緯度下經(jīng)度1°距離≈100km,緯度1°導(dǎo)致0.49%誤差
d1=new AMap.LngLat(111,55).distance(new AMap.LngLat(112,55));
d2=new AMap.LngLat(111,56).distance(new AMap.LngLat(112,56));
console.log(d2, (d1-d2)/d2*100+"%") //高緯度下經(jīng)度1°距離≈60km,緯度1°導(dǎo)致2.57%誤差

由于是通過圓上的坐標(biāo)點連起來得到的一個圓,本質(zhì)上是一個近似圓的多邊形,只要坐標(biāo)點足夠多就越接近圓,當(dāng)坐標(biāo)點少的情況下肉眼可見的不是那么圓(最少3個坐標(biāo)點,三角形),誤差也會很大。但考慮到點數(shù)越多,會導(dǎo)致使用上很多地方的計算量會變的很大,所以構(gòu)成圓的坐標(biāo)點數(shù)也是一個綜合考慮的數(shù)量,我選擇24個坐標(biāo)點構(gòu)成一個圓,每個象限6個點,點之間角度為15°。

【完】文章來源地址http://www.zghlxwxcb.cn/news/detail-475415.html

到了這里,關(guān)于經(jīng)緯度坐標(biāo)為中心點生成米距離長度半徑的圓形面,含java js源碼+在線繪制,代碼簡單零依賴的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包