grimzy/laravel-mysql-spatial

Method for retrieving as original (lat, lng) not (lng, lat)

dhcmega opened this issue · 3 comments

Hi!
I've been reading issues regarding the coords flipping.
I understand that fliping is necessary because of x,y, etc
So, coords will be stored flipped and all operation will work ok (contains, distance, etc)
But, when I need to edit the coords (polygon for example) there is no way to retrieve them as they were originaly.
Wouldn't it be good to have a method such as getOriginalPolygons() or getPolygons($lat_lng = true)?

As I understand, coordinates need to be flipped, but why can't this be hidden inside the methods, but the input and output remain consistent?

Am I missing something?
Thanks a lot.

dhcmega

Ok, so this is what I am using now:

    public static function flipMultiPolygon($multipolygon)
    {
        $flipped = [];
        foreach ($multipolygon as $polygon) {
            $flipped[] = self::flipPolygon($polygon);
        }

        return new MultiPolygon($flipped);
    }

    public static function flipPolygon($polygon)
    {
        $flipped = [];
        foreach ($polygon as $lineString) {
            $flipped[] = self::flipLineString($lineString);
        }

        return new Polygon($flipped);
    }

    public static function flipLineString($lineString)
    {
        $flipped = [];
        foreach ($lineString as $point) {
            $flipped[] = self::flipPoint($point);
        }

        return new LineString($flipped);
    }

    public static function flipPoint($point)
    {
        return new Point($point->getLng(), $point->getLat());
    }

    public static function flipCoords($coords)
    {
        $type = new \ReflectionClass($coords);
        $name = class_basename($type->getName());
        switch($name) {
            case 'MultiPolygon':
                return self::flipMultiPolygon($coords);
            case 'Polygon':
                return self::flipPolygon($coords);
            case 'LineString':
                return self::flipLineString($coords);
            case 'Point':
                return self::flipPoint($coords);
        }
        return null;
    }

We're seeing a similar issue with the Point() type.

When using this library's new Point(lat, lng) to insert a new Point into the database, then doing a raw SELECT X(geolocation) AS lat, Y(geolocation) as lng FROM locations, lat and lng are in the wrong order.

X in MySQL means lat and Y in MySQL means lng, so I guess that this library is the problem as it differs from the MySQL standards? For now, we'll do something similar to what @dhcmega has done above, to simply just flip the latitude and longitude.

Hi @dennisameling , the library is ok, the problem is the way I was thinking about it.
All packages turn lat and lng into x, y to use it as a cartesian coordinates. MySQL use it "flipped"
I'm also using a VueJS package that, to my surprise, does the same, and there was no need to map variables, I'm just passing it as json from the mysql model to the vuejs app and it works.
I would suggest trying to adapt to it.
Regards