You are here

farm_map_kml.module in farmOS 7

Farm map KML.

File

modules/farm/farm_map/farm_map_kml/farm_map_kml.module
View source
<?php

/**
 * @file
 * Farm map KML.
 */

/**
 * Implements hook_theme().
 */
function farm_map_kml_theme($existing, $type, $theme, $path) {
  return array(
    'farm_map_kml' => array(
      'variables' => array(
        'content' => NULL,
        'placemarks' => array(),
      ),
      'template' => 'farm_map_kml',
      'file' => 'farm_map_kml.theme.inc',
    ),
    'farm_map_kml_placemark' => array(
      'variables' => array(
        'pid' => NULL,
        'name' => NULL,
        'description' => NULL,
        'geometry' => NULL,
        'kml' => NULL,
      ),
      'template' => 'farm_map_kml_placemark',
      'file' => 'farm_map_kml.theme.inc',
    ),
  );
}

/**
 * Implements hook_action_info().
 */
function farm_map_kml_action_info() {
  return array(
    'farm_map_kml_action' => array(
      'type' => 'entity',
      'label' => t('KML'),
      'triggers' => array(
        'any',
      ),
      'configurable' => FALSE,
      'aggregate' => TRUE,
    ),
  );
}

/**
 * Action function for farm_map_kml_action.
 *
 * Creates a KML file containing shapes from selected entities.
 *
 * @param array $entities
 *   An array of entities.
 * @param array $context
 *   Array with parameters for this action.
 */
function farm_map_kml_action(array $entities, $context = array()) {

  // Iterate through the entities to generate placemarks.
  $placemarks = array();
  foreach ($entities as $entity) {

    // Ask modules to extract geometries from this entity.
    $geometries = farm_map_entity_geometries($context['entity_type'], $entity);

    // Get the entity id and label.
    list($id, $rid, $bundle) = entity_extract_ids($context['entity_type'], $entity);
    $label = entity_label($context['entity_type'], $entity);

    // Create a placemark for each geometry.
    foreach ($geometries as $key => $geometry) {

      // Create a placemark.
      $placemark = array(
        'pid' => $id,
        // We use htmlspecialchars() so that apostrophes are not escaped.
        'name' => htmlspecialchars($label),
        'geometry' => $geometry,
      );

      // If a non-numeric key is set, tag the ID and label with it.
      if (!is_numeric($key)) {
        $placemark['pid'] .= '-' . check_plain($key);
        $placemark['name'] .= ' (' . check_plain($key) . ')';
      }

      // If this is an area entity (taxonomy_term), add the description.
      if ($context['entity_type'] == 'taxonomy_term' && $entity->vocabulary_machine_name == 'farm_areas') {
        if (!empty($entity->description)) {
          $placemark['description'] = check_plain($entity->description);
        }
      }

      // Add the placemark to the list.
      $placemarks[] = $placemark;
    }
  }

  // If there are no placemarks, bail with a warning.
  if (empty($placemarks)) {
    drupal_set_message(t('No placemarks were found.'), 'warning');
    return;
  }

  // Create KML output.
  $kml = theme('farm_map_kml', array(
    'placemarks' => $placemarks,
  ));

  // Ensure that a directory exists to store the KML file in.
  $scheme = variable_get('file_default_scheme', 'public');
  $directory = $scheme . '://kml';
  file_prepare_directory($directory, FILE_CREATE_DIRECTORY);

  // Create the temporary KML file.
  $filename = 'kml_export-' . date('c') . '.kml';
  $destination = $directory . '/' . $filename;
  $file = file_save_data($kml, $destination);

  // Make the file temporary.
  $file->status = 0;
  file_save($file);

  // Show a link to the file.
  $message = 'KML file created: <a href="!path">%filename</a>';
  $args = array(
    '!path' => file_create_url($file->uri),
    '%filename' => $file->filename,
  );
  drupal_set_message(t($message, $args));
}

/**
 * Helper function for converting KML to a set of geometries.
 *
 * @param string $kml
 *   The KML string to parse.
 *
 * @return array
 *   Returns an array of geometries, with name, description, and WKT for each.
 */
function farm_map_kml_parse_geometries($kml) {

  // Start an array to hold the geometries.
  $geometries = array();

  // Load the GeoPHP library.
  geophp_load();

  // Parse the KML into an XML object.
  $xml = simplexml_load_string($kml);

  // Determine the root element. Sometimes it is "Document".
  $root = $xml;
  if (isset($xml->Document)) {
    $root = $xml->Document;
  }

  // If the KML file is organized into folders, iterate through them.
  if (isset($root->Folder)) {
    $folders = $folders = $root->Folder;
    foreach ($folders as $folder) {

      // Iterate through the KML Placemarks and parse their geometry info.
      $placemarks = $folder->Placemark;
      foreach ($placemarks as $placemark) {
        $geometries[] = farm_map_kml_parse_placemark($placemark);
      }
    }
  }
  else {
    $placemarks = $root->Placemark;
    foreach ($placemarks as $placemark) {
      $geometries[] = farm_map_kml_parse_placemark($placemark);
    }
  }

  // Return the geometries.
  return $geometries;
}

/**
 * Helper function for extracting information about a KML placemark.
 *
 * @param $placemark
 *   A SimpleXML Placemark object.
 *
 * @return array
 *   Returns information about the placemark, including name, description, and
 *   geometry in Well-Known Text (WKT).
 */
function farm_map_kml_parse_placemark($placemark) {

  // Start a new array for the geometry info.
  $geometry = array();

  // Get the placemark name as a string.
  $geometry['name'] = (string) $placemark->name;

  // Get the placemark description as a string.
  $geometry['description'] = (string) $placemark->description;

  // Parse the placemark into a GeoPHP geometry object.
  $placemark_xml = $placemark
    ->asXML();
  $geophp_geometry = geoPHP::load($placemark_xml, 'kml');

  // Convert the geometry to WKT.
  $geometry['wkt'] = $geophp_geometry
    ->out('wkt');

  // Return the geometry.
  return $geometry;
}

Functions

Namesort descending Description
farm_map_kml_action Action function for farm_map_kml_action.
farm_map_kml_action_info Implements hook_action_info().
farm_map_kml_parse_geometries Helper function for converting KML to a set of geometries.
farm_map_kml_parse_placemark Helper function for extracting information about a KML placemark.
farm_map_kml_theme Implements hook_theme().