Exemple #1
0
    void object::test<6>()
    {
        // Create feature without geometry
        std::string tmp(data_tmp_);
        tmp += SEP;
        tmp += "tpoly.shp";
        OGRDataSourceH ds = OGR_Dr_Open(drv_, tmp.c_str(), true);
        ensure("Can't open layer", NULL != ds);

        OGRLayerH lyr = OGR_DS_GetLayer(ds, 0);
        ensure("Can't get layer", NULL != lyr);

        OGRFeatureDefnH featDefn = OGR_L_GetLayerDefn(lyr);
        ensure("Layer schema is NULL", NULL != featDefn);

        OGRFeatureH featNonSpatial = OGR_F_Create(featDefn);
        ensure("Can't create non-spatial feature", NULL != featNonSpatial);

        int fldIndex = OGR_FD_GetFieldIndex(featDefn, "PRFEDEA");
        ensure("Can't find field 'PRFEDEA'", fldIndex >= 0);

        OGR_F_SetFieldString(featNonSpatial, fldIndex, "nulled");
       
        OGRErr err = OGR_L_CreateFeature(lyr, featNonSpatial);
        ensure_equals("Can't write non-spatial feature to layer", OGRERR_NONE, err);

        OGR_F_Destroy(featNonSpatial);
        OGR_DS_Destroy(ds);
    }
Exemple #2
0
void OGR::writeDensity(hexer::HexGrid *grid)
{
    int counter(0);
    for (hexer::HexIter iter = grid->hexBegin(); iter != grid->hexEnd(); ++iter)
    {

        hexer::HexInfo hi = *iter;
        OGRGeometryH polygon = collectHexagon(hi, grid);
        OGRFeatureH hFeature;

        hFeature = OGR_F_Create(OGR_L_GetLayerDefn(m_layer));
        OGR_F_SetFieldInteger( hFeature, OGR_F_GetFieldIndex(hFeature, "ID"),
            counter);
        OGR_F_SetFieldInteger( hFeature, OGR_F_GetFieldIndex(hFeature, "COUNT"),
            hi.m_density);

        OGR_F_SetGeometry(hFeature, polygon);
        OGR_G_DestroyGeometry(polygon);

        if( OGR_L_CreateFeature( m_layer, hFeature ) != OGRERR_NONE )
        {
            std::ostringstream oss;
            oss << "Unable to create feature for multipolygon with error '"
                << CPLGetLastErrorMsg() << "'";
            throw pdal::pdal_error(oss.str());
        }
        OGR_F_Destroy( hFeature );
        counter++;
    }
}
Exemple #3
0
/* OGRFeatureDefnH OGR_L_GetLayerDefn(OGRLayerH hLayer)

{ok, DataSource} = lgeo_ogr:open("test/polygon.shp"),
{ok, Layer} = lgeo_ogr:ds_get_layer(DataSource, 0),
{ok, FeatureDefn} = lgeo_ogr:l_get_layer_defn(Layer).

*/
static ERL_NIF_TERM
l_get_layer_defn(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    EnvLayer_t **layer;
    ERL_NIF_TERM eterm;

    if (argc != 1) {
        return enif_make_badarg(env);
    }

    if(!enif_get_resource(env, argv[0], OGR_L_RESOURCE, (void**)&layer)) {
        return enif_make_badarg(env);
    }

    OGRFeatureDefnH feat_defn = OGR_L_GetLayerDefn((**layer).obj);

    EnvFeatureDefn_t **feature_defn = \
        enif_alloc_resource(OGR_FD_RESOURCE, sizeof(EnvFeatureDefn_t*));

    ErlNifEnv *feature_defn_env = enif_alloc_env();

    *feature_defn = (EnvFeatureDefn_t*) enif_alloc(sizeof(EnvFeatureDefn_t));
    (**feature_defn).env = feature_defn_env;
    (**feature_defn).obj = feat_defn;

    // Save copy of layer so is not garbage collected
    enif_make_copy(feature_defn_env, argv[0]);

    eterm = enif_make_resource(env, feature_defn);
    enif_release_resource(feature_defn);
    return enif_make_tuple2(env, enif_make_atom(env, "ok"), eterm);
}
Exemple #4
0
void GDALWPrintRecords(GDALWConnection conn) {
	char * wkt;
	int i;
	OGRFeatureH feature;
	OGRGeometryH geometry;
	OGRFeatureDefnH featureDefn;
	featureDefn = OGR_L_GetLayerDefn(conn.layer);
	OGR_L_ResetReading(conn.layer);
	while( (feature = OGR_L_GetNextFeature(conn.layer)) != NULL ) {
		for(i = 0; i < OGR_FD_GetFieldCount(featureDefn); i++ ) {
			OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( featureDefn, i );
		    if( OGR_Fld_GetType(hFieldDefn) == OFTInteger )
		    	printf( "%d,", OGR_F_GetFieldAsInteger( feature, i ) );
		    else if( OGR_Fld_GetType(hFieldDefn) == OFTReal )
		        printf( "%.3f,", OGR_F_GetFieldAsDouble( feature, i) );
		    else
		    	printf( "%s,", OGR_F_GetFieldAsString( feature, i) );

		}
		geometry = OGR_F_GetGeometryRef(feature);
		OGR_G_ExportToWkt(geometry, &wkt);
		printf("%s", wkt);
		printf("\n");
		CPLFree(wkt);
		OGR_F_Destroy(feature);
	}
}
Exemple #5
0
static QgsOgrLayerItem* dataItemForLayer( QgsDataItem* parentItem, QString name, QString path, OGRDataSourceH hDataSource, int layerId )
{
  OGRLayerH hLayer = OGR_DS_GetLayer( hDataSource, layerId );
  OGRFeatureDefnH hDef = OGR_L_GetLayerDefn( hLayer );

  QgsLayerItem::LayerType layerType = QgsLayerItem::Vector;
  OGRwkbGeometryType ogrType = QgsOgrProvider::getOgrGeomType( hLayer );
  switch ( ogrType )
  {
    case wkbUnknown:
    case wkbGeometryCollection:
      break;
    case wkbNone:
      layerType = QgsLayerItem::TableLayer;
      break;
    case wkbPoint:
    case wkbMultiPoint:
    case wkbPoint25D:
    case wkbMultiPoint25D:
      layerType = QgsLayerItem::Point;
      break;
    case wkbLineString:
    case wkbMultiLineString:
    case wkbLineString25D:
    case wkbMultiLineString25D:
      layerType = QgsLayerItem::Line;
      break;
    case wkbPolygon:
    case wkbMultiPolygon:
    case wkbPolygon25D:
    case wkbMultiPolygon25D:
      layerType = QgsLayerItem::Polygon;
      break;
    default:
      break;
  }

  QgsDebugMsgLevel( QString( "ogrType = %1 layertype = %2" ).arg( ogrType ).arg( layerType ), 2 );

  QString layerUri = path;

  if ( name.isEmpty() )
  {
    // we are in a collection
    name = FROM8( OGR_FD_GetName( hDef ) );
    QgsDebugMsg( "OGR layer name : " + name );

    layerUri += "|layerid=" + QString::number( layerId );

    path += "/" + name;
  }

  QgsDebugMsgLevel( "OGR layer uri : " + layerUri, 2 );

  return new QgsOgrLayerItem( parentItem, name, path, layerUri, layerType );
}
static QgsOgrLayerItem *dataItemForLayer( QgsDataItem *parentItem, QString name,
    QString path, GDALDatasetH hDataSource,
    int layerId,
    bool isSubLayer, bool uniqueNames )
{
  OGRLayerH hLayer = GDALDatasetGetLayer( hDataSource, layerId );
  OGRFeatureDefnH hDef = OGR_L_GetLayerDefn( hLayer );

  QgsLayerItem::LayerType layerType = QgsLayerItem::Vector;
  GDALDriverH hDriver = GDALGetDatasetDriver( hDataSource );
  QString driverName = QString::fromUtf8( GDALGetDriverShortName( hDriver ) );
  OGRwkbGeometryType ogrType = QgsOgrProvider::getOgrGeomType( driverName, hLayer );
  QgsWkbTypes::Type wkbType = QgsOgrProviderUtils::qgisTypeFromOgrType( ogrType );
  switch ( QgsWkbTypes::geometryType( wkbType ) )
  {
    case QgsWkbTypes::UnknownGeometry:
      break;
    case QgsWkbTypes::NullGeometry:
      layerType = QgsLayerItem::TableLayer;
      break;
    case QgsWkbTypes::PointGeometry:
      layerType = QgsLayerItem::Point;
      break;
    case QgsWkbTypes::LineGeometry:
      layerType = QgsLayerItem::Line;
      break;
    case QgsWkbTypes::PolygonGeometry:
      layerType = QgsLayerItem::Polygon;
      break;
  }

  QgsDebugMsgLevel( QStringLiteral( "ogrType = %1 layertype = %2" ).arg( ogrType ).arg( layerType ), 2 );

  QString layerUri = path;

  if ( isSubLayer )
  {
    // we are in a collection
    name = QString::fromUtf8( OGR_FD_GetName( hDef ) );
    QgsDebugMsg( "OGR layer name : " + name );
    if ( !uniqueNames )
    {
      layerUri += "|layerid=" + QString::number( layerId );
    }
    else
    {
      layerUri += "|layername=" + name;
    }
    path += '/' + name;
  }
  Q_ASSERT( !name.isEmpty() );

  QgsDebugMsgLevel( "OGR layer uri : " + layerUri, 2 );

  return new QgsOgrLayerItem( parentItem, name, path, layerUri, layerType, isSubLayer );
}
QVector<QgsDataItem *> QgsOgrDataCollectionItem::createChildren()
{
  QVector<QgsDataItem *> children;
  QStringList skippedLayerNames;

  char **papszOptions = nullptr;
  papszOptions = CSLSetNameValue( papszOptions, "@LIST_ALL_TABLES", "YES" );
  gdal::dataset_unique_ptr hDataSource( GDALOpenEx( mPath.toUtf8().constData(), GDAL_OF_VECTOR, nullptr, papszOptions, nullptr ) );
  CSLDestroy( papszOptions );

  GDALDriverH hDriver = GDALGetDatasetDriver( hDataSource.get() );
  QString driverName = QString::fromUtf8( GDALGetDriverShortName( hDriver ) );
  if ( driverName == QStringLiteral( "SQLite" ) )
  {
    skippedLayerNames = QgsSqliteUtils::systemTables();
  }

  if ( !hDataSource )
    return children;
  int numLayers = GDALDatasetGetLayerCount( hDataSource.get() );

  // Check if layer names are unique, so we can use |layername= in URI
  QMap< QString, int > mapLayerNameToCount;
  QList< int > skippedLayers;
  bool uniqueNames = true;
  for ( int i = 0; i < numLayers; ++i )
  {
    OGRLayerH hLayer = GDALDatasetGetLayer( hDataSource.get(), i );
    OGRFeatureDefnH hDef = OGR_L_GetLayerDefn( hLayer );
    QString layerName = QString::fromUtf8( OGR_FD_GetName( hDef ) );
    ++mapLayerNameToCount[layerName];
    if ( mapLayerNameToCount[layerName] > 1 )
    {
      uniqueNames = false;
      break;
    }
    if ( ( driverName == QStringLiteral( "SQLite" ) && layerName.contains( QRegularExpression( QStringLiteral( "idx_.*_geometry($|_.*)" ) ) ) )
         || skippedLayerNames.contains( layerName ) )
    {
      skippedLayers << i;
    }
  }

  children.reserve( numLayers );
  for ( int i = 0; i < numLayers; ++i )
  {
    if ( !skippedLayers.contains( i ) )
    {
      QgsOgrLayerItem *item = dataItemForLayer( this, QString(), mPath, hDataSource.get(), i, true, uniqueNames );
      children.append( item );
    }
  }

  return children;
}
Exemple #8
0
static int        _ogrLoadCell(const char *filename, S52_loadLayer_cb loadLayer_cb, S52_loadObject_cb loadObject_cb)
{
    OGRDataSourceH hDS         = NULL;;
    OGRSFDriverH   hDriver     = NULL;

    PRINTF("DEBUG: starting to load cell (%s)\n", filename);

    hDS = OGROpen(filename, FALSE, &hDriver);

    if (NULL == hDS) {
        PRINTF("WARNING: file loading failed (%s)\n", filename);
        return FALSE;
    }

    if (NULL == loadLayer_cb) {
        PRINTF("ERROR: should be using default S52_loadLayer() callback\n");
        g_assert(0);
        return FALSE;
    }

    if (NULL == loadObject_cb) {
        PRINTF("ERROR: should be using default S52_loadObject_cb() callback\n");
        g_assert(0);
        return FALSE;
    }

    //_loadAux(hDS);
    int nLayer = OGR_DS_GetLayerCount(hDS);
    for (int iLayer=0; iLayer<nLayer; ++iLayer) {
        OGRLayerH       ogrlayer  = OGR_DS_GetLayer(hDS, iLayer);
        OGRFeatureDefnH defn      = OGR_L_GetLayerDefn(ogrlayer);
        const char     *layername = OGR_FD_GetName(defn);

#ifdef _MINGW
        // on Windows 32 the callback is broken
        S52_loadLayer(layername, ogrlayer, NULL);
#else
        //loadLayer_cb(layername, ogrlayer, NULL);
        loadLayer_cb(layername, ogrlayer, loadObject_cb);
#endif

    }

    //OGR_DS_Destroy(hDS);
    OGRReleaseDataSource(hDS);

    return TRUE;
}
Exemple #9
0
GDALWConnection * GDALWConnect(char * source) {
	GDALWConnection * conn = NULL;
	OGRFeatureDefnH featureDefn;
	int fieldCount, i;
	OGRRegisterAll();
	conn = malloc(sizeof(GDALWConnection));
	if (conn == NULL) {
		fprintf(stderr, "Could not allocate memory\n");
		return NULL;
	}
	conn->handler = OGROpen(source, 0 , &(conn->driver));
	if (conn->handler == NULL) {
		free(conn);
		return NULL;
	}


	conn->layer = OGR_DS_GetLayer(conn->handler, 0);
	if (conn->layer == NULL) {
		OGRReleaseDataSource(conn->handler);
		free(conn);
		return NULL;
	}

	conn->layername = (const char *) OGR_L_GetName(conn->layer);

	featureDefn = OGR_L_GetLayerDefn(conn->layer);
	fieldCount = OGR_FD_GetFieldCount(featureDefn);
	conn->numFieldDefinitions = fieldCount;
	conn->fieldDefinitions = malloc(fieldCount * sizeof(OGRFieldDefnH));
	if (conn->fieldDefinitions == NULL) {
		OGRReleaseDataSource(conn->handler);
		free(conn);
		fprintf(stderr, "Could not allocate memory\n");
		return NULL;
	}
	for (i=0 ; i<fieldCount ; i++) {
		conn->fieldDefinitions[i] = OGR_FD_GetFieldDefn(featureDefn, i);
	}

	return conn;
}
Exemple #10
0
void OgrFileImport::importLayer(MapPart* map_part, OGRLayerH layer)
{
	Q_ASSERT(map_part);
	
	auto feature_definition = OGR_L_GetLayerDefn(layer);
	
	OGR_L_ResetReading(layer);
	while (auto feature = ogr::unique_feature(OGR_L_GetNextFeature(layer)))
	{
		auto geometry = OGR_F_GetGeometryRef(feature.get());
		if (!geometry || OGR_G_IsEmpty(geometry))
		{
			++empty_geometries;
			continue;
		}
		
		OGR_G_FlattenTo2D(geometry);
		importFeature(map_part, feature_definition, feature.get(), geometry);
	}
}
Exemple #11
0
bool CUtils::insideInPolygons(OGRDataSourceH poDS, double x, double y)
{
	bool res = false;
	OGRGeometryH pt = OGR_G_CreateGeometry(wkbPoint);
	OGR_G_AddPoint_2D(pt, x, y);

	for(int iLayer = 0; iLayer < OGR_DS_GetLayerCount(poDS); iLayer++)	
	{
		OGRLayerH poLayer = OGR_DS_GetLayer(poDS, iLayer);
		if(poLayer!=NULL)
		{
			OGREnvelope layerBounds;
			OGR_L_GetExtent(poLayer, &layerBounds, 1);
			
			if(	(layerBounds.MinX <= x) && (layerBounds.MinY <= y) && 
				(layerBounds.MaxX >= x) && (layerBounds.MaxY >= y) )
			{
				OGR_L_ResetReading(poLayer);
				if(OGR_FD_GetGeomType( OGR_L_GetLayerDefn(poLayer) ) == wkbPolygon)
				{
					OGRFeatureH poFeat;
					while((poFeat = OGR_L_GetNextFeature(poLayer))!= NULL)
					{
						OGRGeometryH hGeom = OGR_F_GetGeometryRef(poFeat);
						if(OGR_G_Within(pt, hGeom))
						{
							res = true;
							break;
						}
					}
					if(res) { OGR_L_ResetReading(poLayer); break; }
				}
			}
		}
	}	
	OGR_G_DestroyGeometry(pt);
	return res;
}
Exemple #12
0
void OGR::writeBoundary(hexer::HexGrid *grid)
{
    OGRGeometryH multi = OGR_G_CreateGeometry(wkbMultiPolygon);

    const std::vector<hexer::Path *>& paths = grid->rootPaths();
    for (auto pi = paths.begin(); pi != paths.end(); ++pi)
    {
        OGRGeometryH polygon = OGR_G_CreateGeometry(wkbPolygon);
        collectPath(*pi, polygon);

        if( OGR_G_AddGeometryDirectly(multi, polygon ) != OGRERR_NONE )
        {
            std::ostringstream oss;
            oss << "Unable to add polygon to multipolygon with error '"
                << CPLGetLastErrorMsg() << "'";
            throw pdal::pdal_error(oss.str());
        }
    }

    OGRFeatureH hFeature;

    hFeature = OGR_F_Create(OGR_L_GetLayerDefn(m_layer));
    OGR_F_SetFieldInteger( hFeature, OGR_F_GetFieldIndex(hFeature, "ID"), 0);

    OGR_F_SetGeometry(hFeature, multi);
    OGR_G_DestroyGeometry(multi);

    if( OGR_L_CreateFeature( m_layer, hFeature ) != OGRERR_NONE )
    {
        std::ostringstream oss;
        oss << "Unable to create feature for multipolygon with error '"
            << CPLGetLastErrorMsg() << "'";
        throw pdal::pdal_error(oss.str());
    }
    OGR_F_Destroy( hFeature );
}
Exemple #13
0
int db__driver_describe_table(dbString * table_name, dbTable ** table)
{
    int i, nlayers;
    OGRLayerH hLayer = NULL;
    OGRFeatureDefnH hFeatureDefn;

    /* Find data source */
    nlayers = OGR_DS_GetLayerCount(hDs);

    for (i = 0; i < nlayers; i++) {
	hLayer = OGR_DS_GetLayer(hDs, i);
	hFeatureDefn = OGR_L_GetLayerDefn(hLayer);
	if (G_strcasecmp
	    ((char *)OGR_FD_GetName(hFeatureDefn),
	     db_get_string(table_name)) == 0) {
	    break;
	}
	hLayer = NULL;
    }

    if (hLayer == NULL) {
	append_error("Table '%s' does not exist\n",
		     db_get_string(table_name));
	report_error();
	return DB_FAILED;
    }

    G_debug(3, "->>");
    if (describe_table(hLayer, table, NULL) == DB_FAILED) {
	append_error("Cannot describe table\n");
	report_error();
	return DB_FAILED;
    }

    return DB_OK;
}
static CPLErr ProcessLayer(
    OGRLayerH hSrcLayer, int bSRSIsSet,
    GDALDatasetH hDstDS, std::vector<int> anBandList,
    const std::vector<double> &adfBurnValues, int b3D, int bInverse,
    const char *pszBurnAttribute, char **papszRasterizeOptions,
    GDALProgressFunc pfnProgress, void* pProgressData )

{
/* -------------------------------------------------------------------- */
/*      Checkout that SRS are the same.                                 */
/*      If -a_srs is specified, skip the test                           */
/* -------------------------------------------------------------------- */
    OGRCoordinateTransformationH hCT = NULL;
    if (!bSRSIsSet)
    {
        OGRSpatialReferenceH  hDstSRS = NULL;
        if( GDALGetProjectionRef( hDstDS ) != NULL )
        {
            char *pszProjection;

            pszProjection = (char *) GDALGetProjectionRef( hDstDS );

            hDstSRS = OSRNewSpatialReference(NULL);
            if( OSRImportFromWkt( hDstSRS, &pszProjection ) != OGRERR_NONE )
            {
                OSRDestroySpatialReference(hDstSRS);
                hDstSRS = NULL;
            }
        }

        OGRSpatialReferenceH hSrcSRS = OGR_L_GetSpatialRef(hSrcLayer);
        if( hDstSRS != NULL && hSrcSRS != NULL )
        {
            if( OSRIsSame(hSrcSRS, hDstSRS) == FALSE )
            {
                hCT = OCTNewCoordinateTransformation(hSrcSRS, hDstSRS);
                if( hCT == NULL )
                {
                    CPLError(CE_Warning, CPLE_AppDefined,
                        "The output raster dataset and the input vector layer do not have the same SRS.\n"
                        "And reprojection of input data did not work. Results might be incorrect.");
                }
            }
        }
        else if( hDstSRS != NULL && hSrcSRS == NULL )
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                    "The output raster dataset has a SRS, but the input vector layer SRS is unknown.\n"
                    "Ensure input vector has the same SRS, otherwise results might be incorrect.");
        }
        else if( hDstSRS == NULL && hSrcSRS != NULL )
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                    "The input vector layer has a SRS, but the output raster dataset SRS is unknown.\n"
                    "Ensure output raster dataset has the same SRS, otherwise results might be incorrect.");
        }

        if( hDstSRS != NULL )
        {
            OSRDestroySpatialReference(hDstSRS);
        }
    }

/* -------------------------------------------------------------------- */
/*      Get field index, and check.                                     */
/* -------------------------------------------------------------------- */
    int iBurnField = -1;

    if( pszBurnAttribute )
    {
        iBurnField = OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hSrcLayer ),
                                           pszBurnAttribute );
        if( iBurnField == -1 )
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Failed to find field %s on layer %s, skipping.",
                    pszBurnAttribute,
                    OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) );
            if( hCT != NULL )
                OCTDestroyCoordinateTransformation(hCT);
            return CE_Failure;
        }
    }

