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; }
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); }
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); }
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); }
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 }