/****************************************************************************** * $Id$ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Program to generate a UMN MapServer compatible tile index for a * set of OGR data sources. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2002, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ import org.gdal.gdal.gdal; import org.gdal.ogr.DataSource; import org.gdal.ogr.Driver; import org.gdal.ogr.Feature; import org.gdal.ogr.FeatureDefn; import org.gdal.ogr.FieldDefn; import org.gdal.ogr.Geometry; import org.gdal.ogr.Layer; import org.gdal.ogr.ogr; import org.gdal.osr.SpatialReference; /* Note : this is the most direct port of ogrtindex.cpp possible */ /* It could be made much more java'ish ! */ public class ogrtindex { public static void main(String[] args) { boolean bLayersWildcarded = true; int nFirstSourceDataset = -1; String pszFormat = "ESRI Shapefile"; String pszTileIndexField = "LOCATION"; String pszOutputName = null; boolean write_absolute_path = false; boolean skip_different_projection = false; String current_path = null; boolean accept_different_schemas = false; boolean bFirstWarningForNonMatchingAttributes = true; ogr.DontUseExceptions(); /* -------------------------------------------------------------------- */ /* Register format(s). */ /* -------------------------------------------------------------------- */ // fixed: http://osgeo-org.1803224.n2.nabble.com/GDAL-Java-Binding-meomory-problem-under-intensive-method-calls-td7155011.html#a7157916 if( ogr.GetDriverCount() == 0 ) ogr.RegisterAll(); /* -------------------------------------------------------------------- */ /* Processing command line arguments. */ /* -------------------------------------------------------------------- */ args = ogr.GeneralCmdLineProcessor( args ); if( args.length < 2 ) { Usage(); return; } for( int iArg = 0; iArg < args.length; iArg++ ) { if( args[iArg].equalsIgnoreCase("-f") && iArg < args.length-1 ) { pszFormat = args[++iArg]; } else if( args[iArg].equalsIgnoreCase("-write_absolute_path") ) { write_absolute_path = true; } else if( args[iArg].equalsIgnoreCase("-skip_different_projection") ) { skip_different_projection = true; } else if( args[iArg].equalsIgnoreCase("-accept_different_schemas") ) { accept_different_schemas = true; } else if( args[iArg].equalsIgnoreCase("-tileindex") && iArg < args.length-1 ) { pszTileIndexField = args[++iArg]; } else if( args[iArg].equalsIgnoreCase("-lnum") || args[iArg].equalsIgnoreCase("-lname") ) { iArg++; bLayersWildcarded = false; } else if( args[iArg].charAt(0) == '-' ) Usage(); else if( pszOutputName == null ) pszOutputName = args[iArg]; else if( nFirstSourceDataset == -1 ) nFirstSourceDataset = iArg; } if( pszOutputName == null || nFirstSourceDataset == -1 ) 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 = (int)poDstLayer.GetFeatureCount(); if (nExistingLayers > 0) { existingLayersTab = new String[nExistingLayers]; for(int i=0;i=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