Coder Social home page Coder Social logo

geo's People

Contributors

benmorel avatar cevou avatar gbuckingham89 avatar kolyunya avatar michaelcurry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geo's Issues

IO GeoJSON Support

@BenMorel : It looks like Geojson, KML, etc... is not currently supported. If a Pull Request came in that expanded the ability to Init and ToString multiple Geo String Types, would you be up for reviewing / merging?

PHP 5.6 requirement

Hi,

is there a reason, why the minimum requirement changed from 5.5 to 5.6? I had a quick lock at the recent changes and didn't find any usage of new features.
PErsonally, I think that the lib should not always use the latest PHP functionality, because you should be at least able to use this lib for example with the latest Ubuntu LTS release.

Best,
Christoph

Public query functions for DatabaseEngine

It would be nice if you could use the query functions from the DatabaseEngine to do operations on geometry objects withing the application. Currently they are deplcared as private. Is there any reason (besides that there is no common API with the GEOS lib) why this is done?

Can I use brick/geo for a wood cutting project ?

example
Hello,

This is my first project in Geometry. I'm used to develop and search for PHP libraries but WKT, WKB, Geometry Calculation is quiet new for me. I'm not sure yet how to construct a simple closed circle so be tolerant :)

Context

I need to construct an HTML/JS/PHP for e-commerce website. This application should construct a final shape for woods panels (for kitchen, desktops, etc...).

I start with a simple shape (rectangle or ellipse). Then I add many cuts : interns and externals.

Then I will transform all my shapes in jpeg layers to make a preview.

Technical Context

Nginx Server/ PHP 7.1+ / MySql / Geos extension installed

Technical Expectations

I need to store each shapes to be sure there is no intersection between them, calculate a minimal distance between shapes, get the area (bonus to calculate the final weight).

I find easily how to store polygons (for my rectangle) but I understand that 'circle' (or curve) are not standard shapes so many functions are not available (distance, intersection).

Issue :

  • Should I use the brick/geo library for my project ? Alone ? With an other library ?
  • If not, do you have any advice or person to recommend ?

Thanks,

PHP8.1 deprecated on IteratorAggregate::getIterator()

Hi,
Currently testing PHP8.1 and I have this deprecated error for all class Requiring interface IteratorAggregate:

\composer\vendor\brick\geo\src\Polygon.php:249;"Return type of Brick\Geo\Polygon::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice"
\composer\vendor\brick\geo\src\Point.php:331;"Return type of Brick\Geo\Point::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice"
\composer\vendor\brick\geo\src\LineString.php:274;"Return type of Brick\Geo\LineString::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice"

My temporary workaround (see getIterator.patch) was to add ReturnTypeWillChange on all getIterator functions but it may have a better answer to this

WKTReader throws Exception

Code

<?php
define( 'DEFAULT_SRID', 4326 );

function getGeometry( string $wkt ) : Geometry
{
	return (new WKTReader())
		->read( $wkt, DEFAULT_SRID );
}

getGeometry( 'MULTIPOLYGON(((-96.5198207634025 39.0656352587354,-96.5337852030667 39.0657393639196,-96.5337039197601 39.0730173561199,-96.5198057421105 39.0728878509279,-96.5198207634025 39.0656352587354)))' );

Output

Expected word but encountered '('

#0 /opt/site/vendor/brick/geo/src/IO/AbstractWKTReader.php(35): Brick\\Geo\\IO\\WKTParser->getNextWord()
#1 /opt/site/vendor/brick/geo/src/IO/WKTReader.php(24): Brick\\Geo\\IO\\AbstractWKTReader->readGeometry()
#2 /opt/site/app/myCode.php(7): Brick\\Geo\\IO\\WKTReader->read()

Thoughts

I believe the format is correct - it has been inserted into a multi polygon column in a PostGIS enabled database and is coming back out as text. I'm trying to take the string and convert it back into a brick/geo object.

I can take my field value and plot it out on this tool:

https://clydedacruz.github.io/openstreetmap-wkt-playground/

and that parses it just fine.

Any help would be appreciated - thanks!

PDO + Spatialite - Any way at all?

Do you know if it's possible (in any way at all) to get PDO + Spatialite working?

My issue is that Laravel relies on PDO and there's no way (that I know of) to actually call ->loadExtension('mod_spatialite.so'); using pdo_sqlite, so you have to use SELECT load_extension('mod_spatialite');, which is obviously disabled.

