Skip to content

Commit

Permalink
Merge pull request #1342 from weather-gov/mgwalker/1331-multipolygon-bug
Browse files Browse the repository at this point in the history
Fix a bug with transforming GeoJSON to WKT
  • Loading branch information
greg-does-weather committed Jun 20, 2024
2 parents 73f5269 + 0af5121 commit 91d8a08
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 11 deletions.
6 changes: 2 additions & 4 deletions web/modules/weather_data/src/Service/AlertTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,11 @@ public function getAlerts($grid, $point, $self = false, $now = false)
// If there's a geometry for this alert, use that to determine
// whether it's relevant for our location.
if ($alert->geometry) {
$alertWKT = SpatialUtility::geometryArrayToWKT(
$alert->geometry->coordinates[0],
);
$alertSQL = SpatialUtility::geoJSONtoSQL($alert->geometry);

$sql = "SELECT ST_INTERSECTS(
$gridWKT,
$alertWKT
$alertSQL
) as yes";

$intersects = $this->dataLayer->databaseFetch($sql)->yes;
Expand Down
48 changes: 44 additions & 4 deletions web/modules/weather_data/src/Service/SpatialUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,51 @@ public static function geometryObjectToWKT($geometry)
return "ST_GEOMFROMTEXT('POLYGON(($wkt))')";
}

public static function geometryArrayToWKT($geometry)
public static function geoJSONtoSQL($geoJSON)
{
return self::geometryObjectToWKT(
self::geometryArrayToObject($geometry),
);
$type = strtoupper($geoJSON->type);
$points = false;

switch ($type) {
case "POINT":
$points = $geoJSON->coordinates;

return "ST_GEOMFROMTEXT('POINT(" .
$points[0] .
" " .
$points[1] .
")')";

case "POLYGON":
$points = $geoJSON->coordinates[0];

$points = array_map(function ($point) {
return $point[0] . " " . $point[1];
}, $points);
$wkt = implode(",", $points);

return "ST_GEOMFROMTEXT('POLYGON((" . $wkt . "))')";

case "MULTIPOLYGON":
$points = array_map(function ($polygon) {
return $polygon[0];
}, $geoJSON->coordinates);

$polygons = array_map(function ($polygon) {
$points = array_map(function ($point) {
return $point[0] . " " . $point[1];
}, $polygon);
$wkt = implode(",", $points);

return "(($wkt))";
}, $points);
$wkt = implode(",", $polygons);

return "ST_GEOMFROMTEXT('MULTIPOLYGON(" . $wkt . ")')";

default:
throw new \Exception("Unsupported GeoJSON type: " . $type);
}
}

// For geographic projects, MySQL returns coordinates in lat/lon order
Expand Down
58 changes: 55 additions & 3 deletions web/modules/weather_data/src/Service/Test/SpatialUtility.php.test
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,65 @@ final class SpatialUtilityTest extends TestCase
* @group unit
* @group spatial-utility
*/
public function testGeometryArrayToWKT(): void
public function testGeoJSONtoSQLWithPoint(): void
{
$expected = "ST_GEOMFROMTEXT('POLYGON((1 2,3 4,5 6))')";
$actual = SpatialUtility::geometryArrayToWKT([[1, 2], [3, 4], [5, 6]]);
$expected = "ST_GEOMFROMTEXT('POINT(1 2)')";
$actual = SpatialUtility::geoJSONtoSQL(
(object) [
"type" => "point",
"coordinates" => [1, 2],
],
);
$this->assertEquals($expected, $actual);
}

/**
* @group unit
* @group spatial-utility
*/
public function testGeoJSONtoSQLWithPolygon(): void
{
$expected = "ST_GEOMFROMTEXT('POLYGON((1 2))')";
$actual = SpatialUtility::geoJSONtoSQL(
(object) [
"type" => "PolyGON",
"coordinates" => [[[1, 2]]],
],
);
$this->assertEquals($expected, $actual);
}

/**
* @group unit
* @group spatial-utility
*/
public function testGeoJSONtoSQLWithMultipolygon(): void
{
$expected = "ST_GEOMFROMTEXT('MULTIPOLYGON(((1 2)),((3 4)))')";
$actual = SpatialUtility::geoJSONtoSQL(
(object) [
"type" => "MuLtIpOlYgOn",
"coordinates" => [[[[1, 2]]], [[[3, 4]]]],
],
);
$this->assertEquals($expected, $actual);
}

/**
* @group unit
* @group spatial-utility
*/
public function testGeoJSONtoSQLWithUnsupportedType(): void
{
$this->expectException(\Exception::class);
$actual = SpatialUtility::geoJSONtoSQL(
(object) [
"type" => "Line",
"coordinates" => [[1, 2], [3, 4]],
],
);
}

/**
* @group unit
* @group spatial-utility
Expand Down

0 comments on commit 91d8a08

Please sign in to comment.