String pszWHERE,
ProgressCallback pfnProgress)
{
Layer poDstLayer;
FeatureDefn poSrcFDefn;
int eErr;
boolean bForceToPolygon = false;
boolean bForceToMultiPolygon = false;
boolean bForceToMultiLineString = false;
if( pszNewLayerName == null )
pszNewLayerName = poSrcLayer.GetLayerDefn().GetName();
if( wkbFlatten(eGType) == ogr.wkbPolygon )
bForceToPolygon = true;
else if( wkbFlatten(eGType) == ogr.wkbMultiPolygon )
bForceToMultiPolygon = true;
else if( wkbFlatten(eGType) == ogr.wkbMultiLineString )
bForceToMultiLineString = true;
/* -------------------------------------------------------------------- */
/* Setup coordinate transformation if we need it. */
/* -------------------------------------------------------------------- */
CoordinateTransformation poCT = null;
if( bTransform )
{
if( poSourceSRS == null )
poSourceSRS = poSrcLayer.GetSpatialRef();
if( poSourceSRS == null )
{
System.err.println("Can't transform coordinates, source layer has no\n" +
"coordinate system. Use -s_srs to set one." );
System.exit( 1 );
}
/*CPLAssert( null != poSourceSRS );
CPLAssert( null != poOutputSRS );*/
/* New in GDAL 1.10. Before was "new CoordinateTransformation(srs,dst)". */
poCT = CoordinateTransformation.CreateCoordinateTransformation( poSourceSRS, poOutputSRS );
if( poCT == null )
{
String pszWKT = null;
System.err.println("Failed to create coordinate transformation between the\n" +
"following coordinate systems. This may be because they\n" +
"are not transformable, or because projection services\n" +
"(PROJ.4 DLL/.so) could not be loaded." );
pszWKT = poSourceSRS.ExportToPrettyWkt( 0 );
System.err.println( "Source:\n" + pszWKT );
pszWKT = poOutputSRS.ExportToPrettyWkt( 0 );
System.err.println( "Target:\n" + pszWKT );
System.exit( 1 );
}
}
/* -------------------------------------------------------------------- */
/* Get other info. */
/* -------------------------------------------------------------------- */
poSrcFDefn = poSrcLayer.GetLayerDefn();
if( poOutputSRS == null )
poOutputSRS = poSrcLayer.GetSpatialRef();
/* -------------------------------------------------------------------- */
/* Find the layer. */
/* -------------------------------------------------------------------- */
/* GetLayerByName() can instanciate layers that would have been */
/* 'hidden' otherwise, for example, non-spatial tables in a */
/* Postgis-enabled database, so this apparently useless command is */
/* not useless... (#4012) */
gdal.PushErrorHandler("CPLQuietErrorHandler");
poDstLayer = poDstDS.GetLayerByName(pszNewLayerName);
gdal.PopErrorHandler();
gdal.ErrorReset();
int iLayer = -1;
if( poDstLayer != null )
{
int nLayerCount = poDstDS.GetLayerCount();
for( iLayer = 0; iLayer < nLayerCount; iLayer++ )
{
Layer poLayer = poDstDS.GetLayer(iLayer);
if( poLayer != null
&& poLayer.GetName().equals(poDstLayer.GetName()) )
{
break;
}
}
if (iLayer == nLayerCount)
/* shouldn't happen with an ideal driver */
poDstLayer = null;
}
/* -------------------------------------------------------------------- */
/* If the user requested overwrite, and we have the layer in */
/* question we need to delete it now so it will get recreated */
/* (overwritten). */
/* -------------------------------------------------------------------- */
if( poDstLayer != null && bOverwrite )
{
if( poDstDS.DeleteLayer( iLayer ) != 0 )
{
System.err.println(
"DeleteLayer() failed when overwrite requested." );
return false;
}
poDstLayer = null;
}
/* -------------------------------------------------------------------- */
/* If the layer does not exist, then create it. */
/* -------------------------------------------------------------------- */
if( poDstLayer == null )
{
if( eGType == -2 )
{
eGType = poSrcFDefn.GetGeomType();
if ( bExplodeCollections )
{
int n25DBit = eGType & ogr.wkb25DBit;
if (wkbFlatten(eGType) == ogr.wkbMultiPoint)
{
eGType = ogr.wkbPoint | n25DBit;
}
else if (wkbFlatten(eGType) == ogr.wkbMultiLineString)
{
eGType = ogr.wkbLineString | n25DBit;
}
else if (wkbFlatten(eGType) == ogr.wkbMultiPolygon)
{
eGType = ogr.wkbPolygon | n25DBit;
}
else if (wkbFlatten(eGType) == ogr.wkbGeometryCollection)
{
eGType = ogr.wkbUnknown | n25DBit;
}
}
if ( pszZField != null )
eGType |= ogr.wkb25DBit;
}
if( poDstDS.TestCapability( ogr.ODsCCreateLayer ) == false)
{
System.err.println(
"Layer " + pszNewLayerName + "not found, and CreateLayer not supported by driver.");
return false;
}
gdal.ErrorReset();
poDstLayer = poDstDS.CreateLayer( pszNewLayerName, poOutputSRS,
eGType, papszLCO );
if( poDstLayer == null )
return false;
bAppend = false;
}
/* -------------------------------------------------------------------- */
/* Otherwise we will append to it, if append was requested. */
/* -------------------------------------------------------------------- */
else if( !bAppend )
{
System.err.println("FAILED: Layer " + pszNewLayerName + "already exists, and -append not specified.\n" +
" Consider using -append, or -overwrite.");
return false;
}
else
{
if( papszLCO.size() > 0 )
{
System.err.println("WARNING: Layer creation options ignored since an existing layer is\n" +
" being appended to." );
}
}
/* -------------------------------------------------------------------- */
/* Add fields. Default to copy all field. */
/* If only a subset of all fields requested, then output only */
/* the selected fields, and in the order that they were */
/* selected. */
/* -------------------------------------------------------------------- */
int iField;
/* Initialize the index-to-index map to -1's */
int nSrcFieldCount = poSrcFDefn.GetFieldCount();
int[] panMap = new int [nSrcFieldCount];
for( iField=0; iField < nSrcFieldCount; iField++)
panMap[iField] = -1;
FeatureDefn poDstFDefn = poDstLayer.GetLayerDefn();
if (papszSelFields != null && !bAppend )
{
int nDstFieldCount = 0;
if (poDstFDefn != null)
nDstFieldCount = poDstFDefn.GetFieldCount();
for( iField=0; iField < papszSelFields.size(); iField++)
{
int iSrcField = poSrcFDefn.GetFieldIndex((String)papszSelFields.get(iField));
if (iSrcField >= 0)
{
FieldDefn poSrcFieldDefn = poSrcFDefn.GetFieldDefn(iSrcField);
FieldDefn oFieldDefn = new FieldDefn( poSrcFieldDefn.GetNameRef(),
poSrcFieldDefn.GetFieldType() );
oFieldDefn.SetWidth( poSrcFieldDefn.GetWidth() );
oFieldDefn.SetPrecision( poSrcFieldDefn.GetPrecision() );
if (papszFieldTypesToString != null &&
(CSLFindString(papszFieldTypesToString, "All") != -1 ||
CSLFindString(papszFieldTypesToString,
ogr.GetFieldTypeName(poSrcFDefn.GetFieldDefn(iSrcField).GetFieldType())) != -1))
oFieldDefn.SetType(ogr.OFTString);
/* The field may have been already created at layer creation */
int iDstField = -1;
if (poDstFDefn != null)
iDstField = poDstFDefn.GetFieldIndex(oFieldDefn.GetNameRef());
if (iDstField >= 0)
{
panMap[iSrcField] = iDstField;
}
else if (poDstLayer.CreateField( oFieldDefn ) == 0)
{
/* now that we've created a field, GetLayerDefn() won't return NULL */
if (poDstFDefn == null)
poDstFDefn = poDstLayer.GetLayerDefn();
/* Sanity check : if it fails, the driver is buggy */
if (poDstFDefn != null &&
poDstFDefn.GetFieldCount() != nDstFieldCount + 1)
{
System.err.println(
"The output driver has claimed to have added the " + oFieldDefn.GetNameRef() + " field, but it did not!");
}
else
{
panMap[iSrcField] = nDstFieldCount;
nDstFieldCount ++;
}
}
}
else
{
System.err.println("Field '" + (String)papszSelFields.get(iField) + "' not found in source layer.");
if( !bSkipFailures )
return false;
}
}
/* -------------------------------------------------------------------- */
/* Use SetIgnoredFields() on source layer if available */
/* -------------------------------------------------------------------- */
/* Here we differ from the ogr2ogr.cpp implementation since the OGRFeatureQuery */
/* isn't mapped to swig. So in that case just don't use SetIgnoredFields() */
/* to avoid issue raised in #4015 */
if (poSrcLayer.TestCapability(ogr.OLCIgnoreFields) && pszWHERE == null)
{
int iSrcField;
Vector papszIgnoredFields = new Vector();
for(iSrcField=0;iSrcField<nSrcFieldCount;iSrcField++)
{
String pszFieldName =
poSrcFDefn.GetFieldDefn(iSrcField).GetNameRef();
boolean bFieldRequested = false;
for( iField=0; iField < papszSelFields.size(); iField++)
{
if (pszFieldName.equalsIgnoreCase((String)papszSelFields.get(iField)))
{
bFieldRequested = true;
break;
}
}
if (pszZField != null && pszFieldName.equalsIgnoreCase(pszZField))
bFieldRequested = true;
/* If source field not requested, add it to ignored files list */
if (!bFieldRequested)
papszIgnoredFields.addElement(pszFieldName);
}
poSrcLayer.SetIgnoredFields(papszIgnoredFields);
}
}
else if( !bAppend )
{
int nDstFieldCount = 0;
if (poDstFDefn != null)
nDstFieldCount = poDstFDefn.GetFieldCount();
for( iField = 0; iField < nSrcFieldCount; iField++ )
{
FieldDefn poSrcFieldDefn = poSrcFDefn.GetFieldDefn(iField);
FieldDefn oFieldDefn = new FieldDefn( poSrcFieldDefn.GetNameRef(),
poSrcFieldDefn.GetFieldType() );
oFieldDefn.SetWidth( poSrcFieldDefn.GetWidth() );
oFieldDefn.SetPrecision( poSrcFieldDefn.GetPrecision() );
if (papszFieldTypesToString != null &&
(CSLFindString(papszFieldTypesToString, "All") != -1 ||
CSLFindString(papszFieldTypesToString,
ogr.GetFieldTypeName(poSrcFDefn.GetFieldDefn(iField).GetFieldType())) != -1))
oFieldDefn.SetType(ogr.OFTString);
/* The field may have been already created at layer creation */
int iDstField = -1;
if (poDstFDefn != null)
iDstField = poDstFDefn.GetFieldIndex(oFieldDefn.GetNameRef());
if (iDstField >= 0)
{
panMap[iField] = iDstField;
}
else if (poDstLayer.CreateField( oFieldDefn ) == 0)
{
/* now that we've created a field, GetLayerDefn() won't return NULL */
if (poDstFDefn == null)
poDstFDefn = poDstLayer.GetLayerDefn();
/* Sanity check : if it fails, the driver is buggy */
if (poDstFDefn != null &&
poDstFDefn.GetFieldCount() != nDstFieldCount + 1)
{
System.err.println(
"The output driver has claimed to have added the " + oFieldDefn.GetNameRef() + " field, but it did not!");
}
else
{
panMap[iField] = nDstFieldCount;
nDstFieldCount ++;
}
}
}
}
else
{
/* For an existing layer, build the map by fetching the index in the destination */
/* layer for each source field */
if (poDstFDefn == null)
{
System.err.println("poDstFDefn == NULL.\n" );
return false;
}
for( iField = 0; iField < nSrcFieldCount; iField++ )
{
FieldDefn poSrcFieldDefn = poSrcFDefn.GetFieldDefn(iField);
int iDstField = poDstFDefn.GetFieldIndex(poSrcFieldDefn.GetNameRef());
if (iDstField >= 0)
panMap[iField] = iDstField;
}
}