【问题标题】:Save geofield programmatically in Drupal 8在 Drupal 8 中以编程方式保存 geofield
【发布时间】:2018-04-27 08:13:10
【问题描述】:

我已经阅读了很多资料,当我尝试以编程方式在 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);

【问题讨论】:

    标签: drupal coordinates geospatial drupal-8


    【解决方案1】:

    似乎您正在尝试使用 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 文件可能是了解如何在您的实施中使用该服务的良好开端。

    【讨论】:

      【解决方案2】:

      此功能在 Drupal 8 中不可用。您必须依赖扩展 FieldItemBase 的基本 GeofieldItem 类。另外,正如阿曼所说,您可以使用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 应该如何处理它。例如,以下两条语句是等价的:

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

      但是依赖 WktGenerator 更安全,尤其是对于更复杂的数据类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-19
        • 2017-09-28
        • 2016-03-19
        • 2014-08-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多