我在很多资料中都读过,在尝试以编程方式保存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);
答案 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.php和GeofieldItemTest.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更安全,特别是对于更复杂的数据类型。