We are looking to take a point and compare it against the nearest point to an adjacent line. All values are in lat/long.
We tried using some of the concept found on the board but found it did not work if the points share a same lat or long as it ends up multiplying by zero when subtracting the differences
Does anyone have working Java or PHP scripts they can share? Here is the code version 1 we have been working with
function IntersectionDAN ($startLat, $startLon, $endLat, $endLon, $pointlato, $pointlono)
{
//Find if points are in the same plane
if ($pointlato == $endLat) {
return Intersectingdistance ($pointlato,$pointlono,$endlat,$endLon );
}else
if ($pointlono == $endlat) {
return Intersectingdistance ($pointlato,$pointlono,$endlat,$endLon );
}else
if ($pointlato == $startLat) {
return Intersectingdistance ($pointlato,$pointlono,$startLat,$startLon);
}else
if ($pointlono == $startLon) {
return Intersectingdistance ($pointlato,$pointlono,$startLat,$startLon);
}
$startLat = ($startLat);
$startLon = ($startLon);
$endLat = ($endLat);
$endLon = ($endLon);
$pointlat = ($pointlato);
$pointlon = ($pointlono);
$Xline1 = $endLon - $startLon;
$Yline2 = $endLat - $startLat;
$ShortestLength =(($Xline1 *($pointlon - $startLon)) + ($Yline2 * ($pointlat - $startLat))) / (($Xline1 * $Xline1) + ($Yline2 *$Yline2));
$Xcrosssection1lon = ($startLon + $Xline1) * $ShortestLength;
$Ycrosssection1lat = ($endLat + $Yline2 )* $ShortestLength;
if (($Ycrosssection1lat < $endLat && $Ycrosssection1lat > $endLon) && ($Xcrosssection1lon < $endLon && $Xcrosssection1lon > $startLon)) {
return array(
"lat" => $Ycrosssection1lat,
"lon" => $Xcrosssection1lon
);
}else {
echo "nothing";
}
var_dump($ShortestLength);
var_dump($Ycrosssection1lat);
var_dump($Xcrosssection1lon);
return Intersectingdistance($pointlato, $pointlono, $Ycrosssection1lat, $Xcrosssection1lon);
}
function Intersectingdistance($pointlat,$pointlon,$Ycrosssection1lat,$Xcrosssection1lon)
{
$R = 6378.137; // Radius of earth in KM
$pi = pi(); // It's delicious and cut precisely
$pointlat = ($pointlat);
$pointlon = ($pointlon);
$Ycrosssection1lat = ($Ycrosssection1lat);
$Xcrosssection1lon = ($Xcrosssection1lon);
$dLat = ($pointlat - $Ycrosssection1lat);
$dLon = ($pointlon - $Xcrosssection1lon);
$a = sin(deg2rad($pointlat)) * sin(deg2rad($Ycrosssection1lat)) + cos(deg2rad($pointlat)) * cos(deg2rad($Ycrosssection1lat)) *sin(deg2rad($dLon));
//$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
//$d = $R * $c;
$a = rad2deg($a);
$d = acos($a);
$miles = $d * 60 * 1.1515;
$Distance = ($miles); // feet
var_dump($Distance);
}
$IntersectionDAN = IntersectionDAN(40.124423,-74.326886, 40.124561,-74.327066,40.124561,-74.326886);
In addion we have been working on a much more complex version and are completely stuck and getting the incorrect results back.
public function intersection($line1Lat, $line1Lon, $line1bear, $line2Lat, $line2Lon, $line2bear, &$line3Lat, &$line3Lon)
{
$pi = pi();
$line1Lat = $line1Lat * $pi / 180;
$line1Lon = $line1Lon * $pi / 180;
$line1bear = $line1bear * $pi / 180;
$line2Lat = $line2Lat * $pi / 180;
$line2Lon = $line2Lon * $pi / 180;
$line2bear = $line2bear * $pi / 180;
$dst12=2*asin(sqrt((sin(($line1Lat-$line2Lat)/2))*(sin(($line1Lat-$line2Lat)/2)) +cos($line1Lat)*cos($line2Lat)*(sin(($line1Lon-$line2Lon)/2))*(sin(($line1Lon-$line2Lon)/2))));
if (sin($line2Lon-$line1Lon)<0)
{
$crs12=acos((sin($line2Lat)-sin($line1Lat)*cos($dst12))/(sin($dst12)*cos($line1Lat)));
$crs21=2.*$pi-acos((sin($line1Lat)-sin($line2Lat)*cos($dst12))/(sin($dst12)*cos($line2Lat)));
}
else
{
$crs12=2.*$pi-acos((sin($line2Lat)-sin($line1Lat)*cos($dst12))/(sin($dst12)*cos($line1Lat)));
$crs21=acos((sin($line1Lat)-sin($line2Lat)*cos($dst12))/(sin($dst12)*cos($line2Lat)));
}
$ang1=(crs13-$crs12+$pi)%(2.*$pi)-$pi;
$ang2=($crs21-crs23+$pi)%(2.*$pi)-$pi;
if (sin($ang1)==0 && sin($ang2)==0)
{
echo "infinity of intersections";
}
elseif (sin($ang1)*sin($ang2)<0)
{
echo "intersection ambiguous";
}
else
{
$ang1=abs($ang1);
$ang2=abs($ang2);
$ang3=acos(-cos($ang1)*cos($ang2)+sin($ang1)*sin($ang2)*cos($dst12));
$dst13=atan2(sin($dst12)*sin($ang1)*sin($ang2),cos($ang2)+cos($ang1)*cos(ang3));
$line3Lat=asin(sin($line1Lat)*cos($dst13)+cos($line1Lat)*sin($dst13)*cos(crs13));
$dlon=atan2(sin(crs13)*sin($dst13)*cos($line1Lat),cos($dst13)-sin($line1Lat)*sin(lat3));
$line3Lon=($line1Lon-$dlon+$pi)%(2*$pi)-$pi;
}
}
public function bearing($lat1, $lon1, $lat2, $lon2)
{
echo " Bearing Start ";
$pi = pi();
$lat1 = $lat1 * $pi / 180;
$lon1 = $lon1 * $pi / 180;
$lat2 = $lat2 * $pi / 180;
$lon2 = $lon2 * $pi / 180;
$dLon = ($lon2 - $lon1);
$y = sin($dLon) * cos($lat2);
var_dump($y);
$x = cos($lat1)*sin($lat2)-sin($lat1)*cos($lat2)*cos($dLon);
var_dump($x);
echo " Bearing Stop ";
return (atan2($y, $x) + (2*$pi))%(2*$pi) * 180 / $pi;
}
public function destination($lat, $lon, $bearing, $distance, &$outputLat, &$outputLon)
{
$R = 6378.137; //km
$pi = pi();
$distance = $distance / 3.2808399 / 1000; //input feet to km
$outputLat = asin(sin($lat * $pi / 180)*cos($distance/$R) + cos($lat * $pi / 180)*sin($distance/$R)*cos($bearing * $pi / 180)) * 180 / $pi;
$outputLon = ($lon * $pi / 180 + atan2(sin($bearing * $pi / 180)*sin($distance/$R)*cos($lat * $pi / 180), cos($distance/$R)-sin($lat * $pi / 180)*sin($outputLat * $pi / 180))) * 180 / $pi;
}
public function crossProduct(&$v1, &$v2, &$vR)
{
$vR[0] = (($v1[1] * $v2[2]) - ($v1[2] * $v2[1]));
$vR[1] = -(($v1[0] * $v2[2]) - ($v1[2] * $v2[0]));
$vR[2] = (($v1[0] * $v2[1]) - ($v1[1] * $v2[0]));
}
public function normalize(&$v1, &$vR)
{
$fMag = sqrt((pow($v1[0], 2)) +
(pow($v1[1], 2)) +
(pow($v1[2], 2))
);
$vR[0] = $v1[0] / $fMag;
$vR[1] = $v1[1] / $fMag;
$vR[2] = $v1[2] / $fMag;
}
public function magnitude(&$vR)
{
$fMag = sqrt((pow($vR[0], 2)) +
(pow($vR[1], 2)) +
(pow($vR[2], 2))
);
return $fMag;
}
/**
* Determine distance between point and line in feet
*
* @param $xpoint1
* @param $ypoint1
* @param $xline2
* @param $yline2
* @param $xline3
* @param $yline3
* @return float
*/
public function pointToLineDistance($pointLat, $pointLon, $line1Lat, $line1Lon, $line2Lat, $line2Lon)
{
if ($line1Lat < $line2Lat)
{
$temp1 = $line1Lat;
$temp2 = $line1Lon;
$line1Lat = $line2Lat;
$line1Lon = $line2Lon;
$line2Lat = $temp1;
$line2Lon = $temp2;
}
$lineBear = $this->bearing($line2Lat, $line2Lon, $line1Lat, $line1Lon);
echo "lineBear ";
var_dump($lineBear);
if ($lineBear > 180)
{
$temp1 = $line1Lat;
$temp2 = $line1Lon;
$line1Lat = $line2Lat;
$line1Lon = $line2Lon;
$line2Lat = $temp1;
$line2Lon = $temp2;
}
echo "line1Lat ";
var_dump($line1Lat);
echo "line1Lon ";
var_dump($line1Lon);
echo "line2Lat ";
var_dump($line2Lat);
echo "line2Lon ";
var_dump($line2Lon);
$v1bear = $this->bearing($pointLat, $pointLon, $line1Lat, $line1Lon);
echo "v1bear ";
var_dump($v1bear);
$v2bear = $this->bearing($pointLat, $pointLon, $line2Lat, $line2Lon);
echo "v2bear ";
var_dump($v2bear);
$v1dist = $this->pointToPointDistance($pointLat, $pointLon, $line1Lat, $line1Lon);
echo "v1dist ";
var_dump($v1dist);
$v2dist = $this->pointToPointDistance($pointLat, $pointLon, $line2Lat, $line2Lon);
echo "v2dist ";
var_dump($v2dist);
$v1[0] = sin((180-($v1bear-$lineBear)+360)%360 * $pi / 180) * $v1dist;
$v1[1] = cos((180-($v1bear-$lineBear)+360)%360 * $pi / 180) * $v1dist;
$v1[2] = 0;
echo "v1";
var_dump($v1);
$v2[0] = sin(($v2bear+$lineBear+360)%360 * $pi / 180) * $v2dist;
$v2[1] = cos(($v2bear+$lineBear+360)%360 * $pi / 180) * $v2dist;
$v2[2] = 0;
echo "v2";
var_dump($v2);
$vR = null;
$this->crossProduct($v1, $v2, $vR);
echo "vR";
var_dump($vR);
$mag = $this->magnitude($vR);
echo "vR mag";
var_dump($mag);
$mag2 = $this->pointToPointDistance($line1Lat, $line1Lon, $line2Lat, $line2Lon);
echo "line mag";
var_dump($mag2);
$d = $mag / $mag2;
echo "result";
var_dump($d);
//$R = 6378.137;
//$d = $d * 1000 * 3.2808;
return $d;
Our goal is to have an accurate Point to Line Segment Calculation so point C can be compared against Line AB
Sorry for the confusion here and hope you can help Thanks!
No comments:
Post a Comment