brick / geo

GIS geometry library for PHP
MIT License
220 stars 31 forks source link

No documentation #34

Closed NikitaObukhov closed 3 years ago

NikitaObukhov commented 3 years ago

That's so sad PHP does not have st_distance function and the only library simply queries db to get distance between to points. But even so, this lib has no documentation at all. How to use it? How to simply get distance between points? How to create a point? Why it has 3 arguments? I guess I should dive into the beautiful world of patterns in sources to understand how it works..

What can be easier to make a function st_distance? Looks like an impossible challenge to PHP world.

BenMorel commented 3 years ago

Hi, this library does lack some proper documentation, and is probably only currently useful to people already familiar with GIS.

It's mostly the result of a one-man job, and any help to improve the code or docs is always appreciated.

Now to your question. GIS is much more complex than just a distance calculation between points expressed in GPS coordinates:

The complexity is so huge, that the choice made in this library is the following:

A basic example to get the distance between 2 GPS coordinates, using MySQL 8.0 would be:

use Brick\Geo\Engine\GeometryEngineRegistry;
use Brick\Geo\Engine\PDOEngine;
use Brick\Geo\Point;

$pdo = new PDO('mysql:host=localhost', 'root', '');
$geometryEngine = new PDOEngine($pdo);

$srid = 4326; // GPS coordinates

$paris = Point::xy(48.8566, 2.3522, $srid);
$newYork = Point::xy(40.7128, -74.0060, $srid);

echo $geometryEngine->distance($paris, $newYork); // 5852928.3237389 (meters)

The distance is in meters on MySQL 8.0, but that depends on the chosen engine (other engines may return the distance in degrees here).

All in all, if all you need is a distance in meters between 2 GPS coordinates, you'll find relatively simple formulas for this, and this library is definitely overkill. If you need more advanced calculations, support for polygons, support for WKT/WKB/GeoJSON/..., then you may find this library useful.

NikitaObukhov commented 2 years ago

Hello,

I've returned here as we are now facing problems with this library. The distance is basically wrong. Your's example gives me other results. I've used both PDO (10.3.28-MariaDB-1:10.3.28) and GEOSEngine (libgeos-3.7.1).

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        GeometryEngineRegistry::set(new PDOEngine($this->em->getConnection()->getWrappedConnection()));
        //GeometryEngineRegistry::set(new GEOSEngine());
        $srid = 4326;

        $paris = Point::xy(48.8566, 2.3522, $srid);
        $newYork = Point::xy(40.7128, -74.0060, $srid);

        $output->writeln('Distance:'. $paris->distance($newYork)); // 5852928.3237389 (mete)
        // Output: Distance:76.791250710481 (WRONG)
        return 0;
    }
NikitaObukhov commented 2 years ago

The first problem is that lib use ST_DISTANCE instead of ST_DISTANCE_SPHERE Second is that it assumes Earth is flat and it seems to be ok, until you take 2 points with shortest path through the Pole (Novosibirsk and Quebec for instance). Third it is not obvious what is X and what is Y. It rather depends on version of MYSQL and optional paramters. Why in your example X is lat and Y is lon? Mysql docs says it should be SOMETIMES lon,lat and sometimes lat,lon 4rth is return value of st_distance. Is it meters? or radians? or whatever. it depends on version of underlying db. 5th. GEOSEngine could probably solve issues with this mess in mysql versions of st_distance. but it does not work too!

Such a simple function to get distance does not work. Why need 4-D distances? 99% users want a php lib that gives distance in meters. Others will never use php for math things. Who uses language for math that event can't provide such a simple thing?