brick / geo Goto Github PK
View Code? Open in Web Editor NEWGIS geometry library for PHP
License: MIT License
GIS geometry library for PHP
License: MIT License
@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?
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
Implement : static
return types once this is solved: vimeo/psalm#8057
Returns a new geometry with its coordinates transformed to a different spatial reference system.
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?
Concave Hull is supported by PostGIS (>=2.0.0) and GEOS (>=3.11).
https://postgis.net/docs/ST_ConcaveHull.html
https://libgeos.org/doxygen/classgeos_1_1algorithm_1_1hull_1_1ConcaveHull.html
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 :
Thanks,
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
<?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)))' );
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()
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!
Some proxy classes (for example GeometryProxy) miss the to array function. They should be regenerated.
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!
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
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 currentlyI'm suddenly getting the following when I try to run composer update. Any ideas? Thanks!
Problem 1
- Root composer.json requires brick/geo ^0.7.2, dev-master, found brick/geo[dev-master, 0.1.0, ..., v0.9.x-dev] but it does not match the constraint.
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))
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).
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
.
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.
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 metersGeometryEngineRegistry::set(new GEOSEngine());
return an angleSame 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
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.
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.
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.
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 in PDOEngine
ST_GeomFromText()
calls with ST_GeographyFromText()
Geometry
method signatures are unchangedST_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.We could add a $useSpheroid
parameter to all methods that support it:
public function distance(Geometry $geometry, bool $useSpheroid = false) : float
use_ellipsoid
parametersThis 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
is true
4326
and $useSpheroid
is false
4326
and $useSpheroid
is true
But this again has downsides:
$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?
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.
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
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,
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());
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.
Line 100 in 2121812
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
Line 49 in 2121812
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 ?, ?))';
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?
It's great to have the option of isValid, in instances where there is a problem it would be good to natively be able to run the geometry through the MakeValid method and see if it's fixable.
Thoughts?
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!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.