Skip to content

Commit

Permalink
port geodata changes from 0.11-feat-showcase and fix new tests
Browse files Browse the repository at this point in the history
Signed-off-by: Vinzenz Rosenkranz <[email protected]>
  • Loading branch information
v1r0x committed Nov 26, 2024
1 parent 76289e5 commit 0c63a82
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 87 deletions.
5 changes: 2 additions & 3 deletions app/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use App\AttributeTypes\AttributeBase;
use Illuminate\Database\Eloquent\Model;
use MStaack\LaravelPostgis\Geometries\Geometry;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;

Expand Down Expand Up @@ -59,7 +58,7 @@ public function getEntityAttributeValueName() {

public function getAttributeValueFromEntityPivot()
{
switch ($this->datatype) {
switch($this->datatype) {
case 'string-sc':
$this->pivot->thesaurus_val = ThConcept::where('concept_url', $this->pivot->thesaurus_val)->first();
break;
Expand All @@ -73,7 +72,7 @@ public function getAttributeValueFromEntityPivot()
$this->pivot->thesaurus_val ??
json_decode($this->pivot->json_val) ??
$this->pivot->dt_val ??
Geometry::fromWKB($this->pivot->geography_val)->toWKT();
Geodata::wkb2wkt($this->pivot->geography_val);
}

public function getSelection() {
Expand Down
9 changes: 3 additions & 6 deletions app/AttributeTypes/GeographyAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use App\Exceptions\InvalidDataException;
use App\Geodata;
use Clickbar\Magellan\IO\Generator\WKT\WKTGenerator;
use App\Utils\StringUtils;
use Exception;

Expand All @@ -18,7 +17,7 @@ public static function parseImport(int|float|bool|string $data) : mixed {
$data = StringUtils::useGuard(InvalidDataException::class)($data);
$geodata = null;
try {
$geodata = Geodata::parseWkt($data);
$geodata = Geodata::fromWKT($data);
} catch(Exception $e) {
throw InvalidDataException::invalidGeoData($data);
}
Expand All @@ -27,12 +26,10 @@ public static function parseImport(int|float|bool|string $data) : mixed {
}

public static function unserialize(mixed $data) : mixed {
return Geodata::parseWkt($data);
return Geodata::fromWKT($data);
}

public static function serialize(mixed $data) : mixed {
// TODO already fixed in 0.11-feat-showcase with the following code:
// return Geodata::toWKT($data);
return (new WKTGenerator())->generate($data);
return Geodata::toWKT($data);
}
}
4 changes: 2 additions & 2 deletions app/AttributeValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App;

use App\Plugins\Map\App\Geodata;
use App\Geodata;
use App\AttributeTypes\AttributeBase;
use Illuminate\Database\Eloquent\Model;
use Clickbar\Magellan\Database\Eloquent\HasPostgisColumns;
Expand Down Expand Up @@ -113,7 +113,7 @@ public static function getValueFromKey($arr) {
return $arr['dt_val'];
}
if(isset($arr['geography_val'])) {
return Geodata::arrayToWkt($arr['geography_val']);
return Geodata::arrayToWKT($arr['geography_val']);
}
}

Expand Down
53 changes: 35 additions & 18 deletions app/Geodata.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,59 @@
namespace App;

use Clickbar\Magellan\Data\Geometries\Geometry;
use Clickbar\Magellan\Database\Eloquent\HasPostgisColumns;
use MStaack\LaravelPostgis\Exceptions\UnknownWKTTypeException;
use Clickbar\Magellan\IO\Generator\WKB\WKBGenerator;
use Clickbar\Magellan\IO\Generator\WKT\WKTGenerator;
use Clickbar\Magellan\IO\Parser\WKB\WKBParser;
use Clickbar\Magellan\IO\Parser\WKT\WKTParser;
use Illuminate\Support\Facades\DB;

class Geodata
{
use HasPostgisColumns;

protected static $availableGeometryTypes = [
'Point', 'LineString', 'Polygon', 'MultiPoint', 'MultiLineString', 'MultiPolygon'
];

public static function getAvailableGeometryTypes() {
public static function getAvailableGeometryTypes(): array {
return self::$availableGeometryTypes;
}


public static function fromWKB(string $wkb): Geometry {
$parser = app(WKBParser::class);
return $parser->parse($wkb);
}

/**
* Parses a WKT string into a Geometry object
* if the WKT string is invalid, an exception is thrown.
*
*
* @param string $wkt
* @return Geometry
* @throws MStaack\LaravelPostgis\Exceptions\UnknownWKTTypeException
* @throws Clickbar\Magellan\Exception\UnknownWKTTypeException
*/
public static function parseWkt($wkt) {
try {
$geom = Geometry::getWKTClass($wkt);
$parsed = $geom::fromWKT($wkt);
return $parsed;
} catch(UnknownWKTTypeException $e) {
return null;
}
public static function fromWKT(string $wkt): Geometry {
$parser = app(WKTParser::class);
// SRID=4326;POINT (2, 2)
return $parser->parse($wkt);
}

public static function arrayToWkt($arr) {
public static function toWKB(Geometry $geometry): string {
return (new WKBGenerator())->generate($geometry);
}

public static function toWKT(Geometry $geometry): string {
return (new WKTGenerator())->generate($geometry);
}

public static function wkt2wkb(string $wkt): string {
return self::toWKB(self::fromWKT($wkt));
}

public static function wkb2wkt(string $wkb) : string {
return self::toWKT(self::fromWKB($wkb));
}

public static function arrayToWKT(array $arr) : string {
$json = json_encode($arr);
return DB::select("SELECT ST_AsText(ST_GeomFromGeoJSON('$json')) AS wkt")[0]->wkt;

}
}
34 changes: 20 additions & 14 deletions tests/Unit/Attributes/GeographyAttributeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ public function testFromImportTruthy($input) {
}

private function assertPoint($expected, $actual) {
$this->assertEquals($expected[0], $actual->getLng());
$this->assertEquals($expected[1], $actual->getLat());
$this->assertEquals($expected[0], $actual->getX());
$this->assertEquals($expected[1], $actual->getY());
$this->assertEquals(isset($expected[2]), $actual->is3d());
if($actual->is3d()) {
$this->assertEquals($expected[2], $actual->getZ());
}
}

private function assertLineString($expected, $actual) {
Expand Down Expand Up @@ -77,21 +81,23 @@ public function testFromImportReturnValues($input, $type, $coordinates) {
* @dataProvider falsyProvider
*/
public function testFromImportFalsy($input) {
$this->expectException(InvalidDataException::class);
GeographyAttribute::fromImport($input);
$this->expectException(InvalidDataException::class);
GeographyAttribute::fromImport($input);
}

public static function truthyProvider() {
return [
"empty" => ["", null, null],
"point" => ["POINT(1 1)", 'point', [1,1]],
"linestring" => ["LINESTRING(0 0, 1 1, 2 2)",'linestring', [[0,0], [1,1], [2,2]]],
"polygon" => ["POLYGON((0 0, 1 1, 1 0, 0 0))",'polygon', [[[0,0], [1,1], [1,0], [0,0]]]],
"multipoint" => ["MULTIPOINT(0 0, 1 1, 2 2)", 'multipoint', [[0,0], [1,1], [2,2]]],
"multilinestring" => ["MULTILINESTRING((0 0, 1 1, 2 2), (3 3, 4 4, 5 5))", "multilinestring", [[[0,0], [1,1], [2,2]], [[3,3], [4,4], [5,5]]]],
"multipolygon" => ["MULTIPOLYGON(((0 0, 1 1, 1 0, 0 0)), ((2 2, 3 3, 3 2, 2 2)))", "multipolygon", [[[[0,0], [1,1], [1,0], [0,0]]], [[[2,2], [3,3], [3,2], [2,2]]]]],
"point with floating point" => ["POINT(1.15847 1.13687)","point", [1.15847, 1.13687]],
];
return [
"empty" => ["", null, null],
"point" => ["POINT(1 1)", 'point', [1,1]],
"point3d0" => ["POINTZ(1 3 0)", 'point', [1,3,0]],
"point3d" => ["POINTZ(2 1 5)", 'point', [2,1,5]],
"linestring" => ["LINESTRING(0 0, 1 1, 2 2)",'linestring', [[0,0], [1,1], [2,2]]],
"polygon" => ["POLYGON((0 0, 1 1, 1 0, 0 0))",'polygon', [[[0,0], [1,1], [1,0], [0,0]]]],
"multipoint" => ["MULTIPOINT(0 0, 1 1, 2 2)", 'multipoint', [[0,0], [1,1], [2,2]]],
"multilinestring" => ["MULTILINESTRING((0 0, 1 1, 2 2), (3 3, 4 4, 5 5))", "multilinestring", [[[0,0], [1,1], [2,2]], [[3,3], [4,4], [5,5]]]],
"multipolygon" => ["MULTIPOLYGON(((0 0, 1 1, 1 0, 0 0)), ((2 2, 3 3, 3 2, 2 2)))", "multipolygon", [[[[0,0], [1,1], [1,0], [0,0]]], [[[2,2], [3,3], [3,2], [2,2]]]]],
"point with floating point" => ["POINT(1.15847 1.13687)","point", [1.15847, 1.13687]],
];
}

public static function falsyProvider() {
Expand Down
90 changes: 46 additions & 44 deletions tests/Unit/GeodataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,57 @@

namespace Tests\Unit;

use Tests\TestCase;


use App\Geodata;
use Clickbar\Magellan\Data\Geometries\Dimension;
use Clickbar\Magellan\Exception\UnknownWKTTypeException;
use Tests\TestCase;

// TODO move to Map Plugin
class GeodataTest extends TestCase
{
public function testExample()
{
$this->assertTrue(true);
/**
* Test fromWKT function
*
* @return void
*/
public function testFromWktWithTypo() {
$this->expectException(UnknownWKTTypeException::class);
Geodata::fromWKT('PIONT(1 2)');
}
// /**
// * Test relations of a geodata object (id=2)
// *
// * @return void
// */
// public function testRelations()
// {
// $geodata = Geodata::with(['entity'])->find(2);

// $this->assertEquals(1, $geodata->entity->id);
// $this->assertEquals('Site A', $geodata->entity->name);
// }

// /**
// * Test parseWkt function
// *
// * @return void
// */
// public function testParseWkt()
// {
// $data = Geodata::parseWkt('PIONT(1 2)');
// $this->assertNull($data);

// $data = Geodata::parseWkt('POINT Z(1 2 3)');
// $this->assertEquals(2, $data->getLat());
// $this->assertEquals(1, $data->getLng());
// $this->assertEquals(3, $data->getAlt());
// }
/**
* Test fromWKT function
*
* @return void
*/
public function testFromWktWith3dPoint() {
$point3d = Geodata::fromWKT('POINT Z(1 2 3)');
$this->assertEquals(1, $point3d->getX());
$this->assertEquals(2, $point3d->getY());
$this->assertEquals(3, $point3d->getZ());
$this->assertEquals(Dimension::DIMENSION_3DZ, $point3d->getDimension());
$this->assertFalse($point3d->hasSrid());
}

// /**
// * Test get last editor of first geodata
// *
// * @return void
// */
// public function testGetGeodataLasteditor()
// {
// $geodata = Geodata::first();
// $this->assertEquals(1, $geodata->user->id);
// }
/**
* Test fromWKT function
*
* @return void
*/
public function testFromWktWith2dPointAndSrid() {
// FIXME: currently Magellan uses a Singleton/Service Container approach which leads to
// a problem in case an unsupported/wrong WKT-Type is provided
// For this wrong type the singleton's $dimension is set to 2D
// if later a non-2D-WKT-type is provided, a Exception is thrown, because
// the internal $dimension of the singleton is still 2D and does (of course)
// not match e.g. 3DZ
// $typoData = Geodata::fromWKT('PIONT(1 2)');
// $this->assertNull($typoData);

$sridPoint2d = Geodata::fromWKT('SRID=4326;POINT(1 2)');
$this->assertEquals(1, $sridPoint2d->getLongitude());
$this->assertEquals(2, $sridPoint2d->getLatitude());
$this->assertNull($sridPoint2d->getAltitude());
$this->assertEquals(Dimension::DIMENSION_2D, $sridPoint2d->getDimension());
$this->assertTrue($sridPoint2d->hasSrid());
}
}

0 comments on commit 0c63a82

Please sign in to comment.