View source
<?php
namespace Drupal\geolocation\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\MapDataDefinition;
class GeolocationItem extends FieldItemBase {
public static function schema(FieldStorageDefinitionInterface $field_definition) {
return [
'columns' => [
'lat' => [
'description' => 'Stores the latitude value',
'type' => 'float',
'size' => 'big',
'not null' => TRUE,
],
'lng' => [
'description' => 'Stores the longitude value',
'type' => 'float',
'size' => 'big',
'not null' => TRUE,
],
'lat_sin' => [
'description' => 'Stores the sine of latitude',
'type' => 'float',
'size' => 'big',
'not null' => TRUE,
],
'lat_cos' => [
'description' => 'Stores the cosine of latitude',
'type' => 'float',
'size' => 'big',
'not null' => TRUE,
],
'lng_rad' => [
'description' => 'Stores the radian longitude',
'type' => 'float',
'size' => 'big',
'not null' => TRUE,
],
'data' => [
'description' => 'Serialized array of geolocation meta information.',
'type' => 'blob',
'size' => 'big',
'not null' => FALSE,
'serialize' => TRUE,
],
],
'indexes' => [
'lat' => [
'lat',
],
'lng' => [
'lng',
],
],
];
}
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties['lat'] = DataDefinition::create('float')
->setLabel(t('Latitude'));
$properties['lng'] = DataDefinition::create('float')
->setLabel(t('Longitude'));
$properties['lat_sin'] = DataDefinition::create('float')
->setLabel(t('Latitude sine'))
->setComputed(TRUE);
$properties['lat_cos'] = DataDefinition::create('float')
->setLabel(t('Latitude cosine'))
->setComputed(TRUE);
$properties['lng_rad'] = DataDefinition::create('float')
->setLabel(t('Longitude radian'))
->setComputed(TRUE);
$properties['data'] = MapDataDefinition::create()
->setLabel(t('Meta data'));
return $properties;
}
public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
$values['lat'] = rand(-90, 90) - rand(0, 999999) / 1000000;
$values['lng'] = rand(-180, 180) - rand(0, 999999) / 1000000;
return $values;
}
public function isEmpty() {
$lat = $this
->get('lat')
->getValue();
$lng = $this
->get('lng')
->getValue();
return $lat === NULL || $lat === '' || $lng === NULL || $lng === '';
}
public function setValue($values, $notify = TRUE) {
parent::setValue($values, $notify);
if ((empty($values['lat_sin']) || empty($values['lat_cos']) || empty($values['lat_rad'])) && !$this
->isEmpty()) {
$this
->get('lat_sin')
->setValue(sin(deg2rad(trim($this
->get('lat')
->getValue()))), FALSE);
$this
->get('lat_cos')
->setValue(cos(deg2rad(trim($this
->get('lat')
->getValue()))), FALSE);
$this
->get('lng_rad')
->setValue(deg2rad(trim($this
->get('lng')
->getValue())), FALSE);
}
}
public function getValue() {
foreach ($this->properties as $name => $property) {
$value = $property
->getValue();
if (isset($this->values) || isset($value)) {
$this->values[$name] = $value;
}
}
if (array_key_exists('data', $this->values) && empty($this->values['data'])) {
unset($this->values['data']);
}
return $this->values;
}
public function onChange($property_name, $notify = TRUE) {
parent::onChange($property_name, $notify);
if ($property_name == 'lat' || $property_name == 'lng') {
$this
->get('lat_sin')
->setValue(sin(deg2rad(trim($this
->get('lat')
->getValue()))), FALSE);
$this
->get('lat_cos')
->setValue(cos(deg2rad(trim($this
->get('lat')
->getValue()))), FALSE);
$this
->get('lng_rad')
->setValue(deg2rad(trim($this
->get('lng')
->getValue())), FALSE);
}
}
public function preSave() {
$this
->get('lat')
->setValue(trim($this
->get('lat')
->getValue()));
$this
->get('lng')
->setValue(trim($this
->get('lng')
->getValue()));
}
}