/* -------------------------------------------------------------------- */
/*      Collect the geometries from this layer, and build list of       */
/*      burn values.                                                    */
/* -------------------------------------------------------------------- */
    OGRFeatureH hFeat;
    std::vector<OGRGeometryH> ahGeometries;
    std::vector<double> adfFullBurnValues;

    OGR_L_ResetReading( hSrcLayer );

    while( (hFeat = OGR_L_GetNextFeature( hSrcLayer )) != NULL )
    {
        OGRGeometryH hGeom;

        if( OGR_F_GetGeometryRef( hFeat ) == NULL )
        {
            OGR_F_Destroy( hFeat );
            continue;
        }

        hGeom = OGR_G_Clone( OGR_F_GetGeometryRef( hFeat ) );
        if( hCT != NULL )
        {
            if( OGR_G_Transform(hGeom, hCT) != OGRERR_NONE )
            {
                OGR_F_Destroy( hFeat );
                OGR_G_DestroyGeometry(hGeom);
                continue;
            }
        }
        ahGeometries.push_back( hGeom );

        for( unsigned int iBand = 0; iBand < anBandList.size(); iBand++ )
        {
            if( adfBurnValues.size() > 0 )
                adfFullBurnValues.push_back(
                    adfBurnValues[MIN(iBand,adfBurnValues.size()-1)] );
            else if( pszBurnAttribute )
            {
                adfFullBurnValues.push_back( OGR_F_GetFieldAsDouble( hFeat, iBurnField ) );
            }
            /* I have made the 3D option exclusive to other options since it
               can be used to modify the value from "-burn value" or
               "-a attribute_name" */
            if( b3D )
            {
                // TODO: get geometry "z" value
                /* Points and Lines will have their "z" values collected at the
                   point and line levels respectively. However filled polygons
                   (GDALdllImageFilledPolygon) can use some help by getting
                   their "z" values here. */
                adfFullBurnValues.push_back( 0.0 );
            }
        }

        OGR_F_Destroy( hFeat );
    }

    if( hCT != NULL )
        OCTDestroyCoordinateTransformation(hCT);

/* -------------------------------------------------------------------- */
/*      If we are in inverse mode, we add one extra ring around the     */
/*      whole dataset to invert the concept of insideness and then      */
/*      merge everything into one geometry collection.                  */
/* -------------------------------------------------------------------- */
    if( bInverse )
    {
        if( ahGeometries.size() == 0 )
        {
            for( unsigned int iBand = 0; iBand < anBandList.size(); iBand++ )
            {
                if( adfBurnValues.size() > 0 )
                    adfFullBurnValues.push_back(
                        adfBurnValues[MIN(iBand,adfBurnValues.size()-1)] );
                else /* FIXME? Not sure what to do exactly in the else case, but we must insert a value */
                    adfFullBurnValues.push_back( 0.0 );
            }
        }

        InvertGeometries( hDstDS, ahGeometries );
    }

/* -------------------------------------------------------------------- */
/*      Perform the burn.                                               */
/* -------------------------------------------------------------------- */
    CPLErr eErr = GDALRasterizeGeometries( hDstDS, static_cast<int>(anBandList.size()), &(anBandList[0]),
                             static_cast<int>(ahGeometries.size()), &(ahGeometries[0]),
                             NULL, NULL, &(adfFullBurnValues[0]),
                             papszRasterizeOptions,
                             pfnProgress, pProgressData );

/* -------------------------------------------------------------------- */
/*      Cleanup geometries.                                             */
/* -------------------------------------------------------------------- */
    int iGeom;

    for( iGeom = static_cast<int>(ahGeometries.size())-1; iGeom >= 0; iGeom-- )
        OGR_G_DestroyGeometry( ahGeometries[iGeom] );

    return eErr;
}
Exemple #15
0
int OGRCDump(const char *pszFname)
{
    OGRDataSourceH datasource;
    int i, numLayers;

    /* Register all OGR drivers */
    OGRRegisterAll();

    /* Open data source */
    datasource = OGROpen(pszFname, 0 /* bUpdate */, NULL);

    if (datasource == NULL)
    {
        printf("Unable to open %s\n", pszFname);
        return -1;
    }

    /* Loop through layers and dump their contents */

    numLayers = OGR_DS_GetLayerCount(datasource);
    for(i=0; i<numLayers; i++)
    {
        OGRLayerH layer;
        int j, numFields;
        OGRFeatureH feature;
        OGRFeatureDefnH layerDefn;

        layer = OGR_DS_GetLayer( datasource, i );

        /* Dump info about this layer */
        layerDefn = OGR_L_GetLayerDefn( layer );
        numFields = OGR_FD_GetFieldCount( layerDefn );

        printf("\n===================\n");
        printf("Layer %d: '%s'\n\n", i, OGR_FD_GetName(layerDefn));

        for(j=0; j<numFields; j++)
        {
            OGRFieldDefnH fieldDefn;

            fieldDefn = OGR_FD_GetFieldDefn( layerDefn, j );
            printf(" Field %d: %s (%s)\n", 
                   j, OGR_Fld_GetNameRef(fieldDefn), 
                   OGR_GetFieldTypeName(OGR_Fld_GetType(fieldDefn)) );
        }
        printf("\n");

        /* And dump each feature individually */
        while( (feature = OGR_L_GetNextFeature( layer )) != NULL )
        {
            OGR_F_DumpReadable( feature, stdout );
            OGR_F_Destroy( feature );
        }

        /* No need to free layer handle, it belongs to the datasource */
    }

    /* Close data source */
    OGR_DS_Destroy( datasource );

    return 0;
}
Exemple #16
0
int OGRCCreate(const char *pszFname)
{
    OGRSFDriverH    driver;
    int             i, numDrivers;
    OGRDataSourceH  datasource;
    OGRLayerH       layer;
    OGRFeatureDefnH layerDefn;
    OGRFieldDefnH   fieldDefn;
    OGRFeatureH     feature;
    OGRGeometryH    geometry, ring;

    /* Register all OGR drivers */
    OGRRegisterAll();

    /* Fetch MITAB driver - we want to create a TAB file */
    numDrivers = OGRGetDriverCount();
    for(i=0; i<numDrivers; i++)
    {
        driver = OGRGetDriver(i);
        if (EQUAL("MapInfo File", OGR_Dr_GetName(driver)))
            break;  /* Found it! */
        driver = NULL;
    }

    if (!driver)
    {
        printf("Driver not found!\n");
        return -1;
    }

    /* Create new file using this driver */
    datasource = OGR_Dr_CreateDataSource(driver, pszFname, NULL);

    if (datasource == NULL)
    {
        printf("Unable to create %s\n", pszFname);
        return -1;
    }

    /* MapInfo data sources are created with one empty layer.
       Fetch the layer handle */
    layer = OGR_DS_GetLayer(datasource, 0);

    if (layer == NULL)
    {
        printf("Unable to create new layer in %s\n", pszFname);
        return -1;
    }

    /* Add a few fields to the layer defn */
    fieldDefn = OGR_Fld_Create( "id", OFTInteger );
    OGR_L_CreateField(layer, fieldDefn, 0);

    fieldDefn = OGR_Fld_Create( "area", OFTReal );
    OGR_L_CreateField(layer, fieldDefn, 0);

    fieldDefn = OGR_Fld_Create( "name", OFTString );
    OGR_L_CreateField(layer, fieldDefn, 0);

    /* We'll need the layerDefn handle to create new features in this layer */
    layerDefn = OGR_L_GetLayerDefn( layer );

    /* Create a new point */
    feature = OGR_F_Create( layerDefn );
    OGR_F_SetFieldInteger( feature, 0, 1);
    OGR_F_SetFieldDouble( feature, 1, 123.45);
    OGR_F_SetFieldString( feature, 2, "Feature #1");

    geometry = OGR_G_CreateGeometry( wkbPoint );
    OGR_G_SetPoint(geometry, 0, 123.45, 456.78, 0);

    OGR_F_SetGeometryDirectly(feature, geometry);

    OGR_L_CreateFeature( layer, feature );

    /* Create a new line */
    feature = OGR_F_Create( layerDefn );
    OGR_F_SetFieldInteger( feature, 0, 2);
    OGR_F_SetFieldDouble( feature, 1, 42.45);
    OGR_F_SetFieldString( feature, 2, "Feature #2");

    geometry = OGR_G_CreateGeometry( wkbLineString );
    OGR_G_AddPoint(geometry, 123.45, 456.78, 0);
    OGR_G_AddPoint(geometry, 12.34,  45.67, 0);

    OGR_F_SetGeometryDirectly(feature, geometry);
 
    OGR_L_CreateFeature( layer, feature );

    /* Create a new polygon (square) */
    feature = OGR_F_Create( layerDefn );
    OGR_F_SetFieldInteger( feature, 0, 3);
    OGR_F_SetFieldDouble( feature, 1, 49.71);
    OGR_F_SetFieldString( feature, 2, "Feature #3");

    geometry = OGR_G_CreateGeometry( wkbPolygon );
    ring = OGR_G_CreateGeometry( wkbLinearRing );
    OGR_G_AddPoint(ring, 123.45, 456.78, 0);
    OGR_G_AddPoint(ring, 12.34,  456.78, 0);
    OGR_G_AddPoint(ring, 12.34,  45.67, 0);
    OGR_G_AddPoint(ring, 123.45, 45.67, 0);
    OGR_G_AddPoint(ring, 123.45, 456.78, 0);
    OGR_G_AddGeometryDirectly(geometry, ring);

    OGR_F_SetGeometryDirectly(feature, geometry);
 
    OGR_L_CreateFeature( layer, feature );

    /* Close data source */
    OGR_DS_Destroy( datasource );

    return 0;
}
CPLErr RasterliteDataset::CreateOverviewLevel(int nOvrFactor,
                                              GDALProgressFunc pfnProgress,
                                              void * pProgressData)
{

    double dfXResolution = padfXResolutions[0] * nOvrFactor;
    double dfYResolution = padfXResolutions[0] * nOvrFactor;
    
    CPLString osSQL;

    int nBlockXSize = 256;
    int nBlockYSize = 256;
    int nOvrXSize = nRasterXSize / nOvrFactor;
    int nOvrYSize = nRasterYSize / nOvrFactor;
    
    if (nOvrXSize == 0 || nOvrYSize == 0)
        return CE_Failure;
    
    int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize;
    int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize;
    
    const char* pszDriverName = "GTiff";
    GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
    if (hTileDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
        return CE_Failure;
    }
    
    GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
    if (hMemDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
        return CE_Failure;
    }   

    GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType();
    int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
    GByte* pabyMEMDSBuffer =
        (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
    if (pabyMEMDSBuffer == NULL)
    {
        return CE_Failure;
    }
    
    char** papszTileDriverOptions = NULL;
    
    CPLString osTempFileName;
    osTempFileName.Printf("/vsimem/%p", hDS);
    
    int nTileId = 0;
    int nBlocks = 0;
    int nTotalBlocks = nXBlocks * nYBlocks;
    
    CPLString osRasterLayer;
    osRasterLayer.Printf("%s_rasters", osTableName.c_str());
    
    CPLString osMetatadataLayer;
    osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());
    
    OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
    OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
    
    CPLString osSourceName = "unknown";
    
    osSQL.Printf("SELECT source_name FROM \"%s\" WHERE "
                 "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
                 "pixel_y_size >= %.15f AND pixel_y_size <= %.15f LIMIT 1",
                 osMetatadataLayer.c_str(),
                 padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
                 padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
    OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    if (hSQLLyr)
    {
        OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
        if (hFeat)
        {
            const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0);
            if (pszVal)
                osSourceName = pszVal;
            OGR_F_Destroy(hFeat);
        }
        OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
    }
    
/* -------------------------------------------------------------------- */
/*      Compute up to which existing overview level we can use for      */
/*      computing the requested overview                                */
/* -------------------------------------------------------------------- */
    int iLev;
    nLimitOvrCount = 0;
    for(iLev=1;iLev<nResolutions;iLev++)
    {
        if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 &&
              padfYResolutions[iLev] < dfYResolution - 1e-10))
        {
            break;
        }
        nLimitOvrCount++;
    }
    
/* -------------------------------------------------------------------- */
/*      Iterate over blocks to add data into raster and metadata tables */
/* -------------------------------------------------------------------- */

    OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
    
    CPLErr eErr = CE_None;
    int nBlockXOff, nBlockYOff;
    for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
    {
        for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
        {
/* -------------------------------------------------------------------- */
/*      Create in-memory tile                                           */
/* -------------------------------------------------------------------- */
            int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
            if ((nBlockXOff+1) * nBlockXSize > nOvrXSize)
                nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize;
            if ((nBlockYOff+1) * nBlockYSize > nOvrYSize)
                nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize;
            
            eErr = RasterIO(GF_Read,
                            nBlockXOff * nBlockXSize * nOvrFactor,
                            nBlockYOff * nBlockYSize * nOvrFactor,
                            nReqXSize * nOvrFactor, nReqYSize * nOvrFactor,
                            pabyMEMDSBuffer, nReqXSize, nReqYSize,
                            eDataType, nBands, NULL,
                            0, 0, 0);
            if (eErr != CE_None)
            {
                break;
            }
            
            GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
                                              nReqXSize, nReqYSize, 0, 
                                              eDataType, NULL);
            if (hMemDS == NULL)
            {
                eErr = CE_Failure;
                break;
            }
            
            int iBand;
            for(iBand = 0; iBand < nBands; iBand ++)
            {
                char** papszOptions = NULL;
                char szTmp[64];
                memset(szTmp, 0, sizeof(szTmp));
                CPLPrintPointer(szTmp,
                                pabyMEMDSBuffer + iBand * nDataTypeSize *
                                nReqXSize * nReqYSize, sizeof(szTmp));
                papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
                GDALAddBand(hMemDS, eDataType, papszOptions);
                CSLDestroy(papszOptions);
            }
            
            GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
                                        osTempFileName.c_str(), hMemDS, FALSE,
                                        papszTileDriverOptions, NULL, NULL);

            GDALClose(hMemDS);
            if (hOutDS)
                GDALClose(hOutDS);
            else
            {
                eErr = CE_Failure;
                break;
            }

/* -------------------------------------------------------------------- */
/*      Insert new entry into raster table                              */
/* -------------------------------------------------------------------- */

            vsi_l_offset nDataLength;
            GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
                                                   &nDataLength, FALSE);

            OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
            OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
            
            OGR_L_CreateFeature(hRasterLayer, hFeat);
            /* Query raster ID to set it as the ID of the associated metadata */
            int nRasterID = (int)OGR_F_GetFID(hFeat);
            
            OGR_F_Destroy(hFeat);
            
            VSIUnlink(osTempFileName.c_str());
            
/* -------------------------------------------------------------------- */
/*      Insert new entry into metadata table                            */
/* -------------------------------------------------------------------- */
            
            hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
            OGR_F_SetFID(hFeat, nRasterID);
            OGR_F_SetFieldString(hFeat, 0, osSourceName);
            OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
            OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
            OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
            OGR_F_SetFieldDouble(hFeat, 4, dfXResolution);
            OGR_F_SetFieldDouble(hFeat, 5, dfYResolution);
            
            double minx, maxx, maxy, miny;
            minx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff) * dfXResolution;
            maxx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution;
            maxy = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff) * (-dfYResolution);
            miny = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution);
            
            OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
            OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
            
            OGR_F_SetGeometryDirectly(hFeat, hRectangle);
            
            OGR_L_CreateFeature(hMetadataLayer, hFeat);
            OGR_F_Destroy(hFeat);
            
            nBlocks++;
            if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
                                            NULL, pProgressData))
                eErr = CE_Failure;
        }
    }
    
    nLimitOvrCount = -1;
    
    if (eErr == CE_None)
        OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
    else
        OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
    
    VSIFree(pabyMEMDSBuffer);
    
/* -------------------------------------------------------------------- */
/*      Update raster_pyramids table                                    */
/* -------------------------------------------------------------------- */
    if (eErr == CE_None)
    {
        OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
        if (hRasterPyramidsLyr == NULL)
        {
            osSQL.Printf   ("CREATE TABLE raster_pyramids ("
                            "table_prefix TEXT NOT NULL,"
                            "pixel_x_size DOUBLE NOT NULL,"
                            "pixel_y_size DOUBLE NOT NULL,"
                            "tile_count INTEGER NOT NULL)");
            OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
            
            /* Re-open the DB to take into account the new tables*/
            OGRReleaseDataSource(hDS);
            
            CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
            CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
            hDS = OGROpen(osFileName.c_str(), TRUE, NULL);
            CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
        }

        /* Insert base resolution into raster_pyramids if not already done */
        int bHasBaseResolution = FALSE;
        osSQL.Printf("SELECT * FROM raster_pyramids WHERE "
                     "table_prefix = '%s' AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
                     "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
                     osTableName.c_str(),
                     padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
                     padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);
        hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
        if (hSQLLyr)
        {
            OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
            if (hFeat)
            {
                bHasBaseResolution = TRUE;
                OGR_F_Destroy(hFeat);
            }
            OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
        }

        if (!bHasBaseResolution)
        {
            osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE "
                          "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
                          "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
                          osMetatadataLayer.c_str(),
                          padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15,
                          padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15);

            int nBlocksMainRes = 0;

            hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
            if (hSQLLyr)
            {
                OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
                if (hFeat)
                {
                    nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0);
                    OGR_F_Destroy(hFeat);
                }
                OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
            }

            osSQL.Printf("INSERT INTO raster_pyramids "
                         "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) "
                         "VALUES ( '%s', %.18f, %.18f, %d )",
                         osTableName.c_str(), padfXResolutions[0], padfYResolutions[0],
                         nBlocksMainRes);
            OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
        }

        osSQL.Printf("INSERT INTO raster_pyramids "
                     "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) "
                     "VALUES ( '%s', %.18f, %.18f, %d )",
                     osTableName.c_str(), dfXResolution, dfYResolution,
                     nTotalBlocks);
        OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    }

    return eErr;
}
Exemple #18
0
    void object::test<3>()
    {
        OGRErr err = OGRERR_NONE;

        OGRDataSourceH ds = NULL;
        ds = OGR_Dr_CreateDataSource(drv_, data_tmp_.c_str(), NULL);
        ensure("Can't open or create data source", NULL != ds);

        // Create memory Layer
        OGRLayerH lyr = NULL;
        lyr = OGR_DS_CreateLayer(ds, "tpoly", NULL, wkbPolygon, NULL);
        ensure("Can't create layer", NULL != lyr);

        // Create schema
        OGRFieldDefnH fld = NULL;

        fld = OGR_Fld_Create("AREA", OFTReal);
        err = OGR_L_CreateField(lyr, fld, true);
        OGR_Fld_Destroy(fld);
        ensure_equals("Can't create field", OGRERR_NONE, err);

        fld = OGR_Fld_Create("EAS_ID", OFTInteger);
        err = OGR_L_CreateField(lyr, fld, true);
        OGR_Fld_Destroy(fld);
        ensure_equals("Can't create field", OGRERR_NONE, err);

        fld = OGR_Fld_Create("PRFEDEA", OFTString);
        err = OGR_L_CreateField(lyr, fld, true);
        OGR_Fld_Destroy(fld);
        ensure_equals("Can't create field", OGRERR_NONE, err);

        // Check schema
        OGRFeatureDefnH featDefn = OGR_L_GetLayerDefn(lyr);
        ensure("Layer schema is NULL", NULL != featDefn);
        ensure_equals("Fields creation failed", 3, OGR_FD_GetFieldCount(featDefn));

        // Copy ogr/poly.shp to temporary layer
        OGRFeatureH featDst = OGR_F_Create(featDefn);
        ensure("Can't create empty feature", NULL != featDst);

        std::string source(data_);
        source += SEP;
        source += "poly.shp";
        OGRDataSourceH dsSrc = OGR_Dr_Open(drv_, source.c_str(), false);
        ensure("Can't open source layer", NULL != dsSrc);

        OGRLayerH lyrSrc = OGR_DS_GetLayer(dsSrc, 0);
        ensure("Can't get source layer", NULL != lyrSrc);

        OGRFeatureH featSrc = NULL;
        while (NULL != (featSrc = OGR_L_GetNextFeature(lyrSrc)))
        {
            err = OGR_F_SetFrom(featDst, featSrc, true);
            ensure_equals("Can't set festure from source", OGRERR_NONE, err);

            err = OGR_L_CreateFeature(lyr, featDst);
            ensure_equals("Can't write feature to layer", OGRERR_NONE, err);

            OGR_F_Destroy(featSrc);
        }

        // Release and close resources
        OGR_F_Destroy(featDst);
        OGR_DS_Destroy(dsSrc);
        OGR_DS_Destroy(ds);
    }
