Вы здесь

Объединение Geofield Yandex Maps с Search API

0

Есть поле geofield, виджет у него Geofield Yandex Maps, с помощью этого же модуля сделан вывод в views, основанном на search_api_solr.

Но в теле views: Добавьте поле Geofield, но нет выбора поля Карта (GeoObject), как в случае views по Нодам.
Пробовал http://dgo.to/project/search_api_location тот же результат.
Что сделать можно?

Забросить Geofield Yandex Maps и вернуться на leaflet?

Версия Drupal: 
7.x
Связанные проекты: 
Geofield Yandex MapsSearch API Solr Search
Вопрос задан 20.07.2016 - 16:16
Аватар пользователя VVS
VVS
31

Ответы

0

модуль не совместим с search_api

Ответ дан 21.07.2016 - 15:39

Остаётся второй вариант? Какова вероятность, что связка leaflet + карты яндекс + serach api заработает?

Комментарий оставлен 29.08.2016 - 19:44
0

Что сделать можно?

Нужно программировать.

Алгоритм:

  1. Создаем свой модуль
  2. Делаем свой плагин для вьюса на основе Geofield Yandex Maps
  3. Переопределяем render() в своем плагине.

MYMODULE.info:

name = MYMODULE Yandex Maps alters
description =
package = Custom
core = 7.x
version = 7.x-1.x

files[] = views/plugins/MYMODULE_map_plugin_style_geofield_ymap.inc
dependencies[] = geofield
dependencies[] = geofield_ymap

MYMODULE.module:

/**
 * Implements hook_views_api().
 */
function MYMODULE_map_views_api() {
  return array('api' => 3);
}

MYMODULE.views.module:

/**
 * Implements hook_views_plugins().
 */
function MYMODULE_map_views_plugins() {
  return array(
    'module' => 'MYMODULE_map',
    'style' => array(
      'MYMODULE_map' => array(
        'title' => t('Yandex Map - MYMODULE'),
        'handler' => 'MYMODULE_map_plugin_style_geofield_ymap',
        'type' => 'normal',
        'uses row plugin' => TRUE,
        'uses fields' => TRUE,
        'uses options' => TRUE,
        'uses grouping' => FALSE,
        'even empty' => TRUE,
      ),
    ),
  );
}

views/plugins/MYMODULE_map_plugin_style_geofield_ymap.inc

class MYMODULE_map_plugin_style_geofield_ymap extends geofield_ymap_plugin_style_geofield_ymap {