I'm even open to somehow recompiling php 7.2 without that SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION flag, but I'm not sure where to start because I honestly have no idea "how" SQLite is compiled into php (since it's included out of the box in Debian).

Thanks!

Use SSL/TLS within PDO declaration

Hi there,

our dev team got some issues when trying to initiate the PDO connection with SSL/TLS support
The main documentation doesn't mentions this options, so we tried several configurations
Here some details of our environment :
Database instance : MariaDB 10.3, with SSL/TLS v2
Framework : Laravel 8
PHP version : 8.0

In our Laravel project, we have a folder config/database.php with a mysql array with the following content :

        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

Our first issue was :
SQLSTATE[HY000] [9002] SSL connection is required. Please specify SSL options and retry.

Then, we tried several things at PDO declaration :

$options = [ config('database.connections.mysql.options'), ];
$pdo = new PDO('mysql:host=' . env('DB_HOST') . ':' . env('DB_PORT'), env('DB_USERNAME'), env('DB_PASSWORD'), Arr::flatten($options));
$pdo = new PDO('mysql:host=' . env('DB_HOST') . ':' . env('DB_PORT'), env('DB_USERNAME'), env('DB_PASSWORD'), array(PDO::MYSQL_ATTR_SSL_CA => '/etc/ssl/certs/Baltimore_CyberTrust_Root.pem');

Then, we finally got the following error message :
SQLSTATE[HY000] [2002] {"exception":"[object] (PDOException(code: 2002): SQLSTATE[HY000] [2002] at /xxxxxx/xxxx/xxxxxx/xxxxx/xxxxx/xxxxxx.php:40)

Some help will be appreciated
Best,

Joseph

Add GeometryCollection support in GeoJSONReader|Writer

According to RFC 7946, GeoJSON supports the GeometryCollection type as well. As such:

  • GeoJSONReader should be able to read GeometryCollection
  • GeoJSONWriter should export GeometryCollection objects as such, and not as FeatureCollection as it does currently

Class 'GEOSWKBReader' not found

I keep getting the following error when trying to use the GEOS engine. Looks like this class wasn't included in the package. Any idea where I can find it or resolve the error?


Class 'GEOSWKBReader' not found

at vendor/brick/geo/src/Engine/GEOSEngine.php:63
59▕ * Class constructor.
60▕ */
61▕ public function __construct()
62▕ {
➜ 63▕ $this->wkbReader = new \GEOSWKBReader();
64▕ $this->wkbWriter = new \GEOSWKBWriter();
65▕
66▕ $this->wktReader = new \GEOSWKTReader();
67▕ $this->wktWriter = new \GEOSWKTWriter();

1 database/seeders/TestTableSeeder.php:31
Brick\Geo\Engine\GEOSEngine::__construct()

  +22 vendor frames 

24 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

st_buffer(POLYGON) has not been implemented - SRID 4326 bug

I got this error when I use the mysql engine (got a similar with postgres).

Uncaught PDOException: SQLSTATE[22S00]: <<Unknown error>>: 3618 st_buffer(POLYGON) has not been implemented for geographic spatial reference systems.

I'm loading a geojson polygon and wanted to buffer that one.

The strange thing is that this default example code from the readme worked:

$polygon = Polygon::fromText('POLYGON ((0 0, 0 3, 3 3, 0 0))');

echo $polygon->asText()."\n";
$polygon = $polygon->buffer(1);
echo $polygon->asText()."\n";

/* output
POLYGON ((0 0, 0 3, 3 3, 0 0))
POLYGON ((-1 0, -0.98078528040323 -0.19509032201613, -0.92387953251129 -0.38268343236509, -0.83146961230255 -0.5555702330196, -0.70710678118655 -0.70710678118655, -0.5555702330196 -0.83146961230255, -0.38268343236509 -0.92387953251129, -0.19509032201613 -0.98078528040323, 6.1232339957368E-17 -1, 0.19509032201613 -0.98078528040323, 0.38268343236509 -0.92387953251129, 0.5555702330196 -0.83146961230255, 0.70710678118655 -0.70710678118655, 3.7071067811865 2.2928932188135, 3.8314696123025 2.4444297669804, 3.9238795325113 2.6173165676349, 3.9807852804032 2.8049096779839, 4 3, 3.9807852804032 3.1950903220161, 3.9238795325113 3.3826834323651, 3.8314696123025 3.5555702330196, 3.7071067811865 3.7071067811865, 3.5555702330196 3.8314696123025, 3.3826834323651 3.9238795325113, 3.1950903220161 3.9807852804032, 3 4, 0 4, -0.19509032201613 3.9807852804032, -0.38268343236509 3.9238795325113, -0.5555702330196 3.8314696123025, -0.70710678118655 3.7071067811865, -0.83146961230254 3.5555702330196, -0.92387953251129 3.3826834323651, -0.98078528040323 3.1950903220161, -1 3, -1 0))
*/

There is no error throw, and the buffer function works.

I figured that the SRID by default is 0.
However I set this to 4326 like:

$polygon = Polygon::fromText('POLYGON ((0 0, 0 3, 3 3, 0 0))', 4326);

I get the st_buffer not implemented error when I run the above code...

I figured a hacky workaround to remove the 4326 SRID

$polygon = Polygon::fromText('POLYGON ((0 0, 0 3, 3 3, 0 0))', 4326);

// set SRID to 0... 
$polygon = Polygon::fromText($polygon->asText(), 0);

echo $polygon->asText()."\n";
$polygon = $polygon->buffer(1);//->asText();
echo $polygon->asText()."\n";

Like this I could process my geojson polygons as well (I used this example code to make a minimal example of the bug).

Proxies: instantiate the correct sub-type

When instantiating a proxy from a WKB or a WKT, we need to introspect the data to find out the correct sub-type of the Geometry to instantiate.

For example, when we use Geometry as a Doctrine type, but we hydrate with the WKB of a Point, the proxy must be a PointProxy, not a GeometryProxy.

Impossible to declare types for Doctrine entities

I was trying to incorporate Doctrine types into my project. Types themselves seem to be working fine.
But I came across a problem with type declarations of properties. When I declare property type like this

private Point $point;

I get a error:

The annotation "@noproxy" in method Brick\Geo\Point::geometryType() was never imported. Did you maybe forget to add "use" statement for this annotation?

Moreover this problem persists even if I give up the PHP type declarations and use PHPDoc instead.

So the only option is to remove all type declarations altogether which is obviously a huge issue.

Distance function result differ between engines

Salut @BenMorel,

I’m currently looking for performance and accuracy methods in distance calculation between two 4326 (lat/lon) points and I’ve noticed that unit return depends on engine:

	$latf = 45.832615;
	$lonf = 6.865129;
	$latt = 44.922525;
	$lont = 6.359967;
	echo (Point::fromText('POINT ('.$latf.' '.$lonf.')', 4326))->distance(Point::fromText('POINT ('.$latt.' '.$lont.')', 4326));
  • GeometryEngineRegistry::set(new PDOEngine($pdo)); return a distance in meters
  • GeometryEngineRegistry::set(new GEOSEngine()); return an angle

Same result when using php-geos with geos engine enable and pure MySQL request.

c:\php>php calcul_distance.php

# methode                      | time     | meters
------------------------------ | -------- | ----------
haversineGreatCircleDistance   | 5.95     | 108616.75
vincentyGreatCircleDistance    | 8.4      | 108616.75
phpGeosDistanceLatLon          | 248.9    | 1.04
phpGeosHausdorffDistanceLatLon | 245.58   | 1.04
brickGeosDistanceLatLon        | 209.67   | 1.04
brickMySQLDistanceLatLon       | 2970.37  | 108610.81
MySQLDistanceLatLon            | 2464.14  | 108610.81

Does I missed something in my wkt Point definition?
If not, does these different results (because it’s not an issue) seems for you normal ?

++NoNo

No documentation

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.

Support for calculations on the spheroid on PostGIS & SpatiaLite

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:

public function distance(Geometry $geometry, bool $useSpheroid = false) : float

Pros

  • 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.

What's your take on this, @cevou, @michaelcurry, @dchaffin, @zlanich, @Kolyunya, @EbashuOnHolidays?

Any better ideas?

Class 'Brick\Geo\Engine\GeometryEngineRegistry' not found

Hi, I'm trying to use this repository but after creating a module and using it (with php 7.0):

`<?php
use Brick\Geo\Engine\GeometryEngineRegistry;
use Brick\Geo\Engine\PDOEngine;

class GisModule extends CWebModule
{

public function init()
{
    // this method is called when the module is being created
    // you may place code here to customize the module or the application

    // import the module-level models and components
    $pdo = new PDO('mysql:host=localhost', 'root', 'cecchino08');
    GeometryEngineRegistry::set(new PDOEngine($pdo));
}

`

it return me this issue >> Class 'Brick\Geo\Engine\GeometryEngineRegistry' not found, the strange is that if I do ctrl + click the editor brings me to the class definition correctly.

Add support for ST_Split

How hard would it be to allow the ST_Split operation on geometries? It would be really useful for us in our current projekt :)
Kind regards
Morten, qLER ApS

Is the order important when we call distance function ?

Hi,

Context : POSTGIS function - PHP7.4 - Wood cutting project

I've noticed when I call this function that way :

        $distance = $existingCut->getGISForme()->distance($new_cut->getGISForme() );

or that whay :

        $distance = $new_cut->getGISForme()->distance($existingCut->getGISForme() );

I don't have the same result.

With the first row, I sometime get a distance between my curvepolygon (circle) equals to 0 ( WITH no intersections with intersect function). How is that possible ? How can I get no intersections between curve-polygons but with zero distance ?

I'v changed my code for the second row but I would prefer to understand the difference.

Thanks,

as binary return 0 srid

Great extension,

I have an issue here, I need to insert the wkb geometry to database. when I used asbinary function, the query return 0 srid. When I check used srid function, the query return 4326. How can I solved this issue? Here you are the code

$encodejson = $request->coordinates[$i];
$readgeojson = new GeoJSONReader();
$geom = $readgeojson->read($encodejson);
$geom2 = bin2hex($geom->asBinary());

PDO Statement preparation failure on MySQL

Hello,

I am trying to use the library in one of my projects, for both its GeoJson support, and its geometry operations.
However, when trying the operations on geometry, using the PDOEngine against a MySQL database, the engine fails to prepare the statement, with an error :

This operation is not supported by the geometry engine. …\vendor\brick\geo\src\Exception\GeometryEngineException.php:28

with the underlying SQL error

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?, ?), ST_GeomFromWKB(_binary ?, ?))'

Trying to dig in, this seems to be the _binary keyword with is causing issue, and I am wondering whether this should be binary instead.

return 'ST_GeomFromWKB(_binary ?, ?)';

Example

brick/geo version: 0.6.0
PHP Version: 8.0.3
MySQL Database version: 8.0.15

My code is basically

GeometryEngineRegistry::set(new PDOEngine(DB::connection()->getPdo()));
$point = Point::xy(1, 1);
return $point->equals($point);

which raises an exception at the following line

$this->statements[$query] = $this->pdo->prepare($query);

with

$query = 'SELECT ST_Equals(ST_GeomFromWKB(_binary ?, ?), ST_GeomFromWKB(_binary ?, ?))'

Indeed, I get an error when running in MySQL

PREPARE stmt1 FROM 'SELECT ST_Equals(ST_GeomFromWKB(_binary ?, ?), ST_GeomFromWKB(_binary ?, ?))';

whereas the below runs successfully, and my code runs as well if I modify the code accordingly.

PREPARE stmt1 FROM 'SELECT ST_Equals(ST_GeomFromWKB(binary ?, ?), ST_GeomFromWKB(binary ?, ?))';

Add support for Coordinate Reference System

In a previous version of the GeoJson format, a Coordinate Reference System https://datatracker.ietf.org/doc/html/rfc7946#section-4, was supported and defined in the format.

According to the documentation:

Note: the use of alternative coordinate reference systems was
specified in [GJ2008], but it has been removed from this version of
the specification because the use of different coordinate reference
systems -- especially in the manner specified in [GJ2008] -- has
proven to have interoperability issues.

Would you accept a PR introducing the parsing of the crs in the GeoJsonReader class?
This would help in the reading of such property, when GeoJson from a legacy format is provided, instead of requiring to parse the JSON contents twice (first with this library, and the second time to extract the CRS property and apply the SRID to all geometries in the GeoJson file).

Note: other libraries supports that: https://rdrr.io/cran/geojson/man/crs.html

WDYT?

GeoJSON right-hand rule

I'm trying to use the union function to combine some shapes. The GeoJSONReader outputs each shape individually correct, but if I run union on them, the output doesn't follow the 'right-hand rule' (https://mapster.me/right-hand-rule-geojson-fixer/).

EDIT: I'm using MySQL for the GeometryEngine

Am I missing something or does this not support that yet? Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.