Example #1
0
 /**
  * Returns the singleton instance of geometric class of the given type.
  *
  * @param string $type type of the geometric object
  *
  * @return PMA_GIS_Geometry the singleton instance of geometric class
  *                          of the given type
  *
  * @access public
  * @static
  */
 public static function factory($type)
 {
     include_once './libraries/gis/pma_gis_geometry.php';
     $type_lower = strtolower($type);
     if (!file_exists('./libraries/gis/pma_gis_' . $type_lower . '.php')) {
         return false;
     }
     if (include_once './libraries/gis/pma_gis_' . $type_lower . '.php') {
         switch (strtoupper($type)) {
             case 'MULTIPOLYGON':
                 return PMA_GIS_Multipolygon::singleton();
             case 'POLYGON':
                 return PMA_GIS_Polygon::singleton();
             case 'MULTIPOINT':
                 return PMA_GIS_Multipoint::singleton();
             case 'POINT':
                 return PMA_GIS_Point::singleton();
             case 'MULTILINESTRING':
                 return PMA_GIS_Multilinestring::singleton();
             case 'LINESTRING':
                 return PMA_GIS_Linestring::singleton();
             case 'GEOMETRYCOLLECTION':
                 return PMA_GIS_Geometrycollection::singleton();
             default:
                 return false;
         }
     } else {
         return false;
     }
 }
 /**
  * Returns the singleton instance of geometric class of the given type.
  *
  * @param string $type type of the geometric object
  *
  * @return PMA_GIS_Geometry the singleton instance of geometric class
  *                          of the given type
  *
  * @access public
  * @static
  */
 public static function factory($type)
 {
     include_once './libraries/gis/GIS_Geometry.class.php';
     $type_lower = strtolower($type);
     $file = './libraries/gis/GIS_' . ucfirst($type_lower) . '.class.php';
     if (!PMA_isValid($type_lower, PMA_Util::getGISDatatypes()) || !file_exists($file)) {
         return false;
     }
     if (include_once $file) {
         switch (strtoupper($type)) {
             case 'MULTIPOLYGON':
                 return PMA_GIS_Multipolygon::singleton();
             case 'POLYGON':
                 return PMA_GIS_Polygon::singleton();
             case 'MULTIPOINT':
                 return PMA_GIS_Multipoint::singleton();
             case 'POINT':
                 return PMA_GIS_Point::singleton();
             case 'MULTILINESTRING':
                 return PMA_GIS_Multilinestring::singleton();
             case 'LINESTRING':
                 return PMA_GIS_Linestring::singleton();
             case 'GEOMETRYCOLLECTION':
                 return PMA_GIS_Geometrycollection::singleton();
             default:
                 return false;
         }
     } else {
         return false;
     }
 }
 /**
  * Returns the singleton instance of geometric class of the given type.
  *
  * @param string $type type of the geometric object
  *
  * @return PMA_GIS_Geometry the singleton instance of geometric class
  *                          of the given type
  *
  * @access public
  * @static
  */
 public static function factory($type)
 {
     include_once './libraries/gis/GIS_Geometry.class.php';
     /** @var PMA_String $pmaString */
     $pmaString = $GLOBALS['PMA_String'];
     $file = './libraries/gis/GIS_' . ucfirst($pmaString->strtolower($type)) . '.class.php';
     if (!file_exists($file)) {
         return false;
     }
     if (include_once $file) {
         switch ($pmaString->strtoupper($type)) {
             case 'MULTIPOLYGON':
                 return PMA_GIS_Multipolygon::singleton();
             case 'POLYGON':
                 return PMA_GIS_Polygon::singleton();
             case 'MULTIPOINT':
                 return PMA_GIS_Multipoint::singleton();
             case 'POINT':
                 return PMA_GIS_Point::singleton();
             case 'MULTILINESTRING':
                 return PMA_GIS_Multilinestring::singleton();
             case 'LINESTRING':
                 return PMA_GIS_Linestring::singleton();
             case 'GEOMETRYCOLLECTION':
                 return PMA_GIS_Geometrycollection::singleton();
             default:
                 return false;
         }
     } else {
         return false;
     }
 }
 /**
  * test for getPointOnSurface
  *
  * @param array $ring array of points forming the ring
  *
  * @dataProvider providerForTestGetPointOnSurface
  * @return void
  */
 public function testGetPointOnSurface($ring)
 {
     $this->assertEquals(
         $this->object->isPointInsidePolygon(
             $this->object->getPointOnSurface($ring),
             $ring
         ),
         true
     );
 }
 /**
  * Returns a point that is guaranteed to be on the surface of the ring.
  * (for simple closed rings)
  *
  * @param array $ring array of points forming the ring
  *
  * @return array|void a point on the surface of the ring
  * @access public
  * @static
  */
 public static function getPointOnSurface($ring)
 {
     // Find two consecutive distinct points.
     for ($i = 0, $nb = count($ring) - 1; $i < $nb; $i++) {
         if ($ring[$i]['y'] != $ring[$i + 1]['y']) {
             $x0 = $ring[$i]['x'];
             $x1 = $ring[$i + 1]['x'];
             $y0 = $ring[$i]['y'];
             $y1 = $ring[$i + 1]['y'];
             break;
         }
     }
     if (!isset($x0)) {
         return false;
     }
     // Find the mid point
     $x2 = ($x0 + $x1) / 2;
     $y2 = ($y0 + $y1) / 2;
     // Always keep $epsilon < 1 to go with the reduction logic down here
     $epsilon = 0.1;
     $denominator = sqrt(PMA_Util::pow($y1 - $y0, 2) + PMA_Util::pow($x0 - $x1, 2));
     $pointA = array();
     $pointB = array();
     while (true) {
         // Get the points on either sides of the line
         // with a distance of epsilon to the mid point
         $pointA['x'] = $x2 + $epsilon * ($y1 - $y0) / $denominator;
         $pointA['y'] = $y2 + ($pointA['x'] - $x2) * ($x0 - $x1) / ($y1 - $y0);
         $pointB['x'] = $x2 + $epsilon * ($y1 - $y0) / (0 - $denominator);
         $pointB['y'] = $y2 + ($pointB['x'] - $x2) * ($x0 - $x1) / ($y1 - $y0);
         // One of the points should be inside the polygon,
         // unless epsilon chosen is too large
         if (PMA_GIS_Polygon::isPointInsidePolygon($pointA, $ring)) {
             return $pointA;
         }
         if (PMA_GIS_Polygon::isPointInsidePolygon($pointB, $ring)) {
             return $pointB;
         }
         //If both are outside the polygon reduce the epsilon and
         //recalculate the points(reduce exponentially for faster convergence)
         $epsilon = PMA_Util::pow($epsilon, 2);
         if ($epsilon == 0) {
             return false;
         }
     }
 }
 /**
  * test case for isOuterRing() method
  *
  * @param array $ring coordinates of the points in a ring
  *
  * @return void
  * @dataProvider providerForIsOuterRing
  */
 public function testIsOuterRing($ring)
 {
     $this->assertTrue($this->object->isOuterRing($ring));
 }
 /**
  * Generate the WKT for the data from ESRI shape files.
  *
  * @param array $row_data GIS data
  *
  * @return string the WKT for the data from ESRI shape files
  * @access public
  */
 public function getShape($row_data)
 {
     // Determines whether each line ring is an inner ring or an outer ring.
     // If it's an inner ring get a point on the surface which can be used to
     // correctly classify inner rings to their respective outer rings.
     include_once './libraries/gis/GIS_Polygon.class.php';
     foreach ($row_data['parts'] as $i => $ring) {
         $row_data['parts'][$i]['isOuter'] = PMA_GIS_Polygon::isOuterRing($ring['points']);
     }
     // Find points on surface for inner rings
     foreach ($row_data['parts'] as $i => $ring) {
         if (!$ring['isOuter']) {
             $row_data['parts'][$i]['pointOnSurface'] = PMA_GIS_Polygon::getPointOnSurface($ring['points']);
         }
     }
     // Classify inner rings to their respective outer rings.
     foreach ($row_data['parts'] as $j => $ring1) {
         if ($ring1['isOuter']) {
             continue;
         }
         foreach ($row_data['parts'] as $k => $ring2) {
             if (!$ring2['isOuter']) {
                 continue;
             }
             // If the pointOnSurface of the inner ring
             // is also inside the outer ring
             if (PMA_GIS_Polygon::isPointInsidePolygon($ring1['pointOnSurface'], $ring2['points'])) {
                 if (!isset($ring2['inner'])) {
                     $row_data['parts'][$k]['inner'] = array();
                 }
                 $row_data['parts'][$k]['inner'][] = $j;
             }
         }
     }
     $wkt = 'MULTIPOLYGON(';
     // for each polygon
     foreach ($row_data['parts'] as $ring) {
         if (!$ring['isOuter']) {
             continue;
         }
         $wkt .= '(';
         // start of polygon
         $wkt .= '(';
         // start of outer ring
         foreach ($ring['points'] as $point) {
             $wkt .= $point['x'] . ' ' . $point['y'] . ',';
         }
         $wkt = mb_substr($wkt, 0, mb_strlen($wkt) - 1);
         $wkt .= ')';
         // end of outer ring
         // inner rings if any
         if (isset($ring['inner'])) {
             foreach ($ring['inner'] as $j) {
                 $wkt .= ',(';
                 // start of inner ring
                 foreach ($row_data['parts'][$j]['points'] as $innerPoint) {
                     $wkt .= $innerPoint['x'] . ' ' . $innerPoint['y'] . ',';
                 }
                 $wkt = mb_substr($wkt, 0, mb_strlen($wkt) - 1);
                 $wkt .= ')';
                 // end of inner ring
             }
         }
         $wkt .= '),';
         // end of polygon
     }
     $wkt = mb_substr($wkt, 0, mb_strlen($wkt) - 1);
     $wkt .= ')';
     // end of multipolygon
     return $wkt;
 }