int create_grid(char *infile, char *outfile, int gridsize, char *format, char *layer) {

	OGRSFDriverH out_driver;
	OGRDataSourceH out_ds;
	OGRLayerH out_layer;
	OGRFieldDefnH field;
	OGRFeatureH feat;
	OGRGeometryH geom;
	morph *mgrid;
	int xstep, ystep, step;
	double topleftx, toplefty, weres, nsres, rot1, rot2;
	int i,j, fid, row, col;
	
	
	OGRRegisterAll();
	
	// Read the morph grid file.
	mgrid = read_grid(infile);
	if (mgrid == NULL) {
		fprintf(stderr, "Error. Unable to read input morph file '%s'.\n", infile);
		exit(1);
	}
	
	// Create the ouptut layer.
	out_driver = OGRGetDriverByName(format);
	if (out_driver == NULL) {
		fprintf(stderr, "Error. Driver for format '%s' not available.\n", format);
		exit(1);
	}
	out_ds = OGR_Dr_CreateDataSource(out_driver, outfile, NULL);
	if (out_ds == NULL) {
		fprintf(stderr, "Error. Unable to create output data source.\n");
		exit(1);
	}
	out_layer = OGR_DS_CreateLayer(out_ds, layer, NULL, wkbLineString, NULL);
	if (out_layer == NULL) {
		fprintf(stderr, "Error. Unable to create output layer.\n");
		exit(1);
	}
	
	// Add the attributes to the new layer.
	field = OGR_Fld_Create("ID", OFTInteger);
	OGR_Fld_SetWidth(field, 11);
	if (OGR_L_CreateField(out_layer, field, TRUE) != OGRERR_NONE) {
		fprintf(stderr, "Error. Creating ID attribute failed.\n");
		exit(1);
	}
	OGR_Fld_Destroy(field);
	
	field = OGR_Fld_Create("ROW", OFTInteger);
	OGR_Fld_SetWidth(field, 6);
	if (OGR_L_CreateField(out_layer, field, TRUE) != OGRERR_NONE) {
		fprintf(stderr, "Error. Creating ROW attribute failed.\n");
		exit(1);
	}
	OGR_Fld_Destroy(field);
	
	field = OGR_Fld_Create("COL", OFTInteger);
	OGR_Fld_SetWidth(field, 6);
	if (OGR_L_CreateField(out_layer, field, TRUE) != OGRERR_NONE) {
		fprintf(stderr, "Error. Creating COL attribute failed.\n");
		exit(1);
	}
	OGR_Fld_Destroy(field);
	
	// Compute the step size.
	xstep = mgrid->xsize / gridsize;
	if (xstep < 1) {
		xstep = 1;
	}
	if (xstep > (mgrid->xsize / 2)) {
		xstep = mgrid->xsize / 2;
	}
	ystep = mgrid->ysize / gridsize;
	if (ystep < 1) {
		ystep = 1;
	}
	if (ystep > (mgrid->ysize / 2)) {
		ystep = mgrid->ysize / 2;
	}
	if (xstep < ystep) {
		step = ystep;
	} else {
		step = xstep;
	}
	
	// Read the georeference
	topleftx = mgrid->georef[0];
	weres = mgrid->georef[1];
	rot1 = mgrid->georef[2];
	toplefty = mgrid->georef[3];
	rot2 = mgrid->georef[4];
	nsres = mgrid->georef[5];
	
	// Write all horizontal lines.
	fid = 1;
	row = 1;
	for (j = 0; j < mgrid->ysize; j += step) {
		// Create a new Feature with the projected coordinates.
		feat = OGR_F_Create(OGR_L_GetLayerDefn(out_layer));
		OGR_F_SetFieldInteger(feat, OGR_F_GetFieldIndex(feat, "ID"), fid);
		OGR_F_SetFieldInteger(feat, OGR_F_GetFieldIndex(feat, "ROW"), row);
		OGR_F_SetFieldInteger(feat, OGR_F_GetFieldIndex(feat, "COL"), 0);

		// Create a new geometry object.
		geom = OGR_G_CreateGeometry(wkbLineString);
		for (i = 0; i < mgrid->xsize; i++) {
			OGR_G_SetPoint_2D(
							  geom, 
							  i, 
							  topleftx + mgrid->x[i][j]*weres + mgrid->y[i][j]*rot1, 
							  toplefty + mgrid->x[i][j]*rot2 + mgrid->y[i][j]*nsres);
		}
		OGR_F_SetGeometry(feat, geom);
		OGR_G_DestroyGeometry(geom);
		
		// Write the feature to the output vector layer.
		if (OGR_L_CreateFeature(out_layer, feat) != OGRERR_NONE) {
			fprintf(stderr, "Error. Unable to create new feature.\n");
			exit(1);
		}
		OGR_F_Destroy(feat);
		
		row++;
		fid++;
	}
	
	// Write all vertical lines.
	col = 1;
	for (i = 0; i < mgrid->xsize; i += step) {
		// Create a new Feature with the projected coordinates.
		feat = OGR_F_Create(OGR_L_GetLayerDefn(out_layer));
		OGR_F_SetFieldInteger(feat, OGR_F_GetFieldIndex(feat, "ID"), fid);
		OGR_F_SetFieldInteger(feat, OGR_F_GetFieldIndex(feat, "ROW"), 0);
		OGR_F_SetFieldInteger(feat, OGR_F_GetFieldIndex(feat, "COL"), col);
		
		// Create a new geometry object.
		geom = OGR_G_CreateGeometry(wkbLineString);
		for (j = 0; j < mgrid->ysize; j++) {
			OGR_G_SetPoint_2D(
							  geom, 
							  j, 
							  topleftx + mgrid->x[i][j]*weres + mgrid->y[i][j]*rot1, 
							  toplefty + mgrid->x[i][j]*rot2 + mgrid->y[i][j]*nsres);
		}
		OGR_F_SetGeometry(feat, geom);
		OGR_G_DestroyGeometry(geom);
		
		// Write the feature to the output vector layer.
		if (OGR_L_CreateFeature(out_layer, feat) != OGRERR_NONE) {
			fprintf(stderr, "Error. Unable to create new feature.\n");
			exit(1);
		}
		OGR_F_Destroy(feat);
		
		col++;
		fid++;
	}

	// Close the datasources and free the memory.
	OGR_DS_Destroy(out_ds);
	free_morph(mgrid);
	
	return 0;
}
Exemple #20
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct _param {
        struct Option *dsn, *out, *layer, *spat, *where,
                   *min_area;
        struct Option *snap, *type, *outloc, *cnames;
    } param;
    struct _flag {
        struct Flag *list, *tlist, *no_clean, *z, *notab,
                   *region;
        struct Flag *over, *extend, *formats, *tolower, *no_import;
    } flag;

    int i, j, layer, arg_s_num, nogeom, ncnames;
    float xmin, ymin, xmax, ymax;
    int ncols = 0, type;
    double min_area, snap;
    char buf[2000], namebuf[2000], tempvect[GNAME_MAX];
    char *separator;

    struct Key_Value *loc_proj_info, *loc_proj_units;
    struct Key_Value *proj_info, *proj_units;
    struct Cell_head cellhd, loc_wind, cur_wind;
    char error_msg[8192];

    /* Vector */
    struct Map_info Map, Tmp, *Out;
    int cat;

    /* Attributes */
    struct field_info *Fi;
    dbDriver *driver;
    dbString sql, strval;
    int dim, with_z;

    /* OGR */
    OGRDataSourceH Ogr_ds;
    OGRLayerH Ogr_layer;
    OGRFieldDefnH Ogr_field;
    char *Ogr_fieldname;
    OGRFieldType Ogr_ftype;
    OGRFeatureH Ogr_feature;
    OGRFeatureDefnH Ogr_featuredefn;
    OGRGeometryH Ogr_geometry, Ogr_oRing, poSpatialFilter;
    OGRSpatialReferenceH Ogr_projection;
    OGREnvelope oExt;
    OGRwkbGeometryType Ogr_geom_type;

    int OFTIntegerListlength;

    char *output;
    char **layer_names;		/* names of layers to be imported */
    int *layers;		/* layer indexes */
    int nlayers;		/* number of layers to import */
    char **available_layer_names;	/* names of layers to be imported */
    int navailable_layers;
    int layer_id;
    unsigned int n_features, feature_count;
    int overwrite;
    double area_size;
    int use_tmp_vect;

    xmin = ymin = xmax = ymax = 0.0;
    loc_proj_info = loc_proj_units = NULL;
    Ogr_ds = Ogr_oRing = poSpatialFilter = NULL;
    OFTIntegerListlength = 40;	/* hack due to limitation in OGR */
    area_size = 0.0;
    use_tmp_vect = FALSE;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("import"));
    module->description = _("Converts vector data into a GRASS vector map using OGR library.");

    param.dsn = G_define_option();
    param.dsn->key = "dsn";
    param.dsn->type = TYPE_STRING;
    param.dsn->required =YES;
    param.dsn->label = _("OGR datasource name");
    param.dsn->description = _("Examples:\n"
                               "\t\tESRI Shapefile: directory containing shapefiles\n"
                               "\t\tMapInfo File: directory containing mapinfo files");

    param.layer = G_define_option();
    param.layer->key = "layer";
    param.layer->type = TYPE_STRING;
    param.layer->required = NO;
    param.layer->multiple = YES;
    param.layer->label =
        _("OGR layer name. If not given, all available layers are imported");
    param.layer->description =
        _("Examples:\n" "\t\tESRI Shapefile: shapefile name\n"
          "\t\tMapInfo File: mapinfo file name");
    param.layer->guisection = _("Selection");

    param.out = G_define_standard_option(G_OPT_V_OUTPUT);
    param.out->required = NO;
    param.out->guisection = _("Output");

    param.spat = G_define_option();
    param.spat->key = "spatial";
    param.spat->type = TYPE_DOUBLE;
    param.spat->multiple = YES;
    param.spat->required = NO;
    param.spat->key_desc = "xmin,ymin,xmax,ymax";
    param.spat->label = _("Import subregion only");
    param.spat->guisection = _("Selection");
    param.spat->description =
        _("Format: xmin,ymin,xmax,ymax - usually W,S,E,N");

    param.where = G_define_standard_option(G_OPT_DB_WHERE);
    param.where->guisection = _("Selection");

    param.min_area = G_define_option();
    param.min_area->key = "min_area";
    param.min_area->type = TYPE_DOUBLE;
    param.min_area->required = NO;
    param.min_area->answer = "0.0001";
    param.min_area->label =
        _("Minimum size of area to be imported (square units)");
    param.min_area->guisection = _("Selection");
    param.min_area->description = _("Smaller areas and "
                                    "islands are ignored. Should be greater than snap^2");

    param.type = G_define_standard_option(G_OPT_V_TYPE);
    param.type->options = "point,line,boundary,centroid";
    param.type->answer = "";
    param.type->description = _("Optionally change default input type");
    param.type->descriptions =
        _("point;import area centroids as points;"
          "line;import area boundaries as lines;"
          "boundary;import lines as area boundaries;"
          "centroid;import points as centroids");
    param.type->guisection = _("Selection");

    param.snap = G_define_option();
    param.snap->key = "snap";
    param.snap->type = TYPE_DOUBLE;
    param.snap->required = NO;
    param.snap->answer = "-1";
    param.snap->label = _("Snapping threshold for boundaries");
    param.snap->description = _("'-1' for no snap");

    param.outloc = G_define_option();
    param.outloc->key = "location";
    param.outloc->type = TYPE_STRING;
    param.outloc->required = NO;
    param.outloc->description = _("Name for new location to create");
    param.outloc->key_desc = "name";

    param.cnames = G_define_option();
    param.cnames->key = "cnames";
    param.cnames->type = TYPE_STRING;
    param.cnames->required = NO;
    param.cnames->multiple = YES;
    param.cnames->description =
        _("List of column names to be used instead of original names, "
          "first is used for category column");
    param.cnames->guisection = _("Attributes");

    flag.list = G_define_flag();
    flag.list->key = 'l';
    flag.list->description = _("List available OGR layers in data source and exit");
    flag.list->suppress_required = YES;
    flag.list->guisection = _("Print");

    flag.tlist = G_define_flag();
    flag.tlist->key = 'a';
    flag.tlist->description = _("List available OGR layers including feature types "
                                "in data source and exit");
    flag.tlist->suppress_required = YES;
    flag.tlist->guisection = _("Print");

    flag.formats = G_define_flag();
    flag.formats->key = 'f';
    flag.formats->description = _("List supported formats and exit");
    flag.formats->suppress_required = YES;
    flag.formats->guisection = _("Print");

    /* if using -c, you lose topological information ! */
    flag.no_clean = G_define_flag();
    flag.no_clean->key = 'c';
    flag.no_clean->description = _("Do not clean polygons (not recommended)");
    flag.no_clean->guisection = _("Output");

    flag.z = G_define_flag();
    flag.z->key = 'z';
    flag.z->description = _("Create 3D output");
    flag.z->guisection = _("Output");

    flag.notab = G_define_flag();
    flag.notab->key = 't';
    flag.notab->description = _("Do not create attribute table");
    flag.notab->guisection = _("Attributes");

    flag.over = G_define_flag();
    flag.over->key = 'o';
    flag.over->description =
        _("Override dataset projection (use location's projection)");

    flag.region = G_define_flag();
    flag.region->key = 'r';
    flag.region->guisection = _("Selection");
    flag.region->description = _("Limit import to the current region");

    flag.extend = G_define_flag();
    flag.extend->key = 'e';
    flag.extend->description =
        _("Extend location extents based on new dataset");

    flag.tolower = G_define_flag();
    flag.tolower->key = 'w';
    flag.tolower->description =
        _("Change column names to lowercase characters");
    flag.tolower->guisection = _("Attributes");

    flag.no_import = G_define_flag();
    flag.no_import->key = 'i';
    flag.no_import->description =
        _("Create the location specified by the \"location\" parameter and exit."
          " Do not import the vector data.");

    /* The parser checks if the map already exists in current mapset, this is
     * wrong if location options is used, so we switch out the check and do it
     * in the module after the parser */
    overwrite = G_check_overwrite(argc, argv);

    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    G_begin_polygon_area_calculations();	/* Used in geom() */

    OGRRegisterAll();

    /* list supported formats */
    if (flag.formats->answer) {
        int iDriver;

        G_message(_("Available OGR Drivers:"));

        for (iDriver = 0; iDriver < OGRGetDriverCount(); iDriver++) {
            OGRSFDriverH poDriver = OGRGetDriver(iDriver);
            const char *pszRWFlag;

            if (OGR_Dr_TestCapability(poDriver, ODrCCreateDataSource))
                pszRWFlag = "rw";
            else
                pszRWFlag = "ro";

            fprintf(stdout, " %s (%s): %s\n",
                    OGR_Dr_GetName(poDriver),
                    pszRWFlag, OGR_Dr_GetName(poDriver));
        }
        exit(EXIT_SUCCESS);
    }

    if (param.dsn->answer == NULL) {
        G_fatal_error(_("Required parameter <%s> not set"), param.dsn->key);
    }

    min_area = atof(param.min_area->answer);
    snap = atof(param.snap->answer);
    type = Vect_option_to_types(param.type);

    ncnames = 0;
    if (param.cnames->answers) {
        i = 0;
        while (param.cnames->answers[i++]) {
            ncnames++;
        }
    }

    /* Open OGR DSN */
    Ogr_ds = NULL;
    if (strlen(param.dsn->answer) > 0)
        Ogr_ds = OGROpen(param.dsn->answer, FALSE, NULL);

    if (Ogr_ds == NULL)
        G_fatal_error(_("Unable to open data source <%s>"), param.dsn->answer);

    /* Make a list of available layers */
    navailable_layers = OGR_DS_GetLayerCount(Ogr_ds);
    available_layer_names =
        (char **)G_malloc(navailable_layers * sizeof(char *));

    if (flag.list->answer || flag.tlist->answer)
        G_message(_("Data source <%s> (format '%s') contains %d layers:"),
                  param.dsn->answer,
                  OGR_Dr_GetName(OGR_DS_GetDriver(Ogr_ds)), navailable_layers);
    for (i = 0; i < navailable_layers; i++) {
        Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);
        Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
        Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);

        available_layer_names[i] =
            G_store((char *)OGR_FD_GetName(Ogr_featuredefn));

        if (flag.tlist->answer)
            fprintf(stdout, "%s (%s)\n", available_layer_names[i],
                    OGRGeometryTypeToName(Ogr_geom_type));
        else if (flag.list->answer)
            fprintf(stdout, "%s\n", available_layer_names[i]);
    }
    if (flag.list->answer || flag.tlist->answer) {
        fflush(stdout);
        exit(EXIT_SUCCESS);
    }

    /* Make a list of layers to be imported */
    if (param.layer->answer) {	/* From option */
        nlayers = 0;
        while (param.layer->answers[nlayers])
            nlayers++;

        layer_names = (char **)G_malloc(nlayers * sizeof(char *));
        layers = (int *)G_malloc(nlayers * sizeof(int));

        for (i = 0; i < nlayers; i++) {
            layer_names[i] = G_store(param.layer->answers[i]);
            /* Find it in the source */
            layers[i] = -1;
            for (j = 0; j < navailable_layers; j++) {
                if (strcmp(available_layer_names[j], layer_names[i]) == 0) {
                    layers[i] = j;
                    break;
                }
            }
            if (layers[i] == -1)
                G_fatal_error(_("Layer <%s> not available"), layer_names[i]);
        }
    }
    else {			/* use list of all layers */
        nlayers = navailable_layers;
        layer_names = available_layer_names;
        layers = (int *)G_malloc(nlayers * sizeof(int));
        for (i = 0; i < nlayers; i++)
            layers[i] = i;
    }

    if (param.out->answer) {
        output = G_store(param.out->answer);
    }
    else {
        if (nlayers < 1)
            G_fatal_error(_("No OGR layers available"));
        output = G_store(layer_names[0]);
        G_message(_("All available OGR layers will be imported into vector map <%s>"), output);
    }

    if (!param.outloc->answer) {	/* Check if the map exists */
        if (G_find_vector2(output, G_mapset()) && !overwrite)
            G_fatal_error(_("Vector map <%s> already exists"),
                          output);
    }

    /* Get first imported layer to use for extents and projection check */
    Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layers[0]);

    if (flag.region->answer) {
        if (param.spat->answer)
            G_fatal_error(_("Select either the current region flag or the spatial option, not both"));

        G_get_window(&cur_wind);
        xmin = cur_wind.west;
        xmax = cur_wind.east;
        ymin = cur_wind.south;
        ymax = cur_wind.north;
    }
    if (param.spat->answer) {
        /* See as reference: gdal/ogr/ogr_capi_test.c */

        /* cut out a piece of the map */
        /* order: xmin,ymin,xmax,ymax */
        arg_s_num = 0;
        i = 0;
        while (param.spat->answers[i]) {
            if (i == 0)
                xmin = atof(param.spat->answers[i]);
            if (i == 1)
                ymin = atof(param.spat->answers[i]);
            if (i == 2)
                xmax = atof(param.spat->answers[i]);
            if (i == 3)
                ymax = atof(param.spat->answers[i]);
            arg_s_num++;
            i++;
        }
        if (arg_s_num != 4)
            G_fatal_error(_("4 parameters required for 'spatial' parameter"));
    }
    if (param.spat->answer || flag.region->answer) {
        G_debug(2, "cut out with boundaries: xmin:%f ymin:%f xmax:%f ymax:%f",
                xmin, ymin, xmax, ymax);

        /* in theory this could be an irregular polygon */
        poSpatialFilter = OGR_G_CreateGeometry(wkbPolygon);
        Ogr_oRing = OGR_G_CreateGeometry(wkbLinearRing);
        OGR_G_AddPoint(Ogr_oRing, xmin, ymin, 0.0);
        OGR_G_AddPoint(Ogr_oRing, xmin, ymax, 0.0);
        OGR_G_AddPoint(Ogr_oRing, xmax, ymax, 0.0);
        OGR_G_AddPoint(Ogr_oRing, xmax, ymin, 0.0);
        OGR_G_AddPoint(Ogr_oRing, xmin, ymin, 0.0);
        OGR_G_AddGeometryDirectly(poSpatialFilter, Ogr_oRing);

        OGR_L_SetSpatialFilter(Ogr_layer, poSpatialFilter);
    }

    if (param.where->answer) {
        /* select by attribute */
        OGR_L_SetAttributeFilter(Ogr_layer, param.where->answer);
    }

    /* fetch boundaries */
    if ((OGR_L_GetExtent(Ogr_layer, &oExt, 1)) == OGRERR_NONE) {
        G_get_window(&cellhd);
        cellhd.north = oExt.MaxY;
        cellhd.south = oExt.MinY;
        cellhd.west = oExt.MinX;
        cellhd.east = oExt.MaxX;
        cellhd.rows = 20;	/* TODO - calculate useful values */
        cellhd.cols = 20;
        cellhd.ns_res = (cellhd.north - cellhd.south) / cellhd.rows;
        cellhd.ew_res = (cellhd.east - cellhd.west) / cellhd.cols;
    }
    else {
        cellhd.north = 1.;
        cellhd.south = 0.;
        cellhd.west = 0.;
        cellhd.east = 1.;
        cellhd.top = 1.;
        cellhd.bottom = 1.;
        cellhd.rows = 1;
        cellhd.rows3 = 1;
        cellhd.cols = 1;
        cellhd.cols3 = 1;
        cellhd.depths = 1;
        cellhd.ns_res = 1.;
        cellhd.ns_res3 = 1.;
        cellhd.ew_res = 1.;
        cellhd.ew_res3 = 1.;
        cellhd.tb_res = 1.;
    }

    /* suppress boundary splitting ? */
    if (flag.no_clean->answer) {
        split_distance = -1.;
    }
    else {
        split_distance = 0.;
        area_size =
            sqrt((cellhd.east - cellhd.west) * (cellhd.north - cellhd.south));
    }

    /* Fetch input map projection in GRASS form. */
    proj_info = NULL;
    proj_units = NULL;
    Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer);	/* should not be freed later */

    /* Do we need to create a new location? */
    if (param.outloc->answer != NULL) {
        /* Convert projection information non-interactively as we can't
         * assume the user has a terminal open */
        if (GPJ_osr_to_grass(&cellhd, &proj_info,
                             &proj_units, Ogr_projection, 0) < 0) {
            G_fatal_error(_("Unable to convert input map projection to GRASS "
                            "format; cannot create new location."));
        }
        else {
            G_make_location(param.outloc->answer, &cellhd,
                            proj_info, proj_units, NULL);
            G_message(_("Location <%s> created"), param.outloc->answer);
        }

        /* If the i flag is set, clean up? and exit here */
        if(flag.no_import->answer)
        {
            exit(EXIT_SUCCESS);
        }
    }
    else {
        int err = 0;

        /* Projection only required for checking so convert non-interactively */
        if (GPJ_osr_to_grass(&cellhd, &proj_info,
                             &proj_units, Ogr_projection, 0) < 0)
            G_warning(_("Unable to convert input map projection information to "
                        "GRASS format for checking"));

        /* Does the projection of the current location match the dataset? */
        /* G_get_window seems to be unreliable if the location has been changed */
        G__get_window(&loc_wind, "", "DEFAULT_WIND", "PERMANENT");
        /* fetch LOCATION PROJ info */
        if (loc_wind.proj != PROJECTION_XY) {
            loc_proj_info = G_get_projinfo();
            loc_proj_units = G_get_projunits();
        }

        if (flag.over->answer) {
            cellhd.proj = loc_wind.proj;
            cellhd.zone = loc_wind.zone;
            G_message(_("Over-riding projection check"));
        }
        else if (loc_wind.proj != cellhd.proj
                 || (err =
                         G_compare_projections(loc_proj_info, loc_proj_units,
                                               proj_info, proj_units)) != TRUE) {
            int i_value;

            strcpy(error_msg,
                   _("Projection of dataset does not"
                     " appear to match current location.\n\n"));

            /* TODO: output this info sorted by key: */
            if (loc_wind.proj != cellhd.proj || err != -2) {
                if (loc_proj_info != NULL) {
                    strcat(error_msg, _("GRASS LOCATION PROJ_INFO is:\n"));
                    for (i_value = 0; i_value < loc_proj_info->nitems;
                            i_value++)
                        sprintf(error_msg + strlen(error_msg), "%s: %s\n",
                                loc_proj_info->key[i_value],
                                loc_proj_info->value[i_value]);
                    strcat(error_msg, "\n");
                }

                if (proj_info != NULL) {
                    strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
                    for (i_value = 0; i_value < proj_info->nitems; i_value++)
                        sprintf(error_msg + strlen(error_msg), "%s: %s\n",
                                proj_info->key[i_value],
                                proj_info->value[i_value]);
                }
                else {
                    strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
                    if (cellhd.proj == PROJECTION_XY)
                        sprintf(error_msg + strlen(error_msg),
                                "Dataset proj = %d (unreferenced/unknown)\n",
                                cellhd.proj);
                    else if (cellhd.proj == PROJECTION_LL)
                        sprintf(error_msg + strlen(error_msg),
                                "Dataset proj = %d (lat/long)\n",
                                cellhd.proj);
                    else if (cellhd.proj == PROJECTION_UTM)
                        sprintf(error_msg + strlen(error_msg),
                                "Dataset proj = %d (UTM), zone = %d\n",
                                cellhd.proj, cellhd.zone);
                    else if (cellhd.proj == PROJECTION_SP)
                        sprintf(error_msg + strlen(error_msg),
                                "Dataset proj = %d (State Plane), zone = %d\n",
                                cellhd.proj, cellhd.zone);
                    else
                        sprintf(error_msg + strlen(error_msg),
                                "Dataset proj = %d (unknown), zone = %d\n",
                                cellhd.proj, cellhd.zone);
                }
            }
            else {
                if (loc_proj_units != NULL) {
                    strcat(error_msg, "GRASS LOCATION PROJ_UNITS is:\n");
                    for (i_value = 0; i_value < loc_proj_units->nitems;
                            i_value++)
                        sprintf(error_msg + strlen(error_msg), "%s: %s\n",
                                loc_proj_units->key[i_value],
                                loc_proj_units->value[i_value]);
                    strcat(error_msg, "\n");
                }

                if (proj_units != NULL) {
                    strcat(error_msg, "Import dataset PROJ_UNITS is:\n");
                    for (i_value = 0; i_value < proj_units->nitems; i_value++)
                        sprintf(error_msg + strlen(error_msg), "%s: %s\n",
                                proj_units->key[i_value],
                                proj_units->value[i_value]);
                }
            }
            sprintf(error_msg + strlen(error_msg),
                    _("\nYou can use the -o flag to %s to override this projection check.\n"),
                    G_program_name());
            strcat(error_msg,
                   _("Consider generating a new location with 'location' parameter"
                     " from input data set.\n"));
            G_fatal_error(error_msg);
        }
        else {
            G_message(_("Projection of input dataset and current location "
                        "appear to match"));
        }
    }

    db_init_string(&sql);
    db_init_string(&strval);

    /* open output vector */
    /* strip any @mapset from vector output name */
    G_find_vector(output, G_mapset());
    Vect_open_new(&Map, output, flag.z->answer != 0);
    Out = &Map;

    n_polygon_boundaries = 0;
    if (!flag.no_clean->answer) {
        /* check if we need a tmp vector */

        /* estimate distance for boundary splitting --> */
        for (layer = 0; layer < nlayers; layer++) {
            layer_id = layers[layer];

            Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id);
            Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);

            n_features = feature_count = 0;

            n_features = OGR_L_GetFeatureCount(Ogr_layer, 1);
            OGR_L_ResetReading(Ogr_layer);

            /* count polygons and isles */
            G_message(_("Counting polygons for %d features (OGR layer <%s>)..."),
                      n_features, layer_names[layer]);
            while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) {
                G_percent(feature_count++, n_features, 1);	/* show something happens */
                /* Geometry */
                Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature);
                if (Ogr_geometry != NULL) {
                    poly_count(Ogr_geometry, (type & GV_BOUNDARY));
                }
                OGR_F_Destroy(Ogr_feature);
            }
        }

        G_debug(1, "n polygon boundaries: %d", n_polygon_boundaries);
        if (n_polygon_boundaries > 50) {
            split_distance =
                area_size / log(n_polygon_boundaries);
            /* divisor is the handle: increase divisor to decrease split_distance */
            split_distance = split_distance / 5.;
            G_debug(1, "root of area size: %f", area_size);
            G_verbose_message(_("Boundary splitting distance in map units: %G"),
                              split_distance);
        }
        /* <-- estimate distance for boundary splitting */

        use_tmp_vect = n_polygon_boundaries > 0;

        if (use_tmp_vect) {
            /* open temporary vector, do the work in the temporary vector
             * at the end copy alive lines to output vector
             * in case of polygons this reduces the coor file size by a factor of 2 to 5
             * only needed when cleaning polygons */
            sprintf(tempvect, "%s_tmp", output);
            G_verbose_message(_("Using temporary vector <%s>"), tempvect);
            Vect_open_new(&Tmp, tempvect, flag.z->answer != 0);
            Out = &Tmp;
        }
    }

    Vect_hist_command(&Map);

    /* Points and lines are written immediately with categories. Boundaries of polygons are
     * written to the vector then cleaned and centroids are calculated for all areas in cleaan vector.
     * Then second pass through finds all centroids in each polygon feature and adds its category
     * to the centroid. The result is that one centroids may have 0, 1 ore more categories
     * of one ore more (more input layers) fields. */
    with_z = 0;
    for (layer = 0; layer < nlayers; layer++) {
        layer_id = layers[layer];

        Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id);
        Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);

        /* Add DB link */
        if (!flag.notab->answer) {
            char *cat_col_name = GV_KEY_COLUMN;

            if (nlayers == 1) {	/* one layer only */
                Fi = Vect_default_field_info(&Map, layer + 1, NULL,
                                             GV_1TABLE);
            }
            else {
                Fi = Vect_default_field_info(&Map, layer + 1, NULL,
                                             GV_MTABLE);
            }

            if (ncnames > 0) {
                cat_col_name = param.cnames->answers[0];
            }
            Vect_map_add_dblink(&Map, layer + 1, layer_names[layer], Fi->table,
                                cat_col_name, Fi->database, Fi->driver);

            ncols = OGR_FD_GetFieldCount(Ogr_featuredefn);
            G_debug(2, "%d columns", ncols);

            /* Create table */
            sprintf(buf, "create table %s (%s integer", Fi->table,
                    cat_col_name);
            db_set_string(&sql, buf);
            for (i = 0; i < ncols; i++) {

                Ogr_field = OGR_FD_GetFieldDefn(Ogr_featuredefn, i);
                Ogr_ftype = OGR_Fld_GetType(Ogr_field);

                G_debug(3, "Ogr_ftype: %i", Ogr_ftype);	/* look up below */

                if (i < ncnames - 1) {
                    Ogr_fieldname = G_store(param.cnames->answers[i + 1]);
                }
                else {
                    /* Change column names to [A-Za-z][A-Za-z0-9_]* */
                    Ogr_fieldname = G_store(OGR_Fld_GetNameRef(Ogr_field));
                    G_debug(3, "Ogr_fieldname: '%s'", Ogr_fieldname);

                    G_str_to_sql(Ogr_fieldname);

                    G_debug(3, "Ogr_fieldname: '%s'", Ogr_fieldname);

                }

                /* avoid that we get the 'cat' column twice */
                if (strcmp(Ogr_fieldname, GV_KEY_COLUMN) == 0) {
                    sprintf(namebuf, "%s_", Ogr_fieldname);
                    Ogr_fieldname = G_store(namebuf);
                }

                /* captial column names are a pain in SQL */
                if (flag.tolower->answer)
                    G_str_to_lower(Ogr_fieldname);

                if (strcmp(OGR_Fld_GetNameRef(Ogr_field), Ogr_fieldname) != 0) {
                    G_warning(_("Column name changed: '%s' -> '%s'"),
                              OGR_Fld_GetNameRef(Ogr_field), Ogr_fieldname);
                }

                /** Simple 32bit integer                     OFTInteger = 0        **/

                /** List of 32bit integers                   OFTIntegerList = 1    **/

                /** Double Precision floating point          OFTReal = 2           **/

                /** List of doubles                          OFTRealList = 3       **/

                /** String of ASCII chars                    OFTString = 4         **/

                /** Array of strings                         OFTStringList = 5     **/

                /** Double byte string (unsupported)         OFTWideString = 6     **/

                /** List of wide strings (unsupported)       OFTWideStringList = 7 **/

                /** Raw Binary data (unsupported)            OFTBinary = 8         **/

                /**                                          OFTDate = 9           **/

                /**                                          OFTTime = 10          **/

                /**                                          OFTDateTime = 11      **/


                if (Ogr_ftype == OFTInteger) {
                    sprintf(buf, ", %s integer", Ogr_fieldname);
                }
                else if (Ogr_ftype == OFTIntegerList) {
                    /* hack: treat as string */
                    sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname,
                            OFTIntegerListlength);
                    G_warning(_("Writing column <%s> with fixed length %d chars (may be truncated)"),
                              Ogr_fieldname, OFTIntegerListlength);
                }
                else if (Ogr_ftype == OFTReal) {
                    sprintf(buf, ", %s double precision", Ogr_fieldname);
#if GDAL_VERSION_NUM >= 1320
                }
                else if (Ogr_ftype == OFTDate) {
                    sprintf(buf, ", %s date", Ogr_fieldname);
                }
                else if (Ogr_ftype == OFTTime) {
                    sprintf(buf, ", %s time", Ogr_fieldname);
                }
                else if (Ogr_ftype == OFTDateTime) {
                    sprintf(buf, ", %s datetime", Ogr_fieldname);
#endif
                }
                else if (Ogr_ftype == OFTString) {
                    int fwidth;

                    fwidth = OGR_Fld_GetWidth(Ogr_field);
                    /* TODO: read all records first and find the longest string length */
                    if (fwidth == 0) {
                        G_warning(_("Width for column %s set to 255 (was not specified by OGR), "
                                    "some strings may be truncated!"),
                                  Ogr_fieldname);
                        fwidth = 255;
                    }
                    sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname,
                            fwidth);
                }
                else if (Ogr_ftype == OFTStringList) {
                    /* hack: treat as string */
                    sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname,
                            OFTIntegerListlength);
                    G_warning(_("Writing column %s with fixed length %d chars (may be truncated)"),
                              Ogr_fieldname, OFTIntegerListlength);
                }
                else {
                    G_warning(_("Column type not supported (%s)"),
                              Ogr_fieldname);
                    buf[0] = 0;
                }
                db_append_string(&sql, buf);
                G_free(Ogr_fieldname);
            }
            db_append_string(&sql, ")");
            G_debug(3, db_get_string(&sql));

            driver =
                db_start_driver_open_database(Fi->driver,
                                              Vect_subst_var(Fi->database,
                                                      &Map));
            if (driver == NULL) {
                G_fatal_error(_("Unable open database <%s> by driver <%s>"),
                              Vect_subst_var(Fi->database, &Map), Fi->driver);
            }

            if (db_execute_immediate(driver, &sql) != DB_OK) {
                db_close_database(driver);
                db_shutdown_driver(driver);
                G_fatal_error(_("Unable to create table: '%s'"),
                              db_get_string(&sql));
            }

            if (db_create_index2(driver, Fi->table, cat_col_name) != DB_OK)
                G_warning(_("Unable to create index for table <%s>, key <%s>"),
                          Fi->table, cat_col_name);

            if (db_grant_on_table
                    (driver, Fi->table, DB_PRIV_SELECT,
                     DB_GROUP | DB_PUBLIC) != DB_OK)
                G_fatal_error(_("Unable to grant privileges on table <%s>"),
                              Fi->table);

            db_begin_transaction(driver);
        }

        /* Import feature */
        cat = 1;
        nogeom = 0;
        OGR_L_ResetReading(Ogr_layer);
        n_features = feature_count = 0;

        n_features = OGR_L_GetFeatureCount(Ogr_layer, 1);

        G_important_message(_("Importing %d features (OGR layer <%s>)..."),
                            n_features, layer_names[layer]);
        while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) {
            G_percent(feature_count++, n_features, 1);	/* show something happens */
            /* Geometry */
            Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature);
            if (Ogr_geometry == NULL) {
                nogeom++;
            }
            else {
                dim = OGR_G_GetCoordinateDimension(Ogr_geometry);
                if (dim > 2)
                    with_z = 1;

                geom(Ogr_geometry, Out, layer + 1, cat, min_area, type,
                     flag.no_clean->answer);
            }

            /* Attributes */
            if (!flag.notab->answer) {
                sprintf(buf, "insert into %s values ( %d", Fi->table, cat);
                db_set_string(&sql, buf);
                for (i = 0; i < ncols; i++) {
                    Ogr_field = OGR_FD_GetFieldDefn(Ogr_featuredefn, i);
                    Ogr_ftype = OGR_Fld_GetType(Ogr_field);
                    if (OGR_F_IsFieldSet(Ogr_feature, i)) {
                        if (Ogr_ftype == OFTInteger || Ogr_ftype == OFTReal) {
                            sprintf(buf, ", %s",
                                    OGR_F_GetFieldAsString(Ogr_feature, i));
#if GDAL_VERSION_NUM >= 1320
                            /* should we use OGR_F_GetFieldAsDateTime() here ? */
                        }
                        else if (Ogr_ftype == OFTDate || Ogr_ftype == OFTTime
                                 || Ogr_ftype == OFTDateTime) {
                            char *newbuf;

                            db_set_string(&strval, (char *)
                                          OGR_F_GetFieldAsString(Ogr_feature,
                                                                 i));
                            db_double_quote_string(&strval);
                            sprintf(buf, ", '%s'", db_get_string(&strval));
                            newbuf = G_str_replace(buf, "/", "-");	/* fix 2001/10/21 to 2001-10-21 */
                            sprintf(buf, "%s", newbuf);
#endif
                        }
                        else if (Ogr_ftype == OFTString ||
                                 Ogr_ftype == OFTIntegerList) {
                            db_set_string(&strval, (char *)
                                          OGR_F_GetFieldAsString(Ogr_feature,
                                                                 i));
                            db_double_quote_string(&strval);
                            sprintf(buf, ", '%s'", db_get_string(&strval));
                        }

                    }
                    else {
                        /* G_warning (_("Column value not set" )); */
                        if (Ogr_ftype == OFTInteger || Ogr_ftype == OFTReal) {
                            sprintf(buf, ", NULL");
#if GDAL_VERSION_NUM >= 1320
                        }
                        else if (Ogr_ftype == OFTString ||
                                 Ogr_ftype == OFTIntegerList ||
                                 Ogr_ftype == OFTDate) {
#else
                        }
                        else if (Ogr_ftype == OFTString ||
                                 Ogr_ftype == OFTIntegerList) {
#endif
                            sprintf(buf, ", ''");
                        }
                    }
                    db_append_string(&sql, buf);
                }
                db_append_string(&sql, " )");
                G_debug(3, db_get_string(&sql));

                if (db_execute_immediate(driver, &sql) != DB_OK) {
                    db_close_database(driver);
                    db_shutdown_driver(driver);
                    G_fatal_error(_("Cannot insert new row: %s"),
                                  db_get_string(&sql));
                }
            }

            OGR_F_Destroy(Ogr_feature);
            cat++;
        }
        G_percent(1, 1, 1);	/* finish it */

        if (!flag.notab->answer) {
            db_commit_transaction(driver);
            db_close_database_shutdown_driver(driver);
        }

        if (nogeom > 0)
            G_warning(_("%d %s without geometry"), nogeom,
                      nogeom == 1 ? "feature" : "features");
    }


    separator = "-----------------------------------------------------";
    G_message("%s", separator);

    if (use_tmp_vect) {
        /* TODO: is it necessary to build here? probably not, consumes time */
        /* GV_BUILD_BASE is sufficient to toggle boundary cleaning */
        Vect_build_partial(&Tmp, GV_BUILD_BASE);
    }

    if (use_tmp_vect && !flag.no_clean->answer &&
            Vect_get_num_primitives(Out, GV_BOUNDARY) > 0) {
        int ret, centr, ncentr, otype, n_overlaps, n_nocat;
        CENTR *Centr;
        struct spatial_index si;
        double x, y, total_area, overlap_area, nocat_area;
        struct bound_box box;
        struct line_pnts *Points;
        int nmodif;

        Points = Vect_new_line_struct();

        G_message("%s", separator);

        G_warning(_("Cleaning polygons, result is not guaranteed!"));

        if (snap >= 0) {
            G_message("%s", separator);
            G_message(_("Snapping boundaries (threshold = %.3e)..."), snap);
            Vect_snap_lines(&Tmp, GV_BOUNDARY, snap, NULL);
        }

        /* It is not to clean to snap centroids, but I have seen data with 2 duplicate polygons
         * (as far as decimal places were printed) and centroids were not identical */
        /* Disabled, because overlapping polygons result in many duplicate centroids anyway */
        /*
           fprintf ( stderr, separator );
           fprintf ( stderr, "Snap centroids (threshold 0.000001):\n" );
           Vect_snap_lines ( &Map, GV_CENTROID, 0.000001, NULL, stderr );
         */

        G_message("%s", separator);
        G_message(_("Breaking polygons..."));
        Vect_break_polygons(&Tmp, GV_BOUNDARY, NULL);

        /* It is important to remove also duplicate centroids in case of duplicate input polygons */
        G_message("%s", separator);
        G_message(_("Removing duplicates..."));
        Vect_remove_duplicates(&Tmp, GV_BOUNDARY | GV_CENTROID, NULL);

        /* in non-pathological cases, the bulk of the cleaning is now done */

        /* Vect_clean_small_angles_at_nodes() can change the geometry so that new intersections
         * are created. We must call Vect_break_lines(), Vect_remove_duplicates()
         * and Vect_clean_small_angles_at_nodes() until no more small angles are found */
        do {
            G_message("%s", separator);
            G_message(_("Breaking boundaries..."));
            Vect_break_lines(&Tmp, GV_BOUNDARY, NULL);

            G_message("%s", separator);
            G_message(_("Removing duplicates..."));
            Vect_remove_duplicates(&Tmp, GV_BOUNDARY, NULL);

            G_message("%s", separator);
            G_message(_("Cleaning boundaries at nodes..."));
            nmodif =
                Vect_clean_small_angles_at_nodes(&Tmp, GV_BOUNDARY, NULL);
        } while (nmodif > 0);

        /* merge boundaries */
        G_message("%s", separator);
        G_message(_("Merging boundaries..."));
        Vect_merge_lines(&Tmp, GV_BOUNDARY, NULL, NULL);

        G_message("%s", separator);
        if (type & GV_BOUNDARY) {	/* that means lines were converted to boundaries */
            G_message(_("Changing boundary dangles to lines..."));
            Vect_chtype_dangles(&Tmp, -1.0, NULL);
        }
        else {
            G_message(_("Removing dangles..."));
            Vect_remove_dangles(&Tmp, GV_BOUNDARY, -1.0, NULL);
        }

        G_message("%s", separator);
        if (type & GV_BOUNDARY) {
            G_message(_("Changing boundary bridges to lines..."));
            Vect_chtype_bridges(&Tmp, NULL);
        }
        else {
            G_message(_("Removing bridges..."));
            Vect_remove_bridges(&Tmp, NULL);
        }

        /* Boundaries are hopefully clean, build areas */
        G_message("%s", separator);
        Vect_build_partial(&Tmp, GV_BUILD_ATTACH_ISLES);

        /* Calculate new centroids for all areas, centroids have the same id as area */
        ncentr = Vect_get_num_areas(&Tmp);
        G_debug(3, "%d centroids/areas", ncentr);

        Centr = (CENTR *) G_calloc(ncentr + 1, sizeof(CENTR));
        Vect_spatial_index_init(&si, 0);
        for (centr = 1; centr <= ncentr; centr++) {
            Centr[centr].valid = 0;
            Centr[centr].cats = Vect_new_cats_struct();
            ret = Vect_get_point_in_area(&Tmp, centr, &x, &y);
            if (ret < 0) {
                G_warning(_("Unable to calculate area centroid"));
                continue;
            }

            Centr[centr].x = x;
            Centr[centr].y = y;
            Centr[centr].valid = 1;
            box.N = box.S = y;
            box.E = box.W = x;
            box.T = box.B = 0;
            Vect_spatial_index_add_item(&si, centr, &box);
        }

        /* Go through all layers and find centroids for each polygon */
        for (layer = 0; layer < nlayers; layer++) {
            G_message("%s", separator);
            G_message(_("Finding centroids for OGR layer <%s>..."), layer_names[layer]);
            layer_id = layers[layer];
            Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id);
            n_features = OGR_L_GetFeatureCount(Ogr_layer, 1);
            OGR_L_ResetReading(Ogr_layer);

            cat = 0;		/* field = layer + 1 */
            G_percent(cat, n_features, 2);
            while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) {
                cat++;
                G_percent(cat, n_features, 2);
                /* Geometry */
                Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature);
                if (Ogr_geometry != NULL) {
                    centroid(Ogr_geometry, Centr, &si, layer + 1, cat,
                             min_area, type);
                }

                OGR_F_Destroy(Ogr_feature);
            }
        }

        /* Write centroids */
        G_message("%s", separator);
        G_message(_("Writing centroids..."));

        n_overlaps = n_nocat = 0;
        total_area = overlap_area = nocat_area = 0.0;
        for (centr = 1; centr <= ncentr; centr++) {
            double area;

            G_percent(centr, ncentr, 2);

            area = Vect_get_area_area(&Tmp, centr);
            total_area += area;

            if (!(Centr[centr].valid)) {
                continue;
            }

            if (Centr[centr].cats->n_cats == 0) {
                nocat_area += area;
                n_nocat++;
                continue;
            }

            if (Centr[centr].cats->n_cats > 1) {
                Vect_cat_set(Centr[centr].cats, nlayers + 1,
                             Centr[centr].cats->n_cats);
                overlap_area += area;
                n_overlaps++;
            }

            Vect_reset_line(Points);
            Vect_append_point(Points, Centr[centr].x, Centr[centr].y, 0.0);
            if (type & GV_POINT)
                otype = GV_POINT;
            else
                otype = GV_CENTROID;
            Vect_write_line(&Tmp, otype, Points, Centr[centr].cats);
        }
        if (Centr)
            G_free(Centr);

        Vect_spatial_index_destroy(&si);

        if (n_overlaps > 0) {
            G_warning(_("%d areas represent more (overlapping) features, because polygons overlap "
                        "in input layer(s). Such areas are linked to more than 1 row in attribute table. "
                        "The number of features for those areas is stored as category in layer %d"),
                      n_overlaps, nlayers + 1);
        }

        G_message("%s", separator);

        Vect_hist_write(&Map, separator);
        Vect_hist_write(&Map, "\n");
        sprintf(buf, _("%d input polygons\n"), n_polygons);
        G_message(_("%d input polygons"), n_polygons);
        Vect_hist_write(&Map, buf);

        sprintf(buf, _("Total area: %G (%d areas)\n"), total_area, ncentr);
        G_message(_("Total area: %G (%d areas)"), total_area, ncentr);
        Vect_hist_write(&Map, buf);

        sprintf(buf, _("Overlapping area: %G (%d areas)\n"), overlap_area,
                n_overlaps);
        G_message(_("Overlapping area: %G (%d areas)"), overlap_area,
                  n_overlaps);
        Vect_hist_write(&Map, buf);

        sprintf(buf, _("Area without category: %G (%d areas)\n"), nocat_area,
                n_nocat);
        G_message(_("Area without category: %G (%d areas)"), nocat_area,
                  n_nocat);
        Vect_hist_write(&Map, buf);
        G_message("%s", separator);
    }

    /* needed?
     * OGR_DS_Destroy( Ogr_ds );
     */

    if (use_tmp_vect) {
        /* Copy temporary vector to output vector */
        Vect_copy_map_lines(&Tmp, &Map);
        /* release memory occupied by topo, we may need that memory for main output */
        Vect_set_release_support(&Tmp);
        Vect_close(&Tmp);
        Vect_delete(tempvect);
    }

    Vect_build(&Map);
    Vect_close(&Map);

    /* -------------------------------------------------------------------- */
    /*      Extend current window based on dataset.                         */
    /* -------------------------------------------------------------------- */
    if (flag.extend->answer) {
        G_get_default_window(&loc_wind);

        loc_wind.north = MAX(loc_wind.north, cellhd.north);
        loc_wind.south = MIN(loc_wind.south, cellhd.south);
        loc_wind.west = MIN(loc_wind.west, cellhd.west);
        loc_wind.east = MAX(loc_wind.east, cellhd.east);

        loc_wind.rows = (int)ceil((loc_wind.north - loc_wind.south)
                                  / loc_wind.ns_res);
        loc_wind.south = loc_wind.north - loc_wind.rows * loc_wind.ns_res;

        loc_wind.cols = (int)ceil((loc_wind.east - loc_wind.west)
                                  / loc_wind.ew_res);
        loc_wind.east = loc_wind.west + loc_wind.cols * loc_wind.ew_res;

        G__put_window(&loc_wind, "../PERMANENT", "DEFAULT_WIND");
    }

    if (with_z && !flag.z->answer)
        G_warning(_("Input data contains 3D features. Created vector is 2D only, "
                    "use -z flag to import 3D vector."));

    exit(EXIT_SUCCESS);
}
Exemple #21
0
/*!
  \brief Writes feature on level 1 (OGR interface)

  \param Map pointer to Map_info structure
  \param type feature type
  \param points pointer to line_pnts structure (feature geometry)
  \param cats pointer to line_cats structure (feature categories)

  \return feature offset into file
  \return -1 on error
*/
off_t V1_write_line_ogr(struct Map_info *Map, int type,
                        const struct line_pnts *points,
                        const struct line_cats *cats)
{
    int i, cat, ret;

    struct field_info *Fi;
    struct Format_info_ogr *fInfo;

    OGRGeometryH       Ogr_geometry;
    OGRFeatureH        Ogr_feature;
    OGRFeatureDefnH    Ogr_featuredefn;
    OGRwkbGeometryType Ogr_geom_type;

    if (!Map->fInfo.ogr.layer) {
        if (V2_open_new_ogr(Map, type) < 0)
            return -1;
    }

    cat = -1; /* no attributes to be written */
    if (cats->n_cats > 0) {
        /* check for attributes */
        Fi = Vect_get_dblink(Map, 0);
        if (Fi) {
            if (!Vect_cat_get(cats, Fi->number, &cat))
                G_warning(_("No category defined for layer %d"), Fi->number);
            if (cats->n_cats > 1) {
                G_warning(_("Feature has more categories, using "
                            "category %d (from layer %d)"),
                          cat, cats->field[0]);
            }
        }
    }

    fInfo = &(Map->fInfo.ogr);
    Ogr_featuredefn = OGR_L_GetLayerDefn(fInfo->layer);
    Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);

    /* determine matching OGR feature geometry type */
    /* NOTE: centroids are not supported in OGR,
     *       pseudotopo holds virtual centroids */
    /* NOTE: boundaries are not supported in OGR,
     *       pseudotopo treats polygons as boundaries */

    if (type & (GV_POINT | GV_KERNEL)) {
        if (Ogr_geom_type != wkbPoint &&
                Ogr_geom_type != wkbPoint25D) {
            G_warning(_("Feature is not a point. Skipping."));
            return -1;
        }
        Ogr_geometry = OGR_G_CreateGeometry(wkbPoint);
    }
    else if (type & GV_LINE) {
        if (Ogr_geom_type != wkbLineString &&
                Ogr_geom_type != wkbLineString25D) {
            G_warning(_("Feature is not a line. Skipping."));
            return -1;
        }
        Ogr_geometry = OGR_G_CreateGeometry(wkbLineString);
    }
    else if (type & GV_BOUNDARY) {
        if (Ogr_geom_type != wkbPolygon) {
            G_warning(_("Feature is not a polygon. Skipping."));
            return -1;
        }
        Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
    }
    else if (type & GV_FACE) {
        if (Ogr_geom_type != wkbPolygon25D) {
            G_warning(_("Feature is not a face. Skipping."));
            return -1;
        }
        Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon25D);
    }
    else {
        G_warning(_("Unsupported feature type (%d)"), type);
        return -1;
    }

    G_debug(3, "V1_write_line_ogr(): type = %d", type);

    if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) {
        /* create exterior ring */
        OGRGeometryH Ogr_ring;
        int npoints;

        npoints = points->n_points - 1;
        Ogr_ring = OGR_G_CreateGeometry(wkbLinearRing);
        if (points->x[0] != points->x[npoints] ||
                points->y[0] != points->y[npoints] ||
                points->z[0] != points->z[npoints]) {
            G_warning(_("Boundary is not closed. Skipping."));
            return -1;
        }

        /* add points */
        for (i = 0; i < points->n_points; i++) {
            OGR_G_AddPoint(Ogr_ring, points->x[i], points->y[i],
                           points->z[i]);
        }
        OGR_G_AddGeometry(Ogr_geometry, Ogr_ring);
    }
    else {
        for (i = 0; i < points->n_points; i++) {
            OGR_G_AddPoint(Ogr_geometry, points->x[i], points->y[i],
                           points->z[i]);
        }
    }

    G_debug(4, "   n_points = %d", points->n_points);

    /* create feature & set geometry */
    Ogr_feature = OGR_F_Create(Ogr_featuredefn);
    OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);

    /* write attributes */
    if (cat > -1 && fInfo->dbdriver) {
        write_attributes(fInfo->dbdriver,
                         cat, Fi, fInfo->layer, Ogr_feature);
        G_free(Fi);
    }
    /* write feature into layer */
    ret = OGR_L_CreateFeature(fInfo->layer, Ogr_feature);

    /* update offset array */
    if (fInfo->offset_num >= fInfo->offset_alloc) {
        fInfo->offset_alloc += 1000;
        fInfo->offset = (int *) G_realloc(fInfo->offset,
                                          fInfo->offset_alloc *
                                          sizeof(int));
    }
    /* how to deal with OGRNullFID ? */
    fInfo->offset[fInfo->offset_num] = (int)OGR_F_GetFID(Ogr_feature);

    /* destroy */
    OGR_G_DestroyGeometry(Ogr_geometry);
    OGR_F_Destroy(Ogr_feature);

    if (ret != OGRERR_NONE)
        return -1;

    return fInfo->offset_num++;
}
Exemple #22
0
static CPLErr
EmitPolygonToLayer( OGRLayerH hOutLayer, int iPixValField,
                    RPolygonF *poRPoly, double *padfGeoTransform )

