Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: Program to generate a UMN MapServer compatible tile index for a 5 : * set of OGR data sources. 6 : * Author: Frank Warmerdam, warmerdam@pobox.com 7 : * 8 : ****************************************************************************** 9 : * Copyright (c) 2002, Frank Warmerdam 10 : * Copyright (c) 2007-2010, Even Rouault <even dot rouault at spatialys.com> 11 : * 12 : * SPDX-License-Identifier: MIT 13 : ****************************************************************************/ 14 : 15 : #include "cpl_port.h" 16 : 17 : #include <vector> 18 : 19 : #include "cpl_conv.h" 20 : #include "cpl_string.h" 21 : #include "gdalargumentparser.h" 22 : 23 : #include "gdalalg_vector_index.h" 24 : #include "commonutils.h" 25 : 26 : /************************************************************************/ 27 : /* main() */ 28 : /************************************************************************/ 29 : 30 9 : MAIN_START(nArgc, papszArgv) 31 : 32 : { 33 9 : EarlySetConfigOptions(nArgc, papszArgv); 34 : 35 9 : GDALAllRegister(); 36 : 37 9 : nArgc = GDALGeneralCmdLineProcessor(nArgc, &papszArgv, 0); 38 9 : if (nArgc < 1) 39 1 : exit(-nArgc); 40 : 41 16 : CPLStringList aosArgv; 42 84 : for (int i = 0; i < nArgc; i++) 43 : { 44 76 : aosArgv.AddString(papszArgv[i]); 45 : } 46 : 47 8 : CSLDestroy(papszArgv); 48 : 49 : /* -------------------------------------------------------------------- */ 50 : /* Processing command line arguments. */ 51 : /* -------------------------------------------------------------------- */ 52 16 : std::string osOutputFormat; 53 16 : std::string osTileIndexField; 54 16 : std::string osOutputName; 55 8 : bool bWriteAbsolutePath{false}; 56 8 : bool bSkipDifferentProjection{false}; 57 8 : bool bAcceptDifferentSchemas{false}; 58 16 : std::string osTargetSRS; 59 16 : std::string osSrcSRSName; 60 16 : std::string osSrcSRSFormat; 61 16 : std::vector<std::string> aosSrcDatasets; 62 16 : std::vector<std::string> aosLayerNames; 63 16 : std::vector<int> anLayerNumbers; 64 : 65 24 : GDALArgumentParser argParser{"ogrtindex", true}; 66 : 67 : argParser.add_description( 68 : _("Program to generate a UMN MapServer compatible " 69 8 : "tile index for a set of OGR data sources.")); 70 : 71 : argParser.add_epilog( 72 : _("For more details, see the full documentation for ogrtindex " 73 8 : "at\nhttps://gdal.org/programs/ogrtindex.html")); 74 : 75 8 : argParser.add_argument("-lnum") 76 16 : .metavar("<n>") 77 8 : .append() 78 8 : .scan<'i', int>() 79 8 : .store_into(anLayerNumbers) 80 : .help( 81 8 : _("Add layer number <n> from each source file in the tile index.")); 82 : 83 8 : argParser.add_argument("-lname") 84 16 : .metavar("<name>") 85 8 : .append() 86 8 : .store_into(aosLayerNames) 87 : .help(_( 88 8 : "Add layer named <name> from each source file in the tile index.")); 89 : 90 8 : argParser.add_output_format_argument(osOutputFormat); 91 : 92 8 : argParser.add_argument("-tileindex") 93 16 : .metavar("<tileindex>") 94 8 : .default_value("LOCATION") 95 8 : .nargs(1) 96 8 : .store_into(osTileIndexField) 97 8 : .help(_("Name to use for the dataset name.")); 98 : 99 8 : argParser.add_argument("-write_absolute_path") 100 8 : .flag() 101 8 : .store_into(bWriteAbsolutePath) 102 8 : .help(_("Write absolute path of the source file in the tile index.")); 103 : 104 8 : argParser.add_argument("-skip_different_projection") 105 8 : .flag() 106 8 : .store_into(bSkipDifferentProjection) 107 : .help(_("Skip layers that are not in the same projection as the first " 108 8 : "layer.")); 109 : 110 8 : argParser.add_argument("-t_srs") 111 16 : .metavar("<srs_def>") 112 8 : .store_into(osTargetSRS) 113 : .help( 114 : _("Extent of input files will be transformed to the desired target " 115 8 : "coordinate reference system.")); 116 : 117 8 : argParser.add_argument("-src_srs_name") 118 16 : .metavar("<field_name>") 119 8 : .store_into(osSrcSRSName) 120 8 : .help(_("Name of the field to store the SRS of each tile.")); 121 : 122 8 : argParser.add_argument("-src_srs_format") 123 16 : .metavar("{AUTO|WKT|EPSG|PROJ}") 124 8 : .choices("AUTO", "WKT", "EPSG", "PROJ") 125 8 : .store_into(osSrcSRSFormat) 126 8 : .help(_("Format of the source SRS to store in the tile index file.")); 127 : 128 8 : argParser.add_argument("-accept_different_schemas") 129 8 : .flag() 130 8 : .store_into(bAcceptDifferentSchemas) 131 : .help(_( 132 8 : "Disable check for identical schemas for layers in input files.")); 133 : 134 8 : argParser.add_argument("output_dataset") 135 16 : .metavar("<output_dataset>") 136 8 : .store_into(osOutputName) 137 8 : .help(_("Name of the output dataset.")); 138 : 139 8 : argParser.add_argument("src_dataset") 140 16 : .metavar("<src_dataset>") 141 8 : .nargs(nargs_pattern::at_least_one) 142 8 : .store_into(aosSrcDatasets) 143 8 : .help(_("Name of the source dataset(s).")); 144 : 145 : try 146 : { 147 8 : argParser.parse_args(aosArgv); 148 : } 149 0 : catch (const std::exception &e) 150 : { 151 0 : argParser.display_error_and_usage(e); 152 0 : GDALDestroy(); 153 0 : return 1; 154 : } 155 : 156 : /* -------------------------------------------------------------------- */ 157 : /* Validate input */ 158 : /* -------------------------------------------------------------------- */ 159 : 160 : //srs_name must be specified when srs_format is specified. 161 12 : if (argParser.is_used("-src_srs_format") && 162 12 : !argParser.is_used("-src_srs_name")) 163 : { 164 0 : fprintf(stderr, "-src_srs_name must be specified when -src_srs_format " 165 : "is specified.\n"); 166 0 : GDALDestroy(); 167 0 : return 1; 168 : } 169 : 170 8 : GDALVectorIndexAlgorithm alg; 171 8 : alg["called-from-ogrtindex"] = true; 172 8 : alg["input"] = aosSrcDatasets; 173 8 : alg["output"] = osOutputName; 174 8 : if (!osOutputFormat.empty()) 175 2 : alg["output-format"] = osOutputFormat; 176 8 : if (!aosLayerNames.empty()) 177 1 : alg["source-layer-name"] = aosLayerNames; 178 8 : if (!anLayerNumbers.empty()) 179 1 : alg["source-layer-index"] = anLayerNumbers; 180 8 : if (!osSrcSRSName.empty()) 181 5 : alg["source-crs-field-name"] = osSrcSRSName; 182 8 : if (!osSrcSRSFormat.empty()) 183 4 : alg["source-crs-format"] = osSrcSRSFormat; 184 8 : if (!osTargetSRS.empty()) 185 5 : alg["dst-crs"] = osTargetSRS; 186 8 : alg["accept-different-schemas"] = bAcceptDifferentSchemas; 187 8 : if (bSkipDifferentProjection) 188 2 : alg["skip-different-crs"] = bSkipDifferentProjection; 189 8 : alg["absolute-path"] = bWriteAbsolutePath; 190 8 : alg["location-name"] = osTileIndexField; 191 : 192 : { 193 16 : CPLErrorStateBackuper oBackuper(CPLQuietErrorHandler); 194 16 : if (std::unique_ptr<GDALDataset>( 195 8 : GDALDataset::Open(osOutputName.c_str(), GDAL_OF_VECTOR))) 196 0 : alg["append"] = true; 197 : } 198 : 199 : const int nRetCode = 200 8 : CPLGetLastErrorType() == CE_None && alg.Run() && alg.Finalize() ? 0 : 1; 201 : 202 8 : GDALDestroy(); 203 : 204 8 : return nRetCode; 205 : } 206 : 207 0 : MAIN_END