librenms-librenms/app/ApiClients/GeocodingHelper.php
Tony Murray 3e35ee0e7d Refactored and update Location Geocoding (#9359)
- Fix location so it is a regular database relation (this allows multiple devices to be accurately linked to one location and saves api calls)
- Parse coordinates from the location more consistently
- Add settings to webui
- ~~Used [PHP Geocoder](http://geocoder-php.org/), which has lots of backends and is well tested. (also includes reverse and geoip)~~
- Google Maps, Bing, Mapquest, and OpenStreetMap supported initially.
- Default to OpenStreetMap, which doesn't require a key.  They will liberally hand out bans if you exceed 1 query per second though.
- All other Geocoding APIs require an API key. (Google requires a credit card on file, but seems to be the most accurate)
- Update all (I think) sql queries to handle the new structure
- Remove final vestiges of override_sysLocation as a device attribute
- Update existing device groups and rules in DB
- Tested all APIs with good/bad location, no/bad/good key, and no connection.
- Cannot fix advanced queries that use location

This blocks #8868

DO NOT DELETE THIS TEXT

#### Please note

> Please read this information carefully. You can run `./scripts/pre-commit.php` to check your code before submitting.

- [x] Have you followed our [code guidelines?](http://docs.librenms.org/Developing/Code-Guidelines/)

#### Testers

If you would like to test this pull request then please run: `./scripts/github-apply <pr_id>`, i.e `./scripts/github-apply 5926`
After you are done testing, you can remove the changes with `./scripts/github-remove`.  If there are schema changes, you can ask on discord how to revert.
2018-11-28 22:49:18 +00:00

100 lines
2.7 KiB
PHP

<?php
/**
* GeocodingHelper.php *
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\ApiClients;
use Exception;
use LibreNMS\Config;
use Log;
trait GeocodingHelper
{
/**
* From BaseApi...
*
* @return \GuzzleHttp\Client
*/
abstract protected function getClient();
/**
* Try to get the coordinates of a given address.
* If unsuccessful, the returned array will be empty
*
* @param string $address
* @return array ['lat' => 0, 'lng' => 0]
*/
public function getCoordinates($address)
{
if (!Config::get('geoloc.latlng', true)) {
Log::debug('Geocoding disabled');
return [];
}
try {
$options = $this->buildGeocodingOptions($address);
$response = $this->getClient()->get($this->geocoding_uri, $options);
$response_data = json_decode($response->getBody(), true);
if ($this->checkResponse($response, $response_data)) {
return $this->parseLatLng($response_data);
} else {
Log::error("Geocoding failed.", ['response' => $response_data]);
}
} catch (Exception $e) {
Log::error("Geocoding failed: " . $e->getMessage());
}
return [];
}
/**
* Checks if the request was a success
*
* @param \Psr\Http\Message\ResponseInterface $response
* @param array $data decoded response data
* @return bool
*/
protected function checkResponse($response, $data)
{
return $response->getStatusCode() == 200;
}
/**
* Get latitude and longitude from geocode response
*
* @param array $data
* @return array
*/
abstract protected function parseLatLng($data);
/**
* Build Guzzle request option array
*
* @param string $address
* @return array
* @throws \Exception you may throw an Exception if validation fails
*/
abstract protected function buildGeocodingOptions($address);
}