public Planetiler addShapefileGlobSource(String projection, String sourceName, Path basePath,
    String globPattern, String defaultUrl) {
    Path dirPath = getPath(sourceName, "shapefile glob", basePath, defaultUrl);

    return addStage(sourceName, "Process all files matching " + dirPath + "/" + globPattern,
      ifSourceUsed(sourceName, () -> {
        var sourcePaths = FileUtils.walkPathWithPattern(basePath, globPattern,
          zipPath -> FileUtils.walkPathWithPattern(zipPath, "*.shp"));
        ShapefileReader.processWithProjection(projection, sourceName, sourcePaths, featureGroup, config,
          profile, stats);
      }));
  }
Adds a new ESRI shapefile glob source that will process all files under {@param basePath} matching
{@param globPattern} using an explicit projection. {@param basePath} may be a directory or ZIP archive.
<p>
If {@param globPattern} matches a ZIP archive, all files ending in {@code .shp} within the archive will be used for
this source.
<p>
If the file does not exist and {@code download=true} argument is set, then the file will first be downloaded from
{@code defaultUrl}.
<p>

@param projection  the Coordinate Reference System authority code to use, parsed with
                   {@link org.geotools.referencing.CRS#decode(String)}
@param sourceName  string to use in stats and logs to identify this stage
@param basePath    path to the directory or zip file containing shapefiles to process
@param globPattern string to match filenames against, as described in {@link FileSystem#getPathMatcher(String)}.
@param defaultUrl  remote URL that the file to download if {@code download=true} argument is set and
                   {@code name_url} argument is not set
@return this runner instance for chaining
@see ShapefileReader
planetiler-core/src/main/java/com/onthegomap/planetiler/Planetiler.java