@@ -1452,6 +1452,53 @@ public function getConnectionId(): string
14521452 return $ stmt ->fetchColumn ();
14531453 }
14541454
1455+ /**
1456+ * Handle distance spatial queries
1457+ *
1458+ * @param Query $query
1459+ * @param array<string, mixed> $binds
1460+ * @param string $attribute
1461+ * @param string $alias
1462+ * @param string $placeholder
1463+ * @return string
1464+ */
1465+ protected function handleDistanceSpatialQueries (Query $ query , array &$ binds , string $ attribute , string $ alias , string $ placeholder ): string
1466+ {
1467+ $ distanceParams = $ query ->getValues ()[0 ];
1468+ $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ distanceParams [0 ]);
1469+ $ binds [": {$ placeholder }_1 " ] = $ distanceParams [1 ];
1470+
1471+ $ meters = isset ($ distanceParams [2 ]) && $ distanceParams [2 ] === true ;
1472+
1473+ switch ($ query ->getMethod ()) {
1474+ case Query::TYPE_DISTANCE_EQUAL :
1475+ $ operator = '= ' ;
1476+ break ;
1477+ case Query::TYPE_DISTANCE_NOT_EQUAL :
1478+ $ operator = '!= ' ;
1479+ break ;
1480+ case Query::TYPE_DISTANCE_GREATER_THAN :
1481+ $ operator = '> ' ;
1482+ break ;
1483+ case Query::TYPE_DISTANCE_LESS_THAN :
1484+ $ operator = '< ' ;
1485+ break ;
1486+ default :
1487+ throw new DatabaseException ('Unknown spatial query method: ' . $ query ->getMethod ());
1488+ }
1489+
1490+ if ($ meters ) {
1491+ // Transform both attribute and input geometry to 3857 (meters) for distance calculation
1492+ $ attr = "ST_Transform( {$ alias }. {$ attribute }, 3857) " ;
1493+ $ geom = "ST_Transform(ST_GeomFromText(: {$ placeholder }_0, " . Database::SRID . "), 3857) " ;
1494+ return "ST_Distance( {$ attr }, {$ geom }) {$ operator } : {$ placeholder }_1 " ;
1495+ }
1496+
1497+ // Without meters, use the original SRID (e.g., 4326)
1498+ return "ST_Distance( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database::SRID . ")) {$ operator } : {$ placeholder }_1 " ;
1499+ }
1500+
1501+
14551502 /**
14561503 * Handle spatial queries
14571504 *
@@ -1474,60 +1521,41 @@ protected function handleSpatialQueries(Query $query, array &$binds, string $att
14741521 return "NOT ST_Crosses( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) " ;
14751522
14761523 case Query::TYPE_DISTANCE_EQUAL :
1477- $ distanceParams = $ query ->getValues ()[0 ];
1478- $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ distanceParams [0 ]);
1479- $ binds [": {$ placeholder }_1 " ] = $ distanceParams [1 ];
1480- return "ST_DWithin( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0), : {$ placeholder }_1) " ;
1481-
14821524 case Query::TYPE_DISTANCE_NOT_EQUAL :
1483- $ distanceParams = $ query ->getValues ()[0 ];
1484- $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ distanceParams [0 ]);
1485- $ binds [": {$ placeholder }_1 " ] = $ distanceParams [1 ];
1486- return "NOT ST_DWithin( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0), : {$ placeholder }_1) " ;
1487-
14881525 case Query::TYPE_DISTANCE_GREATER_THAN :
1489- $ distanceParams = $ query ->getValues ()[0 ];
1490- $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ distanceParams [0 ]);
1491- $ binds [": {$ placeholder }_1 " ] = $ distanceParams [1 ];
1492- return "ST_Distance( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) > : {$ placeholder }_1 " ;
1493-
14941526 case Query::TYPE_DISTANCE_LESS_THAN :
1495- $ distanceParams = $ query ->getValues ()[0 ];
1496- $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ distanceParams [0 ]);
1497- $ binds [": {$ placeholder }_1 " ] = $ distanceParams [1 ];
1498- return "ST_Distance( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) < : {$ placeholder }_1 " ;
1499-
1527+ return $ this ->handleDistanceSpatialQueries ($ query , $ binds , $ attribute , $ alias , $ placeholder );
15001528 case Query::TYPE_EQUAL :
15011529 $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ query ->getValues ()[0 ]);
1502- return "ST_Equals( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) " ;
1530+ return "ST_Equals( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database:: SRID . " )) " ;
15031531
15041532 case Query::TYPE_NOT_EQUAL :
15051533 $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ query ->getValues ()[0 ]);
1506- return "NOT ST_Equals( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) " ;
1534+ return "NOT ST_Equals( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database:: SRID . " )) " ;
15071535
15081536 case Query::TYPE_INTERSECTS :
15091537 $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ query ->getValues ()[0 ]);
1510- return "ST_Intersects( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) " ;
1538+ return "ST_Intersects( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database:: SRID . " )) " ;
15111539
15121540 case Query::TYPE_NOT_INTERSECTS :
15131541 $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ query ->getValues ()[0 ]);
1514- return "NOT ST_Intersects( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) " ;
1542+ return "NOT ST_Intersects( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database:: SRID . " )) " ;
15151543
15161544 case Query::TYPE_OVERLAPS :
15171545 $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ query ->getValues ()[0 ]);
1518- return "ST_Overlaps( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) " ;
1546+ return "ST_Overlaps( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database:: SRID . " )) " ;
15191547
15201548 case Query::TYPE_NOT_OVERLAPS :
15211549 $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ query ->getValues ()[0 ]);
1522- return "NOT ST_Overlaps( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) " ;
1550+ return "NOT ST_Overlaps( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database:: SRID . " )) " ;
15231551
15241552 case Query::TYPE_TOUCHES :
15251553 $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ query ->getValues ()[0 ]);
1526- return "ST_Touches( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) " ;
1554+ return "ST_Touches( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database:: SRID . " )) " ;
15271555
15281556 case Query::TYPE_NOT_TOUCHES :
15291557 $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ query ->getValues ()[0 ]);
1530- return "NOT ST_Touches( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) " ;
1558+ return "NOT ST_Touches( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database:: SRID . " )) " ;
15311559
15321560 case Query::TYPE_CONTAINS :
15331561 case Query::TYPE_NOT_CONTAINS :
@@ -1536,8 +1564,8 @@ protected function handleSpatialQueries(Query $query, array &$binds, string $att
15361564 $ isNot = $ query ->getMethod () === Query::TYPE_NOT_CONTAINS ;
15371565 $ binds [": {$ placeholder }_0 " ] = $ this ->convertArrayToWKT ($ query ->getValues ()[0 ]);
15381566 return $ isNot
1539- ? "NOT ST_Covers( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) "
1540- : "ST_Covers( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0)) " ;
1567+ ? "NOT ST_Covers( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database:: SRID . " )) "
1568+ : "ST_Covers( {$ alias }. {$ attribute }, ST_GeomFromText(: {$ placeholder }_0, " . Database:: SRID . " )) " ;
15411569
15421570 default :
15431571 throw new DatabaseException ('Unknown spatial query method: ' . $ query ->getMethod ());
@@ -1716,15 +1744,15 @@ protected function getSQLType(string $type, int $size, bool $signed = true, bool
17161744 case Database::VAR_DATETIME :
17171745 return 'TIMESTAMP(3) ' ;
17181746
1719-
1747+ // in all other DB engines, 4326 is the default SRID
17201748 case Database::VAR_POINT :
1721- return 'GEOMETRY(POINT) ' ;
1749+ return 'GEOMETRY(POINT, ' . Database:: SRID . ' ) ' ;
17221750
17231751 case Database::VAR_LINESTRING :
1724- return 'GEOMETRY(LINESTRING) ' ;
1752+ return 'GEOMETRY(LINESTRING, ' . Database:: SRID . ' ) ' ;
17251753
17261754 case Database::VAR_POLYGON :
1727- return 'GEOMETRY(POLYGON) ' ;
1755+ return 'GEOMETRY(POLYGON, ' . Database:: SRID . ' ) ' ;
17281756
17291757 default :
17301758 throw new DatabaseException ('Unknown Type: ' . $ type . '. Must be one of ' . Database::VAR_STRING . ', ' . Database::VAR_INTEGER . ', ' . Database::VAR_FLOAT . ', ' . Database::VAR_BOOLEAN . ', ' . Database::VAR_DATETIME . ', ' . Database::VAR_RELATIONSHIP . ', ' . Database::VAR_POINT . ', ' . Database::VAR_LINESTRING . ', ' . Database::VAR_POLYGON );
0 commit comments