mirror of
https://gitee.com/niucloud-team/niucloud-admin.git
synced 2026-03-19 04:04:04 +00:00
update niucloud
This commit is contained in:
parent
ede477602a
commit
29041f8f4d
17
niucloud/vendor/composer/InstalledVersions.php
vendored
17
niucloud/vendor/composer/InstalledVersions.php
vendored
@ -98,7 +98,7 @@ class InstalledVersions
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
||||
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ class InstalledVersions
|
||||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints((string) $constraint);
|
||||
$constraint = $parser->parseConstraints($constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
@ -328,9 +328,7 @@ class InstalledVersions
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require $vendorDir.'/composer/installed.php';
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = $required;
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
|
||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $installed[count($installed) - 1];
|
||||
}
|
||||
@ -342,17 +340,12 @@ class InstalledVersions
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||
$required = require __DIR__ . '/installed.php';
|
||||
self::$installed = $required;
|
||||
self::$installed = require __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (self::$installed !== array()) {
|
||||
$installed[] = self::$installed;
|
||||
}
|
||||
$installed[] = self::$installed;
|
||||
|
||||
return $installed;
|
||||
}
|
||||
|
||||
4
niucloud/vendor/composer/autoload_files.php
vendored
4
niucloud/vendor/composer/autoload_files.php
vendored
@ -25,8 +25,6 @@ return array(
|
||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'6b998e7ad3182c0d21d23780badfa07b' => $vendorDir . '/yansongda/supports/src/Functions.php',
|
||||
'66453932bc1be9fb2f910a27947d11b6' => $vendorDir . '/alibabacloud/client/src/Functions.php',
|
||||
'f0e7e63bbb278a92db02393536748c5f' => $vendorDir . '/overtrue/wechat/src/Kernel/Support/Helpers.php',
|
||||
'6747f579ad6817f318cc3a7e7a0abb93' => $vendorDir . '/overtrue/wechat/src/Kernel/Helpers.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => $vendorDir . '/php-di/php-di/src/functions.php',
|
||||
'cd5441689b14144e5573bf989ee47b34' => $vendorDir . '/qcloud/cos-sdk-v5/src/Common.php',
|
||||
'841780ea2e1d6545ea3a253239d59c05' => $vendorDir . '/qiniu/php-sdk/src/Qiniu/functions.php',
|
||||
@ -34,5 +32,7 @@ return array(
|
||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php',
|
||||
'cc56288302d9df745d97c934d6a6e5f0' => $vendorDir . '/topthink/think-queue/src/common.php',
|
||||
'313a9b01f294d730dfc8ff43b9e56416' => $vendorDir . '/w7corp/easywechat/src/Kernel/Support/Helpers.php',
|
||||
'8cfe2b61cc956a1edbaf214308e8c9a1' => $vendorDir . '/w7corp/easywechat/src/Kernel/Helpers.php',
|
||||
'8c783b3a3de2f6d9177022b5ccdcc841' => $vendorDir . '/yansongda/pay/src/Functions.php',
|
||||
);
|
||||
|
||||
3
niucloud/vendor/composer/autoload_psr4.php
vendored
3
niucloud/vendor/composer/autoload_psr4.php
vendored
@ -55,6 +55,7 @@ return array(
|
||||
'MyCLabs\\Enum\\' => array($vendorDir . '/myclabs/php-enum/src'),
|
||||
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
|
||||
'Matrix\\' => array($vendorDir . '/markbaker/matrix/classes/src'),
|
||||
'Location\\' => array($vendorDir . '/mjaschen/phpgeo/src'),
|
||||
'Laravel\\SerializableClosure\\' => array($vendorDir . '/laravel/serializable-closure/src'),
|
||||
'JmesPath\\' => array($vendorDir . '/mtdowling/jmespath.php/src'),
|
||||
'Invoker\\' => array($vendorDir . '/php-di/invoker/src'),
|
||||
@ -68,7 +69,7 @@ return array(
|
||||
'Grafika\\' => array($vendorDir . '/kosinix/grafika/src/Grafika'),
|
||||
'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'),
|
||||
'Fastknife\\' => array($vendorDir . '/fastknife/ajcaptcha/src'),
|
||||
'EasyWeChat\\' => array($vendorDir . '/overtrue/wechat/src'),
|
||||
'EasyWeChat\\' => array($vendorDir . '/w7corp/easywechat/src'),
|
||||
'EasyWeChatComposer\\' => array($vendorDir . '/easywechat-composer/easywechat-composer/src'),
|
||||
'DI\\' => array($vendorDir . '/php-di/php-di/src'),
|
||||
'Cron\\' => array($vendorDir . '/dragonmantank/cron-expression/src/Cron'),
|
||||
|
||||
11
niucloud/vendor/composer/autoload_static.php
vendored
11
niucloud/vendor/composer/autoload_static.php
vendored
@ -26,8 +26,6 @@ class ComposerStaticInitf082efa3600aae2b847c3e8b4e641a4e
|
||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'6b998e7ad3182c0d21d23780badfa07b' => __DIR__ . '/..' . '/yansongda/supports/src/Functions.php',
|
||||
'66453932bc1be9fb2f910a27947d11b6' => __DIR__ . '/..' . '/alibabacloud/client/src/Functions.php',
|
||||
'f0e7e63bbb278a92db02393536748c5f' => __DIR__ . '/..' . '/overtrue/wechat/src/Kernel/Support/Helpers.php',
|
||||
'6747f579ad6817f318cc3a7e7a0abb93' => __DIR__ . '/..' . '/overtrue/wechat/src/Kernel/Helpers.php',
|
||||
'b33e3d135e5d9e47d845c576147bda89' => __DIR__ . '/..' . '/php-di/php-di/src/functions.php',
|
||||
'cd5441689b14144e5573bf989ee47b34' => __DIR__ . '/..' . '/qcloud/cos-sdk-v5/src/Common.php',
|
||||
'841780ea2e1d6545ea3a253239d59c05' => __DIR__ . '/..' . '/qiniu/php-sdk/src/Qiniu/functions.php',
|
||||
@ -35,6 +33,8 @@ class ComposerStaticInitf082efa3600aae2b847c3e8b4e641a4e
|
||||
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
|
||||
'cc56288302d9df745d97c934d6a6e5f0' => __DIR__ . '/..' . '/topthink/think-queue/src/common.php',
|
||||
'313a9b01f294d730dfc8ff43b9e56416' => __DIR__ . '/..' . '/w7corp/easywechat/src/Kernel/Support/Helpers.php',
|
||||
'8cfe2b61cc956a1edbaf214308e8c9a1' => __DIR__ . '/..' . '/w7corp/easywechat/src/Kernel/Helpers.php',
|
||||
'8c783b3a3de2f6d9177022b5ccdcc841' => __DIR__ . '/..' . '/yansongda/pay/src/Functions.php',
|
||||
);
|
||||
|
||||
@ -132,6 +132,7 @@ class ComposerStaticInitf082efa3600aae2b847c3e8b4e641a4e
|
||||
),
|
||||
'L' =>
|
||||
array (
|
||||
'Location\\' => 9,
|
||||
'Laravel\\SerializableClosure\\' => 28,
|
||||
),
|
||||
'J' =>
|
||||
@ -384,6 +385,10 @@ class ComposerStaticInitf082efa3600aae2b847c3e8b4e641a4e
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/markbaker/matrix/classes/src',
|
||||
),
|
||||
'Location\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/mjaschen/phpgeo/src',
|
||||
),
|
||||
'Laravel\\SerializableClosure\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/laravel/serializable-closure/src',
|
||||
@ -438,7 +443,7 @@ class ComposerStaticInitf082efa3600aae2b847c3e8b4e641a4e
|
||||
),
|
||||
'EasyWeChat\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/overtrue/wechat/src',
|
||||
0 => __DIR__ . '/..' . '/w7corp/easywechat/src',
|
||||
),
|
||||
'EasyWeChatComposer\\' =>
|
||||
array (
|
||||
|
||||
285
niucloud/vendor/composer/installed.json
vendored
285
niucloud/vendor/composer/installed.json
vendored
@ -1677,6 +1677,88 @@
|
||||
},
|
||||
"install-path": "../markbaker/matrix"
|
||||
},
|
||||
{
|
||||
"name": "mjaschen/phpgeo",
|
||||
"version": "4.2.0",
|
||||
"version_normalized": "4.2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mjaschen/phpgeo.git",
|
||||
"reference": "b2e593cf1e9aceea36510158ddb80c7395a80d5a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/mjaschen/phpgeo/zipball/b2e593cf1e9aceea36510158ddb80c7395a80d5a",
|
||||
"reference": "b2e593cf1e9aceea36510158ddb80c7395a80d5a",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"squizlabs/php_codesniffer": "^3.6",
|
||||
"vimeo/psalm": "^4.13"
|
||||
},
|
||||
"time": "2022-07-25T08:36:36+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Location\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marcus Jaschen",
|
||||
"email": "mjaschen@gmail.com",
|
||||
"homepage": "https://www.marcusjaschen.de/"
|
||||
}
|
||||
],
|
||||
"description": "Simple Yet Powerful Geo Library",
|
||||
"homepage": "https://phpgeo.marcusjaschen.de/",
|
||||
"keywords": [
|
||||
"Polygon",
|
||||
"area",
|
||||
"bearing",
|
||||
"bounds",
|
||||
"calculation",
|
||||
"coordinate",
|
||||
"distance",
|
||||
"earth",
|
||||
"ellipsoid",
|
||||
"geo",
|
||||
"geofence",
|
||||
"gis",
|
||||
"gps",
|
||||
"haversine",
|
||||
"length",
|
||||
"perpendicular",
|
||||
"point",
|
||||
"polyline",
|
||||
"projection",
|
||||
"simplify",
|
||||
"track",
|
||||
"vincenty"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://phpgeo.marcusjaschen.de/Installation.html",
|
||||
"email": "mjaschen@gmail.com",
|
||||
"issues": "https://github.com/mjaschen/phpgeo/issues",
|
||||
"source": "https://github.com/mjaschen/phpgeo/tree/4.2.0"
|
||||
},
|
||||
"install-path": "../mjaschen/phpgeo"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "2.9.1",
|
||||
@ -2120,108 +2202,6 @@
|
||||
],
|
||||
"install-path": "../overtrue/socialite"
|
||||
},
|
||||
{
|
||||
"name": "overtrue/wechat",
|
||||
"version": "5.30.0",
|
||||
"version_normalized": "5.30.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/w7corp/easywechat.git",
|
||||
"reference": "245d1e821bc5a4609625c3244b111f570692cfc2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/w7corp/easywechat/zipball/245d1e821bc5a4609625c3244b111f570692cfc2",
|
||||
"reference": "245d1e821bc5a4609625c3244b111f570692cfc2",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"easywechat-composer/easywechat-composer": "^1.1",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-simplexml": "*",
|
||||
"guzzlehttp/guzzle": "^6.2 || ^7.0",
|
||||
"monolog/monolog": "^1.22 || ^2.0",
|
||||
"overtrue/socialite": "^3.2 || ^4.0",
|
||||
"php": ">=7.4",
|
||||
"pimple/pimple": "^3.0",
|
||||
"psr/simple-cache": "^1.0||^2.0||^3.0",
|
||||
"symfony/cache": "^3.3 || ^4.3 || ^5.0 || ^6.0",
|
||||
"symfony/event-dispatcher": "^4.3 || ^5.0 || ^6.0",
|
||||
"symfony/http-foundation": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0",
|
||||
"symfony/psr-http-message-bridge": "^0.3 || ^1.0 || ^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"brainmaestro/composer-git-hooks": "^2.7",
|
||||
"dms/phpunit-arraysubset-asserts": "^0.2.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.5.0",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"mockery/mockery": "^1.2.3",
|
||||
"phpstan/phpstan": "^0.12.0",
|
||||
"phpunit/phpunit": "^9.3"
|
||||
},
|
||||
"time": "2022-09-05T08:22:34+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"hooks": {
|
||||
"pre-commit": [
|
||||
"composer test",
|
||||
"composer fix-style"
|
||||
],
|
||||
"pre-push": [
|
||||
"composer test",
|
||||
"composer fix-style"
|
||||
]
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Kernel/Support/Helpers.php",
|
||||
"src/Kernel/Helpers.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"EasyWeChat\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "overtrue",
|
||||
"email": "anzhengchao@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "微信SDK",
|
||||
"keywords": [
|
||||
"easywechat",
|
||||
"sdk",
|
||||
"wechat",
|
||||
"weixin",
|
||||
"weixin-sdk"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/w7corp/easywechat/issues",
|
||||
"source": "https://github.com/w7corp/easywechat/tree/5.30.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/overtrue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"abandoned": "w7corp/easywechat",
|
||||
"install-path": "../overtrue/wechat"
|
||||
},
|
||||
{
|
||||
"name": "php-di/invoker",
|
||||
"version": "2.3.3",
|
||||
@ -5588,6 +5568,107 @@
|
||||
},
|
||||
"install-path": "../topthink/think-view"
|
||||
},
|
||||
{
|
||||
"name": "w7corp/easywechat",
|
||||
"version": "5.30.0",
|
||||
"version_normalized": "5.30.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/w7corp/easywechat.git",
|
||||
"reference": "245d1e821bc5a4609625c3244b111f570692cfc2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/w7corp/easywechat/zipball/245d1e821bc5a4609625c3244b111f570692cfc2",
|
||||
"reference": "245d1e821bc5a4609625c3244b111f570692cfc2",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"easywechat-composer/easywechat-composer": "^1.1",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-simplexml": "*",
|
||||
"guzzlehttp/guzzle": "^6.2 || ^7.0",
|
||||
"monolog/monolog": "^1.22 || ^2.0",
|
||||
"overtrue/socialite": "^3.2 || ^4.0",
|
||||
"php": ">=7.4",
|
||||
"pimple/pimple": "^3.0",
|
||||
"psr/simple-cache": "^1.0||^2.0||^3.0",
|
||||
"symfony/cache": "^3.3 || ^4.3 || ^5.0 || ^6.0",
|
||||
"symfony/event-dispatcher": "^4.3 || ^5.0 || ^6.0",
|
||||
"symfony/http-foundation": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0",
|
||||
"symfony/psr-http-message-bridge": "^0.3 || ^1.0 || ^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"brainmaestro/composer-git-hooks": "^2.7",
|
||||
"dms/phpunit-arraysubset-asserts": "^0.2.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.5.0",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"mockery/mockery": "^1.2.3",
|
||||
"phpstan/phpstan": "^0.12.0",
|
||||
"phpunit/phpunit": "^9.3"
|
||||
},
|
||||
"time": "2022-09-05T08:22:34+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"hooks": {
|
||||
"pre-commit": [
|
||||
"composer test",
|
||||
"composer fix-style"
|
||||
],
|
||||
"pre-push": [
|
||||
"composer test",
|
||||
"composer fix-style"
|
||||
]
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Kernel/Support/Helpers.php",
|
||||
"src/Kernel/Helpers.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"EasyWeChat\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "overtrue",
|
||||
"email": "anzhengchao@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "微信SDK",
|
||||
"keywords": [
|
||||
"easywechat",
|
||||
"sdk",
|
||||
"wechat",
|
||||
"weixin",
|
||||
"weixin-sdk"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/w7corp/easywechat/issues",
|
||||
"source": "https://github.com/w7corp/easywechat/tree/5.30.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/overtrue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"install-path": "../w7corp/easywechat"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.11.0",
|
||||
|
||||
31
niucloud/vendor/composer/installed.php
vendored
31
niucloud/vendor/composer/installed.php
vendored
@ -3,7 +3,7 @@
|
||||
'name' => 'topthink/think',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '50f38f6e5e505e761d5743c3aedc3b9ad2264b36',
|
||||
'reference' => '0e6af7d100b3d33b511309de65f355528845c27f',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -210,6 +210,15 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'mjaschen/phpgeo' => array(
|
||||
'pretty_version' => '4.2.0',
|
||||
'version' => '4.2.0.0',
|
||||
'reference' => 'b2e593cf1e9aceea36510158ddb80c7395a80d5a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../mjaschen/phpgeo',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'monolog/monolog' => array(
|
||||
'pretty_version' => '2.9.1',
|
||||
'version' => '2.9.1.0',
|
||||
@ -261,15 +270,6 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'overtrue/wechat' => array(
|
||||
'pretty_version' => '5.30.0',
|
||||
'version' => '5.30.0.0',
|
||||
'reference' => '245d1e821bc5a4609625c3244b111f570692cfc2',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../overtrue/wechat',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'php-di/invoker' => array(
|
||||
'pretty_version' => '2.3.3',
|
||||
'version' => '2.3.3.0',
|
||||
@ -672,7 +672,7 @@
|
||||
'topthink/think' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '50f38f6e5e505e761d5743c3aedc3b9ad2264b36',
|
||||
'reference' => '0e6af7d100b3d33b511309de65f355528845c27f',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@ -759,6 +759,15 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'w7corp/easywechat' => array(
|
||||
'pretty_version' => '5.30.0',
|
||||
'version' => '5.30.0.0',
|
||||
'reference' => '245d1e821bc5a4609625c3244b111f570692cfc2',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../w7corp/easywechat',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'webmozart/assert' => array(
|
||||
'pretty_version' => '1.11.0',
|
||||
'version' => '1.11.0.0',
|
||||
|
||||
61
niucloud/vendor/mjaschen/phpgeo/.github/workflows/php.yml
vendored
Normal file
61
niucloud/vendor/mjaschen/phpgeo/.github/workflows/php.yml
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
name: phpgeo Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions:
|
||||
- "7.3"
|
||||
- "7.4"
|
||||
- "8.0"
|
||||
- "8.1"
|
||||
|
||||
name: "phpgeo build - PHP ${{ matrix.php-versions }}"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
coverage: xdebug
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate
|
||||
|
||||
- name: Cache Composer packages
|
||||
id: composer-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ matrix.php-versions }}-${{ hashFiles('composer.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-php-${{ matrix.php-versions }}-
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.composer-cache.outputs.cache-hit != 'true'
|
||||
run: composer install --prefer-dist --no-progress --no-suggest
|
||||
|
||||
- name: Lint PHP Sources
|
||||
run: composer run-script ci:lint
|
||||
|
||||
- name: PHP Code Sniffer
|
||||
run: composer run-script ci:sniff
|
||||
|
||||
- name: Static Analysis
|
||||
run: composer run-script ci:psalm
|
||||
|
||||
- name: Unit Tests
|
||||
run: composer run-script ci:tests
|
||||
11
niucloud/vendor/mjaschen/phpgeo/.gitignore
vendored
Normal file
11
niucloud/vendor/mjaschen/phpgeo/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
.DS_Store
|
||||
*~
|
||||
/.idea/
|
||||
/composer.lock
|
||||
/vendor/
|
||||
/docs/phpgeo.html
|
||||
/docs/coverage/
|
||||
/docs/phpdox/
|
||||
/tools/
|
||||
/build/
|
||||
.phpunit.result.cache
|
||||
9
niucloud/vendor/mjaschen/phpgeo/.scrutinizer.yml
vendored
Normal file
9
niucloud/vendor/mjaschen/phpgeo/.scrutinizer.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
filter:
|
||||
paths: ["src/*"]
|
||||
tools:
|
||||
php_code_coverage: true
|
||||
php_sim: true
|
||||
php_mess_detector: true
|
||||
php_pdepend: true
|
||||
php_analyzer: true
|
||||
php_cpd: false
|
||||
50
niucloud/vendor/mjaschen/phpgeo/.travis.yml
vendored
Normal file
50
niucloud/vendor/mjaschen/phpgeo/.travis.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
os: linux
|
||||
dist: xenial
|
||||
language: php
|
||||
|
||||
php:
|
||||
- "7.4"
|
||||
- "7.3"
|
||||
- "7.2"
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
- $HOME/.composer/cache
|
||||
|
||||
env:
|
||||
jobs:
|
||||
- DEPENDENCIES=latest
|
||||
- DEPENDENCIES=oldest
|
||||
|
||||
install:
|
||||
- >
|
||||
if [ "$DEPENDENCIES" = "latest" ]; then
|
||||
echo "Installing the latest dependencies";
|
||||
composer update --with-dependencies --prefer-stable --prefer-dist
|
||||
else
|
||||
echo "Installing the lowest dependencies";
|
||||
composer update --with-dependencies --prefer-stable --prefer-dist --prefer-lowest
|
||||
fi;
|
||||
composer show;
|
||||
|
||||
script:
|
||||
- >
|
||||
echo;
|
||||
echo "Validating the composer.json";
|
||||
composer ci:composer-validate;
|
||||
|
||||
- >
|
||||
echo;
|
||||
echo "Linting all PHP files";
|
||||
composer ci:lint;
|
||||
|
||||
- >
|
||||
echo;
|
||||
echo "Running the Psalm static analyzer";
|
||||
composer ci:psalm;
|
||||
|
||||
- >
|
||||
echo;
|
||||
echo "Running the PHPUnit tests";
|
||||
composer ci:tests;
|
||||
317
niucloud/vendor/mjaschen/phpgeo/CHANGELOG.md
vendored
Normal file
317
niucloud/vendor/mjaschen/phpgeo/CHANGELOG.md
vendored
Normal file
@ -0,0 +1,317 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to `mjaschen/phpgeo` will be documented in this file.
|
||||
Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
|
||||
|
||||
## Unreleased/Upcoming
|
||||
|
||||
### Added
|
||||
|
||||
- `GeometryInterface` provides two new methods: `getBounds()` and `getSegments()`
|
||||
|
||||
### Removed
|
||||
|
||||
- Support for PHP 7.3
|
||||
- `setPoint1()` and `setPoint2()` methods from `Line`
|
||||
- `setSeparator()`, `useCardinalLetters()` and `setUnits()` methods from `DMS`
|
||||
|
||||
## [4.2.0] - Current Version, 2022-07-25
|
||||
|
||||
## Changed
|
||||
|
||||
- point-to-line distance is calculated iteratively now, fixes #92
|
||||
- improved intersection checking for polygon/polygon
|
||||
|
||||
## [4.1.0] - 2022-06-03
|
||||
|
||||
This release has no breaking changes.
|
||||
|
||||
Thanks, @nilshoerrmann, for contributing!
|
||||
|
||||
### Added
|
||||
|
||||
- method `Bounds::getAsPolygon()` which returns a polygon containing the four nodes of the Bounds instance
|
||||
- methods `Bounds::getNorthEast()` and `Bounds::getSouthWest()`
|
||||
- new public methods: `CardinalDirection::isStrictlyNorth()`, `CardinalDirection::isStrictlyEast()`, `CardinalDirection::isStrictlySouth()` and `CardinalDirection::isStrictlyWest()`
|
||||
- new class `Direction` for checking if one point is north, eat, south or west from another point
|
||||
- new Class `Intersection` for checking if two geometries intersect each other
|
||||
|
||||
## [4.0.0] - 2021-11-29
|
||||
|
||||
### Changed
|
||||
|
||||
- drop support for PHP 7.2 **breaking change**
|
||||
- add support for PHP 8.1
|
||||
- add deprecations for setter methods in `DMS` and `Line` classes
|
||||
|
||||
## [3.2.1] - 2021-03-04
|
||||
|
||||
### Fixed
|
||||
|
||||
- Division by zero in `SimplifyBearing` if two consecutive points share the same location, fixes #79.
|
||||
|
||||
## [3.2.0] - 2020-10-09
|
||||
|
||||
### Added
|
||||
|
||||
- Calculation of [Cardinal Distances](https://phpgeo.marcusjaschen.de/Calculations/Cardinal_Distance.html) between two points. Thanks @LeoVie!
|
||||
|
||||
### Changed
|
||||
|
||||
- change `static` to `self` to prevent accidentally calling the constructor with wrong arguments in child classes (`Ellipsoid`, `Line`, `Polygon`, `Polyline`)
|
||||
|
||||
## [3.1.0] - 2020-07-24
|
||||
|
||||
### Added
|
||||
|
||||
- Simplifying polygons is now supported as well, see `simplifyGeometry()` methods in `SimplifyBearing` and `SimplifyDouglasPeucker` classes (fixes #69).
|
||||
|
||||
## [3.0.1] - 2020-05-18
|
||||
|
||||
### Fixed
|
||||
|
||||
- \#68 `CoordinateFactory` emitted a warning if a coordindates string without arc seconds was passed to the `fromString()` method
|
||||
|
||||
## [3.0.0] - 2020-02-07
|
||||
|
||||
### Changed
|
||||
|
||||
- *phpgeo* requires PHP >= 7.2 now
|
||||
- **backwards compatibility breaking:** fix double space in Ellipsoid Name `World␣Geodetic␣System␣␣1984` → `World␣Geodetic␣System␣1984` (#49)
|
||||
- updated tests for PHPUnit 8
|
||||
|
||||
### Added
|
||||
|
||||
- class constant visibiliy modifiers
|
||||
|
||||
### Removed
|
||||
|
||||
- support for PHP 7.0 and PHP 7.1 from Travis CI config
|
||||
|
||||
## [2.6.0] - 2020-02-05
|
||||
|
||||
### Added
|
||||
|
||||
- method `getIntermediatePoint()` to the `Line` class which calculates an intermediate point on a line by following the Great Circle between the two line ends and dividing the line by the given fraction (0.0 ... 1.0)
|
||||
|
||||
## [2.5.0] - 2020-02-04
|
||||
|
||||
### Added
|
||||
|
||||
- method `getMidpoint()` to the `Line` class which calculates the midpoint of a line by following the Great Circle between the two line ends and dividing the line into two halves.
|
||||
- utility class `Cartesian` which abstracts three-dimensional cartesian coordinates *x*, *y*, and *z*
|
||||
|
||||
## [2.4.1] - 2020-01-29
|
||||
|
||||
### Changed
|
||||
|
||||
- access modifier for the `tolerance` attribute is now protected (`SimplifyDouglasPeucker`)
|
||||
|
||||
## [2.4.0] - 2020-01-27
|
||||
|
||||
### Added
|
||||
|
||||
- `BoundsFactory` to create a bounds instance for a center point and a given distance to the bounds' corners. Thanks @sdennler!
|
||||
|
||||
## [2.3.1] - 2019-12-21
|
||||
|
||||
### Fixed
|
||||
|
||||
- improve precision in `PointToLineDistance`
|
||||
|
||||
## [2.3.0] - 2019-12-19
|
||||
|
||||
### Added
|
||||
|
||||
- `PointToLineDistance` calculates the smallest distance between a point and a line
|
||||
|
||||
## [2.2.0] - 2019-11-25
|
||||
|
||||
### Added
|
||||
|
||||
- `hasSameLocation()` checks if two points share the same location (optionally within a distance which defaults to 0.001 m = 1 mm)
|
||||
- `addUniquePoint` adds unique points to a polyline (i.e., points that doesn't already exist in that polyline)
|
||||
- `getAveragePoint()` returns the average value of latitude and longitude values for a polyline
|
||||
|
||||
### Fixed
|
||||
|
||||
- wrongly placed parenthesis in `Polygon::contains()`
|
||||
|
||||
## [2.1.0] - 2019-03-22
|
||||
|
||||
### Added
|
||||
|
||||
- The bounds for a `Polyline` can now be retrieved in form of a `Bound` object.
|
||||
|
||||
### Changed
|
||||
|
||||
- The auto-loader is now PSR-4 compatible; directory structure was flattened by one level.
|
||||
|
||||
## [2.0.5] - 2019-02-27
|
||||
|
||||
### Changed
|
||||
|
||||
- improvements to the Douglas-Peucker processor. Thanks @iamskey!
|
||||
|
||||
## [2.0.3] - 2018-07-19
|
||||
|
||||
### Fixed
|
||||
|
||||
- Links to documentation in README. Thanks @JonathanMH
|
||||
|
||||
### Changed
|
||||
|
||||
- better floating point number comparisons in `Vincenty`
|
||||
- add exception message in `Vincenty`
|
||||
- type-cast regexp matches before doing calculations in `CoordinateFactory`
|
||||
|
||||
## [2.0.2] - 2018-03-27
|
||||
|
||||
### Added
|
||||
|
||||
- Information on how to run checks and tests for developers in the README.
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated internal stuff like type and return hints after running a static analysis.
|
||||
- Updated some PHPDoc blocks after running a static analysis.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Wrongly typed return value in `BearingEllipsoidal::inverseVincenty()`.
|
||||
|
||||
## [2.0.1] - 2018-02-16
|
||||
|
||||
### Added
|
||||
|
||||
- new supported format for coordinates parser. Thanks to @petrknap
|
||||
|
||||
## [2.0.0] - 2017-09-27
|
||||
|
||||
### Changed
|
||||
|
||||
* License: *phpgeo* is now distributed under the MIT license
|
||||
* phpgeo requires at least PHP 7.0
|
||||
|
||||
### Removed
|
||||
|
||||
* deprecated class `Simplify` was removed; alternatives: `SimplifyBearing` or `SimplifyDouglasPeucker`
|
||||
* PHP versions 5.4, 5.5, and 5.6 are no longer supported
|
||||
|
||||
## [1.3.8] - 2017-07-05
|
||||
|
||||
### Fixed
|
||||
|
||||
* Area calculation for polygons works now. Thanks to @felixveysseyre
|
||||
|
||||
## [1.3.7] - 2017-07-01
|
||||
|
||||
### Fixed
|
||||
|
||||
* GeoJSON output for polygon is now compliant with RFC 7946. Thanks to @arsonik
|
||||
|
||||
## [1.3.5] - 2016-08-19
|
||||
|
||||
### Added
|
||||
|
||||
* add method for calculating the final bearing for a `Line` object
|
||||
|
||||
## [1.3.3] - 2016-08-16
|
||||
|
||||
### Fixed
|
||||
|
||||
* bugifx for a division-by-zero error which occurred when symplifying a polyline
|
||||
with the Douglas-Peucker algorithm.
|
||||
|
||||
## [1.3.2] - 2016-03-26
|
||||
|
||||
### Added
|
||||
|
||||
* add an utility class to calculate the perpendicular distance between a point
|
||||
and a line; [documentation](https://phpgeo.marcusjaschen.de/#_perpendicular_distance)
|
||||
|
||||
## [1.3.1] - 2016-03-26
|
||||
|
||||
### Added
|
||||
|
||||
* add method to calculate the bearing of a `Line` instance (point 1 -> point 2)
|
||||
|
||||
## [1.3.0] - 2016-03-26
|
||||
|
||||
### Added
|
||||
|
||||
* A new `SimplifyInterface` was introduced and is implemented in two classes:
|
||||
`SimplifyDouglasPeucker` and `SimplifyBearing`
|
||||
* Added documentation
|
||||
|
||||
### Deprecated
|
||||
|
||||
* The `Simplify` processor class is now deprecated and will be removed in the
|
||||
2.0 release.
|
||||
|
||||
## [1.2.1] - 2016-03-15
|
||||
|
||||
### Added
|
||||
|
||||
* Added functionality to change the direction of Polygon instances
|
||||
* Added documentation
|
||||
|
||||
## [1.2.0] - 2016-03-14
|
||||
|
||||
### Added
|
||||
|
||||
* Added geofence check for arbitrary geometry objects
|
||||
* Extended and updated documentation
|
||||
|
||||
## [1.1.1] - 2016-03-13
|
||||
|
||||
### Added
|
||||
|
||||
* Added formatter for "Decimal Minutes" format, e.g. `43° 37.386' N, 070° 12.472' W`
|
||||
* Added documentation for the new formatter
|
||||
|
||||
## [1.1.0] - 2016-03-12
|
||||
|
||||
### Added
|
||||
|
||||
* Added calculation of the bearing angle between two points (initial and final bearing)
|
||||
* Added calculation of the destination point for a given starting point, the bearing angle, and the distance
|
||||
* Support for spherical and ellipsoidal algorithms for the described bearing calculations
|
||||
* Added documentation for the bearing calculations
|
||||
|
||||
## [1.0.4] - 2016-03-11
|
||||
|
||||
### Added
|
||||
|
||||
* Added functionality to change the direction of Line/Polyline instances
|
||||
* Added documentation
|
||||
|
||||
## [1.0.3] - 2016-03-10
|
||||
|
||||
### Added
|
||||
|
||||
* Added documentation sources in mkdocs format. Documentation is now available online at http://phpgeo.marcusjaschen.de/
|
||||
|
||||
## [1.0.2] - 2016-03-04
|
||||
|
||||
### Changed
|
||||
|
||||
* several optimizations in control structures
|
||||
|
||||
## [1.0.0] - 2016-02-11
|
||||
|
||||
### Added
|
||||
|
||||
* Added license information. *phpgeo* is now licensed under the GPL 3. (see issue [#8](https://github.com/mjaschen/phpgeo/issues/8))
|
||||
|
||||
## [0.4.0] - 2015-10-29
|
||||
|
||||
### Deprecated
|
||||
|
||||
* removed support for PHP 5.3; introduced short array syntax
|
||||
|
||||
## [0.3.0] - 2015-10-29
|
||||
|
||||
### Added
|
||||
|
||||
* added the new Polyline class (thanks [@paulvl](https://github.com/paulvl))
|
||||
46
niucloud/vendor/mjaschen/phpgeo/CODE_OF_CONDUCT.md
vendored
Normal file
46
niucloud/vendor/mjaschen/phpgeo/CODE_OF_CONDUCT.md
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mjaschen@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
17
niucloud/vendor/mjaschen/phpgeo/CONTRIBUTING.md
vendored
Normal file
17
niucloud/vendor/mjaschen/phpgeo/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# Contributing to phpgeo
|
||||
|
||||
Note: It's a good idea to [open an issue](https://github.com/mjaschen/phpgeo/issues)
|
||||
for bugs or feature proposals first.
|
||||
|
||||
The contribution workflow is described as follows:
|
||||
|
||||
1. Fork phpgeo, clone repository (`git clone git@github.com:yourname/phpgeo.git`)
|
||||
2. Checkout your feature or bug-fix branch (e. g. `git checkout -b fix-random-bug`)
|
||||
3. Install dependencies: `composer install`
|
||||
4. Add tests for your changes
|
||||
5. Make your changes
|
||||
6. Run the tests (`composer ci`)
|
||||
7. Iterate through steps 3 to 5 until all tests pass.
|
||||
8. Commit your changes (`git add -A -- . && git commit`)
|
||||
9. Push to your fork (`git push --set-upstream origin fix-random-bug`)
|
||||
10. Create a pull request from your feature or bug-fix branch to phpgeo's "master" branch
|
||||
21
niucloud/vendor/mjaschen/phpgeo/LICENSE
vendored
Normal file
21
niucloud/vendor/mjaschen/phpgeo/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2017 Marcus Jaschen, https://www.marcusjaschen.de/ <mjaschen@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
48
niucloud/vendor/mjaschen/phpgeo/Makefile
vendored
Normal file
48
niucloud/vendor/mjaschen/phpgeo/Makefile
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
UPLOAD_HOST=phpgeo.marcusjaschen.de
|
||||
UPLOAD_PATH=phpgeo.marcusjaschen.de
|
||||
|
||||
PHP ?= php
|
||||
|
||||
.PHONY: docs
|
||||
docs: daux
|
||||
|
||||
.PHONY: daux
|
||||
daux:
|
||||
rm -Rf build/daux
|
||||
mkdir -p build/daux
|
||||
docker run --rm -v "$(PWD)":/src -w /src daux/daux.io daux generate -d build/daux
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -Rf build
|
||||
|
||||
.PHONY: upload_docs
|
||||
upload_docs: docs
|
||||
rsync --recursive --delete build/daux/ $(UPLOAD_HOST):$(UPLOAD_PATH)/
|
||||
|
||||
.PHONY: ci
|
||||
ci: lint coding-standards composer-validate sniff static-analysis-psalm unit-tests
|
||||
|
||||
.PHONY: coding-standards
|
||||
coding-standards: sniff
|
||||
|
||||
.PHONY: composer-validate
|
||||
composer-validate:
|
||||
composer validate --no-check-publish
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
$(PHP) ./vendor/bin/parallel-lint src
|
||||
|
||||
.PHONY: sniff
|
||||
sniff:
|
||||
# the `-` prefix ignores the exit status of the command
|
||||
-$(PHP) ./vendor/bin/phpcs --standard=codesniffer_rules.xml src
|
||||
|
||||
.PHONY: static-analysis-psalm
|
||||
static-analysis-psalm:
|
||||
$(PHP) ./vendor/bin/psalm
|
||||
|
||||
.PHONY: unit-tests
|
||||
unit-tests:
|
||||
$(PHP) ./vendor/bin/phpunit
|
||||
273
niucloud/vendor/mjaschen/phpgeo/README.md
vendored
Normal file
273
niucloud/vendor/mjaschen/phpgeo/README.md
vendored
Normal file
@ -0,0 +1,273 @@
|
||||
# phpgeo - A Simple Geo Library for PHP
|
||||
|
||||
phpgeo provides abstractions to geographical coordinates (including support for different ellipsoids) and allows you to calculate geographical distances between coordinates with high precision.
|
||||
|
||||
[](//packagist.org/packages/mjaschen/phpgeo)
|
||||
[](//packagist.org/packages/mjaschen/phpgeo)
|
||||
[](https://github.com/mjaschen/phpgeo/actions/workflows/php.yml)
|
||||
[](https://scrutinizer-ci.com/g/mjaschen/phpgeo/?branch=master)
|
||||
[](//packagist.org/packages/mjaschen/phpgeo)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<!-- MarkdownTOC autolink=true bracket=round depth=0 autoanchor=false -->
|
||||
|
||||
- [phpgeo - A Simple Geo Library for PHP](#phpgeo---a-simple-geo-library-for-php)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Requirements](#requirements)
|
||||
- [Documentation](#documentation)
|
||||
- [Installation](#installation)
|
||||
- [License](#license)
|
||||
- [Features](#features)
|
||||
- [Examples/Usage](#examplesusage)
|
||||
- [Distance between two coordinates (Vincenty's Formula)](#distance-between-two-coordinates-vincentys-formula)
|
||||
- [Simplifying a polyline](#simplifying-a-polyline)
|
||||
- [Polygon contains a point (e.g. "GPS geofence")](#polygon-contains-a-point-eg-gps-geofence)
|
||||
- [Formatted output of coordinates](#formatted-output-of-coordinates)
|
||||
- [Decimal Degrees](#decimal-degrees)
|
||||
- [Degrees/Minutes/Seconds (DMS)](#degreesminutesseconds-dms)
|
||||
- [GeoJSON](#geojson)
|
||||
- [Development](#development)
|
||||
- [Run Tests](#run-tests)
|
||||
- [Miscellaneous](#miscellaneous)
|
||||
- [Credits](#credits)
|
||||
|
||||
<!-- /MarkdownTOC -->
|
||||
|
||||
## Requirements
|
||||
|
||||
Minimum required PHP version is 7.3. *phpgeo* fully supports PHP 8.
|
||||
|
||||
The 3.x releases require PHP >= 7.2 but don't get feature updates any longer. Bugfixes will be backported.
|
||||
|
||||
The 2.x releases require PHP >= 7.0 but don't get feature updates any longer. Bugfixes won't be backported.
|
||||
|
||||
The 1.x release line has support for PHP >= 5.4. Bugfixes won't be backported.
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation is available at https://phpgeo.marcusjaschen.de/
|
||||
|
||||
## Installation
|
||||
|
||||
Using [Composer](https://getcomposer.org), just add it to your `composer.json` by running:
|
||||
|
||||
```
|
||||
composer require mjaschen/phpgeo
|
||||
```
|
||||
|
||||
## Upgrading
|
||||
|
||||
Update the version constraint in the project's `composer.json` and
|
||||
run `composer update` or require the new version by running:
|
||||
|
||||
```shell
|
||||
composer require mjaschen/phpgeo:^4.0
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Starting with version 2.0.0 phpgeo is licensed under the MIT license. Older versions were GPL-licensed.
|
||||
|
||||
## Features
|
||||
|
||||
**Info:** Please visit the **[documentation site](https://phpgeo.marcusjaschen.de/)** for complete and up-to-date documentation with many examples!
|
||||
|
||||
phpgeo provides the following features (follow the links for examples):
|
||||
|
||||
- abstractions of several geometry objects ([coordinate/point](https://phpgeo.marcusjaschen.de/Geometries/Coordinate.html),
|
||||
[line](https://phpgeo.marcusjaschen.de/Geometries/Line.html),
|
||||
[polyline/GPS track](https://phpgeo.marcusjaschen.de/Geometries/Polyline.html),
|
||||
[polygon](https://phpgeo.marcusjaschen.de/Geometries/Polygon.html)
|
||||
- support for different [ellipsoids](https://phpgeo.marcusjaschen.de/Geometries/Ellipsoid.html), e.g. WGS-84
|
||||
- [length/distance/perimeter calculations](https://phpgeo.marcusjaschen.de/Calculations/Distance_and_Length.html)
|
||||
with different implementations (Haversine, Vincenty)
|
||||
- [Geofence](https://phpgeo.marcusjaschen.de/Calculations/Geofence.html) calculation,
|
||||
i.e. answering the question "Is this point contained in that area/polygon?" and other [intersection](https://phpgeo.marcusjaschen.de/Comparisons/Intersections.html) checks between different geometries
|
||||
- [formatting and output](https://phpgeo.marcusjaschen.de/Formatting_and_Output/index.html) of geometry objects
|
||||
(GeoJSON, nice strings, e. g. `18° 54′ 41″ -155° 40′ 42″`)
|
||||
- calculation of [bearing angle between two points](https://phpgeo.marcusjaschen.de/Calculations/Bearing_and_Destination.html#page_Bearing-between-two-points)
|
||||
(spherical or with Vincenty's formula)
|
||||
- calculation of a [destination point for a given starting point](https://phpgeo.marcusjaschen.de/Calculations/Bearing_and_Destination.html#page_Destination-point-for-given-bearing-and-distance),
|
||||
bearing angle, and distance (spherical or with Vincenty's formula)
|
||||
- calculation of the [perpendicular distance between a point and a line](https://phpgeo.marcusjaschen.de/Calculations/Perpendicular_Distance.html)
|
||||
- calculation of the [Cardinal Distances between two points](https://phpgeo.marcusjaschen.de/Calculations/Cardinal_Distance.html)
|
||||
- getting segments of a [polyline](https://phpgeo.marcusjaschen.de/Geometries/Polyline.html#page_Segments)
|
||||
/[polygon](https://phpgeo.marcusjaschen.de/Geometries/Polygon.html#page_Segments),
|
||||
- [reversing direction](https://phpgeo.marcusjaschen.de/Geometries/Polygon.html#page_Reverse-Direction)
|
||||
of polyline/polygon
|
||||
|
||||
## Examples/Usage
|
||||
|
||||
This list is incomplete, please visit the [documentation site](https://phpgeo.marcusjaschen.de/)
|
||||
for the full monty of documentation and examples!
|
||||
|
||||
### Distance between two coordinates (Vincenty's Formula)
|
||||
|
||||
Use the calculator object directly:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Vincenty;
|
||||
|
||||
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit
|
||||
|
||||
$calculator = new Vincenty();
|
||||
|
||||
echo $calculator->getDistance($coordinate1, $coordinate2); // returns 128130.850 (meters; ≈128 kilometers)
|
||||
```
|
||||
|
||||
or call the `getDistance()` method of a Coordinate object by injecting a calculator object:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Vincenty;
|
||||
|
||||
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit
|
||||
|
||||
echo $coordinate1->getDistance($coordinate2, new Vincenty()); // returns 128130.850 (meters; ≈128 kilometers)
|
||||
```
|
||||
|
||||
### Simplifying a polyline
|
||||
|
||||
Polylines can be simplified to save storage space or bandwidth. Simplification is done with the [Ramer–Douglas–Peucker algorithm](https://en.wikipedia.org/wiki/Ramer–Douglas–Peucker_algorithm) (AKA Douglas-Peucker algorithm).
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polyline;
|
||||
use Location\Distance\Vincenty;
|
||||
|
||||
$polyline = new Polyline();
|
||||
$polyline->addPoint(new Coordinate(10.0, 10.0));
|
||||
$polyline->addPoint(new Coordinate(20.0, 20.0));
|
||||
$polyline->addPoint(new Coordinate(30.0, 10.0));
|
||||
|
||||
$processor = new Simplify($polyline);
|
||||
|
||||
// remove all points which perpendicular distance is less
|
||||
// than 1500 km from the surrounding points.
|
||||
$simplified = $processor->simplify(1500000);
|
||||
|
||||
// simplified is the polyline without the second point (which
|
||||
// perpendicular distance is ~1046 km and therefore below
|
||||
// the simplification threshold)
|
||||
```
|
||||
|
||||
### Polygon contains a point (e.g. "GPS geofence")
|
||||
|
||||
phpgeo has a polygon implementation which can be used to determinate if a point is contained in it or not.
|
||||
A polygon consists of at least three points. Points are instances of the `Coordinate` class.
|
||||
|
||||
**Warning:** The calculation gives wrong results if the polygons has points on both sides of the 180/-180 degrees meridian.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polygon;
|
||||
|
||||
$geofence = new Polygon();
|
||||
|
||||
$geofence->addPoint(new Coordinate(-12.085870,-77.016261));
|
||||
$geofence->addPoint(new Coordinate(-12.086373,-77.033813));
|
||||
$geofence->addPoint(new Coordinate(-12.102823,-77.030938));
|
||||
$geofence->addPoint(new Coordinate(-12.098669,-77.006476));
|
||||
|
||||
$outsidePoint = new Coordinate(-12.075452, -76.985079);
|
||||
$insidePoint = new Coordinate(-12.092542, -77.021540);
|
||||
|
||||
var_dump($geofence->contains($outsidePoint)); // returns bool(false) the point is outside the polygon
|
||||
var_dump($geofence->contains($insidePoint)); // returns bool(true) the point is inside the polygon
|
||||
```
|
||||
|
||||
### Formatted output of coordinates
|
||||
|
||||
You can format a coordinate in different styles.
|
||||
|
||||
#### Decimal Degrees
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DecimalDegrees;
|
||||
|
||||
$coordinate = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
|
||||
echo $coordinate->format(new DecimalDegrees());
|
||||
```
|
||||
|
||||
#### Degrees/Minutes/Seconds (DMS)
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DMS;
|
||||
|
||||
$coordinate = new Coordinate(18.911306, -155.678268); // South Point, HI, USA
|
||||
|
||||
$formatter = new DMS();
|
||||
|
||||
echo $coordinate->format($formatter); // 18° 54′ 41″ -155° 40′ 42″
|
||||
|
||||
$formatter->setSeparator(", ")
|
||||
->useCardinalLetters(true)
|
||||
->setUnits(DMS::UNITS_ASCII);
|
||||
|
||||
echo $coordinate->format($formatter); // 18° 54' 41" N, 155° 40' 42" W
|
||||
```
|
||||
|
||||
#### GeoJSON
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\GeoJSON;
|
||||
|
||||
$coordinate = new Coordinate(18.911306, -155.678268); // South Point, HI, USA
|
||||
|
||||
echo $coordinate->format(new GeoJSON()); // { "type" : "point" , "coordinates" : [ -155.678268, 18.911306 ] }
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Run Tests
|
||||
|
||||
Before submitting a pull request, please be sure to run all checks and tests and ensure everything is green.
|
||||
|
||||
- lint PHP files for syntax errors: `composer ci:lint`
|
||||
- run static analysis with [Psalm][] and report errors: `composer ci:psalm`
|
||||
- run unit tests with PHPUnit: `composer ci:tests`
|
||||
|
||||
To run all checks and tests at once, just use `composer ci`.
|
||||
|
||||
Of course, it's possible to use the test runners directly, e.g. for PHPUnit:
|
||||
|
||||
```shell
|
||||
./vendor/bin/phpunit
|
||||
```
|
||||
|
||||
Psalm:
|
||||
|
||||
```shell
|
||||
./vendor/bin/psalm
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
* Marcus Jaschen <mail@marcusjaschen.de> and [all contributors](https://github.com/mjaschen/phpgeo/graphs/contributors)
|
||||
* [Chris Veness](http://www.movable-type.co.uk/scripts/latlong-vincenty.html) - JavaScript implementation of the [Vincenty formula](http://en.wikipedia.org/wiki/Vincenty%27s_formulae) for distance calculation
|
||||
* Ersts,P.J., Horning, N., and M. Polin[Internet] Perpendicular Distance Calculator(version 1.2.2) [Documentation](http://biodiversityinformatics.amnh.org/open_source/pdc/documentation.php). American Museum of Natural History, Center for Biodiversity and Conservation. Available from http://biodiversityinformatics.amnh.org/open_source/pdc. Accessed on 2013-07-07.
|
||||
* W. Randolph Franklin, PNPOLY - Point Inclusion in Polygon Test [Documentation](http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html)
|
||||
|
||||
[Psalm]: https://github.com/vimeo/psalm
|
||||
77
niucloud/vendor/mjaschen/phpgeo/composer.json
vendored
Normal file
77
niucloud/vendor/mjaschen/phpgeo/composer.json
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "mjaschen/phpgeo",
|
||||
"description": "Simple Yet Powerful Geo Library",
|
||||
"keywords": [
|
||||
"distance",
|
||||
"area",
|
||||
"coordinate",
|
||||
"geo",
|
||||
"gis",
|
||||
"bounds",
|
||||
"ellipsoid",
|
||||
"calculation",
|
||||
"polyline",
|
||||
"polygon",
|
||||
"geofence",
|
||||
"simplify",
|
||||
"length",
|
||||
"vincenty",
|
||||
"haversine",
|
||||
"bearing",
|
||||
"projection",
|
||||
"gps",
|
||||
"earth",
|
||||
"track",
|
||||
"point",
|
||||
"perpendicular"
|
||||
],
|
||||
"homepage": "https://phpgeo.marcusjaschen.de/",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marcus Jaschen",
|
||||
"email": "mjaschen@gmail.com",
|
||||
"homepage": "https://www.marcusjaschen.de/"
|
||||
}
|
||||
],
|
||||
"readme": "README.md",
|
||||
"support" : {
|
||||
"issues" : "https://github.com/mjaschen/phpgeo/issues",
|
||||
"docs": "https://phpgeo.marcusjaschen.de/Installation.html",
|
||||
"email" : "mjaschen@gmail.com"
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3 || ^8.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Location\\": "src/"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"vimeo/psalm": "^4.13",
|
||||
"squizlabs/php_codesniffer": "^3.6"
|
||||
},
|
||||
"scripts": {
|
||||
"ci:composer-validate": "composer validate --no-check-all --no-check-lock --strict",
|
||||
"ci:lint": "find src tests -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l",
|
||||
"ci:psalm": "./vendor/bin/psalm",
|
||||
"ci:sniff": "./vendor/bin/phpcs src tests",
|
||||
"ci:tests": "./vendor/bin/phpunit tests/",
|
||||
"ci:static": [
|
||||
"@ci:composer-validate",
|
||||
"@ci:lint",
|
||||
"@ci:psalm",
|
||||
"@ci:sniff"
|
||||
],
|
||||
"ci:dynamic": [
|
||||
"@ci:tests"
|
||||
],
|
||||
"ci": [
|
||||
"@ci:static",
|
||||
"@ci:dynamic"
|
||||
]
|
||||
}
|
||||
}
|
||||
3408
niucloud/vendor/mjaschen/phpgeo/docs/#intersection-polyline-simple.dxf
vendored
Normal file
3408
niucloud/vendor/mjaschen/phpgeo/docs/#intersection-polyline-simple.dxf
vendored
Normal file
File diff suppressed because it is too large
Load Diff
22
niucloud/vendor/mjaschen/phpgeo/docs/000_Introduction.md
vendored
Normal file
22
niucloud/vendor/mjaschen/phpgeo/docs/000_Introduction.md
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
# What is *phpgeo?*
|
||||
|
||||
_phpgeo_ is a small PHP library which provides abstractions to geographical
|
||||
coordinates (including support for different ellipsoids), polylines
|
||||
("GPS Tracks"), polygons, bounds, and more. _phpgeo_ allows you to perform
|
||||
different calculations with these abstractions, as distances, track
|
||||
lengths, etc.
|
||||
|
||||
_phpgeo_ is developed by [Marcus Jaschen](https://www.marcusjaschen.de/) and all
|
||||
[contributors](https://github.com/mjaschen/phpgeo/graphs/contributors).
|
||||
|
||||
_phpgeo_ is licensed under the [MIT License](https://opensource.org/licenses/MIT).
|
||||
|
||||
The project is hosted on Github:
|
||||
|
||||
- [Github Project Site](https://github.com/mjaschen/phpgeo)
|
||||
- [Issue Tracker](https://github.com/mjaschen/phpgeo/issues)
|
||||
|
||||
## Privacy
|
||||
|
||||
The privacy statement for this documentation site can be found here:
|
||||
[Datenschutzerklärung](https://www.marcusjaschen.de/datenschutzerklaerung/)
|
||||
24
niucloud/vendor/mjaschen/phpgeo/docs/010_Installation.md
vendored
Normal file
24
niucloud/vendor/mjaschen/phpgeo/docs/010_Installation.md
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Getting phpgeo
|
||||
|
||||
## Requirements
|
||||
|
||||
_phpgeo_ requires at least PHP 7.3. _phpgeo_ fully supports PHP 8.
|
||||
|
||||
The 3.x releases require PHP >= 7.2 but don't get feature updates any longer. Bugfixes will be backported.
|
||||
|
||||
The 2.x releases require PHP >= 7.0 but don't get feature updates any longer. Bugfixes won't be backported.
|
||||
|
||||
The 1.x release line has support for PHP >= 5.4. Bugfixes won't be backported.
|
||||
|
||||
## Installation
|
||||
|
||||
_phpgeo_ is best be installed using Composer. Please visit the
|
||||
[Composer website](https://getcomposer.org/) website for more information.
|
||||
|
||||
To install _phpgeo,_ simply “require” it using Composer:
|
||||
|
||||
``` shell
|
||||
composer require mjaschen/phpgeo
|
||||
```
|
||||
|
||||
_phpgeo_ is now ready to be used in your project!
|
||||
38
niucloud/vendor/mjaschen/phpgeo/docs/015_Upgrading.md
vendored
Normal file
38
niucloud/vendor/mjaschen/phpgeo/docs/015_Upgrading.md
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
# Upgrading phpgeo
|
||||
|
||||
## Update from phpgeo 3.x to phpgeo 4.x
|
||||
|
||||
### Requirements
|
||||
|
||||
- _phpgeo_ 4.x requires at least PHP 7.3 and fully supports PHP 8
|
||||
|
||||
### Update phpgeo
|
||||
|
||||
- run `composer require mjaschen/phpgeo:^4.0` or
|
||||
- update the version constraint in your `composer.json` to `^4.0` and run `composer update`
|
||||
|
||||
### Update Your Code
|
||||
|
||||
- Setters in `DMS` and `Line` classes are deprecated and will be removed
|
||||
with the next release. Use constructor arguments instead.
|
||||
|
||||
No breaking changes were introduced with *phpgeo* 3.0.
|
||||
|
||||
## Update from phpgeo 2.x to phpgeo 3.x
|
||||
|
||||
### Requirements
|
||||
|
||||
- _phpgeo_ 3.x requires at least PHP 7.2
|
||||
|
||||
### Update phpgeo
|
||||
|
||||
- run `composer require mjaschen/phpgeo:^3.0` or
|
||||
- update the version constraint in your `composer.json` to `^3.0` and run `composer update`
|
||||
|
||||
### Update Your Code
|
||||
|
||||
The result of `Ellipsoid::getName()` for the built-in *WGS-84* ellipsoid returned `World␣Geodetic␣System␣␣1984` in *phpgeo* 2.x (two space characters before `1984`). Starting with *phpgeo* 3.0, the result is `World␣Geodetic␣System␣1984` (single space character before `1984`). Please verify that your code is still working if you're using that result.
|
||||
|
||||
Starting with *phpgeo* 3.0 class constant visiblity modifiers are used. One class constant was changed to *private* visibility: `BearingSpherical::EARTH_RADIUS`. Please verify that your code isn't using that class constant.
|
||||
|
||||
No further breaking changes were introduced with *phpgeo* 3.0.
|
||||
96
niucloud/vendor/mjaschen/phpgeo/docs/020_Development.md
vendored
Normal file
96
niucloud/vendor/mjaschen/phpgeo/docs/020_Development.md
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
# Development
|
||||
|
||||
## Run Tests
|
||||
|
||||
_phpgeo_ provides unit tests with a quite good coverage. For an easy usage,
|
||||
the test command is wrapped as a Composer script:
|
||||
|
||||
``` shell
|
||||
composer ci:tests
|
||||
```
|
||||
|
||||
Of course it's possible to run PHPUnit directly:
|
||||
|
||||
``` shell
|
||||
./vendor/bin/phpunit
|
||||
```
|
||||
|
||||
To test against another PHP version you can use Docker. The following command runs
|
||||
the tests using PHP 7.3:
|
||||
|
||||
``` shell
|
||||
docker run -it --rm --name phpgeo-phpunit \
|
||||
-v "$PWD":/usr/src/phpgeo \
|
||||
-w /usr/src/phpgeo php:7.3-cli \
|
||||
php vendor/bin/phpunit
|
||||
```
|
||||
|
||||
Or PHP 7.4:
|
||||
|
||||
``` shell
|
||||
docker run -it --rm --name phpgeo-phpunit \
|
||||
-v "$PWD":/usr/src/phpgeo \
|
||||
-w /usr/src/phpgeo php:7.4-cli \
|
||||
php vendor/bin/phpunit
|
||||
```
|
||||
|
||||
PHP 8.0:
|
||||
|
||||
``` shell
|
||||
docker run -it --rm --name phpgeo-phpunit \
|
||||
-v "$PWD":/usr/src/phpgeo \
|
||||
-w /usr/src/phpgeo php:8.0-cli \
|
||||
php vendor/bin/phpunit
|
||||
```
|
||||
|
||||
PHP 8.1:
|
||||
|
||||
``` shell
|
||||
docker run -it --rm --name phpgeo-phpunit \
|
||||
-v "$PWD":/usr/src/phpgeo \
|
||||
-w /usr/src/phpgeo php:8.1-cli \
|
||||
php vendor/bin/phpunit
|
||||
```
|
||||
|
||||
Alongside with the unit tests, static test runners are also provided. Run the lint
|
||||
command to ensure the sources don't contain any syntax error:
|
||||
|
||||
``` shell
|
||||
composer ci:lint
|
||||
```
|
||||
|
||||
A static code analysis with [Psalm](https://psalm.dev/) is configured as well:
|
||||
|
||||
``` shell
|
||||
composer ci:psalm
|
||||
```
|
||||
|
||||
It's possible to run all tests at once:
|
||||
|
||||
``` shell
|
||||
composer ci
|
||||
```
|
||||
|
||||
… or run all CI tasks with different PHP versions one after another:
|
||||
|
||||
```shell
|
||||
for PHP_VERSION in 7.3 7.4 8.0 8.1 ; do \
|
||||
docker run -it --rm -v "$PWD":/phpgeo -w /phpgeo \
|
||||
ghcr.io/mjaschen/php:${PHP_VERSION}-cli-mj composer ci || break ; \
|
||||
done
|
||||
```
|
||||
|
||||
## Creating the documentation
|
||||
|
||||
*phpgeo's* documentation is generated with [Daux](https://daux.io/) from Markdown files.
|
||||
The `Makefile` provides a helper target for generating the complete documentation:
|
||||
|
||||
``` shell
|
||||
make docs
|
||||
```
|
||||
|
||||
*Daux* can also be run from its official Docker image:
|
||||
|
||||
``` shell
|
||||
docker run --rm -it -v "$(pwd)":/phpgeo -w /phpgeo daux/daux.io daux generate -d build/daux
|
||||
```
|
||||
15
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/110_Coordinate.md
vendored
Normal file
15
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/110_Coordinate.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# Coordinate
|
||||
|
||||
The `Coordinate` class is the most important class of phpgeo and provides the
|
||||
base for all features. It's a representation of a geographic location and
|
||||
consists of three parts:
|
||||
|
||||
- Geographic Latitude
|
||||
- Geographic Longitude
|
||||
- Ellipsoid
|
||||
|
||||
Geographic latitude and longitude values are float numbers between
|
||||
-90.0 and 90.0 (degrees latitude) and -180.0 and 180.0 (degrees longitude).
|
||||
|
||||
The Ellipsoid is a representation of an approximated shape of the earth and
|
||||
is abstracted in its own [`Ellipsoid`](Ellipsoid) Link class.
|
||||
170
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/120_Line.md
vendored
Normal file
170
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/120_Line.md
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
# Line
|
||||
|
||||
[TOC]
|
||||
|
||||
A line consists of two points, i. e. instances of the `Coordinate` class.
|
||||
|
||||
## Length
|
||||
|
||||
The `Line` class provides a method to calculate its own length. The method
|
||||
expects an instance of a class which implements the `DistanceInterface`.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Haversine;
|
||||
use Location\Line;
|
||||
|
||||
$line = new Line(
|
||||
new Coordinate(52.5, 13.5),
|
||||
new Coordinate(52.6, 13.4)
|
||||
);
|
||||
|
||||
$length = $line->getLength(new Haversine());
|
||||
|
||||
printf("The line has a length of %.3f meters\n", $length);
|
||||
```
|
||||
|
||||
`Haversine` is one of the currently two available classes for
|
||||
distance calculation. The other one is named `Vincenty`.
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
The line has a length of 13013.849 meters
|
||||
```
|
||||
|
||||
## Midpoint
|
||||
|
||||
The midpoint of a line is calculated by following the Great Circle (defined by the two endpoints) and dividing the line into two halves.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Haversine;
|
||||
use Location\Line;
|
||||
|
||||
$line = new Line(
|
||||
new Coordinate(35, 45),
|
||||
new Coordinate(35, 135)
|
||||
);
|
||||
|
||||
$midpoint = $line->getMidpoint();
|
||||
|
||||
printf(
|
||||
'The midpoint of the line is located at %.3f degrees latitude and %.3f degrees longitude.%s',
|
||||
$midpoint->getLat(),
|
||||
$midpoint->getLng(),
|
||||
PHP_EOL
|
||||
);
|
||||
|
||||
printf(
|
||||
'Its distance from the first point is %.1f meters, its distance from the second point is %.1f meters.%s',
|
||||
$line->getPoint1()->getDistance($midpoint, new Haversine()),
|
||||
$line->getPoint2()->getDistance($midpoint, new Haversine()),
|
||||
PHP_EOL
|
||||
);
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
The midpoint of the line is located at 44.719 degrees latitude and 90.000 degrees longitude.
|
||||
Its distance from the first point is 3935890.0 meters, its distance from the second point is 3935890.0 meters.
|
||||
```
|
||||
|
||||
## Intermediate Point
|
||||
|
||||
Similar to the midpoint calculation but divides the line at the given fraction (between 0.0 … 1.0; but values outside that range work as well).
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DecimalMinutes;
|
||||
use Location\Line;
|
||||
|
||||
$line = new Line(
|
||||
new Coordinate(0, 0),
|
||||
new Coordinate(1, 1)
|
||||
);
|
||||
|
||||
$result = $line->getIntermediatePoint(0.25);
|
||||
|
||||
printf(
|
||||
'The first quarter of the line ends at %s%s',
|
||||
$result->format(new DecimalMinutes(' ')),
|
||||
PHP_EOL
|
||||
);
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
The first quarter of the line ends at 00° 15.001′ 000° 14.999′
|
||||
```
|
||||
|
||||
## Bearing
|
||||
|
||||
The bearing of an instance can be calculated using the `getBearing()` method.
|
||||
An instance of `BearingInterface` must be provided as method argument.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Bearing\BearingEllipsoidal;
|
||||
use Location\Coordinate;
|
||||
use Location\Line;
|
||||
|
||||
$line = new Line(
|
||||
new Coordinate(52.5, 13.5),
|
||||
new Coordinate(52.6, 13.4)
|
||||
);
|
||||
|
||||
$bearing = $line->getBearing(new BearingEllipsoidal());
|
||||
|
||||
printf("The line has a bearing of %.2f degrees\n", $bearing);
|
||||
```
|
||||
|
||||
`BearingEllipsoidal` is one of the currently two available classes for
|
||||
bearing calculation. The other one is named `BearingSpherical`.
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
The line has a bearing of 328.67 degrees
|
||||
```
|
||||
|
||||
This ist the so called _initial bearing._ There exist another bearing angle,
|
||||
called the _final bearing._ It can be calculated as well:
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Bearing\BearingEllipsoidal;
|
||||
use Location\Coordinate;
|
||||
use Location\Line;
|
||||
|
||||
$line = new Line(
|
||||
new Coordinate(52.5, 13.5),
|
||||
new Coordinate(52.6, 13.4)
|
||||
);
|
||||
|
||||
$bearing = $line->getFinalBearing(new BearingEllipsoidal());
|
||||
|
||||
printf("The line has a final bearing of %.2f degrees\n", $bearing);
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
The line has a final bearing of 328.59 degrees
|
||||
```
|
||||
|
||||
See Bearing between two points @TODO Link for more information about bearings.
|
||||
126
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/130_Polyline.md
vendored
Normal file
126
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/130_Polyline.md
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
# Polyline
|
||||
|
||||
[TOC]
|
||||
|
||||
A polyline consists of an ordered list of locations, i. e. instances of
|
||||
the `Coordinate` class.
|
||||
|
||||
## Create a polyline
|
||||
|
||||
To create a polyline, just instantiate the class and add points:
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polyline;
|
||||
|
||||
$polyline = new Polyline();
|
||||
$polyline->addPoint(new Coordinate(52.5, 13.5));
|
||||
$polyline->addPoint(new Coordinate(54.5, 12.5));
|
||||
$polyline->addPoint(new Coordinate(55.5, 14.5));
|
||||
?>
|
||||
```
|
||||
|
||||
It's possible to add points to the end of the polyline at every time with the `addPoint()` method.
|
||||
|
||||
Use `addUniquePoint()` to add unique points, i.e. points which doesn't exist already in the polyline.
|
||||
|
||||
## Segments
|
||||
|
||||
It's possible to get a list of polyline segments. Segments are returned as an
|
||||
array of `Line` instances.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polyline;
|
||||
|
||||
$track = new Polyline();
|
||||
$track->addPoint(new Coordinate(52.5, 13.5));
|
||||
$track->addPoint(new Coordinate(54.5, 12.5));
|
||||
$track->addPoint(new Coordinate(55.5, 14.5));
|
||||
|
||||
foreach ($track->getSegments() as $segment) {
|
||||
printf(
|
||||
"Segment length: %0.2f kilometers\n",
|
||||
($segment->getLength(new Haversine()) / 1000)
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
Segment length: 232.01 kilometers
|
||||
Segment length: 169.21 kilometers
|
||||
```
|
||||
|
||||
## Length
|
||||
|
||||
Length calculation is described in the [Distance and Length](../Calculations/Distance_and_Length) section.
|
||||
|
||||
## Average Point
|
||||
|
||||
The `getAveragePoint()` method returns a point which latitude and longitude is the average of latitude/longitude values from all polyline points.
|
||||
|
||||
CAUTION: This method currently returns wrong values if the polyline crosses the date line at 180/-180 degrees longitude.
|
||||
|
||||
## Reverse Direction
|
||||
|
||||
It's possible to get a new instance with reversed direction while the
|
||||
original polyline stays unchanged:
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polyline;
|
||||
|
||||
$track = new Polyline();
|
||||
$track->addPoint(new Coordinate(52.5, 13.5));
|
||||
$track->addPoint(new Coordinate(54.5, 12.5));
|
||||
|
||||
$reversed = $track->getReverse();
|
||||
|
||||
print_r($reversed);
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
Location\Polyline Object
|
||||
(
|
||||
[points:protected] => Array
|
||||
(
|
||||
[0] => Location\Coordinate Object
|
||||
(
|
||||
[lat:protected] => 54.5
|
||||
[lng:protected] => 12.5
|
||||
[ellipsoid:protected] => Location\Ellipsoid Object
|
||||
(
|
||||
[name:protected] => WGS-84
|
||||
[a:protected] => 6378137
|
||||
[f:protected] => 298.257223563
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
[1] => Location\Coordinate Object
|
||||
(
|
||||
[lat:protected] => 52.5
|
||||
[lng:protected] => 13.5
|
||||
[ellipsoid:protected] => Location\Ellipsoid Object
|
||||
(
|
||||
[name:protected] => WGS-84
|
||||
[a:protected] => 6378137
|
||||
[f:protected] => 298.257223563
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
)
|
||||
```
|
||||
167
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/140_Polygon.md
vendored
Normal file
167
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/140_Polygon.md
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
# Polygon
|
||||
|
||||
[TOC]
|
||||
|
||||
A polygon consists of an ordered list of locations, i. e. instances of
|
||||
the `Coordinate` class. It's very similar to a polyline, but its start
|
||||
and end points are connected.
|
||||
|
||||
## Create a polygon
|
||||
|
||||
To create a polygon, just instantiate the class and add points:
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polygon;
|
||||
|
||||
$polygon = new Polygon();
|
||||
$polygon->addPoint(new Coordinate(52.5, 13.5));
|
||||
$polygon->addPoint(new Coordinate(54.5, 12.5));
|
||||
$polygon->addPoint(new Coordinate(55.5, 14.5));
|
||||
?>
|
||||
```
|
||||
|
||||
It's possible to add points to the end at every time.
|
||||
|
||||
## Get list of points
|
||||
|
||||
`getPoints()` is used to get the list of points, the number of points can be
|
||||
retrieved by calling `getNumberOfPoints()`:
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DMS;
|
||||
use Location\Polygon;
|
||||
|
||||
$polygon = new Polygon();
|
||||
$polygon->addPoint(new Coordinate(52.5, 13.5));
|
||||
$polygon->addPoint(new Coordinate(54.5, 12.5));
|
||||
$polygon->addPoint(new Coordinate(55.5, 14.5));
|
||||
|
||||
printf("The polygon consists of %d points:\n", $polygon->getNumberOfPoints());
|
||||
|
||||
foreach ($polygon->getPoints() as $point) {
|
||||
echo $point->format(new DMS()) . PHP_EOL;
|
||||
}
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
The polygon consists of 3 points:
|
||||
52° 30′ 00″ 013° 30′ 00″
|
||||
54° 30′ 00″ 012° 30′ 00″
|
||||
55° 30′ 00″ 014° 30′ 00″
|
||||
```
|
||||
|
||||
## Segments
|
||||
|
||||
It's possible to get a list of polygon segments. Segments are
|
||||
returned as an array of `Line` instances.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Haversine;
|
||||
use Location\Polygon;
|
||||
|
||||
$polygon = new Polygon();
|
||||
$polygon->addPoint(new Coordinate(52.5, 13.5));
|
||||
$polygon->addPoint(new Coordinate(54.5, 12.5));
|
||||
$polygon->addPoint(new Coordinate(55.5, 14.5));
|
||||
|
||||
foreach ($polygon->getSegments() as $line) {
|
||||
printf("%0.3f m\n", $line->getLength(new Haversine()));
|
||||
}
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
232011.020 m
|
||||
169207.795 m
|
||||
339918.069 m
|
||||
```
|
||||
|
||||
## Length/Perimeter
|
||||
|
||||
Length calculation is described in the [Distance and Length](../Calculations/Distance_and_Length) section.
|
||||
|
||||
## Area
|
||||
|
||||
It's possible to calculate the area of an polygon. The result is given in square meters (m²).
|
||||
|
||||
WARNING: The calculation gives inaccurate results. For relatively small polygons the error should be less than 1 %.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polygon;
|
||||
|
||||
$formatter = new \Location\Formatter\Coordinate\DecimalDegrees(' ', 10);
|
||||
|
||||
$polygon = new Polygon();
|
||||
$polygon->addPoint(new Coordinate(0.0000000000, 0.0000000000));
|
||||
$polygon->addPoint(new Coordinate(0.0000000000, 0.0008983153));
|
||||
$polygon->addPoint(new Coordinate(0.0009043695, 0.0008983153));
|
||||
$polygon->addPoint(new Coordinate(0.0009043695, 0.0000000000));
|
||||
|
||||
printf(
|
||||
'Polygon Area = %f m², Perimeter = %f m%s',
|
||||
$polygon->getArea(),
|
||||
$polygon->getPerimeter(new \Location\Distance\Vincenty()),
|
||||
PHP_EOL
|
||||
);
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
Polygon Area = 10044.905261 m², Perimeter = 400.000000 m
|
||||
```
|
||||
|
||||
## Geofence
|
||||
|
||||
It's possible to check if a geometry object (point, line, polyline,
|
||||
polygon) lies inside a polygon. The documentation can be found in
|
||||
the <<Geofence>> @TODO section.
|
||||
|
||||
## Reverse Direction
|
||||
|
||||
It's possible to get a new instance with reversed direction while the
|
||||
original polygon stays unchanged:
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polygon;
|
||||
use Location\Formatter\Coordinate\DecimalDegrees;
|
||||
|
||||
$polygon = new Polygon();
|
||||
$polygon->addPoint(new Coordinate(52.5, 13.5));
|
||||
$polygon->addPoint(new Coordinate(64.1, - 21.9));
|
||||
$polygon->addPoint(new Coordinate(40.7, - 74.0));
|
||||
$polygon->addPoint(new Coordinate(33.9, - 118.4));
|
||||
|
||||
$reversed = $polygon->getReverse();
|
||||
|
||||
foreach ($reversed->getPoints() as $point) {
|
||||
echo $point->format(new DecimalDegrees(', ')) . PHP_EOL;
|
||||
}
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
33.90000, -118.40000
|
||||
40.70000, -74.00000
|
||||
64.10000, -21.90000
|
||||
52.50000, 13.50000
|
||||
```
|
||||
26
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/200_Bounds.md
vendored
Normal file
26
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/200_Bounds.md
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
# Bounds
|
||||
|
||||
Bounds describe an area which is defined by its north-eastern and south-western points.
|
||||
|
||||
All of *phpgeo's* geometries except for the `Coordindate` class provide a `getBounds()` method via the `GetBoundsTrait`.
|
||||
|
||||
The `Bounds` class has a method to calculate the center point of the bounds object (works correctly for bounds that cross the dateline at 180/-180 degrees longitude too).
|
||||
|
||||
## Create Bounds for a given center point and distance to the corners
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Factory\BoundsFactory;
|
||||
use Location\Coordinate;
|
||||
|
||||
$bounds = BoundsFactory::expandFromCenterCoordinate(
|
||||
new Coordinate(52, 13),
|
||||
1000,
|
||||
new BearingSpherical()
|
||||
);
|
||||
```
|
||||
|
||||
The following image illustrates how the bounds (dashed line in red) are created:
|
||||
|
||||

|
||||
61
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/300_Ellipsoid.md
vendored
Normal file
61
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/300_Ellipsoid.md
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
# Ellipsoid
|
||||
|
||||
An ellipsoid is a mathematically defined approximation of the earth's surface.
|
||||
|
||||
An ellipsoid is defined by two parameters:
|
||||
|
||||
* the semi-major axis _a_ (equatorial radius)
|
||||
* the semi-minor axis _b_ (polar radius)
|
||||
|
||||
_a_ and _b_ together define the flattening of the ellipsoid _f_:
|
||||
|
||||
*f = (a-b) / a*
|
||||
|
||||
NOTE: _phpgeo's_ ellipsoids are defined by _a_ and _1/f_ instead of _a_
|
||||
and _b_. That's not a problem because each of the three values can be
|
||||
calculated from the other two.
|
||||
|
||||
_phpgeo_ supports arbitrary ellipsoids. _WGS-84_ is used as default when
|
||||
no other ellipsoid is given. For day-to-day calculations it's not needed
|
||||
to care about ellipsoids in the most cases.
|
||||
|
||||
It's possible to create an instance of the Ellipsoid class either by
|
||||
specifing a name or by providing the three parameters _name,_ _a_, and _1/f_.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Ellipsoid;
|
||||
|
||||
$ellipsoid = Ellipsoid::createDefault('WGS-84');
|
||||
|
||||
printf(
|
||||
"%s: a=%f; b=%f; 1/f=%f\n",
|
||||
$ellipsoid->getName(),
|
||||
$ellipsoid->getA(),
|
||||
$ellipsoid->getB(),
|
||||
$ellipsoid->getF()
|
||||
);
|
||||
|
||||
$ellipsoid = new Ellipsoid('GRS-80', 6378137, 298.257222);
|
||||
|
||||
printf(
|
||||
"%s: a=%f; b=%f; 1/f=%f\n",
|
||||
$ellipsoid->getName(),
|
||||
$ellipsoid->getA(),
|
||||
$ellipsoid->getB(),
|
||||
$ellipsoid->getF()
|
||||
);
|
||||
```
|
||||
|
||||
The first ellipsoid is created from one the the default configurations. The second one is created by providing a name and the values of *a* and *1/f.*
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
WGS-84: a=6378137.000000; b=6356752.314245; 1/f=298.257224
|
||||
GRS-80: a=6378137.000000; b=6356752.314133; 1/f=298.257222
|
||||
```
|
||||
|
||||
Please take a look into the [`Ellipsoid` source file](https://github.com/mjaschen/phpgeo/blob/master/src/Ellipsoid.php)
|
||||
for a list of pre-defined ellipsoids.
|
||||
BIN
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/bounds-factory.png
vendored
Normal file
BIN
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/bounds-factory.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
14
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/index.md
vendored
Normal file
14
niucloud/vendor/mjaschen/phpgeo/docs/100_Geometries/index.md
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
# Geometries
|
||||
|
||||
_phpgeo_ provides several geometry classes:
|
||||
|
||||
* [`Coordinate`](Coordinate)
|
||||
* [`Line`](Line)
|
||||
* [`Polyline`](Polyline)
|
||||
* [`Polygon`](Polygon)
|
||||
|
||||
A Coordinate represents a geographic location, i. e. it contains a latitude
|
||||
and a longitude - together with an so called Ellipsoid.
|
||||
|
||||
A Line consists of two coordinates, while polylines and polygons are built
|
||||
from two or more coordinates.
|
||||
30
niucloud/vendor/mjaschen/phpgeo/docs/300_Comparisons/310_Same_Point_Comparison.md
vendored
Normal file
30
niucloud/vendor/mjaschen/phpgeo/docs/300_Comparisons/310_Same_Point_Comparison.md
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
## Same Point Comparison
|
||||
|
||||
It's possible to check if two points describe the same location – and optionally allow an error margin.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
|
||||
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit
|
||||
|
||||
echo $coordinate1->hasSameLocation($coordinate2)
|
||||
? 'Mauna Kea and Haleakala share the same location.'
|
||||
: 'Mauna Kea and Haleakala have different locations.';
|
||||
|
||||
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
$coordinate2 = new Coordinate(19.82365, -155.46905); // Gemini North Telescope
|
||||
|
||||
echo $coordinate1->hasSameLocation($coordinate2, 1000)
|
||||
? 'Mauna Kea and the Gemini North Telescope are located within the same 1 km-radius.'
|
||||
: 'Mauna Kea and the Gemini North Telescope are located more than 1 km apart.';
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
Mauna Kea and Haleakala have different locations.
|
||||
Mauna Kea and the Gemini North Telescope are located within the same 1 km-radius.
|
||||
```
|
||||
34
niucloud/vendor/mjaschen/phpgeo/docs/300_Comparisons/320_Directions.md
vendored
Normal file
34
niucloud/vendor/mjaschen/phpgeo/docs/300_Comparisons/320_Directions.md
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
## Directions
|
||||
|
||||
With the `Direction` class it's possible to determine if one point is north, east, south or west of another point.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
|
||||
$berlin = new Coordinate(52.5, 13.5);
|
||||
$rome = new Coordinate(42, 12.5);
|
||||
$helsinki = new Coordinate(60, 25);
|
||||
|
||||
$direction = new Direction();
|
||||
|
||||
if ($direction->pointIsNorthOf(point: $helsinki, compareAgainst: $berlin)) {
|
||||
echo 'Helsinki is located north of Berlin.' . PHP_EOL;
|
||||
} else {
|
||||
echo 'Berlin is located north of Helsinki.' . PHP_EOL;
|
||||
}
|
||||
|
||||
if ($direction->pointIsEastOf(point: $rome, compareAgainst: $berlin)) {
|
||||
echo 'Rome is located east of Berlin.' . PHP_EOL;
|
||||
} else {
|
||||
echo 'Berlin is located east of Rome.' . PHP_EOL;
|
||||
}
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
Helsinki is located north of Berlin.
|
||||
Berlin is located east of Rome.
|
||||
```
|
||||
14
niucloud/vendor/mjaschen/phpgeo/docs/300_Comparisons/340_Intersections.md
vendored
Normal file
14
niucloud/vendor/mjaschen/phpgeo/docs/300_Comparisons/340_Intersections.md
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
## Intersection Checking
|
||||
|
||||
It's possible to check if two geometries intersect each other.
|
||||
|
||||
(Until this documentation page is finished, take a look into `IntersectionTest` – here you'll find some examples on how to use this feature.)
|
||||
|
||||
The following combinations of geometries can be checked for intersection:
|
||||
|
||||
| | Point | Line | Polyline | Polygon |
|
||||
|----------|----------------------------------------------------------------|------|----------|-----------------------------------------------------------|
|
||||
| Point | yes ([same location](/Comparisons/Same_Point_Comparison.html)) | no | no | yes ([point inside polygon](/Calculations/Geofence.html)) |
|
||||
| Line | no | yes | yes | yes |
|
||||
| Polyline | no | yes | yes | yes |
|
||||
| Polygon | yes ([point inside polygon](/Calculations/Geofence.html)) | yes | yes | yes |
|
||||
121
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/410_Distance_and_Length.md
vendored
Normal file
121
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/410_Distance_and_Length.md
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
# Distance and Length
|
||||
|
||||
[TOC]
|
||||
|
||||
## Distance Between Two Points (Vincenty's Formula)
|
||||
|
||||
Use the calculator object directly:
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Vincenty;
|
||||
|
||||
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit
|
||||
|
||||
$calculator = new Vincenty();
|
||||
|
||||
echo $calculator->getDistance($coordinate1, $coordinate2);
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
128130.850
|
||||
```
|
||||
|
||||
or call the `getDistance()` method of a `Coordinate` instance by injecting
|
||||
a calculator instance:
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Vincenty;
|
||||
|
||||
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit
|
||||
|
||||
echo $coordinate1->getDistance($coordinate2, new Vincenty());
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
128130.850
|
||||
```
|
||||
|
||||
## Distance Between Two Points (Haversine Formula)
|
||||
|
||||
There exist different methods for calculating the distance between
|
||||
two points. The [Haversine formula](https://en.wikipedia.org/wiki/Haversine_formula#Law)
|
||||
is much faster than Vincenty's method but less precise:
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Haversine;
|
||||
|
||||
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit
|
||||
|
||||
echo $coordinate1->getDistance($coordinate2, new Haversine());
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
128384.515
|
||||
```
|
||||
|
||||
## Length of a Polyline
|
||||
|
||||
*phpgeo* has a polyline implementation which can be used to calculate the
|
||||
length of a GPS track or a route. A polyline consists of at least two points.
|
||||
Points are instances of the `Coordinate` class.
|
||||
|
||||
For more details about polylines/GPS tracks see the [`Polyline`](../Geometries/Polyline) section.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polyline;
|
||||
use Location\Distance\Vincenty;
|
||||
|
||||
$track = new Polyline();
|
||||
$track->addPoint(new Coordinate(52.5, 13.5));
|
||||
$track->addPoint(new Coordinate(54.5, 12.5));
|
||||
|
||||
echo $track->getLength(new Vincenty());
|
||||
```
|
||||
|
||||
## Perimeter of a Polygon
|
||||
|
||||
The perimeter is calculated as the sum of the length of all segments.
|
||||
The result is given in meters.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Distance\Vincenty;
|
||||
use Location\Coordinate;
|
||||
use Location\Polygon;
|
||||
|
||||
$polygon = new Polygon();
|
||||
$polygon->addPoint(new Coordinate(10, 10));
|
||||
$polygon->addPoint(new Coordinate(10, 20));
|
||||
$polygon->addPoint(new Coordinate(20, 20));
|
||||
$polygon->addPoint(new Coordinate(20, 10));
|
||||
|
||||
echo $polygon->getPerimeter(new Vincenty());
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
4355689.472
|
||||
```
|
||||
143
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/420_Bearing_and_Destination.md
vendored
Normal file
143
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/420_Bearing_and_Destination.md
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
# Bearing and Destination
|
||||
|
||||
[TOC]
|
||||
|
||||
phpgeo can be used to calculate the bearing between two points and to
|
||||
get a destination point for a given start point together with a bearing
|
||||
angle and a distance.
|
||||
|
||||
Multiple calculation algorithms are supported. Currently phpgeo provides
|
||||
methods for calculations with a _spherical_ earth model and with an
|
||||
_ellipsoidal_ model. The spherical calculations are very fast, compared
|
||||
to the ellipsoidal methods. The ellipsoidal algorithms are a bit more
|
||||
precise on the other hand.
|
||||
|
||||
## Bearing between two points
|
||||
|
||||
Given two points, it's possible to calculate the bearing angled between
|
||||
those points.
|
||||
|
||||
phpgeo can calculate the initial bearing (bearing as seen from the first
|
||||
point) and the final bearing (bearing as seen approaching the destination
|
||||
point).
|
||||
|
||||
### Calculation with a spherical earth model
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Bearing\BearingSpherical;
|
||||
use Location\Coordinate;
|
||||
|
||||
$berlin = new Coordinate(52.5, 13.5);
|
||||
$london = new Coordinate(51.5, -0.12);
|
||||
|
||||
$bearingCalculator = new BearingSpherical();
|
||||
|
||||
$startTime = microtime(true);
|
||||
var_dump($bearingCalculator->calculateBearing($berlin, $london));
|
||||
var_dump($bearingCalculator->calculateFinalBearing($berlin, $london));
|
||||
$endTime = microtime(true);
|
||||
printf("Time elapsed: %0.6f s\n", ($endTime - $startTime));
|
||||
```
|
||||
|
||||
The code above will produce the following output:
|
||||
|
||||
``` plaintext
|
||||
double(268.60722336693)
|
||||
double(257.85494586285)
|
||||
Time elapsed: 0.000285 s
|
||||
```
|
||||
|
||||
### Calculation with an ellipsoidal earth model
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Bearing\BearingEllipsoidal;
|
||||
use Location\Coordinate;
|
||||
|
||||
$berlin = new Coordinate(52.5, 13.5);
|
||||
$london = new Coordinate(51.5, -0.12);
|
||||
|
||||
$bearingCalculator = new BearingEllipsoidal();
|
||||
|
||||
$startTime = microtime(true);
|
||||
var_dump($bearingCalculator->calculateBearing($berlin, $london));
|
||||
var_dump($bearingCalculator->calculateFinalBearing($berlin, $london));
|
||||
$endTime = microtime(true);
|
||||
printf("Time elapsed: %0.6f s\n", ($endTime - $startTime));
|
||||
```
|
||||
|
||||
The code above will produce the following output:
|
||||
|
||||
``` plaintext
|
||||
double(268.62436347111)
|
||||
double(257.87203657292)
|
||||
Time elapsed: 0.000304 s
|
||||
```
|
||||
|
||||
Both calculations finish in roughly the same time. One would expect the
|
||||
second calculation to be clearly slower than the first one. It seems
|
||||
the exit condition for the iteration is reached quite fast. There might
|
||||
exist other conditions where the ellipsoidal calculation is noticeable
|
||||
slower.
|
||||
|
||||
## Destination point for given bearing and distance
|
||||
|
||||
As an example, starting from Berlin, calculate the destination point in
|
||||
56.1 km distance with an initial bearing of 153 degrees:
|
||||
|
||||
``` php
|
||||
<?php
|
||||
use Location\Bearing\BearingEllipsoidal;
|
||||
use Location\Bearing\BearingSpherical;
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DecimalDegrees;
|
||||
|
||||
$berlin = new Coordinate(52.5, 13.5);
|
||||
|
||||
$bearingSpherical = new BearingSpherical();
|
||||
$bearingEllipsoidal = new BearingEllipsoidal();
|
||||
|
||||
$destination1 = $BearingSpherical->calculateDestination($berlin, 153, 56100);
|
||||
$destination2 = $bearingEllipsoidal->calculateDestination($berlin, 153, 56100);
|
||||
|
||||
echo "Spherical: " . $destination1->format(new DecimalDegrees()) . PHP_EOL;
|
||||
echo "Ellipsoidal: " . $destination2->format(new DecimalDegrees()) . PHP_EOL;
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
Spherical: 52.04988 13.87628
|
||||
Ellipsoidal: 52.05020 13.87126
|
||||
```
|
||||
|
||||
Oh, look, what a [beautiful spot on earth](https://www.openstreetmap.org/?mlat=52.0499&mlon=13.8762#map=13/52.0499/13.8762) it is. ;-)
|
||||
|
||||
## Final Bearing for a calculated destination
|
||||
|
||||
*phpgeo* can calculate the final bearing angle for a given starting point,
|
||||
an initial bearing, and the distance to the destination.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
use Location\Bearing\BearingEllipsoidal;
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DecimalDegrees;
|
||||
|
||||
$berlin = new Coordinate(52.5, 13.5);
|
||||
|
||||
$bearingEllipsoidal = new BearingEllipsoidal();
|
||||
|
||||
$finalBearing = $bearingEllipsoidal->calculateDestinationFinalBearing($berlin, 153, 56100);
|
||||
|
||||
var_dump($finalBearing);
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
float(153.29365182147)
|
||||
```
|
||||
70
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/425_Cardinal_Distance.md
vendored
Normal file
70
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/425_Cardinal_Distance.md
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
# Cardinal Distance Between Two Points
|
||||
|
||||
The distances how far you have to go to one cardinal direction and eventually to another to reach the second point
|
||||
*P<sub>2</sub>* from the first one *P<sub>1</sub>* is called the Cardinal Distances.
|
||||
|
||||
In the following example the Cardinal Distances are labeled *N* and *E:*
|
||||
|
||||

|
||||
|
||||
[TOC]
|
||||
|
||||
With *phpgeo* there are two ways to calculate the Cardinal Distances:
|
||||
|
||||
## Using the Calculator Instance
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Vincenty;
|
||||
use Location\CardinalDirection\CardinalDirectionDistancesCalculator;
|
||||
|
||||
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit
|
||||
|
||||
$calculator = new Vincenty();
|
||||
$cardinalDirectionDistancesCalculator = new CardinalDirectionDistancesCalculator();
|
||||
|
||||
$result = $cardinalDirectionDistancesCalculator->getCardinalDirectionDistances($coordinate1, $coordinate2, $calculator);
|
||||
|
||||
echo 'Cardinal Distances: north=' . $result->getNorth()
|
||||
. ' m; east=' . $result->getEast()
|
||||
. ' m; south=' . $result->getSouth(
|
||||
. ' m; west=' . $result->getWest() . ' m.';
|
||||
```
|
||||
|
||||
The code above will produce the following output:
|
||||
|
||||
```
|
||||
Cardinal Distances: north=98425.507 m; east=0 m; south=0 m; west=82268.492 m.
|
||||
```
|
||||
|
||||
## Using the `getCardinalDirectionDistances()` method of a Coordinate instance
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Location\CardinalDirection\CardinalDirection;
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Vincenty;
|
||||
|
||||
$point1 = new Coordinate(52.5072, 13.4248); // Berlin, Germany
|
||||
$point2 = new Coordinate(52.4284, 13.0276); // Potsdam, Germany
|
||||
|
||||
$direction = (new CardinalDirection())->getCardinalDirection($point1, $point2);
|
||||
|
||||
$result = $point1->getCardinalDirectionDistances($point2, new Vincenty());
|
||||
|
||||
echo 'Cardinal Distances: direction=' . $direction
|
||||
. '; north=' . $result->getNorth()
|
||||
. ' m; east=' . $result->getEast()
|
||||
. ' m; south=' . $result->getSouth()
|
||||
. ' m; west=' . $result->getWest() . ' m.';
|
||||
```
|
||||
|
||||
The code above will produce the following output:
|
||||
|
||||
```
|
||||
Cardinal Distances: direction=north-east; north=0 m; east=0 m; south=8768.566 m; west=26969.504 m.
|
||||
```
|
||||
43
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/430_Perpendicular_Distance.md
vendored
Normal file
43
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/430_Perpendicular_Distance.md
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
# Perpendicular Distance
|
||||
|
||||
The _perpendicular distance_ is defined as the shortest distance between a point
|
||||
a line (in the two-dimensional plane) respectively between a point and a
|
||||
[great circle](https://en.wikipedia.org/wiki/Great_circle) on a spherical surface.
|
||||
|
||||
With _phpgeo_ it is possible to calculate the perpendicular distance between a
|
||||
point (instance of the [`Coordinate`](../Geometries/Coordinate) class) and a
|
||||
Great Circle - which is defined by a [`Line`](../Geometries/Line). A line is
|
||||
defined by a pair of coordinates.
|
||||
|
||||
The distance between points *P* and *X* is the perpendicular distance in the following sketch:
|
||||
|
||||

|
||||
|
||||
## Example
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Line;
|
||||
use Location\Utility\PerpendicularDistance;
|
||||
|
||||
$point = new Coordinate(52.44468, 13.57455);
|
||||
$line = new Line(
|
||||
new Coordinate(52.4554, 13.5582),
|
||||
new Coordinate(52.4371, 13.5623)
|
||||
);
|
||||
|
||||
$pdCalc = new PerpendicularDistance();
|
||||
|
||||
printf(
|
||||
"perpendicular distance: %.1f meters\n",
|
||||
$pdCalc->getPerpendicularDistance($point, $line)
|
||||
);
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
perpendicular distance: 936.7 meters
|
||||
```
|
||||
46
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/435_Distance_Between_Point_and_Line.md
vendored
Normal file
46
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/435_Distance_Between_Point_and_Line.md
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
# Distance Between a Point and a Line
|
||||
|
||||
It's possible to calculate the shortest distance between a point and a
|
||||
[`Line`](../Geometries/Line). As [`Polyline`](../Geometries/Polyline)
|
||||
and [`Polygon`](../Geometries/Polygon) are also built upon the `Line` class
|
||||
it's also possible to calculate distances from a point the polyline/polygon
|
||||
by iterating over their segments.
|
||||
|
||||
The following image explains how the distance is calcualated: *P* and *R* are
|
||||
located in such a way that the nearest distance to the line is the distance between
|
||||
*P*, *R* and the line end points. Point *Q* is nearer to the actual line than to
|
||||
any of the end points, so the actual distance is the perpendicular distance between *Q*
|
||||
and the line.
|
||||
|
||||

|
||||
|
||||
## Example
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\Vincenty;
|
||||
use Location\Line;
|
||||
use Location\Utility\PointToLineDistance;
|
||||
|
||||
$point = new Coordinate(52.5, 13.5);
|
||||
$line = new Line(
|
||||
new Coordinate(52.5, 13.1),
|
||||
new Coordinate(52.5, 13.1)
|
||||
);
|
||||
|
||||
$pointToLineDistanceCalculator = new PointToLineDistance(new Vincenty());
|
||||
|
||||
printf(
|
||||
'Distance from point to line: %.1f meters%s',
|
||||
$pointToLineDistanceCalculator->getDistance($point, $line),
|
||||
PHP_EOL
|
||||
);
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
Distance from point to line: 27164.1 meters
|
||||
```
|
||||
40
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/440_Geofence.md
vendored
Normal file
40
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/440_Geofence.md
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
# Geofence
|
||||
|
||||
_phpgeo_ has a polygon implementation which can be used to determinate
|
||||
if a geometry (point, line, polyline, polygon) is contained in it or not.
|
||||
A polygon consists of at least three points.
|
||||
|
||||
WARNING: The calculation gives wrong results if the polygons crosses
|
||||
the 180/-180 degrees meridian.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polygon;
|
||||
|
||||
$geofence = new Polygon();
|
||||
|
||||
$geofence->addPoint(new Coordinate(-12.085870,-77.016261));
|
||||
$geofence->addPoint(new Coordinate(-12.086373,-77.033813));
|
||||
$geofence->addPoint(new Coordinate(-12.102823,-77.030938));
|
||||
$geofence->addPoint(new Coordinate(-12.098669,-77.006476));
|
||||
|
||||
$outsidePoint = new Coordinate(-12.075452, -76.985079);
|
||||
$insidePoint = new Coordinate(-12.092542, -77.021540);
|
||||
|
||||
echo $geofence->contains($outsidePoint)
|
||||
? 'Point 1 is located inside the polygon' . PHP_EOL
|
||||
: 'Point 1 is located outside the polygon' . PHP_EOL;
|
||||
|
||||
echo $geofence->contains($insidePoint)
|
||||
? 'Point 2 is located inside the polygon' . PHP_EOL
|
||||
: 'Point 2 is located outside the polygon' . PHP_EOL;
|
||||
```
|
||||
|
||||
The code above will produce the output below:
|
||||
|
||||
``` plaintext
|
||||
Point 1 is located outside the polygon
|
||||
Point 2 is located inside the polygon
|
||||
```
|
||||
BIN
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/cardinal-distance.png
vendored
Normal file
BIN
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/cardinal-distance.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
3
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/index.md
vendored
Normal file
3
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/index.md
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Calculations
|
||||
|
||||
The following chapters describe the possibilities to do geographical calculations with *phpgeo,* e.g. length and distance calculations, determining bearings, etc.
|
||||
BIN
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/perpendicular-distance.png
vendored
Normal file
BIN
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/perpendicular-distance.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/point-to-line-distance.png
vendored
Normal file
BIN
niucloud/vendor/mjaschen/phpgeo/docs/400_Calculations/point-to-line-distance.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@ -0,0 +1,91 @@
|
||||
# Simplifying a polyline/polygon
|
||||
|
||||
[TOC]
|
||||
|
||||
Polylines and polygons can be simplified to save storage space or bandwidth.
|
||||
|
||||
_phpgeo_ provides two implementations for simplifying polyline/polygons.
|
||||
|
||||
The first implementation uses the [_Ramer–Douglas–Peucker algorithm_](https://en.wikipedia.org/wiki/Ramer–Douglas–Peucker_algorithm)
|
||||
(also known as _Douglas-Peucker algorithm_). The other implementation examines
|
||||
the bearings of the segments and removes a segment when its bearing
|
||||
angle is similar to the bearing angle of its predecessor segment. I named it
|
||||
the _Delta-Bearing algorithm_.
|
||||
|
||||
## Ramer-Douglas-Peucker Algorithm
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DecimalDegrees;
|
||||
use Location\Polyline;
|
||||
use Location\Processor\Polyline\SimplifyDouglasPeucker;
|
||||
|
||||
$polyline = new Polyline();
|
||||
$polyline->addPoint(new Coordinate(10.0, 10.0));
|
||||
$polyline->addPoint(new Coordinate(20.0, 20.0));
|
||||
$polyline->addPoint(new Coordinate(30.0, 10.0));
|
||||
|
||||
$processor = new SimplifyDouglasPeucker(1500000);
|
||||
|
||||
$simplified = $processor->simplify($polyline);
|
||||
|
||||
foreach ($simplified->getPoints() as $point) {
|
||||
echo $point->format(new DecimalDegrees()) . PHP_EOL;
|
||||
}
|
||||
```
|
||||
|
||||
The example code will remove all points which perpendicular distance is less
|
||||
than 1,500,000 meters (1,500 km) from the surrounding points.
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
10.00000 10.00000
|
||||
30.00000 10.00000
|
||||
```
|
||||
|
||||
## Delta-Bearing Algorithm
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DecimalDegrees;
|
||||
use Location\Polyline;
|
||||
use Location\Processor\Polyline\SimplifyBearing;
|
||||
|
||||
$polyline = new Polyline();
|
||||
$polyline->addPoint(new Coordinate(10.0, 10.0));
|
||||
$polyline->addPoint(new Coordinate(20.0, 20.0));
|
||||
$polyline->addPoint(new Coordinate(30.0, 10.0));
|
||||
|
||||
$processor = new SimplifyBearing(90);
|
||||
|
||||
$simplified = $processor->simplify($polyline);
|
||||
|
||||
foreach ($simplified->getPoints() as $point) {
|
||||
echo $point->format(new DecimalDegrees()) . PHP_EOL;
|
||||
}
|
||||
```
|
||||
|
||||
The constructor argument for the `SimplifyBearing` class is the minimum
|
||||
required angle in degrees between two adjacent polyline segments so that
|
||||
no points will be removed. If the bearing angle difference is less that
|
||||
the given value, the middle point will be removed from the resulting
|
||||
polyline.
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
10.00000 10.00000
|
||||
30.00000 10.00000
|
||||
```
|
||||
|
||||
The following image shows both a polyline and its simplified version. The
|
||||
simplification was done with the Delta-Bearing Algorithm with a threshold angle
|
||||
of 20 degrees. The original polyline is painted in blue, the simplified polyline
|
||||
is magenta.
|
||||
|
||||

|
||||
5
niucloud/vendor/mjaschen/phpgeo/docs/500_Transformations_and_Processing/index.md
vendored
Normal file
5
niucloud/vendor/mjaschen/phpgeo/docs/500_Transformations_and_Processing/index.md
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Transformations and Processing
|
||||
|
||||
*phpgeo* provides tools for transforming and processing geometry instances.
|
||||
It's possible to simplify a Polyline by removing unneeded points to save
|
||||
storage space for example.
|
||||
BIN
niucloud/vendor/mjaschen/phpgeo/docs/500_Transformations_and_Processing/simplify.png
vendored
Normal file
BIN
niucloud/vendor/mjaschen/phpgeo/docs/500_Transformations_and_Processing/simplify.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 189 KiB |
125
niucloud/vendor/mjaschen/phpgeo/docs/600_Formatting_and_Output/100_Coordinates.md
vendored
Normal file
125
niucloud/vendor/mjaschen/phpgeo/docs/600_Formatting_and_Output/100_Coordinates.md
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
# Formatting Coordinates
|
||||
|
||||
You can format a coordinate in different styles.
|
||||
|
||||
## Decimal Degrees
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DecimalDegrees;
|
||||
|
||||
$coordinate = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
|
||||
echo $coordinate->format(new DecimalDegrees());
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
19.82066 -155.46807
|
||||
```
|
||||
|
||||
The separator string between latitude and longitude can be configured via
|
||||
constructor argument, as well as the number of decimals (default value is
|
||||
5 digits):
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DecimalDegrees;
|
||||
|
||||
$coordinate = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
|
||||
|
||||
echo $coordinate->format(new DecimalDegrees(', ', 3));
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
19.821, -155.468
|
||||
```
|
||||
|
||||
## Degrees/Minutes/Seconds (DMS)
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DMS;
|
||||
|
||||
$coordinate = new Coordinate(18.911306, -155.678268); // South Point, HI, USA
|
||||
|
||||
$formatter = new DMS();
|
||||
|
||||
echo $coordinate->format($formatter) . PHP_EOL;
|
||||
|
||||
$formatter->setSeparator(', ')
|
||||
->useCardinalLetters(true)
|
||||
->setUnits(DMS::UNITS_ASCII);
|
||||
|
||||
echo $coordinate->format($formatter) . PHP_EOL;
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
18° 54′ 41″ -155° 40′ 42″
|
||||
18° 54' 41" N, 155° 40' 42" W
|
||||
```
|
||||
|
||||
## Decimal Minutes
|
||||
|
||||
This format is commonly used in the Geocaching community.
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\DecimalMinutes;
|
||||
|
||||
$coordinate = new Coordinate(43.62310, -70.20787); // Portland Head Light, ME, USA
|
||||
|
||||
$formatter = new DecimalMinutes();
|
||||
|
||||
echo $coordinate->format($formatter) . PHP_EOL;
|
||||
|
||||
$formatter->setSeparator(', ')
|
||||
->useCardinalLetters(true)
|
||||
->setUnits(DecimalMinutes::UNITS_ASCII);
|
||||
|
||||
echo $coordinate->format($formatter) . PHP_EOL;
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
43° 37.386′ -070° 12.472′
|
||||
43° 37.386' N, 070° 12.472' W
|
||||
```
|
||||
|
||||
## GeoJSON
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Formatter\Coordinate\GeoJSON;
|
||||
|
||||
$coordinate = new Coordinate(18.911306, -155.678268); // South Point, HI, USA
|
||||
|
||||
echo $coordinate->format(new GeoJSON());
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` json
|
||||
{"type":"Point","coordinates":[-155.678268,18.911306]}
|
||||
```
|
||||
|
||||
NOTE: Float values processed by `json_encode()` are affected by the ini-setting
|
||||
[`serialize_precision`](https://secure.php.net/manual/en/ini.core.php#ini.serialize-precision).
|
||||
You can change the number of decimal places in the JSON output by changing
|
||||
that ini-option, e. g. with `ini_set('serialize_precision', 8)`.
|
||||
32
niucloud/vendor/mjaschen/phpgeo/docs/600_Formatting_and_Output/130_Polylines.md
vendored
Normal file
32
niucloud/vendor/mjaschen/phpgeo/docs/600_Formatting_and_Output/130_Polylines.md
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
# Formatting Polylines
|
||||
|
||||
You can format a polyline in different styles.
|
||||
|
||||
## GeoJSON
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polyline;
|
||||
use Location\Formatter\Polyline\GeoJSON;
|
||||
|
||||
$polyline = new Polyline;
|
||||
$polyline->addPoint(new Coordinate(52.5, 13.5));
|
||||
$polyline->addPoint(new Coordinate(62.5, 14.5));
|
||||
|
||||
$formatter = new GeoJSON;
|
||||
|
||||
echo $formatter->format($polyline);
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` json
|
||||
{"type":"LineString","coordinates":[[13.5,52.5],[14.5,62.5]]}
|
||||
```
|
||||
|
||||
NOTE: Float values processed by `json_encode()` are affected by the ini-setting
|
||||
[`serialize_precision`](https://secure.php.net/manual/en/ini.core.php#ini.serialize-precision).
|
||||
You can change the number of decimal places in the JSON output by changing
|
||||
that ini-option, e. g. with `ini_set('serialize_precision', 8)`.
|
||||
34
niucloud/vendor/mjaschen/phpgeo/docs/600_Formatting_and_Output/140_Polygons.md
vendored
Normal file
34
niucloud/vendor/mjaschen/phpgeo/docs/600_Formatting_and_Output/140_Polygons.md
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
# Formatting Polygons
|
||||
|
||||
You can format a polygon in different styles.
|
||||
|
||||
## GeoJSON
|
||||
|
||||
``` php
|
||||
<?php
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Polygon;
|
||||
use Location\Formatter\Polygon\GeoJSON;
|
||||
|
||||
$polygon = new Polygon;
|
||||
$polygon->addPoint(new Coordinate(10, 20));
|
||||
$polygon->addPoint(new Coordinate(20, 40));
|
||||
$polygon->addPoint(new Coordinate(30, 40));
|
||||
$polygon->addPoint(new Coordinate(30, 20));
|
||||
|
||||
$formatter = new GeoJSON;
|
||||
|
||||
echo $formatter->format($polygon);
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` json
|
||||
{"type":"Polygon","coordinates":[[20,10],[40,20],[40,30],[20,30]]}
|
||||
```
|
||||
|
||||
NOTE: Float values processed by `json_encode()` are affected by the ini-setting
|
||||
[`serialize_precision`](https://secure.php.net/manual/en/ini.core.php#ini.serialize-precision).
|
||||
You can change the number of decimal places in the JSON output by changing
|
||||
that ini-option, e. g. with `ini_set('serialize_precision', 8)`.
|
||||
5
niucloud/vendor/mjaschen/phpgeo/docs/600_Formatting_and_Output/index.md
vendored
Normal file
5
niucloud/vendor/mjaschen/phpgeo/docs/600_Formatting_and_Output/index.md
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Formatting and Output
|
||||
|
||||
*phpgeo* is able to output supported Geometry instances in many different
|
||||
formats. You're able to provide your own Formatter classes for customization
|
||||
of the output format.
|
||||
53
niucloud/vendor/mjaschen/phpgeo/docs/700_Parsing_and_Input/110_Coordinates_Parser.md
vendored
Normal file
53
niucloud/vendor/mjaschen/phpgeo/docs/700_Parsing_and_Input/110_Coordinates_Parser.md
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
# Coordinates Parser
|
||||
|
||||
_phpgeo_ comes with a parser for several types of coordinate formats.
|
||||
The parser works as a factory which creates an instance of the
|
||||
`Coordinate` class.
|
||||
|
||||
## Supported Formats
|
||||
|
||||
**Decimal Degrees** with or without *cardinal letters*,
|
||||
with or without a comma as separator, with or without
|
||||
whitespace between values and cardinal letters.
|
||||
|
||||
Examples of supported formats:
|
||||
|
||||
- 52.5, 13.5
|
||||
- 52.5 13.5
|
||||
- -52.5 -13.5
|
||||
- 52.345 N, 13.456 E
|
||||
- N52.345 E13.456
|
||||
|
||||
**Decimal Minutes** with or without cardinal letters, with
|
||||
or without degree and minute signs, with or without a comma
|
||||
as separator, with or without whitespace between values
|
||||
and cardinal letters.
|
||||
|
||||
Examples of supported formats:
|
||||
|
||||
- 345, E13° 34.567
|
||||
- 45′ N, E13° 34.567′ E
|
||||
- 5, 013 34.567
|
||||
- 45, -013 34.567
|
||||
|
||||
The [unit test](https://github.com/mjaschen/phpgeo/blob/master/tests/Location/Factory/CoordinateFactoryTest.php)
|
||||
shows some more examples.
|
||||
|
||||
## Example
|
||||
|
||||
```php
|
||||
use Location\Factory\CoordinateFactory;
|
||||
use Location\Formatter\Coordinate\DecimalDegrees;
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$point = CoordinateFactory::fromString('52° 13.698′ 020° 58.536′');
|
||||
|
||||
echo $point->format(new DecimalDegrees());
|
||||
```
|
||||
|
||||
The code above produces the output below:
|
||||
|
||||
``` plaintext
|
||||
52.22830 20.97560
|
||||
```
|
||||
7
niucloud/vendor/mjaschen/phpgeo/docs/700_Parsing_and_Input/index.md
vendored
Normal file
7
niucloud/vendor/mjaschen/phpgeo/docs/700_Parsing_and_Input/index.md
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# Parsing and Input
|
||||
|
||||
The constructor for the `Coordinate` class accepts a pair of float values
|
||||
for creating an instance. Coordinates often come in formatted versions,
|
||||
e.g. with cardinal letters, formatted in degrees, arc minutes, and arc
|
||||
seconds and so on. *phpgeo* provides parsers for many formats which create
|
||||
correctly instantiated `Coordinate` objects.
|
||||
6
niucloud/vendor/mjaschen/phpgeo/docs/900_Further_Reading.md
vendored
Normal file
6
niucloud/vendor/mjaschen/phpgeo/docs/900_Further_Reading.md
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
# Further Reading / Sources
|
||||
|
||||
- [Movable Type Scripts](https://www.movable-type.co.uk/scripts/latlong.html)
|
||||
- [Aviation Formulary V1.24 by Ed Williams](https://www.edwilliams.org/ftp/avsig/avform.txt)
|
||||
- [Perpendicular Distance Calculator](https://biodiversityinformatics.amnh.org/open_source/pdc/index.html) ([Github](https://github.com/persts/GeographicDistanceTools))
|
||||
- [W. Randolph Franklin, PNPOLY - Point Inclusion in Polygon Test](https://wrfranklin.org/Research/Short_Notes/pnpoly.html)
|
||||
BIN
niucloud/vendor/mjaschen/phpgeo/docs/BoundsFactory.afdesign
vendored
Normal file
BIN
niucloud/vendor/mjaschen/phpgeo/docs/BoundsFactory.afdesign
vendored
Normal file
Binary file not shown.
BIN
niucloud/vendor/mjaschen/phpgeo/docs/Cardinal_Distance.afdesign
vendored
Normal file
BIN
niucloud/vendor/mjaschen/phpgeo/docs/Cardinal_Distance.afdesign
vendored
Normal file
Binary file not shown.
BIN
niucloud/vendor/mjaschen/phpgeo/docs/Line_to_Point_Distance.afdesign
vendored
Normal file
BIN
niucloud/vendor/mjaschen/phpgeo/docs/Line_to_Point_Distance.afdesign
vendored
Normal file
Binary file not shown.
BIN
niucloud/vendor/mjaschen/phpgeo/docs/Perpendicular_Distance.afdesign
vendored
Normal file
BIN
niucloud/vendor/mjaschen/phpgeo/docs/Perpendicular_Distance.afdesign
vendored
Normal file
Binary file not shown.
25
niucloud/vendor/mjaschen/phpgeo/docs/config.json
vendored
Normal file
25
niucloud/vendor/mjaschen/phpgeo/docs/config.json
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"title": "phpgeo",
|
||||
"tagline": "A Simple Yet Powerful Geo Library for PHP",
|
||||
"author": "Marcus Jaschen",
|
||||
"format": "html",
|
||||
"timezone": "Europe/Berlin",
|
||||
"html": {
|
||||
"theme": "daux-red",
|
||||
"breadcrumbs": true,
|
||||
"breadcrumb_separator": "Chevrons",
|
||||
"toggle_code": true,
|
||||
"date_modified": true,
|
||||
"inherit_index": true,
|
||||
"search": true,
|
||||
"repo": "mjaschen/phpgeo",
|
||||
"edit_on_github": "mjaschen/phpgeo/blob/master/docs",
|
||||
"piwik_analytics": "metrics.m11n.de",
|
||||
"piwik_analytics_id": "15",
|
||||
"links": {
|
||||
"Download": "https://github.com/mjaschen/phpgeo/archive/master.zip",
|
||||
"GitHub Repo": "https://github.com/mjaschen/phpgeo",
|
||||
"Help/Support/Bugs": "https://github.com/mjaschen/phpgeo/issues"
|
||||
}
|
||||
}
|
||||
}
|
||||
3400
niucloud/vendor/mjaschen/phpgeo/docs/intersection-polyline-simple.dxf
vendored
Normal file
3400
niucloud/vendor/mjaschen/phpgeo/docs/intersection-polyline-simple.dxf
vendored
Normal file
File diff suppressed because it is too large
Load Diff
121
niucloud/vendor/mjaschen/phpgeo/phpcs.xml.dist
vendored
Normal file
121
niucloud/vendor/mjaschen/phpgeo/phpcs.xml.dist
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ruleset name="Coding Standard">
|
||||
<description>
|
||||
This standard requires PHP_CodeSniffer >= 3.4.
|
||||
</description>
|
||||
|
||||
<arg name="colors"/>
|
||||
<arg name="extensions" value="php"/>
|
||||
|
||||
<!--The complete PSR-12 rule set-->
|
||||
<rule ref="PSR12"/>
|
||||
|
||||
<!-- Arrays -->
|
||||
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
|
||||
<rule ref="Squiz.Arrays.ArrayBracketSpacing"/>
|
||||
|
||||
<!-- Classes -->
|
||||
<rule ref="Generic.Classes.DuplicateClassName"/>
|
||||
<rule ref="Squiz.Classes.ClassFileName"/>
|
||||
<rule ref="Squiz.Classes.DuplicateProperty"/>
|
||||
<rule ref="Squiz.Classes.LowercaseClassKeywords"/>
|
||||
<rule ref="Squiz.Classes.SelfMemberReference"/>
|
||||
|
||||
<!-- Code analysis -->
|
||||
<rule ref="Generic.CodeAnalysis.AssignmentInCondition"/>
|
||||
<rule ref="Generic.CodeAnalysis.EmptyStatement"/>
|
||||
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop"/>
|
||||
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall"/>
|
||||
<rule ref="Generic.CodeAnalysis.JumbledIncrementer"/>
|
||||
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement"/>
|
||||
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>
|
||||
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
|
||||
|
||||
<!-- Commenting -->
|
||||
<rule ref="Generic.Commenting.Fixme"/>
|
||||
<rule ref="Generic.Commenting.Todo"/>
|
||||
<rule ref="PEAR.Commenting.InlineComment"/>
|
||||
<rule ref="Squiz.Commenting.DocCommentAlignment"/>
|
||||
<rule ref="Squiz.Commenting.EmptyCatchComment"/>
|
||||
<rule ref="Squiz.Commenting.FunctionCommentThrowTag"/>
|
||||
<rule ref="Squiz.Commenting.PostStatementComment"/>
|
||||
|
||||
<!-- Control structures -->
|
||||
<rule ref="PEAR.ControlStructures.ControlSignature"/>
|
||||
|
||||
<!-- Debug -->
|
||||
<rule ref="Generic.Debug.ClosureLinter"/>
|
||||
|
||||
<!-- Files -->
|
||||
<rule ref="Generic.Files.OneClassPerFile"/>
|
||||
<rule ref="Generic.Files.OneInterfacePerFile"/>
|
||||
<rule ref="Generic.Files.OneObjectStructurePerFile"/>
|
||||
<rule ref="Zend.Files.ClosingTag"/>
|
||||
|
||||
<!-- Formatting -->
|
||||
<rule ref="PEAR.Formatting.MultiLineAssignment"/>
|
||||
|
||||
<!-- Functions -->
|
||||
<rule ref="Generic.Functions.CallTimePassByReference"/>
|
||||
<rule ref="PSR12.Functions.NullableTypeDeclaration"/>
|
||||
<rule ref="Squiz.Functions.FunctionDuplicateArgument"/>
|
||||
<rule ref="Squiz.Functions.GlobalFunction"/>
|
||||
|
||||
<!-- Metrics -->
|
||||
<rule ref="Generic.Metrics.CyclomaticComplexity"/>
|
||||
<rule ref="Generic.Metrics.NestingLevel"/>
|
||||
|
||||
<!-- Naming conventions -->
|
||||
<rule ref="Generic.NamingConventions.ConstructorName"/>
|
||||
<rule ref="PEAR.NamingConventions.ValidClassName"/>
|
||||
|
||||
<!-- Objects -->
|
||||
<rule ref="Squiz.Objects.ObjectMemberComma"/>
|
||||
|
||||
<!-- Operators -->
|
||||
<rule ref="Squiz.Operators.IncrementDecrementUsage"/>
|
||||
<rule ref="Squiz.Operators.ValidLogicalOperators"/>
|
||||
|
||||
<!-- PHP -->
|
||||
<rule ref="Generic.PHP.BacktickOperator"/>
|
||||
<rule ref="Generic.PHP.CharacterBeforePHPOpeningTag"/>
|
||||
<rule ref="Generic.PHP.DeprecatedFunctions"/>
|
||||
<rule ref="Generic.PHP.DisallowAlternativePHPTags"/>
|
||||
<rule ref="Generic.PHP.DiscourageGoto"/>
|
||||
<rule ref="Generic.PHP.ForbiddenFunctions"/>
|
||||
<rule ref="Generic.PHP.NoSilencedErrors"/>
|
||||
<rule ref="Squiz.PHP.CommentedOutCode">
|
||||
<properties>
|
||||
<property name="maxPercentage" value="70"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Squiz.PHP.DisallowMultipleAssignments"/>
|
||||
<rule ref="Squiz.PHP.DisallowSizeFunctionsInLoops"/>
|
||||
<rule ref="Squiz.PHP.DiscouragedFunctions"/>
|
||||
<rule ref="Squiz.PHP.Eval"/>
|
||||
<rule ref="Squiz.PHP.GlobalKeyword"/>
|
||||
<rule ref="Squiz.PHP.Heredoc"/>
|
||||
<rule ref="Squiz.PHP.InnerFunctions"/>
|
||||
<rule ref="Squiz.PHP.LowercasePHPFunctions"/>
|
||||
<rule ref="Squiz.PHP.NonExecutableCode"/>
|
||||
|
||||
<!-- Scope -->
|
||||
<rule ref="Squiz.Scope.MemberVarScope"/>
|
||||
<rule ref="Squiz.Scope.StaticThisUsage"/>
|
||||
|
||||
<!-- Strings -->
|
||||
<rule ref="Squiz.Strings.DoubleQuoteUsage"/>
|
||||
|
||||
<!-- Whitespace -->
|
||||
<rule ref="PEAR.WhiteSpace.ObjectOperatorIndent"/>
|
||||
<rule ref="PEAR.WhiteSpace.ScopeClosingBrace"/>
|
||||
<rule ref="Squiz.WhiteSpace.CastSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.OperatorSpacing">
|
||||
<properties>
|
||||
<property name="ignoreNewlines" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Squiz.WhiteSpace.PropertyLabelSpacing"/>
|
||||
<rule ref="Squiz.WhiteSpace.SemicolonSpacing"/>
|
||||
</ruleset>
|
||||
14
niucloud/vendor/mjaschen/phpgeo/phpunit.xml
vendored
Normal file
14
niucloud/vendor/mjaschen/phpgeo/phpunit.xml
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="tests/bootstrap.php" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
|
||||
<coverage>
|
||||
<include>
|
||||
<directory>src</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="Location Test Suite">
|
||||
<directory>tests/Location/</directory>
|
||||
<directory>tests/Regression/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
||||
13
niucloud/vendor/mjaschen/phpgeo/psalm.xml
vendored
Normal file
13
niucloud/vendor/mjaschen/phpgeo/psalm.xml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="/Users/mjaschen/Code/MarcusJaschen/phpgeo/vendor/vimeo/psalm/src/config.xsd"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
</projectFiles>
|
||||
|
||||
<issueHandlers>
|
||||
<LessSpecificReturnType errorLevel="info" />
|
||||
</issueHandlers>
|
||||
</psalm>
|
||||
256
niucloud/vendor/mjaschen/phpgeo/src/Bearing/BearingEllipsoidal.php
vendored
Normal file
256
niucloud/vendor/mjaschen/phpgeo/src/Bearing/BearingEllipsoidal.php
vendored
Normal file
@ -0,0 +1,256 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Bearing;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Location\Coordinate;
|
||||
use Location\Exception\NotConvergingException;
|
||||
|
||||
/**
|
||||
* Calculation of bearing between two points using a
|
||||
* ellipsoidal model of the earth.
|
||||
*
|
||||
* This class is based on the awesome work Chris Veness
|
||||
* has done. For more information visit the following URL.
|
||||
*
|
||||
* @see http://www.movable-type.co.uk/scripts/latlong-vincenty.html
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class BearingEllipsoidal implements BearingInterface
|
||||
{
|
||||
/**
|
||||
* This method calculates the initial bearing between the
|
||||
* two points.
|
||||
*
|
||||
* If the two points share the same location, the bearing
|
||||
* value will be 0.0.
|
||||
*
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @return float Bearing Angle
|
||||
*/
|
||||
public function calculateBearing(Coordinate $point1, Coordinate $point2): float
|
||||
{
|
||||
if ($point1->hasSameLocation($point2)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return $this->inverseVincenty($point1, $point2)->getBearingInitial();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the final bearing between the two points.
|
||||
*
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function calculateFinalBearing(Coordinate $point1, Coordinate $point2): float
|
||||
{
|
||||
return $this->inverseVincenty($point1, $point2)->getBearingFinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a destination point for the given point, bearing angle,
|
||||
* and distance.
|
||||
*
|
||||
* @param Coordinate $point
|
||||
* @param float $bearing the bearing angle between 0 and 360 degrees
|
||||
* @param float $distance the distance to the destination point in meters
|
||||
*
|
||||
* @return Coordinate
|
||||
*/
|
||||
public function calculateDestination(Coordinate $point, float $bearing, float $distance): Coordinate
|
||||
{
|
||||
return $this->directVincenty($point, $bearing, $distance)->getDestination();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the final bearing angle for a destination point.
|
||||
* The method expects a starting point point, the bearing angle,
|
||||
* and the distance to destination.
|
||||
*
|
||||
* @param Coordinate $point
|
||||
* @param float $bearing
|
||||
* @param float $distance
|
||||
*
|
||||
* @return float
|
||||
*
|
||||
* @throws NotConvergingException
|
||||
*/
|
||||
public function calculateDestinationFinalBearing(Coordinate $point, float $bearing, float $distance): float
|
||||
{
|
||||
return $this->directVincenty($point, $bearing, $distance)->getBearingFinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Coordinate $point
|
||||
* @param float $bearing
|
||||
* @param float $distance
|
||||
*
|
||||
* @return DirectVincentyBearing
|
||||
*
|
||||
* @throws NotConvergingException
|
||||
*/
|
||||
private function directVincenty(Coordinate $point, float $bearing, float $distance): DirectVincentyBearing
|
||||
{
|
||||
$phi1 = deg2rad($point->getLat());
|
||||
$lambda1 = deg2rad($point->getLng());
|
||||
$alpha1 = deg2rad($bearing);
|
||||
|
||||
$a = $point->getEllipsoid()->getA();
|
||||
$b = $point->getEllipsoid()->getB();
|
||||
$f = 1 / $point->getEllipsoid()->getF();
|
||||
|
||||
$sinAlpha1 = sin($alpha1);
|
||||
$cosAlpha1 = cos($alpha1);
|
||||
|
||||
$tanU1 = (1 - $f) * tan($phi1);
|
||||
$cosU1 = 1 / sqrt(1 + $tanU1 * $tanU1);
|
||||
$sinU1 = $tanU1 * $cosU1;
|
||||
$sigma1 = atan2($tanU1, $cosAlpha1);
|
||||
$sinAlpha = $cosU1 * $sinAlpha1;
|
||||
$cosSquAlpha = 1 - $sinAlpha * $sinAlpha;
|
||||
$uSq = $cosSquAlpha * ($a * $a - $b * $b) / ($b * $b);
|
||||
$A = 1 + $uSq / 16384 * (4096 + $uSq * (-768 + $uSq * (320 - 175 * $uSq)));
|
||||
$B = $uSq / 1024 * (256 + $uSq * (-128 + $uSq * (74 - 47 * $uSq)));
|
||||
|
||||
$sigmaS = $distance / ($b * $A);
|
||||
$sigma = $sigmaS;
|
||||
$iterations = 0;
|
||||
|
||||
do {
|
||||
$cos2SigmaM = cos(2 * $sigma1 + $sigma);
|
||||
$sinSigma = sin($sigma);
|
||||
$cosSigma = cos($sigma);
|
||||
$deltaSigma = $B * $sinSigma
|
||||
* ($cos2SigmaM + $B / 4
|
||||
* ($cosSigma
|
||||
* (-1 + 2 * $cos2SigmaM * $cos2SigmaM) - $B / 6
|
||||
* $cos2SigmaM * (-3 + 4 * $sinSigma * $sinSigma)
|
||||
* (-3 + 4 * $cos2SigmaM * $cos2SigmaM)
|
||||
)
|
||||
);
|
||||
$sigmaS = $sigma;
|
||||
$sigma = $distance / ($b * $A) + $deltaSigma;
|
||||
$iterations++;
|
||||
} while (abs($sigma - $sigmaS) > 1e-12 && $iterations < 200);
|
||||
|
||||
if ($iterations >= 200) {
|
||||
throw new NotConvergingException('Inverse Vincenty Formula did not converge');
|
||||
}
|
||||
|
||||
$tmp = $sinU1 * $sinSigma - $cosU1 * $cosSigma * $cosAlpha1;
|
||||
$phi2 = atan2(
|
||||
$sinU1 * $cosSigma + $cosU1 * $sinSigma * $cosAlpha1,
|
||||
(1 - $f) * sqrt($sinAlpha * $sinAlpha + $tmp * $tmp)
|
||||
);
|
||||
$lambda = atan2($sinSigma * $sinAlpha1, $cosU1 * $cosSigma - $sinU1 * $sinSigma * $cosAlpha1);
|
||||
$C = $f / 16 * $cosSquAlpha * (4 + $f * (4 - 3 * $cosSquAlpha));
|
||||
$L = $lambda
|
||||
- (1 - $C) * $f * $sinAlpha
|
||||
* ($sigma + $C * $sinSigma * ($cos2SigmaM + $C * $cosSigma * (-1 + 2 * $cos2SigmaM ** 2)));
|
||||
$lambda2 = fmod($lambda1 + $L + 3 * M_PI, 2 * M_PI) - M_PI;
|
||||
|
||||
$alpha2 = atan2($sinAlpha, -$tmp);
|
||||
$alpha2 = fmod($alpha2 + 2 * M_PI, 2 * M_PI);
|
||||
|
||||
return new DirectVincentyBearing(
|
||||
new Coordinate(rad2deg($phi2), rad2deg($lambda2), $point->getEllipsoid()),
|
||||
rad2deg($alpha2)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @return InverseVincentyBearing
|
||||
*
|
||||
* @throws NotConvergingException
|
||||
*/
|
||||
private function inverseVincenty(Coordinate $point1, Coordinate $point2): InverseVincentyBearing
|
||||
{
|
||||
$φ1 = deg2rad($point1->getLat());
|
||||
$φ2 = deg2rad($point2->getLat());
|
||||
$λ1 = deg2rad($point1->getLng());
|
||||
$λ2 = deg2rad($point2->getLng());
|
||||
|
||||
$a = $point1->getEllipsoid()->getA();
|
||||
$b = $point1->getEllipsoid()->getB();
|
||||
$f = 1 / $point1->getEllipsoid()->getF();
|
||||
|
||||
$L = $λ2 - $λ1;
|
||||
|
||||
$tanU1 = (1 - $f) * tan($φ1);
|
||||
$cosU1 = 1 / sqrt(1 + $tanU1 * $tanU1);
|
||||
$sinU1 = $tanU1 * $cosU1;
|
||||
$tanU2 = (1 - $f) * tan($φ2);
|
||||
$cosU2 = 1 / sqrt(1 + $tanU2 * $tanU2);
|
||||
$sinU2 = $tanU2 * $cosU2;
|
||||
|
||||
$λ = $L;
|
||||
|
||||
$iterations = 0;
|
||||
|
||||
do {
|
||||
$sinλ = sin($λ);
|
||||
$cosλ = cos($λ);
|
||||
$sinSqσ = ($cosU2 * $sinλ) * ($cosU2 * $sinλ)
|
||||
+ ($cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosλ) * ($cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosλ);
|
||||
$sinσ = sqrt($sinSqσ);
|
||||
|
||||
if ($sinσ == 0) {
|
||||
new InverseVincentyBearing(0, 0, 0);
|
||||
}
|
||||
|
||||
$cosσ = $sinU1 * $sinU2 + $cosU1 * $cosU2 * $cosλ;
|
||||
$σ = atan2($sinσ, $cosσ);
|
||||
$sinα = $cosU1 * $cosU2 * $sinλ / $sinσ;
|
||||
$cosSqα = 1 - $sinα * $sinα;
|
||||
|
||||
$cos2σM = 0;
|
||||
if ($cosSqα !== 0.0) {
|
||||
$cos2σM = $cosσ - 2 * $sinU1 * $sinU2 / $cosSqα;
|
||||
}
|
||||
|
||||
$C = $f / 16 * $cosSqα * (4 + $f * (4 - 3 * $cosSqα));
|
||||
$λp = $λ;
|
||||
$λ = $L + (1 - $C) * $f * $sinα
|
||||
* ($σ + $C * $sinσ * ($cos2σM + $C * $cosσ * (-1 + 2 * $cos2σM * $cos2σM)));
|
||||
$iterations++;
|
||||
} while (abs($λ - $λp) > 1e-12 && $iterations < 200);
|
||||
|
||||
if ($iterations >= 200) {
|
||||
throw new NotConvergingException('Inverse Vincenty Formula did not converge');
|
||||
}
|
||||
|
||||
$uSq = $cosSqα * ($a * $a - $b * $b) / ($b * $b);
|
||||
$A = 1 + $uSq / 16384 * (4096 + $uSq * (-768 + $uSq * (320 - 175 * $uSq)));
|
||||
$B = $uSq / 1024 * (256 + $uSq * (-128 + $uSq * (74 - 47 * $uSq)));
|
||||
$Δσ = $B * $sinσ
|
||||
* ($cos2σM + $B / 4
|
||||
* ($cosσ * (-1 + 2 * $cos2σM * $cos2σM) - $B / 6
|
||||
* $cos2σM * (-3 + 4 * $sinσ * $sinσ)
|
||||
* (-3 + 4 * $cos2σM * $cos2σM)
|
||||
)
|
||||
);
|
||||
|
||||
$s = $b * $A * ($σ - $Δσ);
|
||||
|
||||
$α1 = atan2($cosU2 * $sinλ, $cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosλ);
|
||||
$α2 = atan2($cosU1 * $sinλ, -$sinU1 * $cosU2 + $cosU1 * $sinU2 * $cosλ);
|
||||
|
||||
$α1 = fmod($α1 + 2 * M_PI, 2 * M_PI);
|
||||
$α2 = fmod($α2 + 2 * M_PI, 2 * M_PI);
|
||||
|
||||
$s = round($s, 3);
|
||||
|
||||
return new InverseVincentyBearing($s, rad2deg($α1), rad2deg($α2));
|
||||
}
|
||||
}
|
||||
48
niucloud/vendor/mjaschen/phpgeo/src/Bearing/BearingInterface.php
vendored
Normal file
48
niucloud/vendor/mjaschen/phpgeo/src/Bearing/BearingInterface.php
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Bearing;
|
||||
|
||||
use Location\Coordinate;
|
||||
|
||||
/**
|
||||
* Interface BearingInterface
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
interface BearingInterface
|
||||
{
|
||||
/**
|
||||
* This method calculates the initial bearing between the
|
||||
* two points.
|
||||
*
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @return float Bearing Angle
|
||||
*/
|
||||
public function calculateBearing(Coordinate $point1, Coordinate $point2): float;
|
||||
|
||||
/**
|
||||
* Calculates the final bearing between the two points.
|
||||
*
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function calculateFinalBearing(Coordinate $point1, Coordinate $point2): float;
|
||||
|
||||
/**
|
||||
* Calculates a destination point for the given point, bearing angle,
|
||||
* and distance.
|
||||
*
|
||||
* @param Coordinate $point
|
||||
* @param float $bearing the bearing angle between 0 and 360 degrees
|
||||
* @param float $distance the distance to the destination point in meters
|
||||
*
|
||||
* @return Coordinate
|
||||
*/
|
||||
public function calculateDestination(Coordinate $point, float $bearing, float $distance): Coordinate;
|
||||
}
|
||||
89
niucloud/vendor/mjaschen/phpgeo/src/Bearing/BearingSpherical.php
vendored
Normal file
89
niucloud/vendor/mjaschen/phpgeo/src/Bearing/BearingSpherical.php
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Bearing;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Location\Coordinate;
|
||||
|
||||
/**
|
||||
* Calculation of bearing between two points using a
|
||||
* simple spherical model of the earth.
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class BearingSpherical implements BearingInterface
|
||||
{
|
||||
/**
|
||||
* Earth radius in meters.
|
||||
*/
|
||||
private const EARTH_RADIUS = 6371009.0;
|
||||
|
||||
/**
|
||||
* This method calculates the initial bearing (forward azimut) between
|
||||
* the two given points.
|
||||
*
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @return float Bearing Angle in degrees
|
||||
*/
|
||||
public function calculateBearing(Coordinate $point1, Coordinate $point2): float
|
||||
{
|
||||
$lat1 = deg2rad($point1->getLat());
|
||||
$lat2 = deg2rad($point2->getLat());
|
||||
$lng1 = deg2rad($point1->getLng());
|
||||
$lng2 = deg2rad($point2->getLng());
|
||||
|
||||
$y = sin($lng2 - $lng1) * cos($lat2);
|
||||
$x = cos($lat1) * sin($lat2) - sin($lat1) * cos($lat2) * cos($lng2 - $lng1);
|
||||
|
||||
$bearing = rad2deg(atan2($y, $x));
|
||||
|
||||
if ($bearing < 0) {
|
||||
$bearing = fmod($bearing + 360, 360);
|
||||
}
|
||||
|
||||
return $bearing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the final bearing between the two points.
|
||||
*
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function calculateFinalBearing(Coordinate $point1, Coordinate $point2): float
|
||||
{
|
||||
$initialBearing = $this->calculateBearing($point2, $point1);
|
||||
|
||||
return fmod($initialBearing + 180, 360);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a destination point for the given point, bearing angle,
|
||||
* and distance.
|
||||
*
|
||||
* @param Coordinate $point
|
||||
* @param float $bearing the bearing angle between 0 and 360 degrees
|
||||
* @param float $distance the distance to the destination point in meters
|
||||
*
|
||||
* @return Coordinate
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function calculateDestination(Coordinate $point, float $bearing, float $distance): Coordinate
|
||||
{
|
||||
$D = $distance / self::EARTH_RADIUS;
|
||||
$B = deg2rad($bearing);
|
||||
$φ = deg2rad($point->getLat());
|
||||
$λ = deg2rad($point->getLng());
|
||||
|
||||
$Φ = asin(sin($φ) * cos($D) + cos($φ) * sin($D) * cos($B));
|
||||
$Λ = $λ + atan2(sin($B) * sin($D) * cos($φ), cos($D) - sin($φ) * sin($φ));
|
||||
|
||||
return new Coordinate(rad2deg($Φ), rad2deg($Λ));
|
||||
}
|
||||
}
|
||||
53
niucloud/vendor/mjaschen/phpgeo/src/Bearing/DirectVincentyBearing.php
vendored
Normal file
53
niucloud/vendor/mjaschen/phpgeo/src/Bearing/DirectVincentyBearing.php
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Bearing;
|
||||
|
||||
use Location\Coordinate;
|
||||
|
||||
/**
|
||||
* Value object for a "Direct Vincenty" bearing calculation result.
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class DirectVincentyBearing
|
||||
{
|
||||
/**
|
||||
* @var Coordinate
|
||||
*/
|
||||
private $destination;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $bearingFinal;
|
||||
|
||||
/**
|
||||
* Bearing constructor.
|
||||
*
|
||||
* @param Coordinate $destination
|
||||
* @param float $bearingFinal
|
||||
*/
|
||||
public function __construct(Coordinate $destination, float $bearingFinal)
|
||||
{
|
||||
$this->destination = $destination;
|
||||
$this->bearingFinal = $bearingFinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Coordinate
|
||||
*/
|
||||
public function getDestination(): Coordinate
|
||||
{
|
||||
return $this->destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getBearingFinal(): float
|
||||
{
|
||||
return $this->bearingFinal;
|
||||
}
|
||||
}
|
||||
66
niucloud/vendor/mjaschen/phpgeo/src/Bearing/InverseVincentyBearing.php
vendored
Normal file
66
niucloud/vendor/mjaschen/phpgeo/src/Bearing/InverseVincentyBearing.php
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Bearing;
|
||||
|
||||
/**
|
||||
* Value object for a "Direct Vincenty" bearing calculation result.
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class InverseVincentyBearing
|
||||
{
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $distance;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $bearingInitial;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $bearingFinal;
|
||||
|
||||
/**
|
||||
* InverseVincentyBearing constructor.
|
||||
*
|
||||
* @param float $distance
|
||||
* @param float $bearingInitial
|
||||
* @param float $bearingFinal
|
||||
*/
|
||||
public function __construct(float $distance, float $bearingInitial, float $bearingFinal)
|
||||
{
|
||||
$this->distance = $distance;
|
||||
$this->bearingInitial = $bearingInitial;
|
||||
$this->bearingFinal = $bearingFinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getDistance(): float
|
||||
{
|
||||
return $this->distance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getBearingInitial(): float
|
||||
{
|
||||
return $this->bearingInitial;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getBearingFinal(): float
|
||||
{
|
||||
return $this->bearingFinal;
|
||||
}
|
||||
}
|
||||
118
niucloud/vendor/mjaschen/phpgeo/src/Bounds.php
vendored
Normal file
118
niucloud/vendor/mjaschen/phpgeo/src/Bounds.php
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location;
|
||||
|
||||
class Bounds
|
||||
{
|
||||
/**
|
||||
* @var Coordinate
|
||||
*/
|
||||
protected $northWest;
|
||||
|
||||
/**
|
||||
* @var Coordinate
|
||||
*/
|
||||
protected $southEast;
|
||||
|
||||
/**
|
||||
* @param Coordinate $northWest
|
||||
* @param Coordinate $southEast
|
||||
*/
|
||||
public function __construct(Coordinate $northWest, Coordinate $southEast)
|
||||
{
|
||||
$this->northWest = $northWest;
|
||||
$this->southEast = $southEast;
|
||||
}
|
||||
|
||||
public function getNorthWest(): Coordinate
|
||||
{
|
||||
return $this->northWest;
|
||||
}
|
||||
|
||||
public function getSouthEast(): Coordinate
|
||||
{
|
||||
return $this->southEast;
|
||||
}
|
||||
|
||||
public function getNorthEast(): Coordinate
|
||||
{
|
||||
return new Coordinate($this->getNorth(), $this->getEast());
|
||||
}
|
||||
|
||||
public function getSouthWest(): Coordinate
|
||||
{
|
||||
return new Coordinate($this->getSouth(), $this->getWest());
|
||||
}
|
||||
|
||||
public function getNorth(): float
|
||||
{
|
||||
return $this->northWest->getLat();
|
||||
}
|
||||
|
||||
public function getSouth(): float
|
||||
{
|
||||
return $this->southEast->getLat();
|
||||
}
|
||||
|
||||
public function getWest(): float
|
||||
{
|
||||
return $this->northWest->getLng();
|
||||
}
|
||||
|
||||
public function getEast(): float
|
||||
{
|
||||
return $this->southEast->getLng();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the center of this bounds object and returns it as a
|
||||
* Coordinate instance.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function getCenter(): Coordinate
|
||||
{
|
||||
$centerLat = ($this->getNorth() + $this->getSouth()) / 2;
|
||||
|
||||
return new Coordinate($centerLat, $this->getCenterLng());
|
||||
}
|
||||
|
||||
protected function getCenterLng(): float
|
||||
{
|
||||
$centerLng = ($this->getEast() + $this->getWest()) / 2;
|
||||
|
||||
$overlap = $this->getWest() > 0 && $this->getEast() < 0;
|
||||
|
||||
if ($overlap && $centerLng > 0) {
|
||||
return -180.0 + $centerLng;
|
||||
}
|
||||
|
||||
if ($overlap && $centerLng < 0) {
|
||||
return 180.0 + $centerLng;
|
||||
}
|
||||
|
||||
if ($overlap && $centerLng == 0) {
|
||||
return 180.0;
|
||||
}
|
||||
|
||||
return $centerLng;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the polygon described by this bounds object and returns the
|
||||
* Polygon instance.
|
||||
*/
|
||||
public function getAsPolygon(): Polygon
|
||||
{
|
||||
$polygon = new Polygon();
|
||||
|
||||
$polygon->addPoint($this->getNorthWest());
|
||||
$polygon->addPoint($this->getNorthEast());
|
||||
$polygon->addPoint($this->getSouthEast());
|
||||
$polygon->addPoint($this->getSouthWest());
|
||||
|
||||
return $polygon;
|
||||
}
|
||||
}
|
||||
133
niucloud/vendor/mjaschen/phpgeo/src/CardinalDirection/CardinalDirection.php
vendored
Normal file
133
niucloud/vendor/mjaschen/phpgeo/src/CardinalDirection/CardinalDirection.php
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\CardinalDirection;
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Direction\Direction;
|
||||
|
||||
class CardinalDirection
|
||||
{
|
||||
public const CARDINAL_DIRECTION_NONE = 'none';
|
||||
public const CARDINAL_DIRECTION_NORTH = 'north';
|
||||
public const CARDINAL_DIRECTION_EAST = 'east';
|
||||
public const CARDINAL_DIRECTION_SOUTH = 'south';
|
||||
public const CARDINAL_DIRECTION_WEST = 'west';
|
||||
public const CARDINAL_DIRECTION_NORTHEAST = 'north-east';
|
||||
public const CARDINAL_DIRECTION_NORTHWEST = 'north-west';
|
||||
public const CARDINAL_DIRECTION_SOUTHEAST = 'south-east';
|
||||
public const CARDINAL_DIRECTION_SOUTHWEST = 'south-west';
|
||||
|
||||
/**
|
||||
* @var Direction
|
||||
*/
|
||||
private $direction;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->direction = new Direction();
|
||||
}
|
||||
|
||||
public function getCardinalDirection(Coordinate $point1, Coordinate $point2): string
|
||||
{
|
||||
$directionFunctionMapping = [
|
||||
self::CARDINAL_DIRECTION_NORTH => function (Coordinate $point1, Coordinate $point2): bool {
|
||||
return $this->isStrictlyNorth($point1, $point2);
|
||||
},
|
||||
self::CARDINAL_DIRECTION_EAST => function (Coordinate $point1, Coordinate $point2): bool {
|
||||
return $this->isStrictlyEast($point1, $point2);
|
||||
},
|
||||
self::CARDINAL_DIRECTION_SOUTH => function (Coordinate $point1, Coordinate $point2): bool {
|
||||
return $this->isStrictlySouth($point1, $point2);
|
||||
},
|
||||
self::CARDINAL_DIRECTION_WEST => function (Coordinate $point1, Coordinate $point2): bool {
|
||||
return $this->isStrictlyWest($point1, $point2);
|
||||
},
|
||||
self::CARDINAL_DIRECTION_NORTHEAST => function (Coordinate $point1, Coordinate $point2): bool {
|
||||
return $this->isNorthEast($point1, $point2);
|
||||
},
|
||||
self::CARDINAL_DIRECTION_SOUTHEAST => function (Coordinate $point1, Coordinate $point2): bool {
|
||||
return $this->isSouthEast($point1, $point2);
|
||||
},
|
||||
self::CARDINAL_DIRECTION_SOUTHWEST => function (Coordinate $point1, Coordinate $point2): bool {
|
||||
return $this->isSouthWest($point1, $point2);
|
||||
},
|
||||
self::CARDINAL_DIRECTION_NORTHWEST => function (Coordinate $point1, Coordinate $point2): bool {
|
||||
return $this->isNorthWest($point1, $point2);
|
||||
},
|
||||
];
|
||||
|
||||
foreach ($directionFunctionMapping as $direction => $checkFunction) {
|
||||
if ($checkFunction($point1, $point2)) {
|
||||
return $direction;
|
||||
}
|
||||
}
|
||||
|
||||
return self::CARDINAL_DIRECTION_NONE;
|
||||
}
|
||||
|
||||
private function isStrictlyNorth(Coordinate $point1, Coordinate $point2): bool
|
||||
{
|
||||
return !$this->direction->pointIsEastOf($point1, $point2)
|
||||
&& !$this->direction->pointIsSouthOf($point1, $point2)
|
||||
&& !$this->direction->pointIsWestOf($point1, $point2)
|
||||
&& $this->direction->pointIsNorthOf($point1, $point2);
|
||||
}
|
||||
|
||||
private function isStrictlyEast(Coordinate $point1, Coordinate $point2): bool
|
||||
{
|
||||
return $this->direction->pointIsEastOf($point1, $point2)
|
||||
&& !$this->direction->pointIsSouthOf($point1, $point2)
|
||||
&& !$this->direction->pointIsWestOf($point1, $point2)
|
||||
&& !$this->direction->pointIsNorthOf($point1, $point2);
|
||||
}
|
||||
|
||||
private function isStrictlySouth(Coordinate $point1, Coordinate $point2): bool
|
||||
{
|
||||
return !$this->direction->pointIsEastOf($point1, $point2)
|
||||
&& $this->direction->pointIsSouthOf($point1, $point2)
|
||||
&& !$this->direction->pointIsWestOf($point1, $point2)
|
||||
&& !$this->direction->pointIsNorthOf($point1, $point2);
|
||||
}
|
||||
|
||||
private function isStrictlyWest(Coordinate $point1, Coordinate $point2): bool
|
||||
{
|
||||
return !$this->direction->pointIsEastOf($point1, $point2)
|
||||
&& !$this->direction->pointIsSouthOf($point1, $point2)
|
||||
&& $this->direction->pointIsWestOf($point1, $point2)
|
||||
&& !$this->direction->pointIsNorthOf($point1, $point2);
|
||||
}
|
||||
|
||||
private function isNorthEast(Coordinate $point1, Coordinate $point2): bool
|
||||
{
|
||||
return $this->direction->pointIsEastOf($point1, $point2)
|
||||
&& !$this->direction->pointIsSouthOf($point1, $point2)
|
||||
&& !$this->direction->pointIsWestOf($point1, $point2)
|
||||
&& $this->direction->pointIsNorthOf($point1, $point2);
|
||||
}
|
||||
|
||||
private function isSouthEast(Coordinate $point1, Coordinate $point2): bool
|
||||
{
|
||||
return $this->direction->pointIsEastOf($point1, $point2)
|
||||
&& $this->direction->pointIsSouthOf($point1, $point2)
|
||||
&& !$this->direction->pointIsWestOf($point1, $point2)
|
||||
&& !$this->direction->pointIsNorthOf($point1, $point2);
|
||||
}
|
||||
|
||||
private function isSouthWest(Coordinate $point1, Coordinate $point2): bool
|
||||
{
|
||||
return !$this->direction->pointIsEastOf($point1, $point2)
|
||||
&& $this->direction->pointIsSouthOf($point1, $point2)
|
||||
&& $this->direction->pointIsWestOf($point1, $point2)
|
||||
&& !$this->direction->pointIsNorthOf($point1, $point2);
|
||||
}
|
||||
|
||||
private function isNorthWest(Coordinate $point1, Coordinate $point2): bool
|
||||
{
|
||||
return !$this->direction->pointIsEastOf($point1, $point2)
|
||||
&& !$this->direction->pointIsSouthOf($point1, $point2)
|
||||
&& $this->direction->pointIsWestOf($point1, $point2)
|
||||
&& $this->direction->pointIsNorthOf($point1, $point2);
|
||||
}
|
||||
}
|
||||
133
niucloud/vendor/mjaschen/phpgeo/src/CardinalDirection/CardinalDirectionDistances.php
vendored
Normal file
133
niucloud/vendor/mjaschen/phpgeo/src/CardinalDirection/CardinalDirectionDistances.php
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\CardinalDirection;
|
||||
|
||||
use Location\Exception\InvalidDistanceException;
|
||||
|
||||
/** @psalm-immutable */
|
||||
class CardinalDirectionDistances
|
||||
{
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $north;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $east;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $south;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
private $west;
|
||||
|
||||
private function __construct(float $north, float $east, float $south, float $west)
|
||||
{
|
||||
$this->north = $north;
|
||||
$this->east = $east;
|
||||
$this->south = $south;
|
||||
$this->west = $west;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-pure
|
||||
* @psalm-mutation-free
|
||||
*/
|
||||
public static function create(): self
|
||||
{
|
||||
return new self(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-mutation-free
|
||||
*/
|
||||
public function setNorth(float $north): self
|
||||
{
|
||||
$this->assertPositiveFloat($north);
|
||||
|
||||
return new self($north, $this->east, $this->south, $this->west);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-mutation-free
|
||||
*/
|
||||
public function setEast(float $east): self
|
||||
{
|
||||
$this->assertPositiveFloat($east);
|
||||
|
||||
return new self($this->north, $east, $this->south, $this->west);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-mutation-free
|
||||
*/
|
||||
public function setSouth(float $south): self
|
||||
{
|
||||
$this->assertPositiveFloat($south);
|
||||
|
||||
return new self($this->north, $this->east, $south, $this->west);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-mutation-free
|
||||
*/
|
||||
public function setWest(float $west): self
|
||||
{
|
||||
$this->assertPositiveFloat($west);
|
||||
|
||||
return new self($this->north, $this->east, $this->south, $west);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-mutation-free
|
||||
*/
|
||||
public function getNorth(): float
|
||||
{
|
||||
return $this->north;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-mutation-free
|
||||
*/
|
||||
public function getEast(): float
|
||||
{
|
||||
return $this->east;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-mutation-free
|
||||
*/
|
||||
public function getSouth(): float
|
||||
{
|
||||
return $this->south;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-mutation-free
|
||||
*/
|
||||
public function getWest(): float
|
||||
{
|
||||
return $this->west;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-pure
|
||||
* @psalm-mutation-free
|
||||
*
|
||||
* @throws InvalidDistanceException
|
||||
*/
|
||||
private function assertPositiveFloat(float $value): void
|
||||
{
|
||||
if ($value < 0) {
|
||||
throw new InvalidDistanceException('Negative distance is invalid.', 1857757416);
|
||||
}
|
||||
}
|
||||
}
|
||||
78
niucloud/vendor/mjaschen/phpgeo/src/CardinalDirection/CardinalDirectionDistancesCalculator.php
vendored
Normal file
78
niucloud/vendor/mjaschen/phpgeo/src/CardinalDirection/CardinalDirectionDistancesCalculator.php
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\CardinalDirection;
|
||||
|
||||
use Location\Bounds;
|
||||
use Location\Coordinate;
|
||||
use Location\Distance\DistanceInterface;
|
||||
|
||||
class CardinalDirectionDistancesCalculator
|
||||
{
|
||||
public function getCardinalDirectionDistances(
|
||||
Coordinate $point1,
|
||||
Coordinate $point2,
|
||||
DistanceInterface $distanceCalculator
|
||||
): CardinalDirectionDistances {
|
||||
$cardinalDirection = (new CardinalDirection())->getCardinalDirection($point1, $point2);
|
||||
$directDistance = $point1->getDistance($point2, $distanceCalculator);
|
||||
|
||||
switch ($cardinalDirection) {
|
||||
case CardinalDirection::CARDINAL_DIRECTION_NONE:
|
||||
return CardinalDirectionDistances::create();
|
||||
|
||||
case CardinalDirection::CARDINAL_DIRECTION_NORTH:
|
||||
return CardinalDirectionDistances::create()->setSouth($directDistance);
|
||||
|
||||
case CardinalDirection::CARDINAL_DIRECTION_EAST:
|
||||
return CardinalDirectionDistances::create()->setWest($directDistance);
|
||||
|
||||
case CardinalDirection::CARDINAL_DIRECTION_SOUTH:
|
||||
return CardinalDirectionDistances::create()->setNorth($directDistance);
|
||||
|
||||
case CardinalDirection::CARDINAL_DIRECTION_WEST:
|
||||
return CardinalDirectionDistances::create()->setEast($directDistance);
|
||||
|
||||
case CardinalDirection::CARDINAL_DIRECTION_NORTHWEST:
|
||||
$bounds = new Bounds($point1, $point2);
|
||||
$point3 = new Coordinate($bounds->getNorth(), $bounds->getEast());
|
||||
|
||||
return CardinalDirectionDistances::create()
|
||||
->setEast($point1->getDistance($point3, $distanceCalculator))
|
||||
->setSouth($point3->getDistance($point2, $distanceCalculator));
|
||||
|
||||
case CardinalDirection::CARDINAL_DIRECTION_SOUTHWEST:
|
||||
$bounds = new Bounds(
|
||||
new Coordinate($point2->getLat(), $point1->getLng()),
|
||||
new Coordinate($point1->getLat(), $point2->getLng())
|
||||
);
|
||||
$point3 = new Coordinate($bounds->getSouth(), $bounds->getEast());
|
||||
|
||||
return CardinalDirectionDistances::create()
|
||||
->setNorth($point3->getDistance($point2, $distanceCalculator))
|
||||
->setEast($point1->getDistance($point3, $distanceCalculator));
|
||||
|
||||
case CardinalDirection::CARDINAL_DIRECTION_NORTHEAST:
|
||||
$bounds = new Bounds(
|
||||
new Coordinate($point1->getLat(), $point2->getLng()),
|
||||
new Coordinate($point2->getLat(), $point1->getLng())
|
||||
);
|
||||
$point3 = new Coordinate($bounds->getNorth(), $bounds->getWest());
|
||||
|
||||
return CardinalDirectionDistances::create()
|
||||
->setSouth($point3->getDistance($point2, $distanceCalculator))
|
||||
->setWest($point1->getDistance($point3, $distanceCalculator));
|
||||
|
||||
case CardinalDirection::CARDINAL_DIRECTION_SOUTHEAST:
|
||||
$bounds = new Bounds($point2, $point1);
|
||||
$point3 = new Coordinate($bounds->getSouth(), $bounds->getWest());
|
||||
|
||||
return CardinalDirectionDistances::create()
|
||||
->setNorth($point3->getDistance($point2, $distanceCalculator))
|
||||
->setWest($point1->getDistance($point3, $distanceCalculator));
|
||||
}
|
||||
|
||||
return CardinalDirectionDistances::create();
|
||||
}
|
||||
}
|
||||
176
niucloud/vendor/mjaschen/phpgeo/src/Coordinate.php
vendored
Normal file
176
niucloud/vendor/mjaschen/phpgeo/src/Coordinate.php
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Location\CardinalDirection\CardinalDirectionDistances;
|
||||
use Location\CardinalDirection\CardinalDirectionDistancesCalculator;
|
||||
use Location\Distance\DistanceInterface;
|
||||
use Location\Distance\Haversine;
|
||||
use Location\Exception\InvalidGeometryException;
|
||||
use Location\Formatter\Coordinate\FormatterInterface;
|
||||
|
||||
/**
|
||||
* Coordinate Implementation
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class Coordinate implements GeometryInterface
|
||||
{
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $lat;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $lng;
|
||||
|
||||
/**
|
||||
* @var Ellipsoid
|
||||
*/
|
||||
protected $ellipsoid;
|
||||
|
||||
/**
|
||||
* @param float $lat -90.0 .. +90.0
|
||||
* @param float $lng -180.0 .. +180.0
|
||||
* @param ?Ellipsoid $ellipsoid if omitted, WGS-84 is used
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(float $lat, float $lng, ?Ellipsoid $ellipsoid = null)
|
||||
{
|
||||
if (! $this->isValidLatitude($lat)) {
|
||||
throw new InvalidArgumentException('Latitude value must be numeric -90.0 .. +90.0 (given: ' . $lat . ')');
|
||||
}
|
||||
|
||||
if (! $this->isValidLongitude($lng)) {
|
||||
throw new InvalidArgumentException(
|
||||
'Longitude value must be numeric -180.0 .. +180.0 (given: ' . $lng . ')'
|
||||
);
|
||||
}
|
||||
|
||||
$this->lat = $lat;
|
||||
$this->lng = $lng;
|
||||
|
||||
if ($ellipsoid instanceof Ellipsoid) {
|
||||
$this->ellipsoid = $ellipsoid;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->ellipsoid = Ellipsoid::createDefault();
|
||||
}
|
||||
|
||||
public function getLat(): float
|
||||
{
|
||||
return $this->lat;
|
||||
}
|
||||
|
||||
public function getLng(): float
|
||||
{
|
||||
return $this->lng;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<Coordinate>
|
||||
*/
|
||||
public function getPoints(): array
|
||||
{
|
||||
return [$this];
|
||||
}
|
||||
|
||||
public function getEllipsoid(): Ellipsoid
|
||||
{
|
||||
return $this->ellipsoid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the distance between the given coordinate
|
||||
* and this coordinate.
|
||||
*/
|
||||
public function getDistance(Coordinate $coordinate, DistanceInterface $calculator): float
|
||||
{
|
||||
return $calculator->getDistance($this, $coordinate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the cardinal direction distances from this coordinate
|
||||
* to given coordinate.
|
||||
*/
|
||||
public function getCardinalDirectionDistances(
|
||||
Coordinate $coordinate,
|
||||
DistanceInterface $calculator
|
||||
): CardinalDirectionDistances {
|
||||
return (new CardinalDirectionDistancesCalculator())
|
||||
->getCardinalDirectionDistances($this, $coordinate, $calculator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if two points describe the same location within an allowed distance.
|
||||
*
|
||||
* Uses the Haversine distance calculator for distance calculation as it's
|
||||
* precise enough for short-distance calculations.
|
||||
*
|
||||
* @see Haversine
|
||||
*/
|
||||
public function hasSameLocation(Coordinate $coordinate, float $allowedDistance = .001): bool
|
||||
{
|
||||
return $this->getDistance($coordinate, new Haversine()) <= $allowedDistance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this point intersects a given geometry.
|
||||
*
|
||||
* @throws InvalidGeometryException
|
||||
*/
|
||||
public function intersects(GeometryInterface $geometry): bool
|
||||
{
|
||||
if ($geometry instanceof self) {
|
||||
return $this->hasSameLocation($geometry);
|
||||
}
|
||||
|
||||
if ($geometry instanceof Polygon) {
|
||||
return $geometry->contains($this);
|
||||
}
|
||||
|
||||
throw new InvalidGeometryException('Only polygons can contain other geometries', 1655191821);
|
||||
}
|
||||
|
||||
public function format(FormatterInterface $formatter): string
|
||||
{
|
||||
return $formatter->format($this);
|
||||
}
|
||||
|
||||
protected function isValidLatitude(float $latitude): bool
|
||||
{
|
||||
return $this->isNumericInBounds($latitude, -90.0, 90.0);
|
||||
}
|
||||
|
||||
protected function isValidLongitude(float $longitude): bool
|
||||
{
|
||||
return $this->isNumericInBounds($longitude, -180.0, 180.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given value is (1) numeric, and (2) between lower
|
||||
* and upper bounds (including the bounds values).
|
||||
*/
|
||||
protected function isNumericInBounds(float $value, float $lower, float $upper): bool
|
||||
{
|
||||
return !($value < $lower || $value > $upper);
|
||||
}
|
||||
|
||||
public function getBounds(): Bounds
|
||||
{
|
||||
return new Bounds($this, $this);
|
||||
}
|
||||
|
||||
public function getSegments(): array
|
||||
{
|
||||
throw new \RuntimeException('A single point instance does not contain valid segments', 6029644914);
|
||||
}
|
||||
}
|
||||
30
niucloud/vendor/mjaschen/phpgeo/src/Direction/Direction.php
vendored
Normal file
30
niucloud/vendor/mjaschen/phpgeo/src/Direction/Direction.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Direction;
|
||||
|
||||
use Location\Coordinate;
|
||||
|
||||
class Direction
|
||||
{
|
||||
public function pointIsNorthOf(Coordinate $point, Coordinate $compareAgainst): bool
|
||||
{
|
||||
return $point->getLat() > $compareAgainst->getLat();
|
||||
}
|
||||
|
||||
public function pointIsSouthOf(Coordinate $point, Coordinate $compareAgainst): bool
|
||||
{
|
||||
return $point->getLat() < $compareAgainst->getLat();
|
||||
}
|
||||
|
||||
public function pointIsEastOf(Coordinate $point, Coordinate $compareAgainst): bool
|
||||
{
|
||||
return $point->getLng() > $compareAgainst->getLng();
|
||||
}
|
||||
|
||||
public function pointIsWestOf(Coordinate $point, Coordinate $compareAgainst): bool
|
||||
{
|
||||
return $point->getLng() < $compareAgainst->getLng();
|
||||
}
|
||||
}
|
||||
23
niucloud/vendor/mjaschen/phpgeo/src/Distance/DistanceInterface.php
vendored
Normal file
23
niucloud/vendor/mjaschen/phpgeo/src/Distance/DistanceInterface.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Distance;
|
||||
|
||||
use Location\Coordinate;
|
||||
|
||||
/**
|
||||
* Interface for Distance Calculator Classes
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
interface DistanceInterface
|
||||
{
|
||||
/**
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @return float distance between the two coordinates in meters
|
||||
*/
|
||||
public function getDistance(Coordinate $point1, Coordinate $point2): float;
|
||||
}
|
||||
53
niucloud/vendor/mjaschen/phpgeo/src/Distance/Haversine.php
vendored
Normal file
53
niucloud/vendor/mjaschen/phpgeo/src/Distance/Haversine.php
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Distance;
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Exception\NotConvergingException;
|
||||
use Location\Exception\NotMatchingEllipsoidException;
|
||||
|
||||
/**
|
||||
* Implementation of distance calculation with http://en.wikipedia.org/wiki/Law_of_haversines
|
||||
*
|
||||
* @see http://en.wikipedia.org/wiki/Law_of_haversines
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class Haversine implements DistanceInterface
|
||||
{
|
||||
/**
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @throws NotMatchingEllipsoidException
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getDistance(Coordinate $point1, Coordinate $point2): float
|
||||
{
|
||||
if ($point1->getEllipsoid()->getName() !== $point2->getEllipsoid()->getName()) {
|
||||
throw new NotMatchingEllipsoidException('The ellipsoids for both coordinates must match');
|
||||
}
|
||||
|
||||
$lat1 = deg2rad($point1->getLat());
|
||||
$lat2 = deg2rad($point2->getLat());
|
||||
$lng1 = deg2rad($point1->getLng());
|
||||
$lng2 = deg2rad($point2->getLng());
|
||||
|
||||
$dLat = $lat2 - $lat1;
|
||||
$dLng = $lng2 - $lng1;
|
||||
|
||||
$radius = $point1->getEllipsoid()->getArithmeticMeanRadius();
|
||||
|
||||
$distance = 2 * $radius * asin(
|
||||
sqrt(
|
||||
(sin($dLat / 2) ** 2)
|
||||
+ cos($lat1) * cos($lat2) * (sin($dLng / 2) ** 2)
|
||||
)
|
||||
);
|
||||
|
||||
return round($distance, 3);
|
||||
}
|
||||
}
|
||||
111
niucloud/vendor/mjaschen/phpgeo/src/Distance/Vincenty.php
vendored
Normal file
111
niucloud/vendor/mjaschen/phpgeo/src/Distance/Vincenty.php
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Distance;
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Exception\NotConvergingException;
|
||||
use Location\Exception\NotMatchingEllipsoidException;
|
||||
|
||||
/**
|
||||
* Implementation of distance calculation with Vincenty Method
|
||||
*
|
||||
* @see http://www.movable-type.co.uk/scripts/latlong-vincenty.html
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class Vincenty implements DistanceInterface
|
||||
{
|
||||
/**
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @throws NotMatchingEllipsoidException
|
||||
* @throws NotConvergingException
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getDistance(Coordinate $point1, Coordinate $point2): float
|
||||
{
|
||||
if ($point1->getEllipsoid()->getName() !== $point2->getEllipsoid()->getName()) {
|
||||
throw new NotMatchingEllipsoidException('The ellipsoids for both coordinates must match');
|
||||
}
|
||||
|
||||
$lat1 = deg2rad($point1->getLat());
|
||||
$lat2 = deg2rad($point2->getLat());
|
||||
$lng1 = deg2rad($point1->getLng());
|
||||
$lng2 = deg2rad($point2->getLng());
|
||||
|
||||
$a = $point1->getEllipsoid()->getA();
|
||||
$b = $point1->getEllipsoid()->getB();
|
||||
$f = 1 / $point1->getEllipsoid()->getF();
|
||||
|
||||
$L = $lng2 - $lng1;
|
||||
$U1 = atan((1 - $f) * tan($lat1));
|
||||
$U2 = atan((1 - $f) * tan($lat2));
|
||||
|
||||
$iterationsLeft = 100;
|
||||
$lambda = $L;
|
||||
|
||||
$sinU1 = sin($U1);
|
||||
$sinU2 = sin($U2);
|
||||
$cosU1 = cos($U1);
|
||||
$cosU2 = cos($U2);
|
||||
|
||||
do {
|
||||
$sinLambda = sin($lambda);
|
||||
$cosLambda = cos($lambda);
|
||||
|
||||
$sinSigma = sqrt(
|
||||
$cosU2 * $sinLambda * $cosU2 * $sinLambda +
|
||||
($cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosLambda) * ($cosU1 * $sinU2 - $sinU1 * $cosU2 * $cosLambda)
|
||||
);
|
||||
|
||||
if (abs($sinSigma) < 1E-12) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
$cosSigma = $sinU1 * $sinU2 + $cosU1 * $cosU2 * $cosLambda;
|
||||
|
||||
$sigma = atan2($sinSigma, $cosSigma);
|
||||
|
||||
$sinAlpha = $cosU1 * $cosU2 * $sinLambda / $sinSigma;
|
||||
|
||||
$cosSqAlpha = 1 - $sinAlpha * $sinAlpha;
|
||||
|
||||
$cos2SigmaM = 0;
|
||||
if (abs($cosSqAlpha) > 1E-12) {
|
||||
$cos2SigmaM = $cosSigma - 2 * $sinU1 * $sinU2 / $cosSqAlpha;
|
||||
}
|
||||
|
||||
$C = $f / 16 * $cosSqAlpha * (4 + $f * (4 - 3 * $cosSqAlpha));
|
||||
|
||||
$lambdaP = $lambda;
|
||||
|
||||
$lambda = $L
|
||||
+ (1 - $C)
|
||||
* $f
|
||||
* $sinAlpha
|
||||
* ($sigma + $C * $sinSigma * ($cos2SigmaM + $C * $cosSigma * (- 1 + 2 * $cos2SigmaM * $cos2SigmaM)));
|
||||
|
||||
$iterationsLeft--;
|
||||
} while (abs($lambda - $lambdaP) > 1e-12 && $iterationsLeft > 0);
|
||||
|
||||
if ($iterationsLeft === 0) {
|
||||
throw new NotConvergingException('Vincenty calculation does not converge');
|
||||
}
|
||||
|
||||
$uSq = $cosSqAlpha * ($a * $a - $b * $b) / ($b * $b);
|
||||
$A = 1 + $uSq / 16384 * (4096 + $uSq * (- 768 + $uSq * (320 - 175 * $uSq)));
|
||||
$B = $uSq / 1024 * (256 + $uSq * (- 128 + $uSq * (74 - 47 * $uSq)));
|
||||
$deltaSigma = $B * $sinSigma * (
|
||||
$cos2SigmaM
|
||||
+ $B / 4 * ($cosSigma * (- 1 + 2 * $cos2SigmaM * $cos2SigmaM)
|
||||
- $B / 6 * $cos2SigmaM * (- 3 + 4 * $sinSigma * $sinSigma) * (- 3 + 4 * $cos2SigmaM * $cos2SigmaM))
|
||||
);
|
||||
$s = $b * $A * ($sigma - $deltaSigma);
|
||||
|
||||
return round($s, 3);
|
||||
}
|
||||
}
|
||||
128
niucloud/vendor/mjaschen/phpgeo/src/Ellipsoid.php
vendored
Normal file
128
niucloud/vendor/mjaschen/phpgeo/src/Ellipsoid.php
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location;
|
||||
|
||||
/**
|
||||
* Ellipsoid
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class Ellipsoid
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* The semi-major axis
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
protected $a;
|
||||
|
||||
/**
|
||||
* The Inverse Flattening (1/f)
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
protected $f;
|
||||
|
||||
/**
|
||||
* Some often used ellipsoids
|
||||
*
|
||||
* @var array<string, array{name: string, a: float, f: float}>
|
||||
*/
|
||||
protected static $configs = [
|
||||
'WGS-84' => [
|
||||
'name' => 'World Geodetic System 1984',
|
||||
'a' => 6378137.0,
|
||||
'f' => 298.257223563,
|
||||
],
|
||||
'GRS-80' => [
|
||||
'name' => 'Geodetic Reference System 1980',
|
||||
'a' => 6378137.0,
|
||||
'f' => 298.257222100,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param float $a
|
||||
* @param float $f
|
||||
*/
|
||||
public function __construct(string $name, float $a, float $f)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->a = $a;
|
||||
$this->f = $f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return Ellipsoid
|
||||
*/
|
||||
public static function createDefault(string $name = 'WGS-84'): Ellipsoid
|
||||
{
|
||||
return static::createFromArray(static::$configs[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
*
|
||||
* @return Ellipsoid
|
||||
*/
|
||||
public static function createFromArray(array $config): Ellipsoid
|
||||
{
|
||||
return new self($config['name'], $config['a'], $config['f']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getA(): float
|
||||
{
|
||||
return $this->a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculation of the semi-minor axis
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getB(): float
|
||||
{
|
||||
return $this->a * (1 - 1 / $this->f);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getF(): float
|
||||
{
|
||||
return $this->f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the arithmetic mean radius
|
||||
*
|
||||
* @see http://home.online.no/~sigurdhu/WGS84_Eng.html
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getArithmeticMeanRadius(): float
|
||||
{
|
||||
return $this->a * (1 - 1 / $this->f / 3);
|
||||
}
|
||||
}
|
||||
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/BearingNotAvailableException.php
vendored
Normal file
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/BearingNotAvailableException.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Exception;
|
||||
|
||||
class BearingNotAvailableException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/InvalidDistanceException.php
vendored
Normal file
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/InvalidDistanceException.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Exception;
|
||||
|
||||
class InvalidDistanceException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/InvalidGeometryException.php
vendored
Normal file
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/InvalidGeometryException.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Exception;
|
||||
|
||||
class InvalidGeometryException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/InvalidPolygonException.php
vendored
Normal file
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/InvalidPolygonException.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Exception;
|
||||
|
||||
class InvalidPolygonException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/NotConvergingException.php
vendored
Normal file
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/NotConvergingException.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Exception;
|
||||
|
||||
class NotConvergingException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/NotMatchingEllipsoidException.php
vendored
Normal file
9
niucloud/vendor/mjaschen/phpgeo/src/Exception/NotMatchingEllipsoidException.php
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Exception;
|
||||
|
||||
class NotMatchingEllipsoidException extends \InvalidArgumentException
|
||||
{
|
||||
}
|
||||
36
niucloud/vendor/mjaschen/phpgeo/src/Factory/BoundsFactory.php
vendored
Normal file
36
niucloud/vendor/mjaschen/phpgeo/src/Factory/BoundsFactory.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Factory;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Location\Bearing\BearingInterface;
|
||||
use Location\Bounds;
|
||||
use Location\Coordinate;
|
||||
|
||||
/**
|
||||
* Bounds Factory
|
||||
*/
|
||||
class BoundsFactory
|
||||
{
|
||||
/**
|
||||
* Creates a Bounds instance which corners have the given distance from its center.
|
||||
*
|
||||
* @param Coordinate $center
|
||||
* @param float $distance in meters
|
||||
* @param BearingInterface $bearing
|
||||
* @return Bounds
|
||||
* @throws InvalidArgumentException if bounds crosses the 180/-180 degrees meridian.
|
||||
*/
|
||||
public static function expandFromCenterCoordinate(
|
||||
Coordinate $center,
|
||||
float $distance,
|
||||
BearingInterface $bearing
|
||||
): Bounds {
|
||||
$northWest = $bearing->calculateDestination($center, 315, $distance);
|
||||
$southEast = $bearing->calculateDestination($center, 135, $distance);
|
||||
|
||||
return new Bounds($northWest, $southEast);
|
||||
}
|
||||
}
|
||||
163
niucloud/vendor/mjaschen/phpgeo/src/Factory/CoordinateFactory.php
vendored
Normal file
163
niucloud/vendor/mjaschen/phpgeo/src/Factory/CoordinateFactory.php
vendored
Normal file
@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Factory;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Location\Coordinate;
|
||||
use Location\Ellipsoid;
|
||||
|
||||
/**
|
||||
* Coordinate Factory
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class CoordinateFactory implements GeometryFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Creates a Coordinate instance from the given string.
|
||||
*
|
||||
* The string is parsed by a regular expression for a known
|
||||
* format of geographical coordinates.
|
||||
*
|
||||
* @param string $string formatted geographical coordinate
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function fromString(string $string, ?Ellipsoid $ellipsoid = null): Coordinate
|
||||
{
|
||||
$string = self::mergeSecondsToMinutes($string);
|
||||
|
||||
$result = self::parseDecimalMinutesWithoutCardinalLetters($string, $ellipsoid);
|
||||
|
||||
if ($result instanceof Coordinate) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = self::parseDecimalMinutesWithCardinalLetters($string, $ellipsoid);
|
||||
|
||||
if ($result instanceof Coordinate) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = self::parseDecimalDegreesWithoutCardinalLetters($string, $ellipsoid);
|
||||
|
||||
if ($result instanceof Coordinate) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result = self::parseDecimalDegreesWithCardinalLetters($string, $ellipsoid);
|
||||
|
||||
if ($result instanceof Coordinate) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('Format of coordinates was not recognized');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Coordinate|null
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private static function parseDecimalMinutesWithoutCardinalLetters(string $string, ?Ellipsoid $ellipsoid = null)
|
||||
{
|
||||
// Decimal minutes without cardinal letters, e. g. "52 12.345, 13 23.456",
|
||||
// "52° 12.345, 13° 23.456", "52° 12.345′, 13° 23.456′", "52 12.345 N, 13 23.456 E",
|
||||
// "N52° 12.345′ E13° 23.456′"
|
||||
$regexp = '/(-?\d{1,2})°?\s+(\d{1,2}\.?\d*)[\'′]?[, ]\s*(-?\d{1,3})°?\s+(\d{1,2}\.?\d*)[\'′]?/u';
|
||||
|
||||
if (preg_match($regexp, $string, $match) === 1) {
|
||||
$latitude = (int)$match[1] >= 0
|
||||
? (int)$match[1] + (float)$match[2] / 60
|
||||
: (int)$match[1] - (float)$match[2] / 60;
|
||||
$longitude = (int)$match[3] >= 0
|
||||
? (int)$match[3] + (float)$match[4] / 60
|
||||
: (int)$match[3] - (float)$match[4] / 60;
|
||||
|
||||
return new Coordinate($latitude, $longitude, $ellipsoid);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?Coordinate
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private static function parseDecimalMinutesWithCardinalLetters(string $string, ?Ellipsoid $ellipsoid = null)
|
||||
{
|
||||
// Decimal minutes with cardinal letters, e. g. "52 12.345, 13 23.456",
|
||||
// "52° 12.345, 13° 23.456", "52° 12.345′, 13° 23.456′", "52 12.345 N, 13 23.456 E",
|
||||
// "N52° 12.345′ E13° 23.456′"
|
||||
$regexp = '/([NS]?\s*)(\d{1,2})°?\s+(\d{1,2}\.?\d*)[\'′]?(\s*[NS]?)';
|
||||
$regexp .= '[, ]\s*([EW]?\s*)(\d{1,3})°?\s+(\d{1,2}\.?\d*)[\'′]?(\s*[EW]?)/ui';
|
||||
|
||||
if (preg_match($regexp, $string, $match) === 1) {
|
||||
$latitude = (int)$match[2] + (float)$match[3] / 60;
|
||||
if (strtoupper(trim($match[1])) === 'S' || strtoupper(trim($match[4])) === 'S') {
|
||||
$latitude = - $latitude;
|
||||
}
|
||||
$longitude = (int)$match[6] + (float)$match[7] / 60;
|
||||
if (strtoupper(trim($match[5])) === 'W' || strtoupper(trim($match[8])) === 'W') {
|
||||
$longitude = - $longitude;
|
||||
}
|
||||
|
||||
return new Coordinate($latitude, $longitude, $ellipsoid);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Coordinate|null
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private static function parseDecimalDegreesWithoutCardinalLetters(string $string, ?Ellipsoid $ellipsoid = null)
|
||||
{
|
||||
// The most simple format: decimal degrees without cardinal letters,
|
||||
// e. g. "52.5, 13.5" or "53.25732 14.24984"
|
||||
if (preg_match('/(-?\d{1,2}\.?\d*)°?[, ]\s*(-?\d{1,3}\.?\d*)°?/u', $string, $match) === 1) {
|
||||
return new Coordinate((float)$match[1], (float)$match[2], $ellipsoid);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Coordinate|null
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private static function parseDecimalDegreesWithCardinalLetters(string $string, ?Ellipsoid $ellipsoid = null)
|
||||
{
|
||||
// Decimal degrees with cardinal letters, e. g. "N52.5, E13.5",
|
||||
// "40.2S, 135.3485W", or "56.234°N, 157.245°W"
|
||||
$regexp = '/([NS]?\s*)(\d{1,2}\.?\d*)°?(\s*[NS]?)[, ]\s*([EW]?\s*)(\d{1,3}\.?\d*)°?(\s*[EW]?)/ui';
|
||||
|
||||
if (preg_match($regexp, $string, $match) === 1) {
|
||||
$latitude = $match[2];
|
||||
if (strtoupper(trim($match[1])) === 'S' || strtoupper(trim($match[3])) === 'S') {
|
||||
$latitude = - $latitude;
|
||||
}
|
||||
$longitude = $match[5];
|
||||
if (strtoupper(trim($match[4])) === 'W' || strtoupper(trim($match[6])) === 'W') {
|
||||
$longitude = - $longitude;
|
||||
}
|
||||
|
||||
return new Coordinate((float)$latitude, (float)$longitude, $ellipsoid);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function mergeSecondsToMinutes(string $string): string
|
||||
{
|
||||
return preg_replace_callback(
|
||||
'/(\d+)(°|\s)\s*(\d+)(\'|′|\s)(\s*([0-9\.]*))("|\'\'|″|′′)?/u',
|
||||
static function (array $matches): string {
|
||||
return sprintf('%d %f', $matches[1], (float)$matches[3] + (float)$matches[6] / 60);
|
||||
},
|
||||
$string
|
||||
);
|
||||
}
|
||||
}
|
||||
22
niucloud/vendor/mjaschen/phpgeo/src/Factory/GeometryFactoryInterface.php
vendored
Normal file
22
niucloud/vendor/mjaschen/phpgeo/src/Factory/GeometryFactoryInterface.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Factory;
|
||||
|
||||
use Location\GeometryInterface;
|
||||
|
||||
/**
|
||||
* Geometry Factory Interface
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
interface GeometryFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @param string $string
|
||||
*
|
||||
* @return GeometryInterface
|
||||
*/
|
||||
public static function fromString(string $string);
|
||||
}
|
||||
216
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Coordinate/DMS.php
vendored
Normal file
216
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Coordinate/DMS.php
vendored
Normal file
@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Formatter\Coordinate;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Location\Coordinate;
|
||||
|
||||
/**
|
||||
* Coordinate Formatter "DMS"
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class DMS implements FormatterInterface
|
||||
{
|
||||
public const UNITS_UTF8 = 'UTF-8';
|
||||
public const UNITS_ASCII = 'ASCII';
|
||||
|
||||
/**
|
||||
* @var string Separator string between latitude and longitude
|
||||
*/
|
||||
protected $separator;
|
||||
|
||||
/**
|
||||
* Use cardinal letters for N/S and W/E instead of minus sign
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $useCardinalLetters;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @psalm-suppress PropertyNotSetInConstructor
|
||||
*/
|
||||
protected $unitType;
|
||||
|
||||
/**
|
||||
* @var array<string, array{deg: string, min: string, sec: string}>
|
||||
*/
|
||||
protected $units = [
|
||||
'UTF-8' => [
|
||||
'deg' => '°',
|
||||
'min' => '′',
|
||||
'sec' => '″',
|
||||
],
|
||||
'ASCII' => [
|
||||
'deg' => '°',
|
||||
'min' => '\'',
|
||||
'sec' => '"',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(
|
||||
string $separator = ' ',
|
||||
bool $useCardinalLetters = false,
|
||||
string $unitType = self::UNITS_UTF8
|
||||
) {
|
||||
$this->separator = $separator;
|
||||
$this->useCardinalLetters = $useCardinalLetters;
|
||||
$this->unitType = $unitType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the separator between latitude and longitude values
|
||||
*
|
||||
* @param string $separator
|
||||
*
|
||||
* @return DMS
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function setSeparator(string $separator): DMS
|
||||
{
|
||||
$this->separator = $separator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
*
|
||||
* @return DMS
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function useCardinalLetters(bool $value): DMS
|
||||
{
|
||||
$this->useCardinalLetters = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return DMS
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function setUnits(string $type): DMS
|
||||
{
|
||||
if (!array_key_exists($type, $this->units)) {
|
||||
throw new InvalidArgumentException('Invalid unit type');
|
||||
}
|
||||
|
||||
$this->unitType = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUnitType(): string
|
||||
{
|
||||
return $this->unitType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Coordinate $coordinate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(Coordinate $coordinate): string
|
||||
{
|
||||
$lat = $coordinate->getLat();
|
||||
$lng = $coordinate->getLng();
|
||||
|
||||
$latValue = abs($lat);
|
||||
$latDegrees = (int)$latValue;
|
||||
|
||||
$latMinutesDecimal = $latValue - $latDegrees;
|
||||
$latMinutes = (int)(60 * $latMinutesDecimal);
|
||||
|
||||
$latSeconds = 60 * (60 * $latMinutesDecimal - $latMinutes);
|
||||
|
||||
$lngValue = abs($lng);
|
||||
$lngDegrees = (int)$lngValue;
|
||||
|
||||
$lngMinutesDecimal = $lngValue - $lngDegrees;
|
||||
$lngMinutes = (int)(60 * $lngMinutesDecimal);
|
||||
|
||||
$lngSeconds = 60 * (60 * $lngMinutesDecimal - $lngMinutes);
|
||||
|
||||
return sprintf(
|
||||
'%s%02d%s %02d%s %02d%s%s%s%s%03d%s %02d%s %02d%s%s',
|
||||
$this->getLatPrefix($lat),
|
||||
abs($latDegrees),
|
||||
$this->units[$this->unitType]['deg'],
|
||||
$latMinutes,
|
||||
$this->units[$this->unitType]['min'],
|
||||
round($latSeconds, 0),
|
||||
$this->units[$this->unitType]['sec'],
|
||||
$this->getLatSuffix($lat),
|
||||
$this->separator,
|
||||
$this->getLngPrefix($lng),
|
||||
abs($lngDegrees),
|
||||
$this->units[$this->unitType]['deg'],
|
||||
$lngMinutes,
|
||||
$this->units[$this->unitType]['min'],
|
||||
round($lngSeconds, 0),
|
||||
$this->units[$this->unitType]['sec'],
|
||||
$this->getLngSuffix($lng)
|
||||
);
|
||||
}
|
||||
|
||||
protected function getLatPrefix(float $lat): string
|
||||
{
|
||||
if ($this->useCardinalLetters || $lat >= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '-';
|
||||
}
|
||||
|
||||
protected function getLngPrefix(float $lng): string
|
||||
{
|
||||
if ($this->useCardinalLetters || $lng >= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '-';
|
||||
}
|
||||
|
||||
protected function getLatSuffix(float $lat): string
|
||||
{
|
||||
if (!$this->useCardinalLetters) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($lat >= 0) {
|
||||
return ' N';
|
||||
}
|
||||
|
||||
return ' S';
|
||||
}
|
||||
|
||||
protected function getLngSuffix(float $lng): string
|
||||
{
|
||||
if (!$this->useCardinalLetters) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($lng >= 0) {
|
||||
return ' E';
|
||||
}
|
||||
|
||||
return ' W';
|
||||
}
|
||||
}
|
||||
64
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Coordinate/DecimalDegrees.php
vendored
Normal file
64
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Coordinate/DecimalDegrees.php
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Formatter\Coordinate;
|
||||
|
||||
use Location\Coordinate;
|
||||
|
||||
/**
|
||||
* Coordinate Formatter "Decimal Degrees"
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class DecimalDegrees implements FormatterInterface
|
||||
{
|
||||
/**
|
||||
* @var string Separator string between latitude and longitude
|
||||
*/
|
||||
protected $separator;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $digits = 5;
|
||||
|
||||
/**
|
||||
* @param string $separator
|
||||
* @param int $digits
|
||||
*/
|
||||
public function __construct(string $separator = ' ', int $digits = 5)
|
||||
{
|
||||
$this->separator = $separator;
|
||||
$this->digits = $digits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Coordinate $coordinate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(Coordinate $coordinate): string
|
||||
{
|
||||
return sprintf(
|
||||
'%.' . $this->digits . 'f%s%.' . $this->digits . 'f',
|
||||
$coordinate->getLat(),
|
||||
$this->separator,
|
||||
$coordinate->getLng()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the separator between latitude and longitude values
|
||||
*
|
||||
* @param string $separator
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSeparator(string $separator): DecimalDegrees
|
||||
{
|
||||
$this->separator = $separator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
252
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Coordinate/DecimalMinutes.php
vendored
Normal file
252
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Coordinate/DecimalMinutes.php
vendored
Normal file
@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Formatter\Coordinate;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Location\Coordinate;
|
||||
|
||||
/**
|
||||
* Coordinate Formatter "DecimalMinutes"
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class DecimalMinutes implements FormatterInterface
|
||||
{
|
||||
public const UNITS_UTF8 = 'UTF-8';
|
||||
public const UNITS_ASCII = 'ASCII';
|
||||
|
||||
/**
|
||||
* @var string Separator string between latitude and longitude
|
||||
*/
|
||||
protected $separator;
|
||||
|
||||
/**
|
||||
* Use cardinal letters for N/S and W/E instead of minus sign
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $useCardinalLetters;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @psalm-suppress PropertyNotSetInConstructor
|
||||
*/
|
||||
protected $unitType;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $digits = 3;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $decimalPoint = '.';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $units = [
|
||||
'UTF-8' => [
|
||||
'deg' => '°',
|
||||
'min' => '′',
|
||||
],
|
||||
'ASCII' => [
|
||||
'deg' => '°',
|
||||
'min' => '\'',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $separator
|
||||
*/
|
||||
public function __construct(string $separator = ' ')
|
||||
{
|
||||
$this->separator = $separator;
|
||||
$this->useCardinalLetters = false;
|
||||
|
||||
$this->setUnits(self::UNITS_UTF8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the separator between latitude and longitude values
|
||||
*
|
||||
* @param string $separator
|
||||
*
|
||||
* @return DecimalMinutes
|
||||
*/
|
||||
public function setSeparator(string $separator): DecimalMinutes
|
||||
{
|
||||
$this->separator = $separator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
*
|
||||
* @return DecimalMinutes
|
||||
*/
|
||||
public function useCardinalLetters(bool $value): DecimalMinutes
|
||||
{
|
||||
$this->useCardinalLetters = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return DecimalMinutes
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setUnits(string $type): DecimalMinutes
|
||||
{
|
||||
if (! array_key_exists($type, $this->units)) {
|
||||
throw new InvalidArgumentException('Invalid unit type');
|
||||
}
|
||||
|
||||
$this->unitType = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUnitType(): string
|
||||
{
|
||||
return $this->unitType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $digits
|
||||
*
|
||||
* @return DecimalMinutes
|
||||
*/
|
||||
public function setDigits(int $digits): DecimalMinutes
|
||||
{
|
||||
$this->digits = $digits;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $decimalPoint
|
||||
*
|
||||
* @return DecimalMinutes
|
||||
*/
|
||||
public function setDecimalPoint(string $decimalPoint): DecimalMinutes
|
||||
{
|
||||
$this->decimalPoint = $decimalPoint;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Coordinate $coordinate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(Coordinate $coordinate): string
|
||||
{
|
||||
$lat = $coordinate->getLat();
|
||||
$lng = $coordinate->getLng();
|
||||
|
||||
$latValue = abs($lat);
|
||||
$latDegrees = (int)$latValue;
|
||||
|
||||
$latMinutesDecimal = $latValue - $latDegrees;
|
||||
$latMinutes = 60 * $latMinutesDecimal;
|
||||
|
||||
$lngValue = abs($lng);
|
||||
$lngDegrees = (int)$lngValue;
|
||||
|
||||
$lngMinutesDecimal = $lngValue - $lngDegrees;
|
||||
$lngMinutes = 60 * $lngMinutesDecimal;
|
||||
|
||||
return sprintf(
|
||||
'%s%02d%s %s%s%s%s%s%03d%s %s%s%s',
|
||||
$this->getLatPrefix($lat),
|
||||
abs($latDegrees),
|
||||
$this->units[$this->unitType]['deg'],
|
||||
number_format($latMinutes, $this->digits, $this->decimalPoint, $this->decimalPoint),
|
||||
$this->units[$this->unitType]['min'],
|
||||
$this->getLatSuffix($lat),
|
||||
$this->separator,
|
||||
$this->getLngPrefix($lng),
|
||||
abs($lngDegrees),
|
||||
$this->units[$this->unitType]['deg'],
|
||||
number_format($lngMinutes, $this->digits, $this->decimalPoint, $this->decimalPoint),
|
||||
$this->units[$this->unitType]['min'],
|
||||
$this->getLngSuffix($lng)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $lat
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getLatPrefix(float $lat): string
|
||||
{
|
||||
if ($this->useCardinalLetters || $lat >= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $lng
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getLngPrefix(float $lng): string
|
||||
{
|
||||
if ($this->useCardinalLetters || $lng >= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $lat
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getLatSuffix(float $lat): string
|
||||
{
|
||||
if (! $this->useCardinalLetters) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($lat >= 0) {
|
||||
return ' N';
|
||||
}
|
||||
|
||||
return ' S';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $lng
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getLngSuffix(float $lng): string
|
||||
{
|
||||
if (! $this->useCardinalLetters) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($lng >= 0) {
|
||||
return ' E';
|
||||
}
|
||||
|
||||
return ' W';
|
||||
}
|
||||
}
|
||||
22
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Coordinate/FormatterInterface.php
vendored
Normal file
22
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Coordinate/FormatterInterface.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Formatter\Coordinate;
|
||||
|
||||
use Location\Coordinate;
|
||||
|
||||
/**
|
||||
* Coordinate Formatter Interface
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
interface FormatterInterface
|
||||
{
|
||||
/**
|
||||
* @param Coordinate $coordinate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(Coordinate $coordinate): string;
|
||||
}
|
||||
33
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Coordinate/GeoJSON.php
vendored
Normal file
33
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Coordinate/GeoJSON.php
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Formatter\Coordinate;
|
||||
|
||||
use Location\Coordinate;
|
||||
|
||||
/**
|
||||
* GeoJSON Coordinate Formatter
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class GeoJSON implements FormatterInterface
|
||||
{
|
||||
/**
|
||||
* @param Coordinate $coordinate
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(Coordinate $coordinate): string
|
||||
{
|
||||
return json_encode(
|
||||
[
|
||||
'type' => 'Point',
|
||||
'coordinates' => [
|
||||
$coordinate->getLng(),
|
||||
$coordinate->getLat(),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
23
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Polygon/FormatterInterface.php
vendored
Normal file
23
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Polygon/FormatterInterface.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Formatter\Polygon;
|
||||
|
||||
use Location\Polygon;
|
||||
|
||||
/**
|
||||
* Polygon Formatter Interface
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
* @author Richard Barnes <rbarnes@umn.edu>
|
||||
*/
|
||||
interface FormatterInterface
|
||||
{
|
||||
/**
|
||||
* @param Polygon $polygon
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(Polygon $polygon): string;
|
||||
}
|
||||
45
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Polygon/GeoJSON.php
vendored
Normal file
45
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Polygon/GeoJSON.php
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Formatter\Polygon;
|
||||
|
||||
use Location\Coordinate;
|
||||
use Location\Exception\InvalidPolygonException;
|
||||
use Location\Polygon;
|
||||
|
||||
/**
|
||||
* GeoJSON Polygon Formatter
|
||||
*
|
||||
* @author Richard Barnes <rbarnes@umn.edu>
|
||||
*/
|
||||
class GeoJSON implements FormatterInterface
|
||||
{
|
||||
/**
|
||||
* @param Polygon $polygon
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws InvalidPolygonException
|
||||
*/
|
||||
public function format(Polygon $polygon): string
|
||||
{
|
||||
if ($polygon->getNumberOfPoints() < 3) {
|
||||
throw new InvalidPolygonException('A polygon must consist of at least three points.');
|
||||
}
|
||||
|
||||
$points = [];
|
||||
|
||||
/** @var Coordinate $point */
|
||||
foreach ($polygon->getPoints() as $point) {
|
||||
$points[] = [$point->getLng(), $point->getLat()];
|
||||
}
|
||||
|
||||
return json_encode(
|
||||
[
|
||||
'type' => 'Polygon',
|
||||
'coordinates' => [$points],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
22
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Polyline/FormatterInterface.php
vendored
Normal file
22
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Polyline/FormatterInterface.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Formatter\Polyline;
|
||||
|
||||
use Location\Polyline;
|
||||
|
||||
/**
|
||||
* Polyline Formatter Interface
|
||||
*
|
||||
* @author Richard Barnes <rbarnes@umn.edu>
|
||||
*/
|
||||
interface FormatterInterface
|
||||
{
|
||||
/**
|
||||
* @param Polyline $polyline
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(Polyline $polyline): string;
|
||||
}
|
||||
36
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Polyline/GeoJSON.php
vendored
Normal file
36
niucloud/vendor/mjaschen/phpgeo/src/Formatter/Polyline/GeoJSON.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Formatter\Polyline;
|
||||
|
||||
use Location\Polyline;
|
||||
|
||||
/**
|
||||
* GeoJSON Polyline Formatter
|
||||
*
|
||||
* @author Richard Barnes <rbarnes@umn.edu>
|
||||
*/
|
||||
class GeoJSON implements FormatterInterface
|
||||
{
|
||||
/**
|
||||
* @param Polyline $polyline
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(Polyline $polyline): string
|
||||
{
|
||||
$points = [];
|
||||
|
||||
foreach ($polyline->getPoints() as $point) {
|
||||
$points[] = [$point->getLng(), $point->getLat()];
|
||||
}
|
||||
|
||||
return json_encode(
|
||||
[
|
||||
'type' => 'LineString',
|
||||
'coordinates' => $points,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
15
niucloud/vendor/mjaschen/phpgeo/src/GeometryInterface.php
vendored
Normal file
15
niucloud/vendor/mjaschen/phpgeo/src/GeometryInterface.php
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location;
|
||||
|
||||
interface GeometryInterface
|
||||
{
|
||||
/**
|
||||
* Returns an array containing all assigned points.
|
||||
*
|
||||
* @return array<Coordinate>
|
||||
*/
|
||||
public function getPoints(): array;
|
||||
}
|
||||
43
niucloud/vendor/mjaschen/phpgeo/src/GetBoundsTrait.php
vendored
Normal file
43
niucloud/vendor/mjaschen/phpgeo/src/GetBoundsTrait.php
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location;
|
||||
|
||||
/**
|
||||
* Trait GetBoundsTrait
|
||||
*
|
||||
* @package Location
|
||||
*
|
||||
* @property array<Coordinate> $points
|
||||
*/
|
||||
trait GetBoundsTrait
|
||||
{
|
||||
/**
|
||||
* @return array<Coordinate>
|
||||
*/
|
||||
abstract public function getPoints(): array;
|
||||
|
||||
/**
|
||||
* @return Bounds
|
||||
*/
|
||||
public function getBounds(): Bounds
|
||||
{
|
||||
$latMin = 90.0;
|
||||
$latMax = -90.0;
|
||||
$lngMin = 180.0;
|
||||
$lngMax = -180.0;
|
||||
|
||||
foreach ($this->getPoints() as $point) {
|
||||
$latMin = min($point->getLat(), $latMin);
|
||||
$lngMin = min($point->getLng(), $lngMin);
|
||||
$latMax = max($point->getLat(), $latMax);
|
||||
$lngMax = max($point->getLng(), $lngMax);
|
||||
}
|
||||
|
||||
return new Bounds(
|
||||
new Coordinate($latMax, $lngMin),
|
||||
new Coordinate($latMin, $lngMax)
|
||||
);
|
||||
}
|
||||
}
|
||||
90
niucloud/vendor/mjaschen/phpgeo/src/Intersection/Intersection.php
vendored
Normal file
90
niucloud/vendor/mjaschen/phpgeo/src/Intersection/Intersection.php
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location\Intersection;
|
||||
|
||||
use Location\Bounds;
|
||||
use Location\Coordinate;
|
||||
use Location\Direction\Direction;
|
||||
use Location\Exception\InvalidGeometryException;
|
||||
use Location\GeometryInterface;
|
||||
use Location\Line;
|
||||
use Location\Polygon;
|
||||
use Location\Polyline;
|
||||
|
||||
class Intersection
|
||||
{
|
||||
public function intersects(GeometryInterface $geometry1, GeometryInterface $geometry2, bool $precise = false): bool
|
||||
{
|
||||
if ($geometry1 instanceof Polygon && $geometry2 instanceof Coordinate) {
|
||||
return $geometry1->contains($geometry2);
|
||||
}
|
||||
|
||||
if ($geometry1 instanceof Coordinate && $geometry2 instanceof Polygon) {
|
||||
return $geometry2->contains($geometry1);
|
||||
}
|
||||
|
||||
if ($precise === true) {
|
||||
return $this->intersectsGeometry($geometry1, $geometry2);
|
||||
}
|
||||
|
||||
return $this->intersectsBounds($geometry1, $geometry2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this geometry's bounds and the given bounds intersect.
|
||||
*/
|
||||
private function intersectsBounds(GeometryInterface $geometry1, GeometryInterface $geometry2): bool
|
||||
{
|
||||
$direction = new Direction();
|
||||
/** @var Coordinate|Line|Polyline|Polygon $geometry1 */
|
||||
$bounds1 = $geometry1->getBounds();
|
||||
/** @var Coordinate|Line|Polyline|Polygon $geometry2 */
|
||||
$bounds2 = $geometry2->getBounds();
|
||||
|
||||
return !(
|
||||
$direction->pointIsEastOf($bounds1->getSouthWest(), $bounds2->getSouthEast())
|
||||
|| $direction->pointIsSouthOf($bounds1->getNorthWest(), $bounds2->getSouthWest())
|
||||
|| $direction->pointIsWestOf($bounds1->getSouthEast(), $bounds2->getSouthWest())
|
||||
|| $direction->pointIsNorthOf($bounds1->getSouthWest(), $bounds2->getNorthWest())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this geometry and the given geometry intersect by checking
|
||||
* their segments for intersections.
|
||||
*
|
||||
* @throws InvalidGeometryException
|
||||
*/
|
||||
private function intersectsGeometry(GeometryInterface $geometry1, GeometryInterface $geometry2): bool
|
||||
{
|
||||
if ($geometry1 instanceof Coordinate && $geometry2 instanceof Coordinate) {
|
||||
return $geometry1->hasSameLocation($geometry2);
|
||||
}
|
||||
|
||||
if ($geometry1 instanceof Coordinate || $geometry2 instanceof Coordinate) {
|
||||
throw new InvalidGeometryException('Only can check point intersections for polygons', 7311194789);
|
||||
}
|
||||
|
||||
if (($geometry1 instanceof Polygon) && $geometry1->containsGeometry($geometry2)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (($geometry2 instanceof Polygon) && $geometry2->containsGeometry($geometry1)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @var Line|Polyline|Polygon $geometry1 */
|
||||
foreach ($geometry1->getSegments() as $segment) {
|
||||
/** @var Line|Polyline|Polygon $geometry2 */
|
||||
foreach ($geometry2->getSegments() as $otherSegment) {
|
||||
if ($segment->intersectsLine($otherSegment)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
280
niucloud/vendor/mjaschen/phpgeo/src/Line.php
vendored
Normal file
280
niucloud/vendor/mjaschen/phpgeo/src/Line.php
vendored
Normal file
@ -0,0 +1,280 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location;
|
||||
|
||||
use Location\Bearing\BearingInterface;
|
||||
use Location\Distance\DistanceInterface;
|
||||
use Location\Intersection\Intersection;
|
||||
use Location\Utility\Cartesian;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Line Implementation
|
||||
*
|
||||
* @author Marcus Jaschen <mjaschen@gmail.com>
|
||||
*/
|
||||
class Line implements GeometryInterface
|
||||
{
|
||||
use GetBoundsTrait;
|
||||
|
||||
public const ORIENTATION_COLLINEAR = 0;
|
||||
public const ORIENTATION_CLOCKWISE = 1;
|
||||
public const ORIENTATION_ANTI_CLOCKWISE = 2;
|
||||
|
||||
/**
|
||||
* @var Coordinate
|
||||
*/
|
||||
protected $point1;
|
||||
|
||||
/**
|
||||
* @var Coordinate
|
||||
*/
|
||||
protected $point2;
|
||||
|
||||
/**
|
||||
* @param Coordinate $point1
|
||||
* @param Coordinate $point2
|
||||
*/
|
||||
public function __construct(Coordinate $point1, Coordinate $point2)
|
||||
{
|
||||
$this->point1 = $point1;
|
||||
$this->point2 = $point2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Coordinate $point1
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function setPoint1(Coordinate $point1)
|
||||
{
|
||||
$this->point1 = $point1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Coordinate
|
||||
*/
|
||||
public function getPoint1(): Coordinate
|
||||
{
|
||||
return $this->point1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Coordinate $point2
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public function setPoint2(Coordinate $point2)
|
||||
{
|
||||
$this->point2 = $point2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Coordinate
|
||||
*/
|
||||
public function getPoint2(): Coordinate
|
||||
{
|
||||
return $this->point2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the two points.
|
||||
*
|
||||
* @return array<Coordinate>
|
||||
*/
|
||||
public function getPoints(): array
|
||||
{
|
||||
return [$this->point1, $this->point2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing the line segment.
|
||||
*
|
||||
* @return array<Line>
|
||||
*/
|
||||
public function getSegments(): array
|
||||
{
|
||||
return [$this];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the length of the line (distance between the two
|
||||
* coordinates).
|
||||
*
|
||||
* @param DistanceInterface $calculator instance of distance calculation class
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getLength(DistanceInterface $calculator): float
|
||||
{
|
||||
return $calculator->getDistance($this->point1, $this->point2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BearingInterface $bearingCalculator
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getBearing(BearingInterface $bearingCalculator): float
|
||||
{
|
||||
return $bearingCalculator->calculateBearing($this->point1, $this->point2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BearingInterface $bearingCalculator
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getFinalBearing(BearingInterface $bearingCalculator): float
|
||||
{
|
||||
return $bearingCalculator->calculateFinalBearing($this->point1, $this->point2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance with reversed point order, i. e. reversed direction.
|
||||
*
|
||||
* @return Line
|
||||
*/
|
||||
public function getReverse(): Line
|
||||
{
|
||||
return new self($this->point2, $this->point1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the midpoint of a Line segment
|
||||
*
|
||||
* @see http://www.movable-type.co.uk/scripts/latlong.html#midpoint
|
||||
*
|
||||
* @return Coordinate
|
||||
*/
|
||||
public function getMidpoint(): Coordinate
|
||||
{
|
||||
$lat1 = deg2rad($this->point1->getLat());
|
||||
$lng1 = deg2rad($this->point1->getLng());
|
||||
$lat2 = deg2rad($this->point2->getLat());
|
||||
$lng2 = deg2rad($this->point2->getLng());
|
||||
$deltaLng = $lng2 - $lng1;
|
||||
|
||||
$A = new Cartesian(cos($lat1), 0, sin($lat1));
|
||||
$B = new Cartesian(cos($lat2) * cos($deltaLng), cos($lat2) * sin($deltaLng), sin($lat2));
|
||||
$C = $A->add($B);
|
||||
|
||||
$latMid = atan2($C->getZ(), sqrt($C->getX() ** 2 + $C->getY() ** 2));
|
||||
$lngMid = $lng1 + atan2($C->getY(), $C->getX());
|
||||
|
||||
return new Coordinate(rad2deg($latMid), rad2deg($lngMid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the point which is located on the line at the
|
||||
* given fraction (starting at point 1).
|
||||
*
|
||||
* @see http://www.movable-type.co.uk/scripts/latlong.html#intermediate-point
|
||||
* @see http://www.edwilliams.org/avform.htm#Intermediate
|
||||
*
|
||||
* @param float $fraction 0.0 ... 1.0 (smaller or larger values work too)
|
||||
*
|
||||
* @return Coordinate
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getIntermediatePoint(float $fraction): Coordinate
|
||||
{
|
||||
$lat1 = deg2rad($this->point1->getLat());
|
||||
$lng1 = deg2rad($this->point1->getLng());
|
||||
$lat2 = deg2rad($this->point2->getLat());
|
||||
$lng2 = deg2rad($this->point2->getLng());
|
||||
$deltaLat = $lat2 - $lat1;
|
||||
$deltaLng = $lng2 - $lng1;
|
||||
|
||||
if ($lat1 + $lat2 == 0.0 && abs($lng1 - $lng2) == M_PI) {
|
||||
throw new RuntimeException(
|
||||
'Start and end points are antipodes, route is therefore undefined.',
|
||||
5382449689
|
||||
);
|
||||
}
|
||||
|
||||
$a = sin($deltaLat / 2) ** 2 + cos($lat1) * cos($lat2) * sin($deltaLng / 2) ** 2;
|
||||
$delta = 2 * atan2(sqrt($a), sqrt(1 - $a));
|
||||
|
||||
$A = sin((1 - $fraction) * $delta) / sin($delta);
|
||||
$B = sin($fraction * $delta) / sin($delta);
|
||||
|
||||
$x = $A * cos($lat1) * cos($lng1) + $B * cos($lat2) * cos($lng2);
|
||||
$y = $A * cos($lat1) * sin($lng1) + $B * cos($lat2) * sin($lng2);
|
||||
$z = $A * sin($lat1) + $B * sin($lat2);
|
||||
|
||||
$lat = atan2($z, sqrt($x ** 2 + $y ** 2));
|
||||
$lng = atan2($y, $x);
|
||||
|
||||
return new Coordinate(rad2deg($lat), rad2deg($lng));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the location of a given coordinate to this line returning
|
||||
* its orientation as:
|
||||
*
|
||||
* - 0 if the coordinate is collinear to this line segment
|
||||
* - 1 if the coordinate's orientation is clockwise to this line segment
|
||||
* - 2 if the coordinate's orientation is anti-clockwise to this line segment
|
||||
*/
|
||||
public function getOrientation(Coordinate $coordinate): int
|
||||
{
|
||||
$crossproduct1 = ($this->point2->getLat() - $this->point1->getLat())
|
||||
* ($coordinate->getLng() - $this->point2->getLng());
|
||||
$crossproduct2 = ($this->point2->getLng() - $this->point1->getLng())
|
||||
* ($coordinate->getLat() - $this->point2->getLat());
|
||||
$delta = $crossproduct1 - $crossproduct2;
|
||||
|
||||
if ($delta > 0) {
|
||||
return self::ORIENTATION_CLOCKWISE;
|
||||
}
|
||||
|
||||
if ($delta < 0) {
|
||||
return self::ORIENTATION_ANTI_CLOCKWISE;
|
||||
}
|
||||
|
||||
return self::ORIENTATION_COLLINEAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Two lines intersect if:
|
||||
*
|
||||
* 1. the points of the given line are oriented into opposite directions
|
||||
* 2. the points of this line are oriented into opposite directions
|
||||
* 3. the points are collinear and the two line segments are overlapping
|
||||
*/
|
||||
public function intersectsLine(Line $line): bool
|
||||
{
|
||||
$orientation = [];
|
||||
$orientation[11] = $this->getOrientation($line->getPoint1());
|
||||
$orientation[12] = $this->getOrientation($line->getPoint2());
|
||||
$orientation[21] = $line->getOrientation($this->getPoint1());
|
||||
$orientation[22] = $line->getOrientation($this->getPoint2());
|
||||
|
||||
// the lines cross
|
||||
if (
|
||||
$orientation[11] !== $orientation[12]
|
||||
&& $orientation[21] !== $orientation[22]
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// the lines are collinear or touch
|
||||
if (
|
||||
in_array(self::ORIENTATION_COLLINEAR, $orientation, true)
|
||||
&& (new Intersection())->intersects($this, $line, false)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// the lines do not overlap
|
||||
return false;
|
||||
}
|
||||
}
|
||||
260
niucloud/vendor/mjaschen/phpgeo/src/Polygon.php
vendored
Normal file
260
niucloud/vendor/mjaschen/phpgeo/src/Polygon.php
vendored
Normal file
@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Location;
|
||||
|
||||
use Location\Distance\DistanceInterface;
|
||||
use Location\Formatter\Polygon\FormatterInterface;
|
||||
|
||||
class Polygon implements GeometryInterface
|
||||
{
|
||||
use GetBoundsTrait;
|
||||
|
||||
/**
|
||||
* @var array<Coordinate>
|
||||
*/
|
||||
protected $points = [];
|
||||
|
||||
/**
|
||||
* @param Coordinate $point
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPoint(Coordinate $point): void
|
||||
{
|
||||
$this->points[] = $point;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<Coordinate> $points
|
||||
*/
|
||||
public function addPoints(array $points): void
|
||||
{
|
||||
foreach ($points as $point) {
|
||||
$this->addPoint($point);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<Coordinate>
|
||||
*/
|
||||
public function getPoints(): array
|
||||
{
|
||||
return $this->points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all polygon point's latitudes.
|
||||
*
|
||||
* @return array<float>
|
||||
*/
|
||||
public function getLats(): array
|
||||
{
|
||||
$lats = [];
|
||||
|
||||
foreach ($this->points as $point) {
|
||||
/** @var Coordinate $point */
|
||||
$lats[] = $point->getLat();
|
||||
}
|
||||
|
||||
return $lats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all polygon point's longitudes.
|
||||
*
|
||||
* @return array<float>
|
||||
*/
|
||||
public function getLngs(): array
|
||||
{
|
||||
$lngs = [];
|
||||
|
||||
foreach ($this->points as $point) {
|
||||
/** @var Coordinate $point */
|
||||
$lngs[] = $point->getLng();
|
||||
}
|
||||
|
||||
return $lngs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getNumberOfPoints(): int
|
||||
{
|
||||
return count($this->points);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormatterInterface $formatter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(FormatterInterface $formatter): string
|
||||
{
|
||||
return $formatter->format($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<Line>
|
||||
*/
|
||||
public function getSegments(): array
|
||||
{
|
||||
$length = count($this->points);
|
||||
$segments = [];
|
||||
|
||||
if ($length <= 1) {
|
||||
return $segments;
|
||||
}
|
||||
|
||||
for ($i = 1; $i < $length; $i++) {
|
||||
$segments[] = new Line($this->points[$i - 1], $this->points[$i]);
|
||||
}
|
||||
|
||||
// to close the polygon we have to add the final segment between
|
||||
// the last point and the first point
|
||||
$segments[] = new Line($this->points[$i - 1], $this->points[0]);
|
||||
|
||||
return $segments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if given geometry is contained inside the polygon. This is
|
||||
* assumed to be true, if each point of the geometry is inside the polygon.
|
||||
*
|
||||
* Edge cases:
|
||||
*
|
||||
* - it's not detected when a line between two points is outside the polygon
|
||||
* - @see contains() for more restrictions
|
||||
*
|
||||
* @param GeometryInterface $geometry
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function containsGeometry(GeometryInterface $geometry): bool
|
||||
{
|
||||
$geometryInPolygon = true;
|
||||
|
||||
foreach ($geometry->getPoints() as $point) {
|
||||
$geometryInPolygon = $geometryInPolygon && $this->contains($point);
|
||||
}
|
||||
|
||||
return $geometryInPolygon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if given point is contained inside the polygon. Uses the PNPOLY
|
||||
* algorithm by W. Randolph Franklin. Therfore some edge cases may not give the
|
||||
* expected results, e.g. if the point resides on the polygon boundary.
|
||||
*
|
||||
* @see https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html
|
||||
*
|
||||
* For special cases this calculation leads to wrong results:
|
||||
*
|
||||
* - if the polygons spans over the longitude boundaries at 180/-180 degrees
|
||||
*
|
||||
* @param Coordinate $point
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains(Coordinate $point): bool
|
||||
{
|
||||
$numberOfPoints = $this->getNumberOfPoints();
|
||||
$polygonLats = $this->getLats();
|
||||
$polygonLngs = $this->getLngs();
|
||||
|
||||
$polygonContainsPoint = false;
|
||||
|
||||
for ($node = 0, $altNode = $numberOfPoints - 1; $node < $numberOfPoints; $altNode = $node++) {
|
||||
$condition = ($polygonLngs[$node] > $point->getLng()) !== ($polygonLngs[$altNode] > $point->getLng())
|
||||
&& ($point->getLat() < ($polygonLats[$altNode] - $polygonLats[$node])
|
||||
* ($point->getLng() - $polygonLngs[$node])
|
||||
/ ($polygonLngs[$altNode] - $polygonLngs[$node]) + $polygonLats[$node]);
|
||||
|
||||
if ($condition) {
|
||||
$polygonContainsPoint = !$polygonContainsPoint;
|
||||
}
|
||||
}
|
||||
|
||||
return $polygonContainsPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the polygon perimeter.
|
||||
*
|
||||
* @param DistanceInterface $calculator instance of distance calculation class
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getPerimeter(DistanceInterface $calculator): float
|
||||
{
|
||||
$perimeter = 0.0;
|
||||
|
||||
if (count($this->points) < 2) {
|
||||
return $perimeter;
|
||||
}
|
||||
|
||||
foreach ($this->getSegments() as $segment) {
|
||||
$perimeter += $segment->getLength($calculator);
|
||||
}
|
||||
|
||||
return $perimeter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the polygon area.
|
||||
*
|
||||
* This algorithm gives inaccurate results as it ignores
|
||||
* ellipsoid parameters other than to arithmetic mean radius.
|
||||
* The error should be < 1 % for small areas.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getArea(): float
|
||||
{
|
||||
$area = 0;
|
||||
|
||||
if ($this->getNumberOfPoints() <= 2) {
|
||||
return $area;
|
||||
}
|
||||
|
||||
$referencePoint = $this->points[0];
|
||||
$radius = $referencePoint->getEllipsoid()->getArithmeticMeanRadius();
|
||||
$segments = $this->getSegments();
|
||||
|
||||
foreach ($segments as $segment) {
|
||||
$point1 = $segment->getPoint1();
|
||||
$point2 = $segment->getPoint2();
|
||||
|
||||
$x1 = deg2rad($point1->getLng() - $referencePoint->getLng()) * cos(deg2rad($point1->getLat()));
|
||||
$y1 = deg2rad($point1->getLat() - $referencePoint->getLat());
|
||||
|
||||
$x2 = deg2rad($point2->getLng() - $referencePoint->getLng()) * cos(deg2rad($point2->getLat()));
|
||||
$y2 = deg2rad($point2->getLat() - $referencePoint->getLat());
|
||||
|
||||
$area += ($x2 * $y1 - $x1 * $y2);
|
||||
}
|
||||
|
||||
$area *= 0.5 * $radius ** 2;
|
||||
|
||||
return abs($area);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new polygon with reversed order of points, i. e. reversed
|
||||
* polygon direction.
|
||||
*
|
||||
* @return Polygon
|
||||
*/
|
||||
public function getReverse(): Polygon
|
||||
{
|
||||
$reversed = new self();
|
||||
|
||||
foreach (array_reverse($this->points) as $point) {
|
||||
$reversed->addPoint($point);
|
||||
}
|
||||
|
||||
return $reversed;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user