Skip to content

Commit

Permalink
Add GeometryEngine::split()
Browse files Browse the repository at this point in the history
  • Loading branch information
BenMorel committed Jun 5, 2024
1 parent 26f63a0 commit 9aa124a
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 34 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## UNRELEASED (0.11.0)

💥 **Breaking changes**

- interface `GeometryEngine` has a new method: `split()`

**New features**

- New engine method: `GeometryEngine::split()`

## [0.10.0](https://github.com/brick/geo/releases/tag/0.10.0) - 2024-01-23

💥 **Breaking changes**
Expand Down
69 changes: 35 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,46 +272,47 @@ Here is a list of all exceptions:
- `UnexpectedGeometryException` is thrown when a geometry is not an instance of the expected sub-type, for example when
calling `Point::fromText()` with a `LineString` WKT.

Spatial Function Reference
--------------------------
GeometryEngine methods reference
--------------------------------

This is a list of all functions which are currently implemented in the geo project. Some functions are only available
This is a list of all methods available in the `GeometryEngine` interface. Some methods are only available
if you use a specific geometry engine, sometimes with a minimum version.
This table also shows which functions are part of the OpenGIS standard.

| Function Name | GEOS | PostGIS | MySQL | MariaDB | SpatiaLite | OpenGIS standard |
|------------------|------|---------|--------|---------|------------|------------------|
| `area` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `azimuth` | | ✓ | | | ✓ | |
| `boundary` | ✓ | ✓ | | | ✓ | ✓ |
| `buffer` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `centroid` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `contains` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `convexHull` | ✓ | ✓ | 5.7.6 | | ✓ | ✓ |
| `crosses` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `difference` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `disjoint` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `distance` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `envelope` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `equals` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `intersects` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `intersection` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `isSimple` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `isValid` | ✓ | ✓ | 5.7.6 | | ✓ | |
| `length` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `locateAlong` | | ✓ | | | ✓ | |
| `locateBetween` | | ✓ | | | ✓ | |
| `makeValid` | | ✓ | | | ✓ | |
| `maxDistance` | | ✓ | | | ✓ | |
| `overlaps` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `pointOnSurface` | ✓ | ✓ | | | ✓ | ✓ |
| `relate` | ✓ | ✓ | | | ✓ | ✓ |
| `simplify` | ✓ | ✓ | 5.7.6 | | 4.1.0 | |
| `snapToGrid` | | ✓ | | | ✓ | |
| `symDifference` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `touches` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `union` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `within` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `area` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `azimuth` | | ✓ | | | ✓ | |
| `boundary` | ✓ | ✓ | | | ✓ | ✓ |
| `buffer` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `centroid` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `contains` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `convexHull` | ✓ | ✓ | 5.7.6 | | ✓ | ✓ |
| `crosses` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `difference` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `disjoint` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `distance` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `envelope` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `equals` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `intersection` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `intersects` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `isSimple` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `isValid` | ✓ | ✓ | 5.7.6 | | ✓ | |
| `length` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `locateAlong` | | ✓ | | | ✓ | |
| `locateBetween` | | ✓ | | | ✓ | |
| `makeValid` | | ✓ | | | ✓ | |
| `maxDistance` | | ✓ | | | ✓ | |
| `overlaps` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `pointOnSurface` | ✓ | ✓ | | | ✓ | ✓ |
| `relate` | ✓ | ✓ | | | ✓ | ✓ |
| `simplify` | ✓ | ✓ | 5.7.6 | | 4.1.0 | |
| `snapToGrid` | | ✓ | | | ✓ | |
| `split` | | ✓ | | | ✓ | |
| `symDifference` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `touches` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `union` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `within` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |

Importing and exporting geometries
----------------------------------
Expand Down
5 changes: 5 additions & 0 deletions src/Engine/DatabaseEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -433,4 +433,9 @@ public function transform(Geometry $g, int $srid) : Geometry
{
return $this->queryGeometry('ST_Transform', $g, $srid);
}

public function split(Geometry $g, Geometry $blade) : Geometry
{
return $this->queryGeometry('ST_Split', $g, $blade);
}
}
5 changes: 5 additions & 0 deletions src/Engine/GEOSEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,4 +375,9 @@ public function transform(Geometry $g, int $srid) : Geometry
{
throw GeometryEngineException::unimplementedMethod(__METHOD__);
}

public function split(Geometry $g, Geometry $blade) : Geometry
{
throw GeometryEngineException::unimplementedMethod(__METHOD__);
}
}
5 changes: 5 additions & 0 deletions src/Engine/GeometryEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -486,4 +486,9 @@ public function boundingPolygons(Polygon $p) : MultiPolygon;
* Returns a new geometry with its coordinates transformed to a different spatial reference system.
*/
public function transform(Geometry $g, int $srid) : Geometry;

/**
* Splits a geometry into several geometries using a blade.
*/
public function split(Geometry $g, Geometry $blade) : Geometry;
}
27 changes: 27 additions & 0 deletions tests/GeometryEngineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,33 @@ public static function providerTransform() : array
];
}

#[DataProvider('providerSplit')]
public function testSplit(string $originalWKT, string $bladeWKT, string $expectedWKT) : void
{
$geometryEngine = $this->getGeometryEngine();

if (! $this->isPostGIS() && ! $this->isSpatiaLite()) {
self::markTestSkipped('This test currently runs on PostGIS & SpatiaLite only.');
}

$originalGeometry = Geometry::fromText($originalWKT);
$bladeGeometry = Geometry::fromText($bladeWKT);

$splitGeometry = $geometryEngine->split($originalGeometry, $bladeGeometry);

$this->assertSame($expectedWKT, $splitGeometry->asText());
}

public static function providerSplit() : array
{
return [
['LINESTRING (1 1, 3 3)', 'POINT (2 2)', 'GEOMETRYCOLLECTION (LINESTRING (1 1, 2 2), LINESTRING (2 2, 3 3))'],
['LINESTRING (1 1, 1 2, 2 2, 2 1, 1 1)', 'LINESTRING (0 0, 3 3)', 'GEOMETRYCOLLECTION (LINESTRING (1 1, 1 2, 2 2), LINESTRING (2 2, 2 1, 1 1))'],
['POLYGON ((1 1, 1 2, 2 2, 2 1, 1 1))', 'LINESTRING (0 0, 3 3)', 'GEOMETRYCOLLECTION (POLYGON ((1 1, 1 2, 2 2, 1 1)), POLYGON ((2 2, 2 1, 1 1, 2 2)))'],
['POLYGON ((1 1, 1 2, 3 2, 3 1, 1 1))', 'LINESTRING (1 1, 2 2, 3 1)', 'GEOMETRYCOLLECTION (POLYGON ((1 1, 1 2, 2 2, 1 1)), POLYGON ((1 1, 2 2, 3 1, 1 1)), POLYGON ((3 1, 2 2, 3 2, 3 1)))'],
];
}

private function getGeometryEngine(): GeometryEngine
{
if (! isset($GLOBALS['GEOMETRY_ENGINE'])) {
Expand Down

0 comments on commit 9aa124a

Please sign in to comment.