Example #1
0
boost::shared_ptr<GDALDataset> OgrUtilities::openDataSource(const QString url, bool readonly)
{
  /* Check for the correct driver name, if unknown try all drivers.
   * This can be an issue because drivers are tried in the order that they are
   * loaded which has been known to cause issues.
   */
  OgrDriverInfo driverInfo = getDriverInfo(url, readonly);

  // With GDALOpenEx, we need to specify the GDAL_OF_UPDATE option or the dataset will get opened
  // Read Only.
  if (! readonly)
  {
    driverInfo._driverType = driverInfo._driverType | GDAL_OF_UPDATE;
  }
  LOG_VART(driverInfo._driverName);
  LOG_VART(driverInfo._driverType);
  LOG_VART(url.toUtf8().data());

  const char* drivers[2] = { driverInfo._driverName, NULL };

  // Setup read options for various file types
  OgrOptions options;
  if (QString(driverInfo._driverName) == "CSV")
  {
    options["X_POSSIBLE_NAMES"] = ConfigOptions().getOgrReaderCsvLonfield();
    options["Y_POSSIBLE_NAMES"] = ConfigOptions().getOgrReaderCsvLatfield();
//    options["Z_POSSIBLE_NAMES"] = ConfigOptions().getOgrReaderCsvZfield();
    options["KEEP_GEOM_COLUMNS"] = ConfigOptions().getOgrReaderCsvKeepGeomFields();
  }
  if (QString(driverInfo._driverName) == "OGR_OGDI")
  {
    // From the GDAL docs:
    // From GDAL/OGR 1.8.0, setting the OGR_OGDI_LAUNDER_LAYER_NAMES configuration option
    // (or environment variable) to YES causes the layer names to be simplified.
    // For example : watrcrsl_hydro instead of 'watrcrsl@hydro(*)_line'
    options["OGR_OGDI_LAUNDER_LAYER_NAMES"] = ConfigOptions().getOgrReaderOgdiLaunderLayerNames();
  }

  boost::shared_ptr<GDALDataset> result(static_cast<GDALDataset*>(GDALOpenEx(url.toUtf8().data(),
    driverInfo._driverType, (driverInfo._driverName != NULL ? drivers : NULL), options.getCrypticOptions(), NULL)));

  if (!result)
    throw HootException("Unable to open: " + url);

  return result;
}
Example #2
0
void ShapefileWriter::writePolygons(shared_ptr<const OsmMap> map, const QString& path)
{
  OGRRegisterAll();

  _removeShapefile(path);

  const char *pszDriverName = "ESRI Shapefile";
  OGRSFDriver *poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
  if( poDriver == NULL )
  {
    throw HootException(QString("%1 driver not available.").arg(pszDriverName));
  }

  OGRDataSource* poDS = poDriver->CreateDataSource(path.toAscii(), NULL );
  if( poDS == NULL )
  {
    throw HootException(QString("Data source creation failed. %1").arg(path));
  }

  OgrOptions options;
  options["ENCODING"] = "UTF-8";

  OGRLayer *poLayer;

  QString layerName;
  layerName = QFileInfo(path).baseName();
  poLayer = poDS->CreateLayer(layerName.toAscii(),
                              map->getProjection().get(), wkbMultiPolygon,
                              options.getCrypticOptions());
  if( poLayer == NULL )
  {
    throw HootException(QString("Layer creation failed. %1").arg(path));
  }

  QStringList shpColumns;
  QStringList columns = getColumns(map, ElementType::Unknown);

  for (int i = 0; i < columns.size(); i++)
  {
    OGRFieldDefn oField(columns[i].toAscii(), OFTString);

    oField.SetWidth(64);

    if( poLayer->CreateField( &oField ) != OGRERR_NONE )
    {
      throw HootException(QString("Error creating field (%1).").arg(columns[i]));
    }

    shpColumns.append(poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef());
  }

  if (_includeInfo)
  {
    OGRFieldDefn oField("error_circ", OFTReal);
    if( poLayer->CreateField( &oField ) != OGRERR_NONE )
    {
      throw HootException(QString("Error creating field (error:circular)."));
    }
    _circularErrorIndex = poLayer->GetLayerDefn()->GetFieldCount() - 1;
  }

  const WayMap& ways = map->getWays();
  for (WayMap::const_iterator it = ways.begin(); it != ways.end(); it++)
  {
    shared_ptr<Way> way = it->second;

    if (OsmSchema::getInstance().isArea(way))
    {
      _writeWayPolygon(map, way, poLayer, columns, shpColumns);
    }
  }

  const RelationMap& relations = map->getRelationMap();
  for (RelationMap::const_iterator it = relations.begin(); it != relations.end(); it++)
  {
    shared_ptr<Relation> relation = it->second;

    if (relation->isMultiPolygon())
    {
      _writeRelationPolygon(map, relation, poLayer, columns, shpColumns);
    }
  }

  OGRDataSource::DestroyDataSource(poDS);
}
Example #3
0
void ShapefileWriter::writeLines(shared_ptr<const OsmMap> map, const QString& path)
{
  OGRRegisterAll();

  _removeShapefile(path);

  const char *pszDriverName = "ESRI Shapefile";
  OGRSFDriver *poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
  if( poDriver == NULL )
  {
    throw HootException(QString("%1 driver not available.").arg(pszDriverName));
  }

  OGRDataSource* poDS = poDriver->CreateDataSource(path.toAscii(), NULL );
  if( poDS == NULL )
  {
    throw HootException(QString("Data source creation failed. %1").arg(path));
  }

  OGRLayer *poLayer;

  OgrOptions options;
  options["ENCODING"] = "UTF-8";

  QString layerName;
  layerName = QFileInfo(path).baseName();
  poLayer = poDS->CreateLayer(layerName.toAscii(),
                              map->getProjection().get(), wkbLineString,
                              options.getCrypticOptions());
  if( poLayer == NULL )
  {
    throw HootException(QString("Layer creation failed. %1").arg(path));
  }

  QStringList shpColumns;
  QStringList columns = getColumns(map, ElementType::Way);

  for (int i = 0; i < columns.size(); i++)
  {
    OGRFieldDefn oField(columns[i].toAscii(), OFTString);

    oField.SetWidth(64);

    if( poLayer->CreateField( &oField ) != OGRERR_NONE )
    {
      throw HootException(QString("Error creating field (%1).").arg(columns[i]));
    }

    shpColumns.append(poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef());
  }

  if (_includeInfo)
  {
    OGRFieldDefn oField("error_circ", OFTReal);
    if( poLayer->CreateField( &oField ) != OGRERR_NONE )
    {
      throw HootException(QString("Error creating field (error:circular)."));
    }
    _circularErrorIndex = poLayer->GetLayerDefn()->GetFieldCount() - 1;
  }

  const WayMap& ways = map->getWays();
  for (WayMap::const_iterator it = ways.begin(); it != ways.end(); it++)
  {
    shared_ptr<Way> way = it->second;

    if (OsmSchema::getInstance().isArea(way) == false)
    {
      OGRFeature* poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
      // set all the column values.
      for (int i = 0; i < columns.size(); i++)
      {
        if (way->getTags().contains(columns[i]))
        {
          QByteArray c = shpColumns[i].toAscii();
          QByteArray v = way->getTags()[columns[i]].toUtf8();
          poFeature->SetField(c.constData(), v.constData());
        }
      }

      if (_includeInfo)
      {
        poFeature->SetField(_circularErrorIndex, way->getCircularError());
      }

      // convert the geometry.
      std::string wkt = ElementConverter(map).convertToLineString(way)->toString();
      char* t = (char*)wkt.data();
      OGRGeometry* geom;
      if (OGRGeometryFactory::createFromWkt(&t, poLayer->GetSpatialRef(), &geom) != OGRERR_NONE)
      {
        throw HootException(QString("Error parsing WKT (%1)").arg(QString::fromStdString(wkt)));
      }

      if (poFeature->SetGeometryDirectly(geom) != OGRERR_NONE)
      {
        throw HootException(QString("Error setting geometry"));
      }

      if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
      {
        throw HootException(QString("Error creating feature"));
      }

      OGRFeature::DestroyFeature(poFeature);
    }
  }

  OGRDataSource::DestroyDataSource(poDS);
}
Example #4
0
void ShapefileWriter::writePoints(shared_ptr<const OsmMap> map, const QString& path)
{
  OGRRegisterAll();

  _removeShapefile(path);

  const char *pszDriverName = "ESRI Shapefile";
  OGRSFDriver *poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
  if( poDriver == NULL )
  {
    throw HootException(QString("%1 driver not available.").arg(pszDriverName));
  }

  OGRDataSource* poDS = poDriver->CreateDataSource(path.toAscii(), NULL );
  if( poDS == NULL )
  {
    throw HootException(QString("Data source creation failed. %1").arg(path));
  }

  OgrOptions options;
  options["ENCODING"] = "UTF-8";

  OGRLayer *poLayer;

  QString layerName;
  layerName = QFileInfo(path).baseName();
  poLayer = poDS->CreateLayer(layerName.toAscii(),
                              map->getProjection().get(), wkbPoint, options.getCrypticOptions());
  if( poLayer == NULL )
  {
    throw HootException(QString("Layer creation failed. %1").arg(path));
  }

  QStringList shpColumns;
  QStringList columns = getColumns(map, ElementType::Node);

  for (int i = 0; i < columns.size(); i++)
  {
    OGRFieldDefn oField(columns[i].toAscii(), OFTString);

    oField.SetWidth(64);

    if( poLayer->CreateField( &oField ) != OGRERR_NONE )
    {
      throw HootException(QString("Error creating field (%1).").arg(columns[i]));
    }

    shpColumns.append(poLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef());
  }

  if (_includeInfo)
  {
    OGRFieldDefn oField("error_circ", OFTReal);
    if( poLayer->CreateField( &oField ) != OGRERR_NONE )
    {
      throw HootException(QString("Error creating field (error:circular)."));
    }
    _circularErrorIndex = poLayer->GetLayerDefn()->GetFieldCount() - 1;
  }

  const NodeMap& nodes = map->getNodeMap();
  for (NodeMap::const_iterator it = nodes.begin(); it != nodes.end(); ++it)
  {
    const shared_ptr<Node>& node = it->second;

    if (node->getTags().getNonDebugCount() > 0)
    {
      OGRFeature* poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
      // set all the column values.
      for (int i = 0; i < columns.size(); i++)
      {
        if (node->getTags().contains(columns[i]))
        {
          QByteArray c = shpColumns[i].toAscii();
          QByteArray v = node->getTags()[columns[i]].toUtf8();
          poFeature->SetField(c.constData(), v.constData());
        }
      }

      if (_includeInfo)
      {
        poFeature->SetField(_circularErrorIndex, node->getCircularError());
      }

      // convert the geometry.
      OGRGeometry* geom = new OGRPoint(node->getX(), node->getY());

      if (poFeature->SetGeometryDirectly(geom) != OGRERR_NONE)
      {
        throw HootException(QString("Error setting geometry"));
      }

      if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
      {
        throw HootException(QString("Error creating feature"));
      }

      OGRFeature::DestroyFeature(poFeature);
    }
  }

  OGRDataSource::DestroyDataSource(poDS);
}
Example #5
0
void OgrWriter::_createLayer(shared_ptr<const Layer> layer)
{
  OGRLayer *poLayer;

  OGRwkbGeometryType gtype;
  switch(layer->getGeometryType())
  {
  case GEOS_POINT:
    gtype = wkbPoint;
    break;
  case GEOS_LINESTRING:
    gtype = wkbLineString;
    break;
  case GEOS_POLYGON:
    gtype = wkbPolygon;
    break;
  default:
    throw HootException("Unexpected geometry type.");
  }

  OgrOptions options;
  if (_ds->GetDriver())
  {
    // if this is a CSV file
    if (_ds->GetDriver()->GetName() == QString("CSV"))
    {
      // if we're exporting point data, then export with x/y at the front
      if (gtype == wkbPoint)
      {
        options["GEOMETRY"] = "AS_XY";
      }
      // if we're exporting other geometries then export w/ WKT at the front.
      else
      {
        options["GEOMETRY"] = "AS_WKT";
      }
      options["CREATE_CSVT"] = "YES";
    }

    if (_ds->GetDriver()->GetName() == QString("ESRI Shapefile"))
    {
      options["ENCODING"] = "UTF-8";
    }

    // Add a Feature Dataset to a ESRI File GeoDatabase if requested
    if (_ds->GetDriver()->GetName() == QString("FileGDB"))
    {
      if (layer->getFdName() != "")
      {
        options["FEATURE_DATASET"] = layer->getFdName();
        // speed up bulk inserts.
        options["FGDB_BULK_LOAD"] = "YES";
      }
    }
  }

  QString layerName = _prependLayerName + layer->getName();

  // Check if the layer exists in the output.
  poLayer = _ds->GetLayerByName(layerName.toAscii());

  // We only want to add to a layer IFF the config option "ogr.append.data" set
  if (poLayer != NULL && _appendData)
  {
    // Layer exists
    _layers[layer->getName()] = poLayer;
    // Loop through the fields making sure that they exist in the output. Print a warning if
    // they don't exist
    OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();

    shared_ptr<const FeatureDefinition> fd = layer->getFeatureDefinition();
    for (size_t i = 0; i < fd->getFieldCount(); i++)
    {
      shared_ptr<const FieldDefinition> f = fd->getFieldDefinition(i);

      if (poFDefn->GetFieldIndex(f->getName().toAscii()) == -1)
      {
        //        throw HootException(QString("Error: Unable to find output field: %1 in layer %2.").arg(f->getName()).arg(layerName));
        LOG_WARN("Unable to find field: " << QString(f->getName()) << " in layer " << layerName);
      }
    }
  }
  else
  {
    // Layer does not exist
    poLayer = _ds->CreateLayer(layerName.toAscii(),
                  MapReprojector::createWgs84Projection()->Clone(), gtype, options.getCrypticOptions());

    if( poLayer == NULL )
    {
      throw HootException(QString("Layer creation failed. %1").arg(layerName));
    }
    _layers[layer->getName()] = poLayer;

    shared_ptr<const FeatureDefinition> fd = layer->getFeatureDefinition();
    for (size_t i = 0; i < fd->getFieldCount(); i++)
    {
      shared_ptr<const FieldDefinition> f = fd->getFieldDefinition(i);
      OGRFieldDefn oField(f->getName().toAscii(), toOgrFieldType(f->getType()));
      if (f->getWidth() > 0)
      {
        oField.SetWidth(f->getWidth());
      }

      int errCode = poLayer->CreateField(&oField);
      if (errCode != OGRERR_NONE)
      {
        throw HootException(
          QString("Error creating field (%1)  OGR Error Code: (%2).").arg(f->getName()).arg(QString::number(errCode)));
      }
    }
  } // End layer does not exist
}