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;
|
namespace Zoomyboy\Osm;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Http;
|
|
||||||
|
|
||||||
class Address
|
class Address
|
||||||
{
|
{
|
||||||
|
@ -13,29 +12,17 @@ class Address
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCoordinate(): ?Coordinate
|
public function getCoordinate($serviceClass): ?Point
|
||||||
{
|
{
|
||||||
if (!$this->address || !$this->zip || !$this->location) {
|
if (!$this->address || !$this->zip || !$this->location) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = Http::get('https://nominatim.openstreetmap.org/search/'.rawurlencode($this->queryString()).'?'.http_build_query([
|
return app($serviceClass)->getAddress($this->queryString());
|
||||||
'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
|
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\Foundation\Bus\Dispatchable;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Redis;
|
||||||
|
|
||||||
class FillCoordsJob implements ShouldQueue
|
class FillCoordsJob implements ShouldQueue
|
||||||
{
|
{
|
||||||
|
@ -15,16 +16,14 @@ class FillCoordsJob implements ShouldQueue
|
||||||
use Queueable;
|
use Queueable;
|
||||||
use SerializesModels;
|
use SerializesModels;
|
||||||
|
|
||||||
public Geolocatable $model;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @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()
|
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) {
|
return;
|
||||||
$this->model->destroyCoordinate();
|
}
|
||||||
|
$coordinate = $address->getCoordinate($this->model::geolocationService());
|
||||||
|
|
||||||
return;
|
if (!$coordinate) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
$coordinate = $address->getCoordinate();
|
$this->model->fillCoordinate($coordinate);
|
||||||
|
}, function () {
|
||||||
if (!$coordinate) {
|
return $this->release(5);
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
$this->model->fillCoordinate($coordinate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,13 @@ namespace Zoomyboy\Osm;
|
||||||
|
|
||||||
interface Geolocatable
|
interface Geolocatable
|
||||||
{
|
{
|
||||||
public function fillCoordinate(Coordinate $coordinate): void;
|
public function fillCoordinate(Point $point): void;
|
||||||
|
|
||||||
public function getAddressForGeolocation(): ?Address;
|
public function getAddressForGeolocation(): ?Address;
|
||||||
|
|
||||||
public function destroyCoordinate(): void;
|
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) {
|
if (!static::$geolocationEnabled) {
|
||||||
return;
|
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