public Planetiler addOsmSource(String name, Path defaultPath, String defaultUrl) {
    if (osmInputFile != null) {
      // TODO: support more than one input OSM file
      throw new IllegalArgumentException("Currently only one OSM input file is supported");
    }
    Path path = getPath(name, "OSM input file", defaultPath, defaultUrl);
    var thisInputFile = new OsmInputFile(path, config.osmLazyReads());
    osmInputFile = thisInputFile;
    // fail fast if there is some issue with madvise on this system
    if (config.nodeMapMadvise() || config.multipolygonGeometryMadvise()) {
      ByteBufferUtil.init();
    }
    return appendStage(new Stage(
      name,
      List.of(
        name + "_pass1: Pre-process OpenStreetMap input (store node locations then relation members)",
        name + "_pass2: Process OpenStreetMap nodes, ways, then relations"
      ),
      ifSourceUsed(name, () -> {
        var header = osmInputFile.getHeader();
        tileArchiveMetadata.setExtraMetadata("planetiler:" + name + ":osmosisreplicationtime", header.instant());
        tileArchiveMetadata.setExtraMetadata("planetiler:" + name + ":osmosisreplicationseq",
          header.osmosisReplicationSequenceNumber());
        tileArchiveMetadata.setExtraMetadata("planetiler:" + name + ":osmosisreplicationurl",
          header.osmosisReplicationBaseUrl());
        try (
          var nodeLocations =
            LongLongMap.from(config.nodeMapType(), config.nodeMapStorage(), nodeDbPath, config.nodeMapMadvise());
          var multipolygonGeometries = LongLongMultimap.newReplaceableMultimap(
            config.multipolygonGeometryStorage(), multipolygonPath, config.multipolygonGeometryMadvise());
          var osmReader = new OsmReader(name, thisInputFile, nodeLocations, multipolygonGeometries, profile(), stats)
        ) {
          osmReader.pass1(config);
          osmReader.pass2(featureGroup, config);
        } finally {
          FileUtils.delete(nodeDbPath);
          FileUtils.delete(multipolygonPath);
        }
      }))
    );
  }
Adds a new {@code .osm.pbf} source that will be processed when {@link #run()} is called.
<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>
To override the location of the {@code .osm.pbf} file, set {@code name_path=newpath.osm.pbf} in the arguments and
to override the download URL set {@code name_url=http://url/of/osm.pbf}.

@param name        string to use in stats and logs to identify this stage
@param defaultPath path to the input file to use if {@code name_path} argument is not set
@param defaultUrl  remote URL that the file to download if {@code download=true} argument is set and
                   {@code name_url} argument is not set. As a shortcut, can use "geofabrik:monaco" or
                   "geofabrik:australia" shorthand to find an extract by name from
                   <a href="https://download.geofabrik.de/">Geofabrik download site</a> or "aws:latest" to download
                   the latest {@code planet.osm.pbf} file from <a href="https://registry.opendata.aws/osm/">AWS
                   Open Data Registry</a>.
@return this runner instance for chaining
@see OsmInputFile
@see OsmReader
@see Downloader
@see Geofabrik
planetiler-core/src/main/java/com/onthegomap/planetiler/Planetiler.java