{
    OGRFeatureH hFeat;
    OGRGeometryH hPolygon;

/* -------------------------------------------------------------------- */
/*      Turn bits of lines into coherent rings.                         */
/* -------------------------------------------------------------------- */
    poRPoly->Coalesce();

/* -------------------------------------------------------------------- */
/*      Create the polygon geometry.                                    */
/* -------------------------------------------------------------------- */
    size_t iString;

    hPolygon = OGR_G_CreateGeometry( wkbPolygon );
    
    for( iString = 0; iString < poRPoly->aanXY.size(); iString++ )
    {
        std::vector<int> &anString = poRPoly->aanXY[iString];
        OGRGeometryH hRing = OGR_G_CreateGeometry( wkbLinearRing );

        int iVert;

        // we go last to first to ensure the linestring is allocated to 
        // the proper size on the first try.
        for( iVert = anString.size()/2 - 1; iVert >= 0; iVert-- )
        {
            double dfX, dfY;
            int    nPixelX, nPixelY;
            
            nPixelX = anString[iVert*2];
            nPixelY = anString[iVert*2+1];

            dfX = padfGeoTransform[0] 
                + nPixelX * padfGeoTransform[1]
                + nPixelY * padfGeoTransform[2];
            dfY = padfGeoTransform[3] 
                + nPixelX * padfGeoTransform[4]
                + nPixelY * padfGeoTransform[5];

            OGR_G_SetPoint_2D( hRing, iVert, dfX, dfY );
        }

        OGR_G_AddGeometryDirectly( hPolygon, hRing );
    }
    
/* -------------------------------------------------------------------- */
/*      Create the feature object.                                      */
/* -------------------------------------------------------------------- */
    hFeat = OGR_F_Create( OGR_L_GetLayerDefn( hOutLayer ) );

    OGR_F_SetGeometryDirectly( hFeat, hPolygon );

    if( iPixValField >= 0 )
        OGR_F_SetFieldDouble( hFeat, iPixValField, (double)poRPoly->fPolyValue );

/* -------------------------------------------------------------------- */
/*      Write the to the layer.                                         */
/* -------------------------------------------------------------------- */
    CPLErr eErr = CE_None;

    if( OGR_L_CreateFeature( hOutLayer, hFeat ) != OGRERR_NONE )
        eErr = CE_Failure;

    OGR_F_Destroy( hFeat );

    return eErr;
}
Exemple #23
0
/* What we need:  specific condition, is walk in , tactic, distance elevation
 * minsteps, maxsteps, waterdrops, pump/roll, fwa id.
 */
