以编程方式在Drupal 8中保存geofield

时间:2018-04-27 08:13:11

标签: drupal coordinates drupal-8

我在很多资料中都读过,在尝试以编程方式保存Drupal中的坐标时,我应该使用geofield_compute_values()函数。

然而它对我不起作用,在我正在使用的Drupal 8.5.2中该函数未定义。

我已经使用composer安装了geofield,我可以像往常一样在管理区域使用它,并且保存没有问题。

以下是我尝试过的一些示例,第一个示例为我提供了未定义的函数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 :(得分:3)

好像你正在尝试使用7.x版本中提供的geofield_compute_values()函数,而不是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.phpGeofieldItemTest.php文件可以帮助您了解如何在实施中使用该服务。

答案 1 :(得分:2)

Drupal 8中没有此功能。您必须依赖扩展GeofieldItem的基本FieldItemBase类。此外,正如oman所提到的,您可以使用WktGenerator轻松构建点,多边形等。

这是一个有效的例子。假设您有一个实体$cbisProduct,其中包含多值geofield 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();
  }
}

注意:只要您知道地理位置类型以及geophp应如何处理它,您就不一定需要WktGenerator来构建点。例如,以下2个语句是等效的:

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

但是依靠WktGenerator更安全,特别是对于更复杂的数据类型。