Usage();
/* -------------------------------------------------------------------- */
/* Try to open as an existing dataset for update access. */
/* -------------------------------------------------------------------- */
DataSource poDstDS;
Layer poDstLayer = null;
poDstDS = ogr.Open( pszOutputName, true );
/* -------------------------------------------------------------------- */
/* If that failed, find the driver so we can create the tile index.*/
/* -------------------------------------------------------------------- */
if( poDstDS == null )
{
Driver poDriver = null;
for( int iDriver = 0; iDriver < ogr.GetDriverCount() && poDriver == null; iDriver++ )
{
poDriver = ogr.GetDriverByName(pszFormat);
}
if( poDriver == null )
{
System.err.print("Unable to find driver '"+pszFormat+"'.\n");
System.err.print("The following drivers are available:\n" );
for( int iDriver = 0; iDriver < ogr.GetDriverCount(); iDriver++ )
{
System.err.print(" . '"+ogr.GetDriver(iDriver).GetName()+"'\n");
}
return;
}
if( !poDriver.TestCapability( ogr.ODrCCreateDataSource ) )
{
System.err.print(pszFormat + " driver does not support data source creation.\n");
return;
}
/* -------------------------------------------------------------------- */
/* Now create it. */
/* -------------------------------------------------------------------- */
poDstDS = poDriver.CreateDataSource( pszOutputName );
if( poDstDS == null )
{
System.err.print(pszFormat + " driver failed to create "+pszOutputName+"\n");
return;
}
if ( poDstDS.GetLayerCount() == 0 )
{
FieldDefn oLocation = new FieldDefn( pszTileIndexField, ogr.OFTString );
oLocation.SetWidth( 200 );
if( nFirstSourceDataset < args.length-2 && args[nFirstSourceDataset].charAt(0) == '-' )
{
nFirstSourceDataset++;
}
SpatialReference poSrcSpatialRef = null;
/* Fetches the SRS of the first layer and use it when creating the tileindex layer */
if (nFirstSourceDataset < args.length)
{
DataSource poDS = ogr.Open( args[nFirstSourceDataset],false );
if (poDS!=null)
{
for(int iLayer = 0; iLayer < poDS.GetLayerCount(); iLayer++ )
{
boolean bRequested = bLayersWildcarded;
Layer poLayer = poDS.GetLayer(iLayer);
for(int iArg = 0; iArg < args.length && !bRequested; iArg++ )
{
if( args[iArg].equalsIgnoreCase("-lnum")
&& Integer.parseInt(args[iArg+1]) == iLayer )
bRequested = true;
else if( args[iArg].equalsIgnoreCase("-lname")
&& args[iArg+1].equalsIgnoreCase(poLayer.GetLayerDefn().GetName()) )
bRequested = true;
}
if( !bRequested )
continue;
if ( poLayer.GetSpatialRef() != null)
poSrcSpatialRef = poLayer.GetSpatialRef().Clone();
break;
}
}
poDS.delete();
}
poDstLayer = poDstDS.CreateLayer( "tileindex", poSrcSpatialRef );
poDstLayer.CreateField( oLocation, ogr.OFTString );
/* with the OGR Java bindings, avoid using the delete() methods,
* except on the datasource objects, where it is necessary to close properly the
* native file handles.
*/
// poSrcSpatialRef.delete();
}
}
/* -------------------------------------------------------------------- */
/* Identify target layer and field. */
/* -------------------------------------------------------------------- */
int iTileIndexField;
poDstLayer = poDstDS.GetLayer(0);
if( poDstLayer == null )
{
System.err.print("Can't find any layer in output tileindex!\n" );
return;
}
iTileIndexField =
poDstLayer.GetLayerDefn().GetFieldIndex( pszTileIndexField );
if( iTileIndexField == -1 )
{
System.err.print("Can't find "+pszTileIndexField+" field in tile index dataset.\n");
return;
}
FeatureDefn poFeatureDefn = null;
/* Load in memory existing file names in SHP */
int nExistingLayers = 0;
String[] existingLayersTab = null;
SpatialReference alreadyExistingSpatialRef = null;
boolean alreadyExistingSpatialRefValid = false;
nExistingLayers = poDstLayer.GetFeatureCount();
if (nExistingLayers > 0)
{
existingLayersTab = new String[nExistingLayers];
for(int i=0;i<nExistingLayers;i++)
{
Feature feature = poDstLayer.GetNextFeature();
existingLayersTab[i] = feature.GetFieldAsString( iTileIndexField);
if (i == 0)
{
DataSource poDS;
String filename = existingLayersTab[i];
int j;
for(j=filename.length()-1;j>=0;j--)
{
if (filename.charAt(j) == ',')
break;
}
if (j >= 0)
{
int iLayer = Integer.parseInt(filename.substring(j + 1));
filename = filename.substring(0, j);
poDS = ogr.Open(filename,false );
if (poDS!=null)
{
Layer poLayer = poDS.GetLayer(iLayer);
if (poLayer!=null)
{
alreadyExistingSpatialRefValid = true;
alreadyExistingSpatialRef =
(poLayer.GetSpatialRef()!=null) ? poLayer.GetSpatialRef().Clone() : null;
if (poFeatureDefn == null) {
poFeatureDefn = CloneFeatureDefn(poLayer.GetLayerDefn()); // XXX: no Clone supported in java binding!!
}
}
poDS.delete();
}
}
}
}
}
/* ignore check */
//if (write_absolute_path)
//{
// current_path = CPLGetCurrentDir();
// if (current_path == null)
// {
// fprintf( stderr, "This system does not support the CPLGetCurrentDir call. "
// "The option -write_absolute_path will have no effect\n");
// write_absolute_path = false;
// }
//}
/* ==================================================================== */
/* Process each input datasource in turn. */
/* ==================================================================== */
for(; nFirstSourceDataset < args.length; nFirstSourceDataset++ )
{
DataSource poDS;
if( args[nFirstSourceDataset].charAt(0) == '-' )
{
nFirstSourceDataset++;
continue;
}
String fileNameToWrite;
//VSIStatBuf sStatBuf;
// FIXME: handle absolute path check
//if (write_absolute_path && CPLIsFilenameRelative( args[nFirstSourceDataset] ) &&
// VSIStat( args[nFirstSourceDataset], &sStatBuf ) == 0)
//{
// fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path,args[nFirstSourceDataset]));
//}
//else
//{
// fileNameToWrite = args[nFirstSourceDataset];
//}
fileNameToWrite = args[nFirstSourceDataset];
poDS = ogr.Open( args[nFirstSourceDataset], false );
if( poDS == null )
{
System.err.print("Failed to open dataset "+args[nFirstSourceDataset]+", skipping.\n");
continue;
}
/* -------------------------------------------------------------------- */
/* Check all layers, and see if they match requests. */
/* -------------------------------------------------------------------- */
for(int iLayer = 0; iLayer < poDS.GetLayerCount(); iLayer++ )
{
boolean bRequested = bLayersWildcarded;
Layer poLayer = poDS.GetLayer(iLayer);
for(int iArg = 0; iArg < args.length && !bRequested; iArg++ )
{
if( args[iArg].equalsIgnoreCase("-lnum")
&& Integer.parseInt(args[iArg+1]) == iLayer )
bRequested = true;
else if( args[iArg].equalsIgnoreCase("-lname")
&& args[iArg+1].equalsIgnoreCase(poLayer.GetLayerDefn().GetName()) )
bRequested = true;
}
if( !bRequested )
continue;
/* Checks that the layer is not already in tileindex */
int i;
for(i=0;i<nExistingLayers;i++)
{
String szLocation = fileNameToWrite+","+iLayer;
if (szLocation.equalsIgnoreCase(existingLayersTab[i]))
{
System.err.println("Layer "+iLayer+" of "+args[nFirstSourceDataset]+" is already in tileindex. Skipping it.\n");
break;
}
}
if (i != nExistingLayers)
{
continue;
}
SpatialReference spatialRef = poLayer.GetSpatialRef();
if (alreadyExistingSpatialRefValid)
{
if ((spatialRef != null && alreadyExistingSpatialRef != null &&
spatialRef.IsSame(alreadyExistingSpatialRef) == 0) ||
((spatialRef != null) != (alreadyExistingSpatialRef != null)))
{
System.err.print("Warning : layer "+iLayer+" of "+args[nFirstSourceDataset]+" is not using the same projection system as "
+ "other files in the tileindex. This may cause problems when "
+ "using it in MapServer for example."+((skip_different_projection) ? " Skipping it" : "")+"\n");
;
if (skip_different_projection)
{
continue;
}
}
}
else
{
alreadyExistingSpatialRefValid = true;
alreadyExistingSpatialRef = (spatialRef!=null) ? spatialRef.Clone() : null;
}
/* -------------------------------------------------------------------- */
/* Check if all layers in dataset have the same attributes schema. */
/* -------------------------------------------------------------------- */
if( poFeatureDefn == null )
{
poFeatureDefn = CloneFeatureDefn(poLayer.GetLayerDefn()); // XXX: no Clone supported in java binding!!
}
else if ( !accept_different_schemas )
{
FeatureDefn poFeatureDefnCur = poLayer.GetLayerDefn();
assert(null != poFeatureDefnCur);
int fieldCount = poFeatureDefnCur.GetFieldCount();
if( fieldCount != poFeatureDefn.GetFieldCount())
{
System.err.print("Number of attributes of layer "+poLayer.GetLayerDefn().GetName()+" of "+args[nFirstSourceDataset]+" does not match ... skipping it.\n");
if (bFirstWarningForNonMatchingAttributes)
{
System.err.print("Note : you can override this behaviour with -accept_different_schemas option\n"
+ "but this may result in a tileindex incompatible with MapServer\n");
bFirstWarningForNonMatchingAttributes = false;
}
continue;
}
boolean bSkip = false;
for( int fn = 0; fn < poFeatureDefnCur.GetFieldCount(); fn++ )
{
FieldDefn poField = poFeatureDefn.GetFieldDefn(fn);
FieldDefn poFieldCur = poFeatureDefnCur.GetFieldDefn(fn);
/* XXX - Should those pointers be checked against null? */
assert(null != poField);
assert(null != poFieldCur);
if( !poField.GetTypeName().equalsIgnoreCase(poFieldCur.GetTypeName())
|| poField.GetWidth() != poFieldCur.GetWidth()
|| poField.GetPrecision() != poFieldCur.GetPrecision()
|| !poField.GetNameRef().equalsIgnoreCase(poFieldCur.GetNameRef()) )
{
System.err.print("Schema of attributes of layer "+poLayer.GetLayerDefn().GetName()+" of "+args[nFirstSourceDataset]+" does not match ... skipping it.\n");
if (bFirstWarningForNonMatchingAttributes)
{
System.err.print("Note : you can override this behaviour with -accept_different_schemas option\n"
+ "but this may result in a tileindex incompatible with MapServer\n");
bFirstWarningForNonMatchingAttributes = false;
}
bSkip = true;
break;
}
}
if (bSkip)
continue;
}
/* -------------------------------------------------------------------- */
/* Get layer extents, and create a corresponding polygon */
/* geometry. */
/* -------------------------------------------------------------------- */
double sExtents[] = poLayer.GetExtent(true);
Geometry/*Polygon*/ oRegion = new Geometry(ogr.wkbPolygon);
Geometry/*LinearRing*/ oRing = new Geometry(ogr.wkbLinearRing);
if (sExtents == null) {
System.err.print("GetExtent() failed on layer "+poLayer.GetLayerDefn().GetName()+" of "+args[nFirstSourceDataset]+", skipping.\n");
continue;
}
// XXX: sExtents [minX, maxX, minY, maxY]
//oRing.addPoint( sExtents.MinX, sExtents.MinY );
//oRing.addPoint( sExtents.MinX, sExtents.MaxY );
//oRing.addPoint( sExtents.MaxX, sExtents.MaxY );
//oRing.addPoint( sExtents.MaxX, sExtents.MinY );
//oRing.addPoint( sExtents.MinX, sExtents.MinY );
oRing.AddPoint_2D( sExtents[0], sExtents[2] );
oRing.AddPoint_2D( sExtents[0], sExtents[3] );
oRing.AddPoint_2D( sExtents[1], sExtents[3] );
oRing.AddPoint_2D( sExtents[1], sExtents[2] );
oRing.AddPoint_2D( sExtents[0], sExtents[2] );
oRegion.AddGeometry( oRing );
/* -------------------------------------------------------------------- */
/* Add layer to tileindex. */
/* -------------------------------------------------------------------- */
String szLocation = fileNameToWrite+","+iLayer;
Feature oTileFeat = new Feature( poDstLayer.GetLayerDefn() );
oTileFeat.SetGeometry( oRegion );
oTileFeat.SetField( iTileIndexField, szLocation );
if( poDstLayer.CreateFeature( oTileFeat ) != ogr.OGRERR_NONE )
{
System.err.print("Failed to create feature on tile index ... terminating." );
poDS.delete();
poDstDS.delete();
return;
}
}
/* -------------------------------------------------------------------- */
/* Cleanup this data source. */
/* -------------------------------------------------------------------- */
poDS.delete();
}
/* -------------------------------------------------------------------- */
/* Close tile index and clear buffers. */
/* -------------------------------------------------------------------- */