Programowo aktualizuj dane Geofield

9

Moja konfiguracja to:

  1. Pole adresowe w węzłach do zbierania danych adresowych
  2. Geofield przy użyciu „Geokodu z innego pola”, wybierając pole adresu i Google Geocoder

Kiedy edytuję / zapisuję węzeł w interfejsie użytkownika, dane są geokodowane. Mam jednak tysiące węzłów i próbuję napisać skrypt aktualizujący informacje o geokodach na każdym węźle.

Próbowałem załadować wszystkie węzły i wykonać node_save (), ale haki do geokodów nie zadziałały.

Jak mogę programowo zaktualizować informacje o polu geofield? Czy mogę użyć haka?

Funkcja
źródło

Odpowiedzi:

4

Według README.TXT:

UWAGI API

Pola Geofield zawierają dziewięć kolumn informacji o przechowywanych danych geograficznych>. Jego sercem jest kolumna „wkt”, w której zapisano pełną geometrię w formacie „dobrze znanego tekstu” (WKT). Wszystkie pozostałe kolumny są metadanymi pochodzącymi z kolumny WKT. Kolumny są następujące:

„geom” Surowa wartość. Domyślnie przechowywane jako WKB, ładowane jako WKT
„typ geo” Typ geometrii (punkt, linia, wielokąt itp.)
„Lat” Centroid (szerokość geograficzna lub Y)
„lon” centroid (długość geograficzna lub X)
„góra” Obwiednia górna ( Szerokość lub Max Y) 'dolny' Obwiednia Dół (szerokość lub Min Y)
'left' Obwiednia lewo (długość lub MIN X)
'prawo' Obwiednia Right (długość lub Max X)
'geohash' Geohash odpowiednik wartości kolumny geom

Gdy pole geologiczne jest zapisywane przy użyciu dostarczonych widżetów, wartości te są przekazywane przez funkcję geofield_compute_values ​​w celu obliczenia wartości zależnych. Domyślnie wartości zależne są obliczane na podstawie WKT, ale można to zmienić, aby obliczyć wartości na podstawie innych kolumn. Na przykład wartości geofield_compute_values ​​można nazwać tak:

geofield_compute_values ​​($ wartości, „latlon”);

Spowoduje to obliczenie pola wkt (i wszystkich innych pól) na podstawie kolumn lat / lon, w wyniku czego powstanie punkt. Jako programista należy pamiętać, jeśli modyfikujesz informacje o polu geolokalizacyjnym za pomocą node_load i node_save. Upewnij się, aby uruchomić zmodyfikowane instancje geofield poprzez geofield_compute_values, aby wszystkie kolumny były spójne.

Przekłada się to na:

      $spot->field_coordinates[LANGUAGE_NONE][0] = geofield_compute_values(
          array(
              'lat' => $venue->location->lat, 
              'lon' => $venue->location->lng,
      ), GEOFIELD_INPUT_LAT_LON);
duru
źródło
2

Korzystając z takich wartości, byłem w stanie programowo aktualizować dane pola geofield :

PHP

$lat = 42.281646;
$lon = -83.744222;
$geofield = array(
  'geom' => "POINT ($lon $lat)",
  'geo_type' => 'point',
  'lat' => $lat . "000000",
  'lon' => $lon . "000000",
  'left' => $lon . "000000",
  'top' => $lat . "000000",
  'right' => $lon . "000000",
  'bottom' => $lat . "000000"
);
$lang = $node->language;
$node->field_position[$lang][0] = $geofield;

JSON dla modułu usług

{
  "nid":123,
  "field_position":{"und":[
    {"geom":{"lat":"42.2808256","lon":"-83.7430378"}}
  ]}
}

W obu przypadkach widżet dla pola geologicznego jest Latitude / Longitude, więc wyniki mogą się różnić dla innych widżetów, szczególnie w przypadku modułu Usługi .

tyler.frankenstein
źródło
Czy to aktualizuje geohash?
beroe
Nie wiem, co masz na myśli geohash, proszę, dziękuję.
tyler.frankenstein
Cześć. Przepraszam za tajemniczy komentarz. Drupal node__field_geo_fieldma geohashjako ostatnie pole (patrz API w odpowiedzi powyżej). To jest ascii reprezentacja regionu geograficznego . Nie wiem, czy są obowiązkowe czy opcjonalne, ale zamierzałem stworzyć program w języku Python, aby je wygenerować i wstawić (wraz z lat / long) do bazy danych drupal zaplecza.
beroe
Dziękuję za potwierdzenie. Ja sam nie znam geohashwartości, ale być może możesz użyć geofield_compute_valuesfunkcji wymienionej w powyższej odpowiedzi, aby uzyskać tę wartość z lat / lng.
tyler.frankenstein
1

Dzikie przypuszczenie: możesz poprowadzić swój węzeł przez node-edit-formproces, aby wystrzelić magię geofield.

Spójrz na drupal_form_submit () , zwróć uwagę na $form_state['values']zwykłe, ręczne przesyłanie formularza „dodaj treść” swojego typu węzła i przebuduj go programowo, aby wysłać go w drupal_form_submit()funkcji.

Zastanawiam się, czy to zadziała ...

Z drugiej strony możesz po prostu sprawdzić strukturę wartości swojego pola geologicznego i odbudować ją, programowo wykorzystując geocoder()funkcję interfejsu API modułu geokodera .

gue
źródło
0

Możesz użyć metody opisanej w https://www.drupal.org/node/905814#comment-4931016 .

  1. Zrób kopię zapasową bazy danych

  2. Wyświetl swoje treści. Dodaj filtr, aby wybrać treść, w której szerokość geograficzna pola geologicznego jest pusta.

  3. Dodaj moduł Views Bulk Operations, dodaj pole operacji zbiorczych i wybierz jako akcję „wykonaj dowolne php”.

    $test = node_load($entity->nid);    
    module_load_include('inc', 'node', 'node.pages');    
    $test_state['values']['op'] = t('Save');    
    drupal_form_submit('NODENAME_node_form', $test_state, $test);

Podejście to działa doskonale, z wyjątkiem tego, że pola daty korzystające z wyskakującego okienka daty stają się puste, więc należy zachować ostrożność, jeśli istnieją pola daty.

Zauważ również, że geokoder Google ma 24-godzinny limit 2500 adresów do geokodu.

Hans Rossel
źródło