Geofencing
Coordinates obsahuje sadu pomocníkov na geofencing. Ide o čistú matematiku — žiadny poskytovateľ, žiadna sieť:
use RoundlyConsulting\Geolocation\DataTransferObjects\Coordinates;
$here = new Coordinates(48.1486, 17.1077);
$there = new Coordinates(48.21, 16.37);
$here->near($there, radiusKm: 100); // bool — Haversine distance ≤ 100 km
$here->within([$a, $b, $c, $d]); // point-in-polygon, bool
$here->bearingTo($there); // initial bearing, degrees 0–360 clockwise from north
$here->midpointTo($there); // Coordinates on the great circle
$box = $here->boundingBox(radiusKm: 10); // BoundingBox
$box->contains($point); // boolPrehľad metód
| Metóda | Vracia |
|---|---|
distanceTo(Coordinates): float | Vzdialenosť po hlavnej kružnici v metroch (Haversine). |
near(Coordinates, float $radiusKm): bool | Či druhý bod leží v danom okruhu. |
within(list<Coordinates>): bool | Bod v polygóne (ray casting); každá hrana vedie kratšou cestou, takže fungujú aj polygóny cez antimeridián. Menej ako 3 vrcholy vrátia false; polygón okolo pólu nie je podporovaný. |
bearingTo(Coordinates): float | Počiatočný azimut, 0–360° v smere hodinových ručičiek od severu. |
midpointTo(Coordinates): Coordinates | Geografický stred na hlavnej kružnici, dĺžka normalizovaná do -180..180. |
boundingBox(float $radiusKm): BoundingBox | Najmenší obdĺžnik so všetkými bodmi v okruhu. Prechádza cez ±180°; keď kruh siahne na pól, pokryje všetky dĺžky. |
BoundingBox::contains(Coordinates): bool | Či bod leží v obdĺžniku, aj v takom, ktorý prechádza cez ±180°. |
BoundingBox::crossesAntimeridian(): bool | Či obdĺžnik prechádza cez ±180° (dĺžka juhozápadného rohu je potom väčšia ako severovýchodného). |
Antimeridián a póly
Pomocníci fungujú aj cez antimeridián a pri póloch: midpointTo() normalizuje dĺžku do -180..180, obdĺžnik, ktorý prechádza cez ±180°, sa zalomí (crossesAntimeridian() je potom true a dĺžka juhozápadného rohu je väčšia ako severovýchodného) a kruh, ktorý siahne na pól, pokryje všetky dĺžky. within() vedie každú hranu polygónu kratšou cestou, takže funguje aj polygón nakreslený cez antimeridián. Polygón, ktorý obopína pól, podporovaný nie je.
Zóny v tvare polygónu
Zónu opíšte jej vrcholmi — prvý bod netreba na konci opakovať:
$deliveryZone = [
new Coordinates(48.20, 17.00),
new Coordinates(48.20, 17.20),
new Coordinates(48.10, 17.20),
new Coordinates(48.10, 17.00), // no need to repeat the first vertex
];
$customer = new Coordinates(48.15, 17.11);
$customer->within($deliveryZone); // trueOhraničujúce obdĺžniky
BoundingBox je obdĺžnik zarovnaný na osi — ideálny ako lacný predfilter v SQL pred presnou kontrolou vzdialenosti:
$box = (new Coordinates(48.1486, 17.1077))->boundingBox(radiusKm: 10);
$box->southWest; // Coordinates — minimum latitude, western edge
$box->northEast; // Coordinates — maximum latitude, eastern edge
$box->toArray(); // ['minLatitude' => ..., 'minLongitude' => ..., 'maxLatitude' => ..., 'maxLongitude' => ...]
// Near ±180° the box wraps: south-west longitude > north-east longitude
(new Coordinates(0.0, 179.99))->boundingBox(radiusKm: 10)->crossesAntimeridian(); // truePrejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.