geo_shp2sql

geo/includes/shp2sql.inc, line 13

Versions
6
geo_shp2sql($filename, $table_name = '', $create_table = TRUE, $srid = GEO_SRID_DEFAULT)

Code

<?php
function geo_shp2sql($filename, $table_name = '', $create_table = TRUE, $srid = GEO_SRID_DEFAULT) {
  if (!$table_name) {
    $parts = pathinfo($filename);
    $table_name = $parts['filename'];
  }
  $table_name = preg_replace('/[^a-z0-9_]/', '', strtolower($table_name));

  if (!is_readable($filename) || (!is_resource($zip = zip_open($filename)))) {
    drupal_set_message(t('zip file nonexistant or unreadable.'), 'error');
    return FALSE;
  }

  // Catalog the contents of the zip file.
  $files = array();
  while ($res = zip_read($zip)) {
    $ext = strtolower(substr(strrchr(zip_entry_name($res), '.'), 1));
    $files[$ext] = $res;
  }

  // The zip file must minimally contain a shp, dbf and shx file.
  if (!isset($files['shp']) || !isset($files['dbf']) || !isset($files['shx'])) {
    drupal_set_message(t('This does not appear to be an archive that contains valid shp data.'), 'error');
    return FALSE;
  }

  // See if we can get the projection information from the prj file.
  if (isset($files['prj'])) {
    // TODO Parse srid from prj file, for conversion if necessary.
  }

  if (isset($files['dbt'])) {
    drupal_set_message(t('This database contains longtext/memo fields, which are unsupported.  Proceeding to enter other data anyway.'), 'warning');
  }

  // Get headers and table definition from the dbf file.
  $schema = array('description' => t('Geo data table'), 'fields' => array());
  $headers = _dbf_headers($files['dbf'], $schema);

  // Shape file headers are stored in the first 100 bytes of the shp/shx files.
  $headers += _shp_headers(zip_entry_read($files['shp'], 100));

  // Create a new table based on the data we've obtained thus far.
  if ($create_table) {
    $ret = array();
    if (db_table_exists($table_name)) {
      db_drop_table($ret, $table_name);
    }
    db_create_table($ret, $table_name, $schema);
  }

  // Add the geo column that will contain shape data.
  $spec = array(
    'type' => strtolower($headers['geo_type']),
    'not null' => TRUE,
    'description' => t('Geometry field'),
    'srid' => $srid,
  );
  geo('add_field', $ret, $table_name, 'geo', $spec);
  $fields = join(', ', array_keys($headers['field_lengths'])) .', geo';

  $row_count = 0;
  while ($shp = _shp_get_record($files['shp'])) {
    $values = array();
    $dbf_data = zip_entry_read($files['dbf'], $headers['record_size']);
    $dbf_data = substr($dbf_data, 1); // Remove "record deleted" flag.
    foreach($headers['field_lengths'] as $name => $length) {
      $value = substr($dbf_data, 0, $length);
      $dbf_data = substr($dbf_data, $length);

      // Use a predefined function to filter and process each value.
      $process = $headers['field_filters'][$name];
      $values[] = $process($value);
    }

    // Add the geometry text.
    $values[] = "GeomFromText('". $shp['data']['wkt'] ."', $srid)";

    // We've already handled sanitization of table_name, column names and 
    // values, so we're going to skip the substitutions.
    db_query("INSERT INTO {$table_name} ( $fields )
      VALUES (". join(', ', $values) .")");

    $row_count++;
  }

  drupal_set_message(t('Import complete. @count rows imported into @table', array('@count' => $row_count, '@table' => $table_name)));
}
?>