/** * Returns the point which is a fraction along the line between 0 and 1. * * @param Point $point * @param float $fraction between 0 and 1 * * @throw \InvalidArgumentException * @return Point */ public function getFractionAlongLineTo(Point $point, $fraction) { if ($fraction < 0 || $fraction > 1) { throw new \InvalidArgumentException('$fraction must be between 0 and 1'); } if (function_exists('fraction_along_gc_line') && Location::$useSpatialExtension) { $result = fraction_along_gc_line($this->jsonSerialize(), $point->jsonSerialize(), $fraction); return new self($result['coordinates']); } else { $distance = Location::haversine($this, $point); $lat1 = $this->latitudeToRad(); $lat2 = $point->latitudeToRad(); $lon1 = $this->longitudeToRad(); $lon2 = $point->longitudeToRad(); $a = sin((1 - $fraction) * $distance) / sin($distance); $b = sin($fraction * $distance) / sin($distance); $x = $a * cos($lat1) * cos($lon1) + $b * cos($lat2) * cos($lon2); $y = $a * cos($lat1) * sin($lon1) + $b * cos($lat2) * sin($lon2); $z = $a * sin($lat1) + $b * sin($lat2); $res_lat = atan2($z, sqrt(pow($x, 2) + pow($y, 2))); $res_long = atan2($y, $x); return new self(rad2deg($res_lat), rad2deg($res_long)); } }
/** * @expectedException \InvalidArgumentException */ public function testDistanceToException() { $newPoint = new Point(53.48204, -2.23194); $this->point->distanceTo($newPoint, 'foo'); }
private function fractionAlongLine() { $point1 = new Point([5, 10]); $point2 = new Point([15, 10]); $fraction02 = $point1->getFractionAlongLineTo($point2, 0.2); $fraction05 = $point1->getFractionAlongLineTo($point2, 0.5); $midpoint = $point1->getMidpoint($point2); $this->assertEquals(6.9998522347268, $fraction02->getLongitude()); $this->assertEquals(10.023944943799, $fraction02->getLatitude()); $this->assertEquals($midpoint->getLatitude(), $fraction05->getLatitude()); $this->assertEquals($midpoint->getLongitude(), $fraction05->getLongitude()); }
/** * @param Point $point the centre of the bounding box * @param number $radius minimum radius from $point * @param string $unit unit of the radius (default is kilometres) * * @return Polygon the BBox */ public static function getBBoxByRadius(Point $point, $radius, $unit = 'km') { $north = $point->getRelativePoint($radius, 0, $unit); $south = $point->getRelativePoint($radius, 180, $unit); $limits['n'] = $north->getLatitude(); $limits['s'] = $south->getLatitude(); $radDist = $radius / Location::getEllipsoid()->radius($unit); // $minLat = deg2rad( $limits['s'] ); // $maxLat = deg2rad( $limits['n'] ); $radLon = $point->longitudeToRad(); //if ($minLat > deg2rad(-90) && $maxLat < deg2rad(90)) { $deltaLon = asin(sin($radDist) / cos($point->latitudeToRad())); $minLon = $radLon - $deltaLon; if ($minLon < deg2rad(-180)) { $minLon += 2 * pi(); } $maxLon = $radLon + $deltaLon; if ($maxLon > deg2rad(180)) { $maxLon -= 2 * pi(); } //} $limits['w'] = rad2deg($minLon); $limits['e'] = rad2deg($maxLon); $nw = new Point($limits['n'], $limits['w']); $ne = new Point($limits['n'], $limits['e']); $sw = new Point($limits['s'], $limits['w']); $se = new Point($limits['s'], $limits['e']); $polygon = new Polygon([[$nw, $ne, $se, $sw]]); return $polygon; }