int main( int argc, char *argv[] )
{
    GDALAllRegister();
    OGRRegisterAll();

    const char *pszInputfile = NULL;
    const char *pszOutputfile = NULL;
    const char *pszOutputFormat = "CSV";
    char **papszCreateOptions = NULL;
    const char *pszDataPath = NULL;
    const char *pszFpuCode = NULL;
    int nLimit = 0;
    int bProgress = TRUE;
    double dfMaxX, dfMinX, dfMaxY, dfMinY;
    int bLimit = FALSE;
    double dfBuffer = 0.0;

    int i = 1;
    while( i < argc )
    {
        if( EQUAL( argv[i], "-p" ) )
        {
            bProgress = TRUE;
        }
        else if( EQUAL( argv[i], "-d" ) )
        {
            pszDataPath = argv[++i];
        }
        else if( EQUAL( argv[i], "-of" ) )
        {
            pszOutputFormat = argv[++i];
        }        
        else if( EQUAL( argv[i], "-co" ) )
        {
            papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] );
        }
        else if( EQUAL( argv[i], "-sl" ) )
        {
            dfMaxX = atof(argv[++i]);
            dfMinX = atof(argv[++i]);
            dfMaxY = atof(argv[++i]);
            dfMinY = atof(argv[++i]);
            bLimit = TRUE;
        }
        else if( EQUAL( argv[i], "-fpu" ) )
        {
            pszFpuCode = argv[++i];
        }
        else if( EQUAL( argv[i], "-b" ) )
        {
            dfBuffer = atof( argv[++i] );
        }
        else if( EQUAL( argv[i], "-l" ) )
        {
            nLimit = atoi( argv[++i] );
        }        
        else if( EQUAL( argv[i], "-h" ) )
        {
            Usage();
        }
        else if( pszInputfile == NULL )
        {
            pszInputfile = argv[i];
        }
        else if( pszOutputfile == NULL )
        {
            pszOutputfile = argv[i];
        }
        else
        {
            Usage();
        }
        i++;
    }

    if( pszInputfile == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, "No input file provided\n");
        Usage();
    }
    if( pszOutputfile == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, "Invalid output selected, "
                "use database and table or output file\n" );
        Usage();
    }

    pszDataPath = CPLGetConfigOption( "OMFFR_DATA", NULL );

    OGRDataSourceH hInputDS = OGROpen( pszInputfile, FALSE, NULL );
    if( hInputDS == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, "Cannot open input file\n" );
        Usage();
    }

    int year, num, day;
    const char *dow, *disc_time;
    int bi;
    double ros;
    int fuel;
    const char *spec_cond;
    int slope, walkin;
    const char *tactic;
    double dist;
    int elev;
    double ltow;
    int minsteps = 250;
    int maxsteps = 10000;
    const char *sunrise, *sunset;
    int waterdrops, pumproll;
    char *abyFwa;
    const char *fwaid;
    double lon, lat;

    OGRLayerH hInputLayer;
    hInputLayer = OGR_DS_GetLayerByName( hInputDS, CPLGetBasename( pszInputfile ) );
    OGRFeatureDefnH hInputFeatureDefn;

    OGRFeatureH hInputFeature;

    OGRGeometryH hGeometry;

    hInputFeatureDefn = OGR_L_GetLayerDefn( hInputLayer );

    const char *pszTmpFilename =CPLFormFilename( pszDataPath, "irs/FWA", ".dat" );
    std::vector<CFWA>fwas = LoadFwas( pszTmpFilename );
    
    int nFeatures = OGR_L_GetFeatureCount( hInputLayer, TRUE );
    FILE *fout = fopen( pszOutputfile, "w" );

    //CFWA *fwa;

    Random random;

    char pszDb[8192];
    sprintf( pszDb, "%s/omffr.sqlite", pszDataPath );

    IRSDataAccess *poDA = IRSDataAccess::Create( 0, pszDb );
    int rc;
    sqlite3 *db;
    rc = sqlite3_open_v2( pszDb, &db, SQLITE_OPEN_READONLY, NULL );
    rc = sqlite3_enable_load_extension( db, 1 );
    rc = sqlite3_load_extension( db, "/usr/local/lib/libspatialite.so", 0, NULL );
    sqlite3_stmt *stmt;
    rc = sqlite3_prepare_v2( db, "SELECT * from fwa join fwa_bndry USING(fwa_gis_id) " \
                                 "WHERE ST_Contains(fwa_bndry.geometry, MakePoint(?, ?, 4269))",
                                 -1, &stmt, NULL );

    if(rc)
    {
        CPLError( CE_Failure, CPLE_AppDefined, "Could not open DB");
    }

    GDALTermProgress( 0.0, NULL, NULL );
    OGR_L_ResetReading( hInputLayer );
    const char *pszFwaName;
    int nDone = 0;
    while( ( hInputFeature = OGR_L_GetNextFeature( hInputLayer ) ) != NULL )
    {
        /*
        fwaid = OGR_F_GetFieldAsString( hInputFeature,
                                        OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                              "fwa_name" ) );
        abyFwa = CPLStrdup( fwaid );
        LaunderFwaName( abyFwa );
        fwa = FindFwa( fwas, abyFwa );
        if( fwa == NULL )
        {
            CPLError( CE_Warning, CPLE_FileIO,
                    "Could not load fwa (%s)from file, missing\n", abyFwa );
            continue;
        }
        */
        /* Get fwa by point */
        hGeometry = OGR_F_GetGeometryRef( hInputFeature );
        /* Try to handle non-geometry types (csv) */
        if( hGeometry != NULL )
        {
            lat = OGR_G_GetY( hGeometry, 0 );
            lon = OGR_G_GetX( hGeometry, 0 );
        }
        else
        {
            lat = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, 
                                                            "Y") );
            lon = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, 
                                                            "X") );
        }

        std::string oFwaName = poDA->PointQuery( "fwa_bndry", "fwa_lndr_name",
                                                 lon, lat );
        rc = sqlite3_bind_double( stmt, 1, lon );
        rc = sqlite3_bind_double( stmt, 2, lat );
        //sqlite3_bind_text( stmt, 1, oFwaName.c_str(), -1, SQLITE_TRANSIENT);
        rc = sqlite3_step( stmt );
        if( rc != SQLITE_ROW && rc != SQLITE_DONE )
        {
            CPLError( CE_Warning, CPLE_FileIO,
                    "Could not load fwa (%s)from file, missing\n", oFwaName.c_str() );
            sqlite3_reset(stmt);
            continue;
        }

        int nFwaWalkIn, nFwaHead, nFwaTail, nFwaPara, nFwaAttackD;
        int nFwaWaterDrop, nFwaPumpRoll;
        nFwaWalkIn = sqlite3_column_int( stmt, 4 );
        nFwaHead = sqlite3_column_int( stmt, 6 );
        nFwaTail = sqlite3_column_int( stmt, 7 );
        nFwaPara = sqlite3_column_int( stmt, 8 );
        nFwaAttackD = sqlite3_column_int( stmt, 9 );
        nFwaWaterDrop = sqlite3_column_int( stmt, 10 );
        nFwaPumpRoll = sqlite3_column_int( stmt, 5 );

        year = OGR_F_GetFieldAsInteger( hInputFeature,
                                        OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                              "year" ) );
        num = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                           "fire_num" ) );
        day = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                           "day" ) );
        dow = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                           "week_day" ) );
        disc_time = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                                "disc_time" ) );
        bi = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                          "bi" ) );
        ros = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                           "ros" ) );
        fuel = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                            "fuel" ) );
        spec_cond = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                                "spec_cond" ) );
        slope = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                             "slope_perc" ) );
        //if( random.rand3() * 100 > fwa->GetWalkInPct() )
        if( random.rand3() * 100 > nFwaWalkIn )
            walkin = 0;
        else
            walkin = 1;
        //if( fwa->GetHead() == 100 )
        if( nFwaHead == 100 )
            tactic = "HEAD\0";
        //else if( fwa->GetTail() == 100 )
        else if( nFwaTail == 100 )
            tactic = "TAIL\0";
        //else if( fwa->GetParallel() == 100 )
        else if( nFwaTail == 100 )
            tactic = "PARALLEL\0";
        else
        {
            int r = (int)(random.rand3() * 100 );
            int total = 0;
            if( r < nFwaHead )
                tactic = "HEAD\0";
            else if( r < nFwaTail + nFwaTail )
                tactic = "TAIL\0";
            else
                tactic = "PARALLEL\0";
        }
        //dist = fwa->GetAttackDist();
        dist = nFwaAttackD;
        elev = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                            "elev" ) );
        ltow = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                           "ratio" ) );
        sunrise = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                             "sunrise" ) );
        sunset = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn,
                                                             "sunset" ) );
        //if( fwa->GetWaterDrops() )
        if( nFwaWaterDrop )
            waterdrops = TRUE;
        else
            waterdrops = FALSE;
        //if( fwa->GetPumpnRoll() )
        if( nFwaPumpRoll )
            pumproll = TRUE;
        else
            pumproll = FALSE;

        fprintf( fout, "%d %d %d %s %s "
                       "%d %lf %d %s %d "
                       "%d %s %lf %d %lf "
                       "%d %d %s %s %d "
                       "%d %s %lf %lf\n",
                 year, num, day, dow, disc_time,
                 bi, ros, fuel, spec_cond, slope, 
                 walkin, tactic, dist, elev, ltow, 
                 minsteps, maxsteps, sunrise, sunset, waterdrops, 
                 pumproll, /* abyFwa */ oFwaName.c_str(), lat, lon );

        sqlite3_reset(stmt);
        nDone++;
        GDALTermProgress( (float)nDone / (float)nFeatures, NULL, NULL );
    }
    GDALTermProgress( 1.0, NULL, NULL );
    fclose( fout );
    OGR_DS_Destroy( hInputDS );

    return 0;
}
Exemple #24
0
MAIN_START(argc, argv)
{
    // Check that we are running against at least GDAL 1.4.
    // Note to developers: if we use newer API, please change the requirement.
    if( atoi(GDALVersionInfo("VERSION_NUM")) < 1400 )
    {
        fprintf(stderr,
                "At least, GDAL >= 1.4.0 is required for this version of %s, "
                "which was compiled against GDAL %s\n",
                argv[0], GDAL_RELEASE_NAME);
        exit(1);
    }

    GDALAllRegister();
    OGRRegisterAll();

    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

/* -------------------------------------------------------------------- */
/*      Get commandline arguments other than the GDAL raster filenames. */
/* -------------------------------------------------------------------- */
    const char* pszIndexLayerName = nullptr;
    const char *index_filename = nullptr;
    const char *tile_index = "location";
    const char* pszDriverName = nullptr;
    size_t nMaxFieldSize = 254;
    bool write_absolute_path = false;
    char* current_path = nullptr;
    bool skip_different_projection = false;
    const char *pszTargetSRS = "";
    bool bSetTargetSRS = false;
    const char* pszSrcSRSName = nullptr;
    int i_SrcSRSName = -1;
    bool bSrcSRSFormatSpecified = false;
    SrcSRSFormat eSrcSRSFormat = FORMAT_AUTO;

    int iArg = 1;  // Used after for.
    for( ; iArg < argc; iArg++ )
    {
        if( EQUAL(argv[iArg], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against "
                   "GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            CSLDestroy( argv );
            return 0;
        }
        else if( EQUAL(argv[iArg],"--help") )
            Usage(nullptr);
        else if( (strcmp(argv[iArg],"-f") == 0 || strcmp(argv[iArg],"-of") == 0) )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszDriverName = argv[++iArg];
        }
        else if( strcmp(argv[iArg],"-lyr_name") == 0 )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszIndexLayerName = argv[++iArg];
        }
        else if( strcmp(argv[iArg],"-tileindex") == 0 )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            tile_index = argv[++iArg];
        }
        else if( strcmp(argv[iArg],"-t_srs") == 0 )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszTargetSRS = argv[++iArg];
            bSetTargetSRS = true;
        }
        else if ( strcmp(argv[iArg],"-write_absolute_path") == 0 )
        {
            write_absolute_path = true;
        }
        else if ( strcmp(argv[iArg],"-skip_different_projection") == 0 )
        {
            skip_different_projection = true;
        }
        else if( strcmp(argv[iArg], "-src_srs_name") == 0 )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszSrcSRSName = argv[++iArg];
        }
        else if( strcmp(argv[iArg], "-src_srs_format") == 0 )
        {
            const char* pszFormat;
            bSrcSRSFormatSpecified = true;
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszFormat = argv[++iArg];
            if( EQUAL(pszFormat, "AUTO") )
                eSrcSRSFormat = FORMAT_AUTO;
            else if( EQUAL(pszFormat, "WKT") )
                eSrcSRSFormat = FORMAT_WKT;
            else if( EQUAL(pszFormat, "EPSG") )
                eSrcSRSFormat = FORMAT_EPSG;
            else if( EQUAL(pszFormat, "PROJ") )
                eSrcSRSFormat = FORMAT_PROJ;
        }
        else if( argv[iArg][0] == '-' )
            Usage(CPLSPrintf("Unknown option name '%s'", argv[iArg]));
        else if( index_filename == nullptr )
        {
            index_filename = argv[iArg];
            iArg++;
            break;
        }
    }

    if( index_filename == nullptr )
        Usage("No index filename specified.");
    if( iArg == argc )
        Usage("No file to index specified.");
    if( bSrcSRSFormatSpecified && pszSrcSRSName == nullptr )
        Usage("-src_srs_name must be specified when -src_srs_format is "
              "specified.");

