Compare commits
12 Commits
Author | SHA1 | Date |
---|---|---|
|
5cedc661f5 | |
|
03340280d0 | |
|
87300623a3 | |
|
bb40476fdc | |
|
6584953cd8 | |
|
339c17d700 | |
|
63b90ef722 | |
|
30fc4926c4 | |
|
ba403c5f59 | |
|
e924be87df | |
|
132d15f368 | |
|
255a7819f5 |
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Zoomyboy\Osm;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class Address
|
||||
{
|
||||
|
@ -13,29 +12,17 @@ class Address
|
|||
) {
|
||||
}
|
||||
|
||||
public function getCoordinate(): ?Coordinate
|
||||
public function getCoordinate($serviceClass): ?Point
|
||||
{
|
||||
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);
|
||||
return app($serviceClass)->getAddress($this->queryString());
|
||||
}
|
||||
|
||||
public function queryString(): string
|
||||
{
|
||||
return $this->address.', '.$this->zip.' '.$this->location;
|
||||
return $this->address . ', ' . $this->zip . ' ' . $this->location;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Zoomyboy\Osm;
|
||||
|
||||
class Coordinate
|
||||
{
|
||||
public function __construct(public float $lat, public float $lon)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
|
|||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
|
||||
class FillCoordsJob implements ShouldQueue
|
||||
{
|
||||
|
@ -15,16 +16,14 @@ class FillCoordsJob implements ShouldQueue
|
|||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
public Geolocatable $model;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Geolocatable $model)
|
||||
public function __construct(public Geolocatable $model)
|
||||
{
|
||||
$this->model = $model;
|
||||
$this->onQueue('forever');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,20 +33,21 @@ class FillCoordsJob implements ShouldQueue
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
$address = $this->model->getAddressForGeolocation();
|
||||
Redis::throttle('osm')->block(0)->allow(1)->every(3)->then(function () {
|
||||
$address = $this->model->getAddressForGeolocation();
|
||||
if (!$address) {
|
||||
$this->model->destroyCoordinate();
|
||||
|
||||
if (!$address) {
|
||||
$this->model->destroyCoordinate();
|
||||
return;
|
||||
}
|
||||
$coordinate = $address->getCoordinate($this->model::geolocationService());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$coordinate = $address->getCoordinate();
|
||||
|
||||
if (!$coordinate) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->model->fillCoordinate($coordinate);
|
||||
if (!$coordinate) {
|
||||
return;
|
||||
}
|
||||
$this->model->fillCoordinate($coordinate);
|
||||
}, function () {
|
||||
return $this->release(5);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,13 @@ namespace Zoomyboy\Osm;
|
|||
|
||||
interface Geolocatable
|
||||
{
|
||||
public function fillCoordinate(Coordinate $coordinate): void;
|
||||
public function fillCoordinate(Point $point): void;
|
||||
|
||||
public function getAddressForGeolocation(): ?Address;
|
||||
|
||||
public function destroyCoordinate(): void;
|
||||
|
||||
public function needsGeolocationUpdate(): bool;
|
||||
|
||||
public static function geolocationService(): string;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Zoomyboy\Osm;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class GoogleService
|
||||
{
|
||||
public function getAddress(string $query): ?Point
|
||||
{
|
||||
$response = Http::get('https://maps.googleapis.com/maps/api/geocode/json?' . http_build_query([
|
||||
'address' => $query,
|
||||
'key' => config('services.osm.google_key'),
|
||||
]));
|
||||
|
||||
if (!$response->ok()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Point::from([
|
||||
'lat' => (float) data_get($response, 'results.0.geometry.location.lat'),
|
||||
'lon' => (float) data_get($response, 'results.0.geometry.location.lng')
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -12,7 +12,10 @@ trait HasGeolocation
|
|||
if (!static::$geolocationEnabled) {
|
||||
return;
|
||||
}
|
||||
dispatch(new FillCoordsJob($model));
|
||||
|
||||
if ($model->needsGeolocationUpdate()) {
|
||||
dispatch(new FillCoordsJob($model));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Zoomyboy\Osm;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class OsmService
|
||||
{
|
||||
public function getAddress(string $query): ?Point
|
||||
{
|
||||
$response = Http::get('https://nominatim.openstreetmap.org/search?' . http_build_query([
|
||||
'q' => $query,
|
||||
'format' => 'json',
|
||||
'addressdetails' => 1,
|
||||
]));
|
||||
|
||||
if (!$response->ok()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return count($response->json()) ? Point::from(['lat' => (float) data_get($response, '0.lat'), 'lon' => (float) data_get($response, '0.lon')]) : null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Zoomyboy\Osm;
|
||||
|
||||
use Spatie\LaravelData\Data;
|
||||
|
||||
class Point extends Data
|
||||
{
|
||||
public function __construct(public float $lat, public float $lon)
|
||||
{
|
||||
}
|
||||
|
||||
public function imageUrl(): string
|
||||
{
|
||||
return '/osm-static-maps/?' . http_build_query([
|
||||
'center' => $this->lon . ',' . $this->lat,
|
||||
'zoom' => 20,
|
||||
'maxZoom' => 13,
|
||||
]);
|
||||
}
|
||||
|
||||
public function markerUrl(string $zoom = '20'): string
|
||||
{
|
||||
return '/osm-static-maps/?' . http_build_query([
|
||||
'geojson' => json_encode(['type' => 'Point', 'coordinates' => [$this->lon, $this->lat]]),
|
||||
'zoom' => $zoom,
|
||||
'maxZoom' => $zoom,
|
||||
]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue