brick / geo
GIS几何库
Requires
- php: ^8.1
Requires (Dev)
- ext-json: *
- ext-pdo: *
- ext-sqlite3: *
- brick/reflection: ~0.5.0
- php-coveralls/php-coveralls: ^2.0
- phpunit/phpunit: ^10.0
- vimeo/psalm: 5.20.0
This package is auto-updated.
Last update: 2024-09-22 11:54:45 UTC
README
PHP的GIS几何库。
简介
此库是OpenGIS规范(http://www.opengeospatial.org/standards/sfa)的PHP实现。
它提供了几何类(如Point
、LineString
、Polygon
等),并能原生读取/写入多种格式:WKB、WKT、EWKB、EWKT和GeoJSON。
它还提供了一个GeometryEngine
接口用于高级计算(如长度、面积、并集、交集等),以及将这些操作委托给第三方GIS引擎的实现:GEOS扩展或支持GIS的数据库(如MySQL或PostgreSQL)。
要求和安装
此库需要PHP 8.1。对于PHP 8.0,您可以使用版本0.9
。对于PHP 7.4,您可以使用版本0.7
。
使用Composer安装库
composer require brick/geo
如果您只需要基本操作,例如构建几何对象、从/导出到支持的格式(WKB、WKT、EWKB、EWKT或GeoJSON),则已准备好。
如果您需要高级功能,如length()
、union()
、intersection
等,请转到配置部分以选择一个GeometryEngine
实现。
项目状态和发布流程
此库仍在开发中。
当前版本号为0.x.y
。当引入非破坏性更改(添加新方法、优化现有代码等)时,将增加y
。
当引入破坏性更改时,总是开始一个新的0.x
版本周期。
因此,将项目锁定到给定的发布周期,如0.11.*
是安全的。
如果您需要升级到较新的发布周期,请查看发布历史记录以获取每个进一步的0.x.0
版本引入的更改列表。
快速入门
use Brick\Geo\LineString; use Brick\Geo\Point; use Brick\Geo\Polygon; // Building geometries from coordinates $lineString = LineString::of( Point::xy(1, 2), Point::xy(3, 4), ); echo $lineString->asText(); // LINESTRING (1 2, 3 4) // Importing geometries $point = Point::fromText('POINT (1 2)'); echo $point->x(); // 1 echo $point->y(); // 2 // Using advanced calculations from a GeometryEngine // (see the Configuration section) $polygon = Polygon::fromText('POLYGON ((0 0, 0 3, 3 3, 0 0))'); echo $geometryEngine->area($polygon); // 4.5 $centroid = $geometryEngine->centroid($polygon); echo $centroid->asText(); // POINT (1 2)
配置
通过GeometryEngine
接口提供高级计算。该库包含以下实现
PDOEngine
:通过PDO连接与GIS兼容的数据库进行通信。
此引擎目前支持以下数据库- MySQL版本5.6或更高版本(仅限2D几何)
- MariaDB版本5.5或更高版本
- PostgreSQL带有PostGIS扩展
SQLite3Engine
:通过带有SpatiaLite扩展的SQLite3数据库进行通信。GEOSEngine
:使用GEOS PHP扩展
您选择合适的实现应遵循两个标准
- 可用性:如果您已经使用MySQL等支持GIS的数据库,这可能会是一个容易的选择;
- 功能:并非所有数据库都提供相同的GIS功能
- 某些功能可能在PostgreSQL上可用,但在其他数据库上不可用(请参阅空间函数参考部分)
- 某些功能可能仅限于特定的几何类型和/或SRID;例如,
buffer()
在MySQL上工作,但在SRID 4326(GPS坐标,距离以米为单位)的Polygon
上会失败 - 某些数据库可能在SRID 4326上返回米为单位的距离,而其他数据库可能返回度为单位
您可能应该从最简单的方法开始,并测试这种设置是否符合您的期望。
以下是所有可能的配置的逐步指南
使用PDO和MySQL 5.6或更高版本
点击展开
-
确保您的MySQL版本至少为
5.6
。
早期版本仅基于边界框提供部分GIS支持,且不受支持。 -
在您的项目中使用此启动代码
use Brick\Geo\Engine\PDOEngine; $pdo = new PDO('mysql:host=localhost', 'root', ''); $geometryEngine = new PDOEngine($pdo);
使用自己的连接参数更新代码,或者如果您已有(推荐),则使用现有的PDO
连接。
使用PDO和MariaDB 5.5或更高版本
点击展开
MariaDB是MySQL的一个分支,因此您可以遵循与MySQL相同的流程。只需确保您的MariaDB版本为5.5
或更高。
使用PDO和带有PostGIS的PostgreSQL
点击展开
-
如有需要,在数据库服务器上启用PostGIS
CREATE EXTENSION postgis;
-
在您的项目中使用此启动代码
use Brick\Geo\Engine\PDOEngine; $pdo = new PDO('pgsql:host=localhost', 'postgres', ''); $geometryEngine = new PDOEngine($pdo);
使用自己的连接参数更新代码,或者如果您已有(推荐),则使用现有的PDO
连接。
使用PDO和带有SpatiaLite的SQLite
点击展开
由于PDO_SQLITE驱动程序的限制,目前无法*使用SELECT LOAD_EXTENSION()
查询加载SpatiaLite扩展,因此您无法使用PDO驱动程序与SpatiaLite一起使用。
您需要使用SQLite3驱动程序。请注意,您可以使用现有的PDO_SQLITE代码,您需要做的只是创建一个额外的内存SQLite3数据库,仅用于驱动几何引擎。
*实际上是可能的,使用moxio/sqlite-extended-api,它使用FFI和Z-Engine,但请注意,这个库仍然是实验性的!
使用带有SpatiaLite的SQLite3
点击展开
-
确保在您的
php.ini
中启用了SQLite3扩展extension=sqlite3.so
-
确保在您的
php.ini
中配置了SpatiaLite安装的SQLite3扩展目录[sqlite3] sqlite3.extension_dir = /usr/lib
-
在您的项目中使用此启动代码
use Brick\Geo\Engine\SQLite3Engine; $sqlite3 = new SQLite3(':memory:'); $sqlite3->loadExtension('mod_spatialite.so'); $geometryEngine = new SQLite3Engine($sqlite3);
-
根据您使用的函数,您可能需要运行此查询来初始化空间元数据
SELECT InitSpatialMetaData();
如果您的数据库是持久的,则只需运行此查询一次,但如果您的数据库是内存中的,则每次连接都需要运行它。请注意,这可能会影响性能。
在这个例子中,我们为GIS计算创建了一个内存数据库,但您也可以使用现有的SQLite3
连接。
使用GEOS PHP绑定
点击展开
-
确保GEOS的PHP绑定已安装在您的服务器上(GEOS 3.6.0及以后版本;早期版本需要使用带有
--enable-php
标志编译GEOS)。 -
确保在您的
php.ini
中启用了GEOS扩展extension=geos.so
-
在您的项目中使用此启动代码
use Brick\Geo\Engine\GEOSEngine; $geometryEngine = new GEOSEngine();
几何层次结构
所有几何对象都位于Brick\Geo
命名空间中,并扩展了一个基类Geometry
。
几何形状异常
所有几何形状异常都位于 Brick\Geo\Exception
命名空间中,并扩展了基类 GeometryException
对象。
几何形状异常是细粒度的:在整个项目中,只抛出基类 GeometryException
类的子类。这使用户可以选择捕获特定的异常,或者捕获所有与几何形状相关的异常。
以下是所有异常的列表
CoordinateSystemException
在混合具有不同 SRID 或维度(例如 XY 与 XYZ)的对象时抛出EmptyGeometryException
在尝试访问空几何形状上的不存在属性时抛出GeometryEngineException
在当前几何形状引擎不支持功能时抛出GeometryIOException
在读取或写入(E)WKB/T 数据时出错时抛出InvalidGeometryException
在创建无效的几何形状时抛出,例如只有单个Point
的LineString
NoSuchGeometryException
在尝试从一个集合中获取一个不存在索引的几何形状时抛出UnexpectedGeometryException
在几何形状不是预期子类型实例时抛出,例如在调用Point::fromText()
时使用LineString
WKT。
几何形状引擎方法参考
这是 GeometryEngine
接口中所有可用方法的列表。某些方法仅在您使用特定几何形状引擎时可用,有时需要最小版本。
导入和导出几何形状
此库支持从以下格式导入和导出
- WKT
- WKB
- EWKT
- EWKB
- GeoJSON
WKT
已知文本(WKT)是几何形状的标准文本格式。
每个几何形状类都提供了一个方便的方法 fromText()
,它接受一个 WKT 字符串和一个可选的 SRID,并返回一个几何形状对象
use Brick\Geo\Point; $point = Point::fromText('POINT (1.5 2.5)', 4326);
可以使用方便的方法 asText()
将几何形状转换为 WKT
echo $point->asText(); // POINT (1.5 2.5)
您还可以直接使用 WKTReader 和 WKTWriter 类;后者允许您以美观的格式输出。
WKB
已知二进制(WKB)是几何形状的标准二进制格式。
每个几何形状类都提供了一个方便的方法 fromBinary()
,它接受一个 WKB 二进制字符串和一个可选的 SRID,并返回一个几何形状对象
use Brick\Geo\Point; $point = Point::fromBinary(hex2bin('0101000000000000000000f83f0000000000000440'), 4326); echo $point->asText(); // POINT (1.5 2.5) echo $point->SRID(); // 4326
可以使用方便的方法 asBinary()
将几何形状转换为 WKB
echo bin2hex($point->asBinary()); // 0101000000000000000000f83f0000000000000440
您还可以直接使用 WKBReader 和 WKBWriter 类;后者允许您选择输出的字节序(大端或小端)。
EWKT
扩展 WKT 是一个特定于 PostGIS 的文本格式,它包括几何形状对象的 SRID,这在标准 WKT 格式中缺失。您可以使用 EWKTReader 和 EWKTWriter 类导入和导出此格式
use Brick\Geo\Point; use Brick\Geo\IO\EWKTReader; use Brick\Geo\IO\EWKTWriter; $reader = new EWKTReader(); $point = $reader->read('SRID=4326; POINT (1.5 2.5)'); echo $point->asText(); // POINT (1.5 2.5) echo $point->SRID(); // 4326 $writer = new EWKTWriter(); echo $writer->write($point); // SRID=4326; POINT (1.5 2.5)
EWKB
扩展WKB是PostGIS特定的二进制格式,它包含几何对象的SRID,这是标准WKB格式所缺少的。您可以使用EWKBReader和EWKBWriter类从这个格式导入和导出。
use Brick\Geo\Point; use Brick\Geo\IO\EWKBReader; use Brick\Geo\IO\EWKBWriter; $reader = new EWKBReader(); $point = $reader->read(hex2bin('0101000020e6100000000000000000f83f0000000000000440')); echo $point->asText(); // POINT (1.5 2.5) echo $point->SRID(); // 4326 $writer = new EWKBWriter(); echo bin2hex($writer->write($point)); // 0101000020e6100000000000000000f83f0000000000000440
GeoJSON
GeoJSON是一种基于JSON的开放标准格式,旨在表示简单的地理要素,并在RFC 7946中标准化。
此库支持使用GeoJSONReader和GeoJSONWriter类从GeoJSON文档导入几何对象并将其导出。
use Brick\Geo\Point; use Brick\Geo\IO\GeoJSONReader; use Brick\Geo\IO\GeoJSONWriter; $reader = new GeoJSONReader(); $point = $reader->read('{ "type": "Point", "coordinates": [1, 2] }'); echo $point->asText(); // POINT (1 2) echo $point->SRID(); // 4326 $writer = new GeoJSONWriter(); echo $writer->write($point); // {"type":"Point","coordinates":[1,2]}
该库支持读取和写入Feature
和FeatureCollection
对象,以及自定义属性。
GeoJSON旨在仅支持WGS84,因此所有几何对象都使用SRID 4326导入。
减少坐标精度
在将几何对象以文本格式导出之前,您可能需要减少坐标的精度以保持输出文件的大小,同时保留足够的精度。您可以使用RoundCoordinatesProjector
实现这一点。
use Brick\Geo\Point; use Brick\Geo\Projector\RoundCoordinatesProjector; $roundProjector = new RoundCoordinatesProjector(2); $point = Point::xy(1.2345678, 2.3456789); echo $point->asText(); // POINT (1.2345678 2.3456789) $roundedPoint = $point->project($roundProjector); echo $roundedPoint->asText(); // POINT (1.23 2.35)
Doctrine映射
您可以使用brick/geo-doctrine包在您的Doctrine实体中使用brick/geo
类型。