   /*
   * Render the display in this style.
   */
  function render() {
    $geofield = '';
    foreach ($this->view->field as $field_name => $field_handler) {
      if (isset($field_handler->real_field) && preg_match('#:geom$#', $field_handler->real_field)) {
        $geofield = $field_name;
        break;
      }
    }
    if (!$geofield) {
      return t('Add geofield to fields list.');
    }

    $this->view->field[$geofield]->options['exclude'] = TRUE;
    $this->render_fields($this->view->result);

    if ($this->view->result) {
      geophp_load();
    }
    elseif ($this->options['map_hide_empty']) {
      return NULL;
    }

    $features = array();

    // Additional object options without tokens.
    $object_options = array();
    if ($this->options['additional_settings']['object_options'] && !$this->options['additional_settings']['object_options_use_tokens']) {
      $object_options = json_decode($this->options['additional_settings']['object_options'], TRUE);
    }

    foreach ($this->view->result as $row_index => $row) {
      $this->view->row_index = $row_index;
      $geofield_value = $this->view->field[$geofield]->get_value($row);
      if (!$geofield_value) {
        continue;
      }

      $baloon_content  = trim($this->row_plugin->render($row));
      $hint_content    = $this->options['hint_content_field']    ? trim($this->get_field($row_index, $this->options['hint_content_field'])) : '';
      $icon_content    = $this->options['icon_content_field']    ? trim($this->get_field($row_index, $this->options['icon_content_field'])) : '';
      $cluster_caption = $this->options['cluster_caption_field'] ? trim($this->get_field($row_index, $this->options['cluster_caption_field'])) : '';
      $preset          = $this->options['preset_field']          ? trim($this->get_field($row_index, $this->options['preset_field'])) : '';

      // Additional object options with tokens.
      if ($this->options['additional_settings']['object_options'] && $this->options['additional_settings']['object_options_use_tokens']) {
        $object_options = $this->safe_tokenize_value($this->options['additional_settings']['object_options'], $row_index);
        $object_options = json_decode($object_options, TRUE);
      }

      $geoms = array();
      // For views_handler_field_field
      if (is_array($geofield_value)) {
        foreach ($geofield_value as $value) {
          $geom = geoPHP::load($value['geom']);
          $geoms = array_merge($geoms, geofield_ymap_split_objects($geom));
        }
      }
      // For views_handler_field
      else {
        $geom = geoPHP::load($geofield_value, 'wkt');
        $geoms = array_merge($geoms, geofield_ymap_split_objects($geom));
      }

      foreach ($geoms as $geom) {
        $feature = array(
          'type' => 'Feature',
          'geometry' => $geom->out('json', TRUE),
        );
        if ($baloon_content) {
          $feature['properties']['balloonContent'] = $baloon_content;
        }
        if ($hint_content) {
          $feature['properties']['hintContent'] = $hint_content;
        }
        if ($icon_content) {
          $feature['properties']['iconContent'] = $icon_content;
          $feature['options']['preset'] = 'islands#blueStretchyIcon';
        }
        if ($cluster_caption) {
          $feature['properties']['clusterCaption'] = $cluster_caption;
        }
        if ($preset) {
          $feature['options']['preset'] = $preset;
        }
        if ($object_options) {
          $feature_options = isset($feature['options']) ? $feature['options'] : array();
          $feature['options'] = $object_options + $feature_options;
        }
        $features[] = $feature;
      }
    }
    unset($this->view->row_index);

    return array(
      '#theme'              => 'geofield_ymap',
      '#map_objects'        => $features ? array('type' => 'FeatureCollection', 'features' => $features) : array(),
      '#map_type'           => $this->options['map_type'],
      '#map_center'         => $this->options['map_center'],
      '#map_zoom'           => $this->options['map_zoom'],
      '#map_auto_centering' => $this->options['map_auto_centering'],
      '#map_auto_zooming'   => $this->options['map_auto_zooming'],
      '#map_clusterize'     => $this->options['map_clusterize'],
      '#map_object_preset'  => $this->options['map_object_preset'],
      '#map_controls'       => $this->options['map_controls'],
      '#map_behaviors'      => $this->options['map_behaviors'],
      '#map_save_state'     => $this->options['map_save_state'],
      '#id'                 => drupal_html_id('geofield-ymap-' . $this->view->name . '-' . $this->view->current_display),
    );
  }

}

Главное тут поменять:

if (isset($field_handler->real_field) && preg_match('#_geom$#', $field_handler->real_field)) {

На:

if (isset($field_handler->real_field) && preg_match('#:geom$#', $field_handler->real_field)) {

И:

$geom = geoPHP::load($geofield_value, 'wkt');

На

$geom = geoPHP::load($geofield_value, 'wkb');
Ответ дан 22.07.2016 - 11:44

Перенёс в модуль.
В индекс добавил поле Карта » Well-known text field_map:geom типа Latitude/Longitude
При переиндексировании ошибка:

SearchApiException while indexing: "400" Status: Bad Request: Bad Request{"responseHeader":{"status":400,"QTime":985},"error":{"msg":"Can't parse point 'POINT (39.719776534393 47.229201006856)' because: java.lang.NumberFormatException: For input string: \"POINT\"","code":400}} in SearchApiSolrConnection->checkResponse() (line 541 of sites/all/modules/search_api_solr/includes/solr_connection.inc).

После изменения типа поля на Строку индексация завершается, но на странице карты ошибка та же: Добавьте поле Geofield.

Комментарий оставлен 29.08.2016 - 19:40