Сохранить геополе программно в Drupal 8 - PullRequest
0 голосов
/ 27 апреля 2018

Я читал во многих источниках, что я должен использовать функцию geofield_compute_values() при попытке программно сохранить координаты в Drupal.

Однако у меня это не работает, эта функция не определена в Drupal 8.5.2, который я использую.

Я установил геополе с помощью composer, и я могу использовать его как обычно в административной области, и там нет проблем с сохранением.

Вот несколько примеров, с которыми я пробовал, первый пример дает мне undefined function geofield_compute_values():

$geofield_data = geofield_compute_values([
    'lat' => $lat,
    'lon' => $lon,
], GEOFIELD_INPUT_LAT_LON);

$cbisProduct->set('field_koordinater', $geofield_data);

Я также попробовал это без успешного результата и без ошибок:

$geofield = [
    'geom' => "POINT (" . $lon . " " . $lat . ")",
    'geo_type' => 'point',
    'lat' => $lat,
    'lon' => $lon,
    'left' => $lon,
    'top' => $lat,
    'right' => $lon,
    'bottom' => $lat,
];

$cbisProduct->set('field_koordinater', $geofield);

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Эта функция недоступна в Drupal 8. Вы должны полагаться на базовый класс GeofieldItem, который расширяет FieldItemBase. Также, как упомянул Оман, вы можете использовать WktGenerator для простого построения точек, полигонов и т. Д.

Вот рабочий пример. Допустим, у вас есть объект $cbisProduct с многозначным геополем field_koordinater, и вы хотите установить первый элемент с произвольными координатами широты / долготы:

// Get geofield item
$geofield = $cbisProduct->get('field_koordinater')->get(0);

// Generate a point [lat, lon]
$coord = ['45.909621', '6.127147'];
$point = \Drupal::service('geofield.wkt_generator')->WktBuildPoint($coord);

// Calling this function will compute values AND assign geodata to the field instance
$geofield->setValue($point);

// You can read the computed geodata from the field
$geodata = $geofield->getValue();
//dpm($geodata);

// Explicitly set field data (needed if $geofield is not a reference)
$cbisProduct->set('field_koordinater', [$geodata]);

// Save entity
$cbisProduct->save();

Под капотом GeofieldItem::setValue вызывает другой метод, ответственный за непосредственное присвоение вычисленных значений экземпляру поля:

# \Drupal\geofield\Plugin\Field\FieldType\GeofieldItem
protected function populateComputedValues() {
  /* @var \Geometry $geom */
  $geom = \Drupal::service('geofield.geophp')->load($this->value);

  if (!empty($geom)) {
    /* @var \Point $centroid */
    $centroid = $geom->getCentroid();
    $bounding = $geom->getBBox();

    $this->geo_type = $geom->geometryType();
    $this->lon = $centroid->getX();
    $this->lat = $centroid->getY();
    $this->left = $bounding['minx'];
    $this->top = $bounding['maxy'];
    $this->right = $bounding['maxx'];
    $this->bottom = $bounding['miny'];
    $this->geohash = substr($geom->out('geohash'), 0, GEOFIELD_GEOHASH_LENGTH);
    $this->latlon = $centroid->getY() . ',' . $centroid->getX();
  }
}

Примечание: вам не обязательно нужен WktGenerator для построения точек, если вы знаете тип геополя и то, как geophp должен его обрабатывать. Например, следующие 2 утверждения эквивалентны:

$point = \Drupal::service('geofield.wkt_generator')->WktBuildPoint($coord);
// is equivalent to 
$point = GEOFIELD_TYPE_POINT . '(' . implode(' ', $coord) . ')');

Но более безопасно полагаться на WktGenerator, особенно с более сложными типами данных.

0 голосов
/ 01 мая 2018

Похоже, вы пытаетесь использовать функцию geofield_compute_values ​​() , которая была доступна в версии 7.x, но не в версии 8.x

Вам стоит заглянуть в сервис wkt_generator. т.е.

<?php $wktGenerator = \Drupal::service('geofield.wkt_generator'); ?>

Я не пробовал это, но что-то вроде этого должно работать:

<?php

$point = [
  'lat' => $request->get('lat'), 
  'lon' => $request->get('lon'),
];
$value = \Drupal::service('geofield.wkt_generator')->WktBuildPoint($point);

$node->field_koordinater->setValue($value);

Кроме того, файлы WktGeneratorTest.php и GeofieldItemTest.php могут быть хорошим началом, чтобы узнать, как использовать службу в вашей реализации.

...