/* -------------------------------------------------------------------- */
/*      Create and validate target SRS if given.                        */
/* -------------------------------------------------------------------- */
    OGRSpatialReferenceH hTargetSRS = nullptr;
    if( bSetTargetSRS )
    {
        if( skip_different_projection )
        {
            fprintf( stderr,
                     "Warning : -skip_different_projection does not apply "
                     "when -t_srs is requested.\n" );
        }
        hTargetSRS = OSRNewSpatialReference("");
        OSRSetAxisMappingStrategy(hTargetSRS, OAMS_TRADITIONAL_GIS_ORDER);
        // coverity[tainted_data]
        if( OSRSetFromUserInput( hTargetSRS, pszTargetSRS ) != CE_None )
        {
            OSRDestroySpatialReference( hTargetSRS );
            fprintf( stderr, "Invalid target SRS `%s'.\n",
                     pszTargetSRS );
            exit(1);
        }
    }

/* -------------------------------------------------------------------- */
/*      Open or create the target datasource                            */
/* -------------------------------------------------------------------- */
    GDALDatasetH hTileIndexDS = GDALOpenEx(
        index_filename, GDAL_OF_VECTOR | GDAL_OF_UPDATE, nullptr, nullptr, nullptr );
    OGRLayerH hLayer = nullptr;
    CPLString osFormat;
    if( hTileIndexDS != nullptr )
    {
        GDALDriverH hDriver = GDALGetDatasetDriver(hTileIndexDS);
        if( hDriver )
            osFormat = GDALGetDriverShortName(hDriver);

        if( GDALDatasetGetLayerCount(hTileIndexDS) == 1 )
        {
            hLayer = GDALDatasetGetLayer(hTileIndexDS, 0);
        }
        else
        {
            if( pszIndexLayerName == nullptr )
            {
                printf( "-lyr_name must be specified.\n" );
                exit( 1 );
            }
            CPLPushErrorHandler(CPLQuietErrorHandler);
            hLayer = GDALDatasetGetLayerByName(hTileIndexDS, pszIndexLayerName);
            CPLPopErrorHandler();
        }
    }
    else
    {
        printf( "Creating new index file...\n" );
        if( pszDriverName == nullptr )
        {
            std::vector<CPLString> aoDrivers =
                GetOutputDriversFor(index_filename, GDAL_OF_VECTOR);
            if( aoDrivers.empty() )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                        "Cannot guess driver for %s", index_filename);
                exit( 10 );
            }
            else
            {
                if( aoDrivers.size() > 1 )
                {
                    CPLError( CE_Warning, CPLE_AppDefined,
                            "Several drivers matching %s extension. Using %s",
                            CPLGetExtension(index_filename), aoDrivers[0].c_str() );
                }
                osFormat = aoDrivers[0];
            }
        }
        else
        {
            osFormat = pszDriverName;
        }
        if( !EQUAL(osFormat, "ESRI Shapefile") )
            nMaxFieldSize = 0;


        GDALDriverH hDriver = GDALGetDriverByName( osFormat.c_str() );
        if( hDriver == nullptr )
        {
            printf( "%s driver not available.\n", osFormat.c_str() );
            exit( 1 );
        }

        hTileIndexDS = 
            GDALCreate( hDriver, index_filename, 0, 0, 0, GDT_Unknown, nullptr );
    }

    if( hTileIndexDS != nullptr && hLayer == nullptr )
    {
        OGRSpatialReferenceH hSpatialRef = nullptr;
        char* pszLayerName = nullptr;
        if( pszIndexLayerName == nullptr )
        {
            VSIStatBuf sStat;
            if( EQUAL(osFormat, "ESRI Shapefile") ||
                VSIStat(index_filename, &sStat) == 0 )
            {
                pszLayerName = CPLStrdup(CPLGetBasename(index_filename));
            }
            else
            {
                printf( "-lyr_name must be specified.\n" );
                exit( 1 );
            }
        }
        else
        {
            pszLayerName = CPLStrdup(pszIndexLayerName);
        }

        /* get spatial reference for output file from target SRS (if set) */
        /* or from first input file */
        if( bSetTargetSRS )
        {
            hSpatialRef = OSRClone( hTargetSRS );
        }
        else
        {
            GDALDatasetH hDS = GDALOpen( argv[iArg], GA_ReadOnly );
            if( hDS )
            {
                const char* pszWKT = GDALGetProjectionRef(hDS);
                if (pszWKT != nullptr && pszWKT[0] != '\0')
                {
                    hSpatialRef = OSRNewSpatialReference(pszWKT);
                    OSRSetAxisMappingStrategy(hSpatialRef, OAMS_TRADITIONAL_GIS_ORDER);
                }
                GDALClose(hDS);
            }
        }

        hLayer =
            GDALDatasetCreateLayer( hTileIndexDS, pszLayerName, hSpatialRef,
                                wkbPolygon, nullptr );
        CPLFree(pszLayerName);
        if( hSpatialRef )
            OSRRelease(hSpatialRef);

        if( hLayer )
        {
            OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString );
            if( nMaxFieldSize )
                OGR_Fld_SetWidth( hFieldDefn, static_cast<int>(nMaxFieldSize));
            OGR_L_CreateField( hLayer, hFieldDefn, TRUE );
            OGR_Fld_Destroy(hFieldDefn);
            if( pszSrcSRSName != nullptr )
            {
                hFieldDefn = OGR_Fld_Create( pszSrcSRSName, OFTString );
                if( nMaxFieldSize )
                    OGR_Fld_SetWidth(hFieldDefn,
                                     static_cast<int>(nMaxFieldSize));
                OGR_L_CreateField( hLayer, hFieldDefn, TRUE );
                OGR_Fld_Destroy(hFieldDefn);
            }
        }
    }

    if( hTileIndexDS == nullptr || hLayer == nullptr )
    {
        fprintf( stderr, "Unable to open/create shapefile `%s'.\n",
                 index_filename );
        exit(2);
    }

    OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hLayer);

    const int ti_field = OGR_FD_GetFieldIndex( hFDefn, tile_index );
    if( ti_field < 0 )
    {
        fprintf( stderr, "Unable to find field `%s' in file `%s'.\n",
                 tile_index, index_filename );
        exit(2);
    }

    if( pszSrcSRSName != nullptr )
        i_SrcSRSName = OGR_FD_GetFieldIndex( hFDefn, pszSrcSRSName );

    // Load in memory existing file names in SHP.
    int nExistingFiles = static_cast<int>(OGR_L_GetFeatureCount(hLayer, FALSE));
    if( nExistingFiles < 0)
        nExistingFiles = 0;

    char** existingFilesTab = nullptr;
    bool alreadyExistingProjectionRefValid = false;
    char* alreadyExistingProjectionRef = nullptr;
    if( nExistingFiles > 0 )
    {
        OGRFeatureH hFeature = nullptr;
        existingFilesTab = static_cast<char **>(
            CPLMalloc(nExistingFiles * sizeof(char*)));
        for( int i = 0; i < nExistingFiles; i++ )
        {
            hFeature = OGR_L_GetNextFeature(hLayer);
            existingFilesTab[i] =
                CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field ));
            if( i == 0 )
            {
                GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly );
                if( hDS )
                {
                    alreadyExistingProjectionRefValid = true;
                    alreadyExistingProjectionRef =
                        CPLStrdup(GDALGetProjectionRef(hDS));
                    GDALClose(hDS);
                }
            }
            OGR_F_Destroy( hFeature );
        }
    }

    if( write_absolute_path )
    {
        current_path = CPLGetCurrentDir();
        if (current_path == nullptr)
        {
            fprintf( stderr,
                     "This system does not support the CPLGetCurrentDir call. "
                     "The option -write_absolute_path will have no effect\n" );
            write_absolute_path = FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      loop over GDAL files, processing.                               */
/* -------------------------------------------------------------------- */
    for( ; iArg < argc; iArg++ )
    {
        char *fileNameToWrite = nullptr;
        VSIStatBuf sStatBuf;

        // Make sure it is a file before building absolute path name.
        if( write_absolute_path && CPLIsFilenameRelative( argv[iArg] ) &&
            VSIStat( argv[iArg], &sStatBuf ) == 0 )
        {
            fileNameToWrite =
                CPLStrdup(CPLProjectRelativeFilename(current_path, argv[iArg]));
        }
        else
        {
            fileNameToWrite = CPLStrdup(argv[iArg]);
        }

        // Checks that file is not already in tileindex.
        {
            int i = 0;  // Used after for.
            for( ; i < nExistingFiles; i++ )
            {
                if (EQUAL(fileNameToWrite, existingFilesTab[i]))
                {
                    fprintf(stderr,
                            "File %s is already in tileindex. Skipping it.\n",
                            fileNameToWrite);
                    break;
                }
            }
            if (i != nExistingFiles)
            {
                CPLFree(fileNameToWrite);
                continue;
            }
        }

        GDALDatasetH hDS = GDALOpen( argv[iArg], GA_ReadOnly );
        if( hDS == nullptr )
        {
            fprintf( stderr, "Unable to open %s, skipping.\n",
                     argv[iArg] );
            CPLFree(fileNameToWrite);
            continue;
        }

        double adfGeoTransform[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
        GDALGetGeoTransform( hDS, adfGeoTransform );
        if( adfGeoTransform[0] == 0.0
            && adfGeoTransform[1] == 1.0
            && adfGeoTransform[3] == 0.0
            && std::abs(adfGeoTransform[5]) == 1.0 )
        {
            fprintf( stderr,
                     "It appears no georeferencing is available for\n"
                     "`%s', skipping.\n",
                     argv[iArg] );
            GDALClose( hDS );
            CPLFree(fileNameToWrite);
            continue;
        }

        const char *projectionRef = GDALGetProjectionRef(hDS);

        // If not set target srs, test that the current file uses same
        // projection as others.
        if( !bSetTargetSRS )
        {
            if( alreadyExistingProjectionRefValid )
            {
                int projectionRefNotNull, alreadyExistingProjectionRefNotNull;
                projectionRefNotNull = projectionRef && projectionRef[0];
                alreadyExistingProjectionRefNotNull =
                    alreadyExistingProjectionRef &&
                    alreadyExistingProjectionRef[0];
                if ((projectionRefNotNull &&
                     alreadyExistingProjectionRefNotNull &&
                     EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) ||
                    (projectionRefNotNull != alreadyExistingProjectionRefNotNull))
                {
                    fprintf(
                        stderr,
                        "Warning : %s is not using the same projection system "
                        "as other files in the tileindex.\n"
                        "This may cause problems when using it in MapServer "
                        "for example.\n"
                        "Use -t_srs option to set target projection system "
                        "(not supported by MapServer).\n"
                        "%s\n", argv[iArg],
                        skip_different_projection ? "Skipping this file." : "");
                    if( skip_different_projection )
                    {
                        CPLFree(fileNameToWrite);
                        GDALClose( hDS );
                        continue;
                    }
                }
            }
            else
            {
                alreadyExistingProjectionRefValid = true;
                alreadyExistingProjectionRef = CPLStrdup(projectionRef);
            }
        }

        const int nXSize = GDALGetRasterXSize( hDS );
        const int nYSize = GDALGetRasterYSize( hDS );

        double adfX[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 };
        double adfY[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 };
        adfX[0] = adfGeoTransform[0]
            + 0 * adfGeoTransform[1]
            + 0 * adfGeoTransform[2];
        adfY[0] = adfGeoTransform[3]
            + 0 * adfGeoTransform[4]
            + 0 * adfGeoTransform[5];

        adfX[1] = adfGeoTransform[0]
            + nXSize * adfGeoTransform[1]
            + 0 * adfGeoTransform[2];
        adfY[1] = adfGeoTransform[3]
            + nXSize * adfGeoTransform[4]
            + 0 * adfGeoTransform[5];

        adfX[2] = adfGeoTransform[0]
            + nXSize * adfGeoTransform[1]
            + nYSize * adfGeoTransform[2];
        adfY[2] = adfGeoTransform[3]
            + nXSize * adfGeoTransform[4]
            + nYSize * adfGeoTransform[5];

        adfX[3] = adfGeoTransform[0]
            + 0 * adfGeoTransform[1]
            + nYSize * adfGeoTransform[2];
        adfY[3] = adfGeoTransform[3]
            + 0 * adfGeoTransform[4]
            + nYSize * adfGeoTransform[5];

        adfX[4] = adfGeoTransform[0]
            + 0 * adfGeoTransform[1]
            + 0 * adfGeoTransform[2];
        adfY[4] = adfGeoTransform[3]
            + 0 * adfGeoTransform[4]
            + 0 * adfGeoTransform[5];

        OGRSpatialReferenceH hSourceSRS = nullptr;
        if( (bSetTargetSRS || i_SrcSRSName >= 0) &&
            projectionRef != nullptr &&
            projectionRef[0] != '\0' )
        {
            hSourceSRS = OSRNewSpatialReference( projectionRef );
            OSRSetAxisMappingStrategy(hSourceSRS, OAMS_TRADITIONAL_GIS_ORDER);
        }

        // If set target srs, do the forward transformation of all points.
        if( bSetTargetSRS && projectionRef != nullptr && projectionRef[0] != '\0' )
        {
            OGRCoordinateTransformationH hCT = nullptr;
            if( hSourceSRS && !OSRIsSame( hSourceSRS, hTargetSRS ) )
            {
                hCT = OCTNewCoordinateTransformation( hSourceSRS, hTargetSRS );
                if( hCT == nullptr || !OCTTransform( hCT, 5, adfX, adfY, nullptr ) )
                {
                    fprintf(
                        stderr,
                        "Warning : unable to transform points from source "
                        "SRS `%s' to target SRS `%s'\n"
                        "for file `%s' - file skipped\n",
                        projectionRef, pszTargetSRS, fileNameToWrite );
                    if( hCT )
                        OCTDestroyCoordinateTransformation( hCT );
                    if( hSourceSRS )
                        OSRDestroySpatialReference( hSourceSRS );
                    continue;
                }
                if( hCT )
                    OCTDestroyCoordinateTransformation( hCT );
            }
        }

        OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) );
        OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite );

        if( i_SrcSRSName >= 0 && hSourceSRS != nullptr )
        {
            const char* pszAuthorityCode =
                OSRGetAuthorityCode(hSourceSRS, nullptr);
            const char* pszAuthorityName =
                OSRGetAuthorityName(hSourceSRS, nullptr);
            if( eSrcSRSFormat == FORMAT_AUTO )
            {
                if( pszAuthorityName != nullptr && pszAuthorityCode != nullptr )
                {
                    OGR_F_SetFieldString(
                        hFeature, i_SrcSRSName,
                        CPLSPrintf("%s:%s",
                                   pszAuthorityName, pszAuthorityCode) );
                }
                else if( nMaxFieldSize == 0 ||
                         strlen(projectionRef) <= nMaxFieldSize )
                {
                    OGR_F_SetFieldString(hFeature, i_SrcSRSName, projectionRef);
                }
                else
                {
                    char* pszProj4 = nullptr;
                    if( OSRExportToProj4(hSourceSRS, &pszProj4) == OGRERR_NONE )
                    {
                        OGR_F_SetFieldString( hFeature, i_SrcSRSName,
                                              pszProj4 );
                        CPLFree(pszProj4);
                    }
                    else
                    {
                        OGR_F_SetFieldString( hFeature, i_SrcSRSName,
                                              projectionRef );
                    }
                }
            }
            else if( eSrcSRSFormat == FORMAT_WKT )
            {
                if( nMaxFieldSize == 0 ||
                    strlen(projectionRef) <= nMaxFieldSize )
                {
                    OGR_F_SetFieldString( hFeature, i_SrcSRSName,
                                          projectionRef );
                }
                else
                {
                    fprintf(stderr,
                            "Cannot write WKT for file %s as it is too long!\n",
                            fileNameToWrite);
                }
            }
            else if( eSrcSRSFormat == FORMAT_PROJ )
            {
                char* pszProj4 = nullptr;
                if( OSRExportToProj4(hSourceSRS, &pszProj4) == OGRERR_NONE )
                {
                    OGR_F_SetFieldString( hFeature, i_SrcSRSName, pszProj4 );
                    CPLFree(pszProj4);
                }
            }
            else if( eSrcSRSFormat == FORMAT_EPSG )
            {
                if( pszAuthorityName != nullptr && pszAuthorityCode != nullptr )
                    OGR_F_SetFieldString(
                        hFeature, i_SrcSRSName,
                        CPLSPrintf("%s:%s",
                                   pszAuthorityName, pszAuthorityCode) );
            }
        }
        if( hSourceSRS )
            OSRDestroySpatialReference( hSourceSRS );

        OGRGeometryH hPoly = OGR_G_CreateGeometry(wkbPolygon);
        OGRGeometryH hRing = OGR_G_CreateGeometry(wkbLinearRing);
        for( int k = 0; k < 5; k++ )
            OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]);
        OGR_G_AddGeometryDirectly( hPoly, hRing );
        OGR_F_SetGeometryDirectly( hFeature, hPoly );

        if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE )
        {
           printf( "Failed to create feature in shapefile.\n" );
           break;
        }

        OGR_F_Destroy( hFeature );

        CPLFree(fileNameToWrite);

        GDALClose( hDS );
    }

    CPLFree(current_path);

    if (nExistingFiles)
    {
        for( int i = 0; i < nExistingFiles; i++ )
        {
            CPLFree(existingFilesTab[i]);
        }
        CPLFree(existingFilesTab);
    }
    CPLFree(alreadyExistingProjectionRef);

    if ( hTargetSRS )
        OSRDestroySpatialReference( hTargetSRS );

    GDALClose( hTileIndexDS );

    GDALDestroyDriverManager();
    OGRCleanupAll();
    CSLDestroy(argv);

    exit( 0 );
}
CPLErr RasterliteDataset::CreateOverviewLevel(const char * pszResampling,
                                              int nOvrFactor,
                                              char** papszOptions,
                                              GDALProgressFunc pfnProgress,
                                              void * pProgressData)
{

    double dfXResolution = padfXResolutions[0] * nOvrFactor;
    double dfYResolution = padfXResolutions[0] * nOvrFactor;
    
    CPLString osSQL;

    int nOvrXSize = nRasterXSize / nOvrFactor;
    int nOvrYSize = nRasterYSize / nOvrFactor;
    
    if (nOvrXSize == 0 || nOvrYSize == 0)
        return CE_Failure;

    int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES"));
    int nBlockXSize, nBlockYSize;
    if (bTiled)
    {
        nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));
        nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));
        if (nBlockXSize < 64) nBlockXSize = 64;
        else if (nBlockXSize > 4096)  nBlockXSize = 4096;
        if (nBlockYSize < 64) nBlockYSize = 64;
        else if (nBlockYSize > 4096)  nBlockYSize = 4096;
    }
    else
    {
        nBlockXSize = nOvrXSize;
        nBlockYSize = nOvrYSize;
    }
    
    int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize;
    int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize;
    
    const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
    if (EQUAL(pszDriverName, "MEM") || EQUAL(pszDriverName, "VRT"))
    {
        CPLError(CE_Failure, CPLE_AppDefined, "GDAL %s driver cannot be used as underlying driver",
                 pszDriverName);
        return CE_Failure;
    }
    GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
    if (hTileDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
        return CE_Failure;
    }

    GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
    if (hMemDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
        return CE_Failure;
    }   

    GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType();
    int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
    GByte* pabyMEMDSBuffer =
        (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
    if (pabyMEMDSBuffer == NULL)
    {
        return CE_Failure;
    }
    
    CPLString osTempFileName;
    osTempFileName.Printf("/vsimem/%p", hDS);
    
    int nTileId = 0;
    int nBlocks = 0;
    int nTotalBlocks = nXBlocks * nYBlocks;
    
    CPLString osRasterLayer;
    osRasterLayer.Printf("%s_rasters", osTableName.c_str());
    
    CPLString osMetatadataLayer;
    osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());
    
    OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
    OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
    
    CPLString osSourceName = "unknown";
    
    osSQL.Printf("SELECT source_name FROM \"%s\" WHERE "
                 "%s LIMIT 1",
                 osMetatadataLayer.c_str(),
                 RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str());
    OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    if (hSQLLyr)
    {
        OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
        if (hFeat)
        {
            const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0);
            if (pszVal)
                osSourceName = pszVal;
            OGR_F_Destroy(hFeat);
        }
        OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
    }
    
