日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php如何测量坐标周围,php – 如何检查经度/纬度点是否在坐标范围内?

發布時間:2024/9/3 php 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php如何测量坐标周围,php – 如何检查经度/纬度点是否在坐标范围内? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這基本上是球體上的

Point in polygon問題.您可以修改光線投射算法,使其使用大圓弧而不是線段.

>對于構成多邊形的每對相鄰坐標,在它們之間繪制一個大的圓弧段.

>選擇不在多邊形區域內的參考點.

>繪制一個從參考點開始并在車輛終點結束的大圓段.計算此段跨越多邊形段的次數.如果總次數是奇數,則車輛在多邊形內.如果均勻,則車輛在多邊形之外.

或者,如果坐標和車輛足夠靠近,而不是靠近極點或國際日期線,您可以假裝地球是平坦的,并使用經度和緯度作為簡單的x和y坐標.這樣,您可以將光線投射算法與簡單的線段一起使用.如果您對非歐幾里德幾何體感到不舒服,這是更可取的,但是由于弧會扭曲,因此您的多邊形邊界周圍會有一些扭曲.

編輯:關于球體幾何的更多信息.

可以通過垂直于圓所在平面的矢量來識別大圓(AKA,normal vector)

class Vector{

double x;

double y;

double z;

};

class GreatCircle{

Vector normal;

}

不是antipodal的任何兩個緯度/經度坐標恰好共享一個大圓.要找到這個大圓,請將坐標轉換為穿過地球中心的線.這兩條線的cross product是坐標大圓的法線向量.

//arbitrarily defining the north pole as (0,1,0) and (0'N, 0'E) as (1,0,0)

//lattidues should be in [-90, 90] and longitudes in [-180, 180]

//You'll have to convert South lattitudes and East longitudes into their negative North and West counterparts.

Vector lineFromCoordinate(Coordinate c){

Vector ret = new Vector();

//given:

//tan(lat) == y/x

//tan(long) == z/x

//the Vector has magnitude 1, so sqrt(x^2 + y^2 + z^2) == 1

//rearrange some symbols, solving for x first...

ret.x = 1.0 / math.sqrt(tan(c.lattitude)^2 + tan(c.longitude)^2 + 1);

//then for y and z

ret.y = ret.x * tan(c.lattitude);

ret.z = ret.x * tan(c.longitude);

return ret;

}

Vector Vector::CrossProduct(Vector other){

Vector ret = new Vector();

ret.x = this.y * other.z - this.z * other.y;

ret.y = this.z * other.x - this.x * other.z;

ret.z = this.x * other.y - this.y * other.x;

return ret;

}

GreatCircle circleFromCoordinates(Coordinate a, Coordinate b){

Vector a = lineFromCoordinate(a);

Vector b = lineFromCoordinate(b);

GreatCircle ret = new GreatCircle();

ret.normal = a.CrossProdct(b);

return ret;

}

兩個大圓在球體上的兩個點相交.圓的叉積形成通過這些點之一的矢量.該向量的對映體通過另一個點.

Vector intersection(GreatCircle a, GreatCircle b){

return a.normal.CrossProduct(b.normal);

}

Vector antipode(Vector v){

Vector ret = new Vector();

ret.x = -v.x;

ret.y = -v.y;

ret.z = -v.z;

return ret;

}

大圓段可以通過段的起點和終點表示.

class GreatCircleSegment{

Vector start;

Vector end;

Vector getNormal(){return start.CrossProduct(end);}

GreatCircle getWhole(){return new GreatCircle(this.getNormal());}

};

GreatCircleSegment segmentFromCoordinates(Coordinate a, Coordinate b){

GreatCircleSegment ret = new GreatCircleSegment();

ret.start = lineFromCoordinate(a);

ret.end = lineFromCoordinate(b);

return ret;

}

您可以使用dot product測量大圓弧段的圓弧大小或任意兩個向量之間的角度.

double Vector::DotProduct(Vector other){

return this.x*other.x + this.y*other.y + this.z*other.z;

}

double Vector::Magnitude(){

return math.sqrt(pow(this.x, 2) + pow(this.y, 2) + pow(this.z, 2));

}

//for any two vectors `a` and `b`,

//a.DotProduct(b) = a.magnitude() * b.magnitude() * cos(theta)

//where theta is the angle between them.

double angleBetween(Vector a, Vector b){

return math.arccos(a.DotProduct(b) / (a.Magnitude() * b.Magnitude()));

}

您可以測試一個大圓段a是否與一個大圓b相交:

>找到向量c,一個整個大圓與b的交點.

>找到向量d,c的對映體.

>如果c位于a.start和a.end之間,或者d位于a.start和a.end之間,則a與b相交.

//returns true if Vector x lies between Vectors a and b.

//note that this function only gives sensical results if the three vectors are coplanar.

boolean liesBetween(Vector x, Vector a, Vector b){

return angleBetween(a,x) + angleBetween(x,b) == angleBetween(a,b);

}

bool GreatCircleSegment::Intersects(GreatCircle b){

Vector c = intersection(this.getWhole(), b);

Vector d = antipode(c);

return liesBetween(c, this.start, this.end) or liesBetween(d, this.start, this.end);

}

如果出現以下情況,兩個大圓段a和b相交:

> a與b的整個大圓相交

> b與整個大圓相交

bool GreatCircleSegment::Intersects(GreatCircleSegment b){

return this.Intersects(b.getWhole()) and b.Intersects(this.getWhole());

}

現在,您可以構造多邊形并計算參考線在其上經過的次數.

bool liesWithin(Array polygon, Coordinate pointNotLyingInsidePolygon, Coordinate vehiclePosition){

GreatCircleSegment referenceLine = segmentFromCoordinates(pointNotLyingInsidePolygon, vehiclePosition);

int intersections = 0;

//iterate through all adjacent polygon vertex pairs

//we iterate i one farther than the size of the array, because we need to test the segment formed by the first and last coordinates in the array

for(int i = 0; i < polygon.size + 1; i++){

int j = (i+1) % polygon.size;

GreatCircleSegment polygonEdge = segmentFromCoordinates(polygon[i], polygon[j]);

if (referenceLine.Intersects(polygonEdge)){

intersections++;

}

}

return intersections % 2 == 1;

}

總結

以上是生活随笔為你收集整理的php如何测量坐标周围,php – 如何检查经度/纬度点是否在坐标范围内?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。