Exemplo n.º 1
0
 /**
  * If this method returns false, the region does not intersect the given cell.
  * Otherwise, either region intersects the cell, or the intersection
  * relationship could not be determined.
  */
 public function mayIntersect(S2Cell $cell)
 {
     if ($this->numLoops() == 1) {
         return $this->loop(0)->mayIntersect($cell);
     }
     $cellBound = $cell->getRectBound();
     if (!$this->bound->intersects($cellBound)) {
         return false;
     }
     $cellLoop = new S2Loop($cell, $cellBound);
     $cellPoly = new S2Polygon($cellLoop);
     return $this->intersects($cellPoly);
 }
 public function getRectBound()
 {
     if ($this->level > 0) {
         // Except for cells at level 0, the latitude and longitude extremes are
         // attained at the vertices. Furthermore, the latitude range is
         // determined by one pair of diagonally opposite vertices and the
         // longitude range is determined by the other pair.
         //
         // We first determine which corner (i,j) of the cell has the largest
         // absolute latitude. To maximize latitude, we want to find the point in
         // the cell that has the largest absolute z-coordinate and the smallest
         // absolute x- and y-coordinates. To do this we look at each coordinate
         // (u and v), and determine whether we want to minimize or maximize that
         // coordinate based on the axis direction and the cell's (u,v) quadrant.
         $u = $this->uv[0][0] + $this->uv[0][1];
         $v = $this->uv[1][0] + $this->uv[1][1];
         $i = S2Projections::getUAxis($this->face)->z == 0 ? $u < 0 ? 1 : 0 : ($u > 0 ? 1 : 0);
         $j = S2Projections::getVAxis($this->face)->z == 0 ? $v < 0 ? 1 : 0 : ($v > 0 ? 1 : 0);
         $lat = R1Interval::fromPointPair($this->getLatitude($i, $j), $this->getLatitude(1 - $i, 1 - $j));
         $lat = $lat->expanded(self::MAX_ERROR)->intersection(S2LatLngRect::fullLat());
         if ($lat->lo() == -S2::M_PI_2 || $lat->hi() == S2::M_PI_2) {
             return new S2LatLngRect($lat, S1Interval::full());
         }
         $lng = S1Interval::fromPointPair($this->getLongitude($i, 1 - $j), $this->getLongitude(1 - $i, $j));
         return new S2LatLngRect($lat, $lng->expanded(self::MAX_ERROR));
     }
     // The face centers are the +X, +Y, +Z, -X, -Y, -Z axes in that order.
     // assert (S2Projections.getNorm(face).get(face % 3) == ((face < 3) ? 1 : -1));
     switch ($this->face) {
         case 0:
             return new S2LatLngRect(new R1Interval(-S2::M_PI_4, S2::M_PI_4), new S1Interval(-S2::M_PI_4, S2::M_PI_4));
         case 1:
             return new S2LatLngRect(new R1Interval(-S2::M_PI_4, S2::M_PI_4), new S1Interval(S2::M_PI_4, 3 * S2::M_PI_4));
         case 2:
             return new S2LatLngRect(new R1Interval(POLE_MIN_LAT, S2::M_PI_2), new S1Interval(-S2::M_PI, S2::M_PI));
         case 3:
             return new S2LatLngRect(new R1Interval(-S2::M_PI_4, S2::M_PI_4), new S1Interval(3 * S2::M_PI_4, -3 * S2::M_PI_4));
         case 4:
             return new S2LatLngRect(new R1Interval(-S2::M_PI_4, S2::M_PI_4), new S1Interval(-3 * S2::M_PI_4, -S2::M_PI_4));
         default:
             return new S2LatLngRect(new R1Interval(-S2::M_PI_2, -POLE_MIN_LAT), new S1Interval(-S2::M_PI, S2::M_PI));
     }
 }
 public function getRectBound()
 {
     if ($this->isEmpty()) {
         return S2LatLngRect::emptya();
     }
     // Convert the axis to a (lat,lng) pair, and compute the cap angle.
     $axisLatLng = new S2LatLng($this->axis);
     $capAngle = $this->angle()->radians();
     $allLongitudes = false;
     $lat = array();
     $lng = array();
     $lng[0] = -S2::M_PI;
     $lng[1] = S2::M_PI;
     // Check whether cap includes the south pole.
     $lat[0] = $axisLatLng->lat()->radians() - $capAngle;
     if ($lat[0] <= -S2::M_PI_2) {
         $lat[0] = -S2::M_PI_2;
         $allLongitudes = true;
     }
     // Check whether cap includes the north pole.
     $lat[1] = $axisLatLng->lat()->radians() + $capAngle;
     if ($lat[1] >= S2::M_PI_2) {
         $lat[1] = S2::M_PI_2;
         $allLongitudes = true;
     }
     if (!$allLongitudes) {
         // Compute the range of longitudes covered by the cap. We use the law
         // of sines for spherical triangles. Consider the triangle ABC where
         // A is the north pole, B is the center of the cap, and C is the point
         // of tangency between the cap boundary and a line of longitude. Then
         // C is a right angle, and letting a,b,c denote the sides opposite A,B,C,
         // we have sin(a)/sin(A) = sin(c)/sin(C), or sin(A) = sin(a)/sin(c).
         // Here "a" is the cap angle, and "c" is the colatitude (90 degrees
         // minus the latitude). This formula also works for negative latitudes.
         //
         // The formula for sin(a) follows from the relationship h = 1 - cos(a).
         $sinA = sqrt($this->height * (2 - $this->height));
         $sinC = cos($axisLatLng->lat()->radians());
         if ($sinA <= $sinC) {
             $angleA = asin($sinA / $sinC);
             $lng[0] = S2::IEEEremainder($axisLatLng->lng()->radians() - $angleA, 2 * S2::M_PI);
             $lng[1] = S2::IEEEremainder($axisLatLng->lng()->radians() + $angleA, 2 * S2::M_PI);
         }
     }
     return new S2LatLngRect(new R1Interval($lat[0], $lat[1]), new S1Interval($lng[0], $lng[1]));
 }