/* -------------------------------------------------------------------- */
/*      Compute up to which existing overview level we can use for      */
/*      computing the requested overview                                */
/* -------------------------------------------------------------------- */
    int iLev;
    nLimitOvrCount = 0;
    for(iLev=1;iLev<nResolutions;iLev++)
    {
        if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 &&
              padfYResolutions[iLev] < dfYResolution - 1e-10))
        {
            break;
        }
        nLimitOvrCount++;
    }
/* -------------------------------------------------------------------- */
/*      Allocate buffer for tile of previous overview level             */
/* -------------------------------------------------------------------- */

    GDALDataset* poPrevOvrLevel =
        (papoOverviews != NULL && iLev >= 2 && iLev <= nResolutions && papoOverviews[iLev-2]) ?
            papoOverviews[iLev-2] : this;
    double dfRatioPrevOvr = poPrevOvrLevel->GetRasterBand(1)->GetXSize() / nOvrXSize;
    int nPrevOvrBlockXSize = (int)(nBlockXSize * dfRatioPrevOvr + 0.5);
    int nPrevOvrBlockYSize = (int)(nBlockYSize * dfRatioPrevOvr + 0.5);
    GByte* pabyPrevOvrMEMDSBuffer = NULL;

    if( !EQUALN(pszResampling, "NEAR", 4))
    {
        pabyPrevOvrMEMDSBuffer =
            (GByte*)VSIMalloc3(nPrevOvrBlockXSize, nPrevOvrBlockYSize, nBands * nDataTypeSize);
        if (pabyPrevOvrMEMDSBuffer == NULL)
        {
            VSIFree(pabyMEMDSBuffer);
            return CE_Failure;
        }
    }

/* -------------------------------------------------------------------- */
/*      Iterate over blocks to add data into raster and metadata tables */
/* -------------------------------------------------------------------- */

    char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions);

    OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
    
    CPLErr eErr = CE_None;
    int nBlockXOff, nBlockYOff;
    for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
    {
        for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
        {
            GDALDatasetH hPrevOvrMemDS = NULL;

/* -------------------------------------------------------------------- */
/*      Create in-memory tile                                           */
/* -------------------------------------------------------------------- */
            int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
            if ((nBlockXOff+1) * nBlockXSize > nOvrXSize)
                nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize;
            if ((nBlockYOff+1) * nBlockYSize > nOvrYSize)
                nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize;

            if( pabyPrevOvrMEMDSBuffer != NULL )
            {
                int nPrevOvrReqXSize =
                    (int)(nReqXSize * dfRatioPrevOvr + 0.5);
                int nPrevOvrReqYSize =
                    (int)(nReqYSize * dfRatioPrevOvr + 0.5);

                eErr = RasterIO(GF_Read,
                                nBlockXOff * nBlockXSize * nOvrFactor,
                                nBlockYOff * nBlockYSize * nOvrFactor,
                                nReqXSize * nOvrFactor, nReqYSize * nOvrFactor,
                                pabyPrevOvrMEMDSBuffer, nPrevOvrReqXSize, nPrevOvrReqYSize,
                                eDataType, nBands, NULL,
                                0, 0, 0, NULL);

                if (eErr != CE_None)
                {
                    break;
                }

                hPrevOvrMemDS = GDALCreate(hMemDriver, "MEM:::",
                                           nPrevOvrReqXSize, nPrevOvrReqYSize, 0,
                                           eDataType, NULL);

                if (hPrevOvrMemDS == NULL)
                {
                    eErr = CE_Failure;
                    break;
                }

                int iBand;
                for(iBand = 0; iBand < nBands; iBand ++)
                {
                    char** papszOptions = NULL;
                    char szTmp[64];
                    memset(szTmp, 0, sizeof(szTmp));
                    CPLPrintPointer(szTmp,
                                    pabyPrevOvrMEMDSBuffer + iBand * nDataTypeSize *
                                    nPrevOvrReqXSize * nPrevOvrReqYSize, sizeof(szTmp));
                    papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
                    GDALAddBand(hPrevOvrMemDS, eDataType, papszOptions);
                    CSLDestroy(papszOptions);
                }
            }
            else
            {
                eErr = RasterIO(GF_Read,
                                nBlockXOff * nBlockXSize * nOvrFactor,
                                nBlockYOff * nBlockYSize * nOvrFactor,
                                nReqXSize * nOvrFactor, nReqYSize * nOvrFactor,
                                pabyMEMDSBuffer, nReqXSize, nReqYSize,
                                eDataType, nBands, NULL,
                                0, 0, 0, NULL);
                if (eErr != CE_None)
                {
                    break;
                }
            }

            GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
                                              nReqXSize, nReqYSize, 0, 
                                              eDataType, NULL);
            if (hMemDS == NULL)
            {
                eErr = CE_Failure;
                break;
            }
            
            int iBand;
            for(iBand = 0; iBand < nBands; iBand ++)
            {
                char** papszOptions = NULL;
                char szTmp[64];
                memset(szTmp, 0, sizeof(szTmp));
                CPLPrintPointer(szTmp,
                                pabyMEMDSBuffer + iBand * nDataTypeSize *
                                nReqXSize * nReqYSize, sizeof(szTmp));
                papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp);
                GDALAddBand(hMemDS, eDataType, papszOptions);
                CSLDestroy(papszOptions);
            }

            if( hPrevOvrMemDS != NULL )
            {
                for(iBand = 0; iBand < nBands; iBand ++)
                {
                    GDALRasterBandH hDstOvrBand = GDALGetRasterBand(hMemDS, iBand+1);

                    eErr = GDALRegenerateOverviews( GDALGetRasterBand(hPrevOvrMemDS, iBand+1),
                                                    1, &hDstOvrBand,
                                                    pszResampling,
                                                    NULL, NULL );
                    if( eErr != CE_None )
                        break;
                }

                GDALClose(hPrevOvrMemDS);
            }

            GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
                                        osTempFileName.c_str(), hMemDS, FALSE,
                                        papszTileDriverOptions, NULL, NULL);

            GDALClose(hMemDS);
            if (hOutDS)
                GDALClose(hOutDS);
            else
            {
                eErr = CE_Failure;
                break;
            }

/* -------------------------------------------------------------------- */
/*      Insert new entry into raster table                              */
/* -------------------------------------------------------------------- */

            vsi_l_offset nDataLength;
            GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
                                                   &nDataLength, FALSE);

            OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
            OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
            
            OGR_L_CreateFeature(hRasterLayer, hFeat);
            /* Query raster ID to set it as the ID of the associated metadata */
            int nRasterID = (int)OGR_F_GetFID(hFeat);
            
            OGR_F_Destroy(hFeat);
            
            VSIUnlink(osTempFileName.c_str());
            
/* -------------------------------------------------------------------- */
/*      Insert new entry into metadata table                            */
/* -------------------------------------------------------------------- */
            
            hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
            OGR_F_SetFID(hFeat, nRasterID);
            OGR_F_SetFieldString(hFeat, 0, osSourceName);
            OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
            OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
            OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
            OGR_F_SetFieldDouble(hFeat, 4, dfXResolution);
            OGR_F_SetFieldDouble(hFeat, 5, dfYResolution);
            
            double minx, maxx, maxy, miny;
            minx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff) * dfXResolution;
            maxx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution;
            maxy = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff) * (-dfYResolution);
            miny = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution);
            
            OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
            OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
            
            OGR_F_SetGeometryDirectly(hFeat, hRectangle);
            
            OGR_L_CreateFeature(hMetadataLayer, hFeat);
            OGR_F_Destroy(hFeat);
            
            nBlocks++;
            if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
                                            NULL, pProgressData))
                eErr = CE_Failure;
        }
    }

    nLimitOvrCount = -1;
    
    if (eErr == CE_None)
        OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
    else
        OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
    
    VSIFree(pabyMEMDSBuffer);
    VSIFree(pabyPrevOvrMEMDSBuffer);

    CSLDestroy(papszTileDriverOptions);
    papszTileDriverOptions = NULL;

/* -------------------------------------------------------------------- */
/*      Update raster_pyramids table                                    */
/* -------------------------------------------------------------------- */
    if (eErr == CE_None)
    {
        OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
        if (hRasterPyramidsLyr == NULL)
        {
            osSQL.Printf   ("CREATE TABLE raster_pyramids ("
                            "table_prefix TEXT NOT NULL,"
                            "pixel_x_size DOUBLE NOT NULL,"
                            "pixel_y_size DOUBLE NOT NULL,"
                            "tile_count INTEGER NOT NULL)");
            OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
            
            /* Re-open the DB to take into account the new tables*/
            OGRReleaseDataSource(hDS);
            
            hDS = RasterliteOpenSQLiteDB(osFileName.c_str(), GA_Update);

            hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids");
            if (hRasterPyramidsLyr == NULL)
                return CE_Failure;
        }
        OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hRasterPyramidsLyr);

        /* Insert base resolution into raster_pyramids if not already done */
        int bHasBaseResolution = FALSE;
        osSQL.Printf("SELECT * FROM raster_pyramids WHERE "
                     "table_prefix = '%s' AND %s",
                     osTableName.c_str(),
                     RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str());
        hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
        if (hSQLLyr)
        {
            OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
            if (hFeat)
            {
                bHasBaseResolution = TRUE;
                OGR_F_Destroy(hFeat);
            }
            OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
        }

        if (!bHasBaseResolution)
        {
            osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE %s",
                          osMetatadataLayer.c_str(),
                          RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str());

            int nBlocksMainRes = 0;

            hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
            if (hSQLLyr)
            {
                OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr);
                if (hFeat)
                {
                    nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0);
                    OGR_F_Destroy(hFeat);
                }
                OGR_DS_ReleaseResultSet(hDS, hSQLLyr);
            }

            OGRFeatureH hFeat = OGR_F_Create( hFDefn );
            OGR_F_SetFieldString(hFeat, OGR_FD_GetFieldIndex(hFDefn, "table_prefix"), osTableName.c_str());
            OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_x_size"), padfXResolutions[0]);
            OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_y_size"), padfYResolutions[0]);
            OGR_F_SetFieldInteger(hFeat, OGR_FD_GetFieldIndex(hFDefn, "tile_count"), nBlocksMainRes);
            OGR_L_CreateFeature(hRasterPyramidsLyr, hFeat);
            OGR_F_Destroy(hFeat);
        }

        OGRFeatureH hFeat = OGR_F_Create( hFDefn );
        OGR_F_SetFieldString(hFeat, OGR_FD_GetFieldIndex(hFDefn, "table_prefix"), osTableName.c_str());
        OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_x_size"), dfXResolution);
        OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_y_size"), dfYResolution);
        OGR_F_SetFieldInteger(hFeat, OGR_FD_GetFieldIndex(hFDefn, "tile_count"), nTotalBlocks);
        OGR_L_CreateFeature(hRasterPyramidsLyr, hFeat);
        OGR_F_Destroy(hFeat);
    }

    return eErr;
}
Exemple #26
0
/* describe table, if c is not NULL cur->cols and cur->ncols is also set 
 * cursor may be null
 */
int describe_table(OGRLayerH hLayer, dbTable ** table, cursor * c)
{
    int i, ncols, kcols;
    dbColumn *column;
    OGRFeatureDefnH hFeatureDefn;
    OGRFieldDefnH hFieldDefn;
    const char *fieldName;
    int ogrType;
    int *cols;

    G_debug(3, "describe_table()");

    hFeatureDefn = OGR_L_GetLayerDefn(hLayer);
    ncols = OGR_FD_GetFieldCount(hFeatureDefn);

    G_debug(3, "ncols = %d", ncols);

    /* Identify known columns */
    cols = (int *)G_malloc(ncols * sizeof(int));
    kcols = 0;
    for (i = 0; i < ncols; i++) {
	hFieldDefn = OGR_FD_GetFieldDefn(hFeatureDefn, i);
	ogrType = OGR_Fld_GetType(hFieldDefn);
	OGR_Fld_GetNameRef(hFieldDefn);
	fieldName = OGR_Fld_GetNameRef(hFieldDefn);

	if (ogrType != OFTInteger && ogrType != OFTReal &&
	    ogrType != OFTString  && ogrType != OFTDate && 
	    ogrType != OFTTime    && ogrType != OFTDateTime ) {
	    G_warning(_("OGR driver: column '%s', OGR type %d  is not supported"),
		      fieldName, ogrType);
	    cols[i] = 0;
	}
	else {
	    cols[i] = 1;
	    kcols++;
	}
    }

    if (!(*table = db_alloc_table(kcols))) {
	return DB_FAILED;
    }

    /* set the table name */
    /* TODO */
    db_set_table_name(*table, "");

    /* set the table description */
    db_set_table_description(*table, "");

    /* TODO */
    /*
       db_set_table_delete_priv_granted (*table);
       db_set_table_insert_priv_granted (*table);
       db_set_table_delete_priv_not_granted (*table);
       db_set_table_insert_priv_not_granted (*table);
     */

    for (i = 0; i < ncols; i++) {
	int sqlType;
	int size, precision, scale;

	if (!(cols[i]))
	    continue;		/* unknown type */

	hFieldDefn = OGR_FD_GetFieldDefn(hFeatureDefn, i);
	ogrType = OGR_Fld_GetType(hFieldDefn);
	fieldName = OGR_Fld_GetNameRef(hFieldDefn);

	G_debug(3, "field %d : ogrType = %d, name = %s", i, ogrType,
		fieldName);

	switch (ogrType) {
	case OFTInteger:
	    sqlType = DB_SQL_TYPE_INTEGER;
	    size = OGR_Fld_GetWidth(hFieldDefn);	/* OK ? */
	    precision = 0;
	    break;

	case OFTReal:
	    sqlType = DB_SQL_TYPE_DOUBLE_PRECISION;
	    size = OGR_Fld_GetWidth(hFieldDefn);	/* OK ? */
	    precision = OGR_Fld_GetPrecision(hFieldDefn);
	    break;

	case OFTString:
	case OFTDate:
	case OFTTime:
	case OFTDateTime:
	    sqlType = DB_SQL_TYPE_CHARACTER;
	    size = OGR_Fld_GetWidth(hFieldDefn);
	    if (size == 0) {
		G_warning(_("column '%s', type 'string': unknown width -> stored as varchar(250) "
			   "some data may be lost"), fieldName);
		size = 250;
	    }
	    precision = 0;
	    break;

	default:
	    G_warning(_("Unknown type"));
	    break;
	}

	column = db_get_table_column(*table, i);

	db_set_column_host_type(column, ogrType);
	db_set_column_sqltype(column, sqlType);
	db_set_column_name(column, fieldName);
	db_set_column_length(column, size);
	db_set_column_precision(column, precision);

	/* TODO */
	scale = 0;
	/*
	   db_set_column_scale (column, scale);
	 */

	/* TODO */
	db_set_column_null_allowed(column);
	db_set_column_has_undefined_default_value(column);
	db_unset_column_use_default_value(column);

	/* TODO */
	/*
	   db_set_column_select_priv_granted (column);
	   db_set_column_update_priv_granted (column);
	   db_set_column_update_priv_not_granted (column); 
	 */
    }

    if (c) {
	c->cols = cols;
	c->ncols = ncols;
    }
    else {
	G_free(cols);
    }

    return DB_OK;
}
Exemple #27
0
int readoutlets(char *outletsds,char *lyrname, int uselayername,int outletslyr,OGRSpatialReferenceH hSRSRaster,int *noutlets, double*& x, double*& y,int*& id)

{   
	// initializing datasoruce,layer,feature, geomtery, spatial reference
    OGRSFDriverH    driver;
    OGRDataSourceH  hDS1;
	OGRLayerH       hLayer1;
	OGRFeatureDefnH hFDefn1;
	OGRFieldDefnH   hFieldDefn1;
	OGRFeatureH     hFeature1;
	OGRGeometryH    geometry, line;
	OGRSpatialReferenceH hRSOutlet;
	// register all ogr driver related to OGR
	OGRRegisterAll(); 

	// open data source
	hDS1 = OGROpen(outletsds, FALSE, NULL );
	if( hDS1 == NULL )
	{
	printf( "Error Opening OGR Data Source .\n" );
	return 1;
	}
	
    //get layer from layer name
	if(uselayername==1) { hLayer1 = OGR_DS_GetLayerByName(hDS1,lyrname);}
		//get layerinfo from layer number
	else { hLayer1 = OGR_DS_GetLayer(hDS1,outletslyr);} // get layerinfo from layername

	if(hLayer1 == NULL)getlayerfail(hDS1,outletsds,outletslyr);
	OGRwkbGeometryType gtype;
	gtype=OGR_L_GetGeomType(hLayer1);

	// Test that the type is a point
	if(gtype != wkbPoint)getlayerfail(hDS1,outletsds,outletslyr);

	const char* RasterProjectionName;
	const char* sprs;
	const char* sprso;
	const char* OutletProjectionName;
	int pj_raster,pj_outlet;

	// Spatial reference of outlet
	hRSOutlet = OGR_L_GetSpatialRef(hLayer1);
	if(hSRSRaster!=NULL){
	  pj_raster=OSRIsProjected(hSRSRaster); // find if projected or not
	  if(pj_raster==0) {sprs="GEOGCS";} else { sprs="PROJCS"; }
	  RasterProjectionName = OSRGetAttrValue(hSRSRaster,sprs,0); // get projection name
	}
	if(hRSOutlet!=NULL){
	  pj_outlet=OSRIsProjected(hRSOutlet);
	  if(pj_outlet==0) {sprso="GEOGCS";} else { sprso="PROJCS"; }
	  OutletProjectionName = OSRGetAttrValue(hRSOutlet,sprso,0);
	}

	//Write warnings where projections may not match
	if(hRSOutlet!=NULL && hSRSRaster!=NULL){
	
		if (pj_raster==pj_outlet){
			  
			 int rc= strcmp(RasterProjectionName,OutletProjectionName); // compare string
			 if(rc!=0){
				printf( "Warning: Projection of Outlet feature and Raster data may be different.\n" );
				printf("Projection of Raster datasource %s.\n",RasterProjectionName);
                printf("Projection of Outlet feature %s.\n",OutletProjectionName);
			}
		}
    
		else {
			  printf( "Warning: Spatial References of Outlet feature and Raster data are different.\n" );
			  printf("Projection of Raster datasource %s.\n",RasterProjectionName);
              printf("Projection of Outlet feature %s.\n",OutletProjectionName);
		}
	}
	
	else if(hSRSRaster==NULL && hRSOutlet!=NULL) {
		      printf( "Warning: Spatial Reference of Raster is missing.\n" );
              printf("Projection of Outlet feature %s.\n",OutletProjectionName);

	}
	else if(hSRSRaster!=NULL && hRSOutlet==NULL) {
	          printf( "Warning: Spatial Reference of Outlet feature is missing.\n" );
			  printf("Projection of Raster datasource %s.\n",RasterProjectionName);
	}
	else {
	          printf( "Warning: Spatial References of Outlet feature and Raster data are missing.\n" );
	}



	long countPts=0;
	// count number of feature
	countPts=OGR_L_GetFeatureCount(hLayer1,0); 
	// get schema i.e geometry, properties (e.g. ID)
	hFDefn1 = OGR_L_GetLayerDefn(hLayer1); 
	x = new double[countPts];
	y = new double[countPts];
	int iField;
	int nxy=0;
	id = new int[countPts];
	// loop through each feature and get lat,lon and id information

    OGR_L_ResetReading(hLayer1);
    while( (hFeature1 = OGR_L_GetNextFeature(hLayer1)) != NULL ) {

		 //hFeature1=OGR_L_GetFeature(hLayer1,j); // get feature info
		 geometry = OGR_F_GetGeometryRef(hFeature1); // get geometry
         x[nxy] = OGR_G_GetX(geometry, 0);
		 y[nxy] =  OGR_G_GetY(geometry, 0);
		 int idfld =OGR_F_GetFieldIndex(hFeature1,"id");
		 if (idfld >= 0)
		   {
			 
			hFieldDefn1 = OGR_FD_GetFieldDefn( hFDefn1,idfld); // get field definiton based on index
			if( OGR_Fld_GetType(hFieldDefn1) == OFTInteger ) {
					id[nxy] =OGR_F_GetFieldAsInteger( hFeature1, idfld );} // get id value 
		    }
		 else {
		      id[nxy]=1;// if there is no id field         
		 } 
		 nxy++; // count number of outlets point
		 OGR_F_Destroy( hFeature1 ); // destroy feature
	}
	*noutlets=nxy;
	OGR_DS_Destroy( hDS1); // destroy data source
	return 0;
}
static CPLErr ProcessLayer( OGRLayerH hSrcLayer, GDALDatasetH hDstDS,
                          OGRGeometry *poClipSrc,
                          GUInt32 nXSize, GUInt32 nYSize, int nBand,
                          int& bIsXExtentSet, int& bIsYExtentSet,
                          double& dfXMin, double& dfXMax,
                          double& dfYMin, double& dfYMax,
                          const char *pszBurnAttribute,
                          const double dfIncreaseBurnValue,
                          const double dfMultiplyBurnValue,
                          GDALDataType eType,
                          GDALGridAlgorithm eAlgorithm, void *pOptions,
                          int bQuiet, GDALProgressFunc pfnProgress )

{
/* -------------------------------------------------------------------- */
/*      Get field index, and check.                                     */
/* -------------------------------------------------------------------- */
    int iBurnField = -1;

    if ( pszBurnAttribute )
    {
        iBurnField = OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hSrcLayer ),
                                           pszBurnAttribute );
        if( iBurnField == -1 )
        {
            printf( "Failed to find field %s on layer %s, skipping.\n",
                    pszBurnAttribute, 
                    OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) );
            return CE_Failure;
        }
    }

