在 Drupal 8 中以编程方式保存地理域
Save geofield programmatically in Drupal 8
我已经阅读了很多资源,我在尝试以编程方式在 Drupal 中保存坐标时应该使用 geofield_compute_values()
函数。
但是它对我不起作用,我正在使用的 Drupal 8.5.2 中未定义该函数。
我已经使用 composer 安装了 geofield,我可以在管理区像往常一样使用它,在那里保存没有问题。
这是我试过的一些例子,第一个例子给了我 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);
您似乎在尝试使用 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 and GeofieldItemTest.php 文件可能是了解如何在您的实施中使用该服务的良好开端。
此功能在 Drupal 8 中不可用。您必须依赖扩展 FieldItemBase
的基本 GeofieldItem
class。另外,正如阿曼所提到的,您可以使用 WktGenerator
轻松构建点、多边形等。
这是一个工作示例。假设您有一个实体 $cbisProduct
和一个多值地理字段 field_koordinater
,并且您想要使用任意 lat/lon 坐标设置第一个项目:
// 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 更安全,尤其是对于更复杂的数据类型。
我已经阅读了很多资源,我在尝试以编程方式在 Drupal 中保存坐标时应该使用 geofield_compute_values()
函数。
但是它对我不起作用,我正在使用的 Drupal 8.5.2 中未定义该函数。
我已经使用 composer 安装了 geofield,我可以在管理区像往常一样使用它,在那里保存没有问题。
这是我试过的一些例子,第一个例子给了我 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);
您似乎在尝试使用 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 and GeofieldItemTest.php 文件可能是了解如何在您的实施中使用该服务的良好开端。
此功能在 Drupal 8 中不可用。您必须依赖扩展 FieldItemBase
的基本 GeofieldItem
class。另外,正如阿曼所提到的,您可以使用 WktGenerator
轻松构建点、多边形等。
这是一个工作示例。假设您有一个实体 $cbisProduct
和一个多值地理字段 field_koordinater
,并且您想要使用任意 lat/lon 坐标设置第一个项目:
// 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 更安全,尤其是对于更复杂的数据类型。