Initial commit

This commit is contained in:
Philipp Lang 2023-05-16 14:29:51 +02:00
commit 346ca9b449
7 changed files with 170 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/vendor

17
composer.json Normal file
View File

@ -0,0 +1,17 @@
{
"name": "zoomyboy/osm",
"description": "OSM Helper",
"type": "library",
"autoload": {
"psr-4": {
"Zoomyboy\\Osm\\": "src/"
}
},
"authors": [
{
"name": "Philipp Lang",
"email": "philipp@zoomyboy.de"
}
],
"require": {}
}

41
src/Address.php Normal file
View File

@ -0,0 +1,41 @@
<?php
namespace Zoomyboy\Osm;
use Illuminate\Support\Facades\Http;
class Address
{
public function __construct(
public ?string $address,
public ?string $zip,
public ?string $location
) {
}
public function getCoordinate(): ?Coordinate
{
if (!$this->address || !$this->zip || !$this->location) {
return null;
}
$response = Http::get('https://nominatim.openstreetmap.org/search/'.rawurlencode($this->queryString()).'?'.http_build_query([
'format' => 'json',
'addressdetails' => 1,
]));
if (!$response->ok()) {
return null;
}
$lat = (float) data_get($response, '0.lat');
$lon = (float) data_get($response, '0.lon');
return new Coordinate($lat, $lon);
}
public function queryString(): string
{
return $this->address.', '.$this->zip.' '.$this->location;
}
}

10
src/Coordinate.php Normal file
View File

@ -0,0 +1,10 @@
<?php
namespace Zoomyboy\Osm;
class Coordinate
{
public function __construct(public float $lat, public float $lon)
{
}
}

53
src/FillCoordsJob.php Normal file
View File

@ -0,0 +1,53 @@
<?php
namespace Zoomyboy\Osm;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class FillCoordsJob implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
public Geolocatable $model;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(Geolocatable $model)
{
$this->model = $model;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$address = $this->model->getAddressForGeolocation();
if (!$address) {
$this->model->destroyCoordinate();
return;
}
$coordinate = $address->getCoordinate();
if (!$coordinate) {
return;
}
$this->model->fillCoordinate($coordinate);
}
}

12
src/Geolocatable.php Normal file
View File

@ -0,0 +1,12 @@
<?php
namespace Zoomyboy\Osm;
interface Geolocatable
{
public function fillCoordinate(Coordinate $coordinate): void;
public function getAddressForGeolocation(): ?Address;
public function destroyCoordinate();
}

36
src/HasGeolocation.php Normal file
View File

@ -0,0 +1,36 @@
<?php
namespace Zoomyboy\Osm;
trait HasGeolocation
{
public static $geolocationEnabled = true;
public static function bootHasGeolocation(): void
{
static::saved(function (Geolocatable $model) {
if (!static::$geolocationEnabled) {
return;
}
dispatch(new FillCoordsJob($model));
});
}
public static function disableGeolocation(): void
{
static::$geolocationEnabled = false;
}
public static function enableGeolocation(): void
{
static::$geolocationEnabled = true;
}
public function destroyCoordinate(): void
{
$this->updateQuietly([
'lat' => null,
'lon' => null,
]);
}
}