/* -------------------------------------------------------------------- */
/*      Collect the geometries from this layer, and build list of       */
/*      values to be interpolated.                                      */
/* -------------------------------------------------------------------- */
    OGRFeature *poFeat;
    std::vector<double> adfX, adfY, adfZ;

    OGR_L_ResetReading( hSrcLayer );

    while( (poFeat = (OGRFeature *)OGR_L_GetNextFeature( hSrcLayer )) != NULL )
    {
        OGRGeometry *poGeom = poFeat->GetGeometryRef();
        double  dfBurnValue = 0.0;

        if ( iBurnField >= 0 )
            dfBurnValue = poFeat->GetFieldAsDouble( iBurnField );

        ProcessCommonGeometry(poGeom, poClipSrc, iBurnField, dfBurnValue,
            dfIncreaseBurnValue, dfMultiplyBurnValue, adfX, adfY, adfZ);

        OGRFeature::DestroyFeature( poFeat );
    }

    if ( adfX.size() == 0 )
    {
        printf( "No point geometry found on layer %s, skipping.\n",
                OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) );
        return CE_None;
    }

/* -------------------------------------------------------------------- */
/*      Compute grid geometry.                                          */
/* -------------------------------------------------------------------- */
    if ( !bIsXExtentSet || !bIsYExtentSet )
    {
        OGREnvelope sEnvelope;
        OGR_L_GetExtent( hSrcLayer, &sEnvelope, TRUE );

        if ( !bIsXExtentSet )
        {
            dfXMin = sEnvelope.MinX;
            dfXMax = sEnvelope.MaxX;
            bIsXExtentSet = TRUE;
        }

        if ( !bIsYExtentSet )
        {
            dfYMin = sEnvelope.MinY;
            dfYMax = sEnvelope.MaxY;
            bIsYExtentSet = TRUE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Perform gridding.                                               */
/* -------------------------------------------------------------------- */

    const double    dfDeltaX = ( dfXMax - dfXMin ) / nXSize;
    const double    dfDeltaY = ( dfYMax - dfYMin ) / nYSize;

    if ( !bQuiet )
    {
        printf( "Grid data type is \"%s\"\n", GDALGetDataTypeName(eType) );
        printf( "Grid size = (%lu %lu).\n",
                (unsigned long)nXSize, (unsigned long)nYSize );
        printf( "Corner coordinates = (%f %f)-(%f %f).\n",
                dfXMin - dfDeltaX / 2, dfYMax + dfDeltaY / 2,
                dfXMax + dfDeltaX / 2, dfYMin - dfDeltaY / 2 );
        printf( "Grid cell size = (%f %f).\n", dfDeltaX, dfDeltaY );
        printf( "Source point count = %lu.\n", (unsigned long)adfX.size() );
        PrintAlgorithmAndOptions( eAlgorithm, pOptions );
        printf("\n");
    }

    GDALRasterBandH hBand = GDALGetRasterBand( hDstDS, nBand );

    if (adfX.size() == 0)
    {
        // FIXME: Shoulda' set to nodata value instead
        GDALFillRaster( hBand, 0.0 , 0.0 );
        return CE_None;
    }

    GUInt32 nXOffset, nYOffset;
    int     nBlockXSize, nBlockYSize;
    int     nDataTypeSize = GDALGetDataTypeSize(eType) / 8;

    // Try to grow the work buffer up to 16 MB if it is smaller
    GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize );
    const GUInt32 nDesiredBufferSize = 16*1024*1024;
    if( (GUInt32)nBlockXSize < nXSize && (GUInt32)nBlockYSize < nYSize &&
        (GUInt32)nBlockXSize < nDesiredBufferSize / (nBlockYSize * nDataTypeSize) )
    {
        int nNewBlockXSize  = nDesiredBufferSize / (nBlockYSize * nDataTypeSize);
        nBlockXSize = (nNewBlockXSize / nBlockXSize) * nBlockXSize;
        if( (GUInt32)nBlockXSize > nXSize )
            nBlockXSize = nXSize;
    }
    else if( (GUInt32)nBlockXSize == nXSize && (GUInt32)nBlockYSize < nYSize &&
             (GUInt32)nBlockYSize < nDesiredBufferSize / (nXSize * nDataTypeSize) )
    {
        int nNewBlockYSize = nDesiredBufferSize / (nXSize * nDataTypeSize);
        nBlockYSize = (nNewBlockYSize / nBlockYSize) * nBlockYSize;
        if( (GUInt32)nBlockYSize > nYSize )
            nBlockYSize = nYSize;
    }
    CPLDebug("GDAL_GRID", "Work buffer: %d * %d", nBlockXSize, nBlockYSize);

    void    *pData =
        VSIMalloc3( nBlockXSize, nBlockYSize, nDataTypeSize );
    if( pData == NULL )
    {
        CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate work buffer");
        return CE_Failure;
    }

    GUInt32 nBlock = 0;
    GUInt32 nBlockCount = ((nXSize + nBlockXSize - 1) / nBlockXSize)
        * ((nYSize + nBlockYSize - 1) / nBlockYSize);

    CPLErr eErr = CE_None;
    for ( nYOffset = 0; nYOffset < nYSize && eErr == CE_None; nYOffset += nBlockYSize )
    {
        for ( nXOffset = 0; nXOffset < nXSize && eErr == CE_None; nXOffset += nBlockXSize )
        {
            void *pScaledProgress;
            pScaledProgress =
                GDALCreateScaledProgress( (double)nBlock / nBlockCount,
                                          (double)(nBlock + 1) / nBlockCount,
                                          pfnProgress, NULL );
            nBlock ++;

            int nXRequest = nBlockXSize;
            if (nXOffset + nXRequest > nXSize)
                nXRequest = nXSize - nXOffset;

            int nYRequest = nBlockYSize;
            if (nYOffset + nYRequest > nYSize)
                nYRequest = nYSize - nYOffset;

            eErr = GDALGridCreate( eAlgorithm, pOptions,
                            adfX.size(), &(adfX[0]), &(adfY[0]), &(adfZ[0]),
                            dfXMin + dfDeltaX * nXOffset,
                            dfXMin + dfDeltaX * (nXOffset + nXRequest),
                            dfYMin + dfDeltaY * nYOffset,
                            dfYMin + dfDeltaY * (nYOffset + nYRequest),
                            nXRequest, nYRequest, eType, pData,
                            GDALScaledProgress, pScaledProgress );

            if( eErr == CE_None )
                eErr = GDALRasterIO( hBand, GF_Write, nXOffset, nYOffset,
                          nXRequest, nYRequest, pData,
                          nXRequest, nYRequest, eType, 0, 0 );

            GDALDestroyScaledProgress( pScaledProgress );
        }
    }

    CPLFree( pData );
    return eErr;
}
Exemple #29
0
int main(int argc, char* argv[])
{
    int rc = 0;

#ifdef HAVE_GDAL
    try
    {
        ::OGRRegisterAll();

        // Parse command-line options
        std::string in_file;
        std::string out_file;
        std::string out_frmt;
        {
            int on_arg = 1;
            while (on_arg < argc)
            {
                std::string arg(argv[on_arg]);
                if (arg == "-h")
                {
                    usage();
                    return 0;
                }
                else if (arg == "-formats")
                {
                    report_ogr_formats(std::cout);
                    return 0;
                }
                else if (arg == "-i" && (on_arg + 1 < argc))
                {
                    ++on_arg;
                    assert(on_arg < argc);
                    in_file = argv[on_arg];
                }
                else if (arg == "-o" && (on_arg + 1 < argc))
                {
                    ++on_arg;
                    assert(on_arg < argc);
                    out_file = argv[on_arg];
                    out_frmt = "ESRI Shapefile"; // default output format
                }
                else if (arg == "-f" && (on_arg + 1 < argc))
                {
                    ++on_arg;
                    assert(on_arg < argc);
                    out_frmt = argv[on_arg];
                }
                else
                {
                    throw std::runtime_error(std::string("unrecognized parameter: ") + arg);
                }
                ++on_arg;
            }

            if (in_file.empty() || out_file.empty() || out_frmt.empty())
            {
                throw std::runtime_error("missing input paremeters");
            }
        }

        //
        // Source
        //
        std::cout << "Source:" << "\n - dataset: " << in_file << std::endl;

        std::ifstream ifs;
        if (!liblas::Open(ifs, in_file.c_str()))
        {
            throw std::runtime_error(std::string("Can not open \'") + in_file + "\'");
        }
        liblas::Reader reader(ifs);

        //
        // Target
        //
        std::string const lyrname(out_file.substr(0, out_file.find_last_of('.')));

        std::cout << "Target:"
                  << "\n - format: " << out_frmt
                  << "\n - dataset: " << out_file
                  << "\n - layer: " << lyrname
                  << std::endl;

        OGRSFDriverH drv = OGRGetDriverByName(out_frmt.c_str());
        if (0 == drv)
        {
            throw std::runtime_error(out_frmt + " driver not available");
        }

        ogr_wrapper<OGRDataSourceH> ds(OGR_Dr_CreateDataSource(drv, out_file.c_str(), 0), OGR_DS_Destroy);
        if (0 == ds.get())
        {
            throw std::runtime_error(out_file + " datasource creation failed");
        }

        OGRLayerH lyr = OGR_DS_CreateLayer(ds, lyrname.c_str(), 0, wkbPoint25D, 0);
        if (0 == lyr)
        {
            throw std::runtime_error(out_file + " layer creation failed");
        }

        // Prepare layer schema
        create_layer_def(lyr);

        //
        // Translation of points cloud to features set
        //
        boost::uint32_t i = 0;
        boost::uint32_t const size = reader.GetHeader().GetPointRecordsCount();

        std::cout << "Translating " << size << " points:\n";

        ogr_wrapper<OGRFeatureH> feat(OGR_F_Create(OGR_L_GetLayerDefn(lyr)), OGR_F_Destroy);

        while (reader.ReadNextPoint())
        {
            liblas::Point const& p = reader.GetPoint();

            OGR_F_SetFieldInteger(feat, 0, p.GetReturnNumber());
            OGR_F_SetFieldInteger(feat, 1, p.GetScanAngleRank());
            OGR_F_SetFieldInteger(feat, 2, p.GetIntensity());

            std::ostringstream os;
            os << p.GetClassification();
            OGR_F_SetFieldString(feat, 3, os.str().c_str());

            OGR_F_SetFieldInteger(feat, 4, p.GetNumberOfReturns());
            OGR_F_SetFieldDouble(feat, 5, p.GetTime());

            ogr_wrapper<OGRGeometryH> geom(OGR_G_CreateGeometry(wkbPoint25D), OGR_G_DestroyGeometry);
            OGR_G_SetPoint(geom, 0, p.GetX(), p.GetY(), p.GetZ());
            if (OGRERR_NONE != OGR_F_SetGeometry(feat, geom))
            {
                throw std::runtime_error("geometry creation failed");
            }

            if (OGRERR_NONE != OGR_L_CreateFeature(lyr, feat))
            {
                throw std::runtime_error("feature creation failed");
            }

            term_progress(std::cout, (i + 1) / static_cast<double>(size));
            i++;
        }

        std::cout << std::endl;
    }
    catch (std::exception const& e)
    {
        std::cerr << "Error: " << e.what() << std::endl;
        rc = -1;
    }
    catch (...)
    {
        std::cerr << "Unknown error\n";
        rc = -1;
    }
#else
    std::cout << "Missing GDAL/OGR support built-in las2ogr. Aborted." << std::endl;
#endif // #ifdef HAVE_GDAL

    ::OGRCleanupAll();
    return rc;
}
GDALDataset *
RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, 
                       int bStrict, char ** papszOptions, 
                       GDALProgressFunc pfnProgress, void * pProgressData )
{
    int nBands = poSrcDS->GetRasterCount();
    if (nBands == 0)
    {
        CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0");
        return NULL;
    }
    
    const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff");
    GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName);
    if ( hTileDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName);
        return NULL;
    }
    
    GDALDriverH hMemDriver = GDALGetDriverByName("MEM");
    if (hMemDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver");
        return NULL;
    }   

    int nXSize = GDALGetRasterXSize(poSrcDS);
    int nYSize = GDALGetRasterYSize(poSrcDS);
    
    double adfGeoTransform[6];
    if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None)
    {
        adfGeoTransform[0] = 0;
        adfGeoTransform[1] = 1;
        adfGeoTransform[2] = 0;
        adfGeoTransform[3] = 0;
        adfGeoTransform[4] = 0;
        adfGeoTransform[5] = -1;
    }
    else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms");
        return NULL;
    }

    int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES"));
    int nBlockXSize, nBlockYSize;
    if (bTiled)
    {
        nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256"));
        nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256"));
        if (nBlockXSize < 64) nBlockXSize = 64;
        else if (nBlockXSize > 4096)  nBlockXSize = 4096;
        if (nBlockYSize < 64) nBlockYSize = 64;
        else if (nBlockYSize > 4096)  nBlockYSize = 4096;
    }
    else
    {
        nBlockXSize = nXSize;
        nBlockYSize = nYSize;
    }
    
/* -------------------------------------------------------------------- */
/*      Analyze arguments                                               */
/* -------------------------------------------------------------------- */
    
    CPLString osDBName;
    CPLString osTableName;
    VSIStatBuf sBuf;
    int bExists;

    /* Skip optionnal RASTERLITE: prefix */
    const char* pszFilenameWithoutPrefix = pszFilename;
    if (EQUALN(pszFilename, "RASTERLITE:", 11))
        pszFilenameWithoutPrefix += 11;
    
    char** papszTokens = CSLTokenizeStringComplex( 
                pszFilenameWithoutPrefix, ", ", FALSE, FALSE );
    int nTokens = CSLCount(papszTokens);
    if (nTokens == 0)
    {
        osDBName = pszFilenameWithoutPrefix;
        osTableName = CPLGetBasename(pszFilenameWithoutPrefix);
    }
    else
    {
        osDBName = papszTokens[0];
        
        int i;
        for(i=1;i<nTokens;i++)
        {
            if (EQUALN(papszTokens[i], "table=", 6))
                osTableName = papszTokens[i] + 6;
            else
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "Invalid option : %s", papszTokens[i]);
            }
        }
    }
    
    CSLDestroy(papszTokens);
    papszTokens = NULL;
    
    bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0);

    if (osTableName.size() == 0)
    {
        if (bExists)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Database already exists. Explicit table name must be specified");
            return NULL;
        }
        osTableName = CPLGetBasename(osDBName.c_str());
    }    
    
    CPLString osRasterLayer;
    osRasterLayer.Printf("%s_rasters", osTableName.c_str());
    
    CPLString osMetatadataLayer;
    osMetatadataLayer.Printf("%s_metadata", osTableName.c_str());

/* -------------------------------------------------------------------- */
/*      Create or open the SQLite DB                                    */
/* -------------------------------------------------------------------- */
    
    if (OGRGetDriverCount() == 0)
        OGRRegisterAll();
        
    OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite");
    if (hSQLiteDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver");
        return NULL;
    }   
    
    OGRDataSourceH hDS;
    
    CPLString osOldVal =
        CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE");
    CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE");
    if (!bExists)
    {
        char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES");
        hDS = OGR_Dr_CreateDataSource(hSQLiteDriver,
                                      osDBName.c_str(), papszOGROptions);
        CSLDestroy(papszOGROptions);
    }
    else
    {
        hDS = OGROpen(osDBName.c_str(), TRUE, NULL);
    }
    CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str());
    
    if (hDS == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Cannot load or create SQLite database");
        return NULL;
    }

    CPLString osSQL;
    
/* -------------------------------------------------------------------- */
/*      Get the SRID for the SRS                                        */
/* -------------------------------------------------------------------- */
    int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef());

/* -------------------------------------------------------------------- */
/*      Create or wipe existing tables                                  */
/* -------------------------------------------------------------------- */
    int bWipeExistingData =
        CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO"));
        
    hDS = RasterliteCreateTables(hDS, osTableName.c_str(),
                                 nSRSId, bWipeExistingData);
    if (hDS == NULL)
        return NULL;

    OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str());
    OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str());
    if (hRasterLayer == NULL || hMetadataLayer == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Cannot find metadata and/or raster tables");
        OGRReleaseDataSource(hDS);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Check if there is overlapping data and warn the user            */
/* -------------------------------------------------------------------- */
    double minx = adfGeoTransform[0];
    double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1];
    double maxy = adfGeoTransform[3];
    double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5];
    
    osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" "
                 "WHERE rowid IN "
                 "(SELECT pkid FROM \"idx_%s_metadata_geometry\" "
                  "WHERE xmin < %.15f AND xmax > %.15f "
                  "AND ymin < %.15f  AND ymax > %.15f) "
                 "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND "
                 "pixel_y_size >= %.15f AND pixel_y_size <= %.15f",
                  osMetatadataLayer.c_str(),
                  osTableName.c_str(),
                  maxx, minx, maxy, miny,
                  adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15,
                  - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15);
    
    int nOverlappingGeoms = 0;
    OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL);
    if (hCountLyr)
    {
        OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr);
        if (hFeat)
        {
            nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0);
            OGR_F_Destroy(hFeat);
        }
        OGR_DS_ReleaseResultSet(hDS, hCountLyr);
    }
    
    if (nOverlappingGeoms != 0)
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Raster tiles already exist in the %s table within "
                 "the extent of the data to be inserted in",
                 osTableName.c_str());
    }
   
/* -------------------------------------------------------------------- */
/*      Iterate over blocks to add data into raster and metadata tables */
/* -------------------------------------------------------------------- */
    int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize;
    int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize;

    GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8;
    GByte* pabyMEMDSBuffer =
        (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize);
    if (pabyMEMDSBuffer == NULL)
    {
        OGRReleaseDataSource(hDS);
        return NULL;
    }
    
    CPLString osTempFileName;
    osTempFileName.Printf("/vsimem/%p", hDS);
    
    int nTileId = 0;
    int nBlocks = 0;
    int nTotalBlocks = nXBlocks * nYBlocks;

    char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions);
    
    OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL);
    
    CPLErr eErr = CE_None;
    int nBlockXOff, nBlockYOff;
    for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++)
    {
        for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++)
        {
/* -------------------------------------------------------------------- */
/*      Create in-memory tile                                           */
/* -------------------------------------------------------------------- */
            int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize;
            if ((nBlockXOff+1) * nBlockXSize > nXSize)
                nReqXSize = nXSize - nBlockXOff * nBlockXSize;
            if ((nBlockYOff+1) * nBlockYSize > nYSize)
                nReqYSize = nYSize - nBlockYOff * nBlockYSize;

            eErr = poSrcDS->RasterIO(GF_Read,
                                     nBlockXOff * nBlockXSize,
                                     nBlockYOff * nBlockYSize,
                                     nReqXSize, nReqYSize,
                                     pabyMEMDSBuffer, nReqXSize, nReqYSize,
                                     eDataType, nBands, NULL,
                                     0, 0, 0);
            if (eErr != CE_None)
            {
                break;
            }
            
            GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::",
                                              nReqXSize, nReqYSize, 0, 
                                              eDataType, NULL);
            if (hMemDS == NULL)
            {
                eErr = CE_Failure;
                break;
            }
            
            int iBand;
            for(iBand = 0; iBand < nBands; iBand ++)
            {
                char** papszMEMDSOptions = NULL;
                char szTmp[64];
                memset(szTmp, 0, sizeof(szTmp));
                CPLPrintPointer(szTmp,
                                pabyMEMDSBuffer + iBand * nDataTypeSize *
                                nReqXSize * nReqYSize, sizeof(szTmp));
                papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp);
                GDALAddBand(hMemDS, eDataType, papszMEMDSOptions);
                CSLDestroy(papszMEMDSOptions);
            }
            
            GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver,
                                        osTempFileName.c_str(), hMemDS, FALSE,
                                        papszTileDriverOptions, NULL, NULL);

            GDALClose(hMemDS);
            if (hOutDS)
                GDALClose(hOutDS);
            else
            {
                eErr = CE_Failure;
                break;
            }

/* -------------------------------------------------------------------- */
/*      Insert new entry into raster table                              */
/* -------------------------------------------------------------------- */

            vsi_l_offset nDataLength;
            GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(),
                                                   &nDataLength, FALSE);

            OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) );
            OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData);
            
            OGR_L_CreateFeature(hRasterLayer, hFeat);
            /* Query raster ID to set it as the ID of the associated metadata */
            int nRasterID = (int)OGR_F_GetFID(hFeat);
            
            OGR_F_Destroy(hFeat);
            
            VSIUnlink(osTempFileName.c_str());
            
/* -------------------------------------------------------------------- */
/*      Insert new entry into metadata table                            */
/* -------------------------------------------------------------------- */
            
            hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) );
            OGR_F_SetFID(hFeat, nRasterID);
            OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS));
            OGR_F_SetFieldInteger(hFeat, 1, nTileId ++);
            OGR_F_SetFieldInteger(hFeat, 2, nReqXSize);
            OGR_F_SetFieldInteger(hFeat, 3, nReqYSize);
            OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]);
            OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]);
            
            minx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff) * adfGeoTransform[1];
            maxx = adfGeoTransform[0] +
                (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1];
            maxy = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff) * adfGeoTransform[5];
            miny = adfGeoTransform[3] +
                (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5];
            
            OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon);
            OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, maxy);
            OGR_G_AddPoint_2D(hLinearRing, maxx, miny);
            OGR_G_AddPoint_2D(hLinearRing, minx, miny);
            OGR_G_AddGeometryDirectly(hRectangle, hLinearRing);
            
            OGR_F_SetGeometryDirectly(hFeat, hRectangle);
            
            OGR_L_CreateFeature(hMetadataLayer, hFeat);
            OGR_F_Destroy(hFeat);
            
            nBlocks++;
            if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks,
                                            NULL, pProgressData))
                eErr = CE_Failure;
        }
    }
    
    if (eErr == CE_None)
        OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL);
    else
        OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL);
    
    CSLDestroy(papszTileDriverOptions);
    
    VSIFree(pabyMEMDSBuffer);
    
    OGRReleaseDataSource(hDS);
        
    return (GDALDataset*) GDALOpen(pszFilename, GA_Update);
}