You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'd like to introduce support for calculations on the spheroid on both PostGIS and SpatiaLite.
This would solve #24, and probably give some hints on how to solve #23 in an elegant way.
The problem
Unlike MySQL that returns distances in meters for geometries with SRID 4326 (GPS coordinates), PostGIS & SpatiaLite require to pass an explicit use_spheroid=true parameter to functions that support it, like ST_Distance(g1, g2, true) to get the result in meters, otherwise the result is in degrees.
In other words, currently, all brick/geo calculations are returned in degrees on these 2 platforms, with no way to get meters instead.
PostGIS also has a Geography type that defaults to using the spheroid. If I'm not mistaken though, everything a Geography can do, a Geometry can do it as well, provided that an extra use_spheroid=true parameter is given to every function that's supposed to calculate on the spheroid. Someone please correct me if I'm wrong here.
Solution 1
This is the first solution I came up with when I only had PostGIS in mind, so its obvious issue is to be PostGIS-specific. I'll write it down anyway for posterity:
take an optional $usePostgisGeography parameter in PDOEngine
when this parameter is true, replace all ST_GeomFromText() calls with ST_GeographyFromText()
Pros
The current Geometry method signatures are unchanged
Cons
This is not as easy. Why? Because some functions that are implemented for Geometries do not exist for Geographies. The intro to the Geography type gives an example: the basic ST_X() function is not defined with Geography parameters. So we would need to maintain a list of PostGIS functions for which Geography parameters are acceptable, and those for which they are not.
You now have to decide whether calculations will be performed in meters or degrees at project level, when configuring your geometry engine; this may not be flexible enough for some use cases.
This would only work for PostGIS, and not SpatiaLite.
Solution 2
We could add a $useSpheroid parameter to all methods that support it:
You can select the behaviour on every method call, instead of relying on global configuration
This would make it also compatible with SpatiaLite, which has similar use_ellipsoid parameters
Cons
The behaviour of the method becomes highly dependent on the underlying geometry engine:
for MySQL, the parameter would be ignored, plain and simple. The result would only depend on the SRID in use;
for GEOS, the parameter would also be ignored, but the result always be in degrees;
for PostGIS and SpatiaLite, the parameter would be honored.
This is a reasonably attractive solution, but I'm not comfortable with the fact that the parameter is ignored for MySQL / GEOS. A way to harden this a bit would be to make it throw an exception if:
the engine is GEOS and $useSpheroid is true
or the engine is MySQL and:
the SRID is 4326 and $useSpheroid is false
the SRID is not 4326 and $useSpheroid is true
But this again has downsides:
MySQL returns a distance in meters not only for SRID 4326, but also for many others (4324, for example); it's a rather bad idea IMO to try to keep a hardcoded list of SRIDs supposed to calculate on the spheroid;
if $useSpheroid defaults to false, this would be a BC break for MySQL users where the method would start throwing exceptions with the default parameters; OTOH if it defaults to true, this would be a BC break for GEOS users.
I don't have a definitive answer as to what solution is the way to go, so I'm opening this issue to brainstorm ideas.
if set, all functions that accept use_spheroid=true (PostGIS) or use_ellipsoid=true (SpatiaLite) are automatically flagged when called
The downside of having a global configuration still stands, though. Also, the list of functions accepting this parameter may need to be hardcoded if they differ from one platform to another.
Alternative to solution 2
Make $useSpheroid nullable, and be null by default:
I'd like to introduce support for calculations on the spheroid on both PostGIS and SpatiaLite.
This would solve #24, and probably give some hints on how to solve #23 in an elegant way.
The problem
Unlike MySQL that returns distances in meters for geometries with SRID 4326 (GPS coordinates), PostGIS & SpatiaLite require to pass an explicit
use_spheroid=true
parameter to functions that support it, likeST_Distance
(g1, g2, true)
to get the result in meters, otherwise the result is in degrees.In other words, currently, all brick/geo calculations are returned in degrees on these 2 platforms, with no way to get meters instead.
PostGIS also has a Geography type that defaults to using the spheroid. If I'm not mistaken though, everything a
Geography
can do, aGeometry
can do it as well, provided that an extrause_spheroid=true
parameter is given to every function that's supposed to calculate on the spheroid. Someone please correct me if I'm wrong here.Solution 1
This is the first solution I came up with when I only had PostGIS in mind, so its obvious issue is to be PostGIS-specific. I'll write it down anyway for posterity:
$usePostgisGeography
parameter inPDOEngine
ST_GeomFromText()
calls withST_GeographyFromText()
Pros
Geometry
method signatures are unchangedCons
ST_X()
function is not defined with Geography parameters. So we would need to maintain a list of PostGIS functions for which Geography parameters are acceptable, and those for which they are not.Solution 2
We could add a
$useSpheroid
parameter to all methods that support it:Pros
use_ellipsoid
parametersCons
This is a reasonably attractive solution, but I'm not comfortable with the fact that the parameter is ignored for MySQL / GEOS. A way to harden this a bit would be to make it throw an exception if:
$useSpheroid
istrue
4326
and$useSpheroid
isfalse
4326
and$useSpheroid
istrue
But this again has downsides:
$useSpheroid
defaults tofalse
, this would be a BC break for MySQL users where the method would start throwing exceptions with the default parameters; OTOH if it defaults totrue
, this would be a BC break for GEOS users.I don't have a definitive answer as to what solution is the way to go, so I'm opening this issue to brainstorm ideas.
What's your take on this, @cevou, @michaelcurry, @dchaffin, @zlanich, @Kolyunya, @EbashuOnHolidays?
Any better ideas?
The text was updated successfully, but these errors were encountered: