| Title: | Discover, Inspect and Download Airborne Laser Scanning Data |
|---|---|
| Description: | Discover, visualize and download airborne laser scanning data from an international catalogue through R functions and a 'shiny' application. Spatial searches identify point-cloud tiles intersecting an area of interest and retain acquisition metadata, source citations and licence links. Supports three-dimensional visualization, visual comparison, download planning reports and transfers of original files. Integrates supported provider services and configured spatial indexes, including approved community contributions. Distinguishes integrated access from external portals; availability depends on provider coverage. |
| Authors: | Cesar Ivan Alvites Diaz [aut, cre] |
| Maintainer: | Cesar Ivan Alvites Diaz <[email protected]> |
| License: | GPL-3 |
| Version: | 0.2.0 |
| Built: | 2026-10-02 18:39:40 UTC |
| Source: | https://github.com/Cesarito2021/als_downloader |
Create the Shiny application object
als_app( mode = "local", tile_index_dir = NULL, provider_limit = 2L, submission_dir = NULL, reviewer = NULL )als_app( mode = "local", tile_index_dir = NULL, provider_limit = 2L, submission_dir = NULL, reviewer = NULL )
mode |
|
tile_index_dir |
Optional administrator-supplied OpenTopography or contributed index directory. Not exposed as a server path control in hosted mode. |
provider_limit |
Transfer concurrency ceiling after checking provider terms. Defaults to two; hosted mode always uses one. |
submission_dir |
Optional private directory for Zenodo proposals and approved indexes. No directory is created until a proposal is submitted. |
reviewer |
Optional trusted maintainer name; enables private review UI
only in local mode with email-link authentication configured by
|
A shiny.appobj suitable for shiny::runApp() or a deployment entry point.
if (interactive()) shiny::runApp(als_app())if (interactive()) shiny::runApp(als_app())
Generate an HTML or PDF summary of a search/download selection
als_report( tiles, output_dir, format = c("html", "pdf"), aoi_area_km2 = NA_real_, aoi = NULL, figures = character(), details = FALSE, map_image = character(), map_credits = "", figure_captions = NULL )als_report( tiles, output_dir, format = c("html", "pdf"), aoi_area_km2 = NA_real_, aoi = NULL, figures = character(), details = FALSE, map_image = character(), map_credits = "", figure_captions = NULL )
tiles |
An |
output_dir |
Directory to write the report into. Created if it does not already exist. |
format |
|
aoi_area_km2 |
Optional AOI size in square kilometres, shown for context only. |
aoi |
Optional |
figures |
Optional paths to up to six exported PNG figures, included unchanged with their embedded legends and credits. Maximum 10 MiB each. |
details |
Include a technical appendix with transfer-time scenarios
and a sample file table. Defaults to |
map_image |
Optional single PNG path, used instead of the geometry-only map. The app captures a centred basemap with AOI and selected tiles. |
map_credits |
Basemap attribution accompanying |
figure_captions |
Optional short captions, one per attached figure. |
Content is limited to data already carried by tiles: filename,
dataset, provider, provider-reported acquisition dates, known size and
the recorded citation/licence per tile. Transfer-time scenarios use
known bytes and illustrative aggregate speeds, not CPU core counts.
Unknown file sizes are explicitly excluded. Nothing is fetched.
The report is written only to output_dir and is never
transmitted anywhere.
Invisibly, the path to the rendered report file.
# Render a local planning report from synthetic metadata; no downloads. # Rendering can take more than 5 seconds and requires Pandoc. if (requireNamespace("rmarkdown", quietly = TRUE) && rmarkdown::pandoc_available()) { index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) output_dir <- tempfile("als-report-") report <- als_report(tiles, output_dir, format = "html") basename(report) file.exists(report) unlink(output_dir, recursive = TRUE) }# Render a local planning report from synthetic metadata; no downloads. # Rendering can take more than 5 seconds and requires Pandoc. if (requireNamespace("rmarkdown", quietly = TRUE) && rmarkdown::pandoc_available()) { index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) output_dir <- tempfile("als-report-") report <- als_report(tiles, output_dir, format = "html") basename(report) file.exists(report) unlink(output_dir, recursive = TRUE) }
Calculate AOI size
aoi_area(aoi)aoi_area(aoi)
aoi |
Polygon input accepted by |
Geodesic union area in square kilometres, without double-counting overlapping polygons.
ring <- matrix(c(0,0, 1,0, 1,1, 0,1, 0,0), ncol = 2, byrow = TRUE) aoi_area(sf::st_sfc(sf::st_polygon(list(ring)), crs = 4326))ring <- matrix(c(0,0, 1,0, 1,1, 0,1, 0,0), ncol = 2, byrow = TRUE) aoi_area(sf::st_sfc(sf::st_polygon(list(ring)), crs = 4326))
Configure email-link access to local proposal review
configure_reviewer_access(path, emails)configure_reviewer_access(path, emails)
path |
Private allowlist-file path outside public assets and Git. |
emails |
Administrator mailboxes allowed to receive review invitations. |
Access requires a single-use private review link delivered to an allowed mailbox by the administrator-configured mail service. Preview mail cannot authenticate. Reconfiguration revokes sessions and outstanding invitations. Restrict the file's parent directory to the host owner (use Windows ACLs where applicable). The reviewer remains localhost-only; remote HTTPS hosting is separate.
Invisibly, the allowlist-file path. No password is requested or stored.
Set option ALSdownloadeR.reviewer_credentials or environment variable
ALS_REVIEWER_CREDENTIALS to this path at launch.
# Create a temporary allowlist only; this does not send invitations or email. if (requireNamespace("openssl", quietly = TRUE)) { path <- tempfile(fileext = ".rds") configure_reviewer_access(path, "[email protected]") file.exists(path) unlink(path) }# Create a temporary allowlist only; this does not send invitations or email. if (requireNamespace("openssl", quietly = TRUE)) { path <- tempfile(fileext = ".rds") configure_reviewer_access(path, "[email protected]") file.exists(path) unlink(path) }
List persistent country source links
country_links(path = country_links_path(), history = FALSE)country_links(path = country_links_path(), history = FALSE)
path |
Registry file. Defaults to the package's user configuration directory;
override with option |
history |
Return previous revisions instead of current links. |
Reading does not create a file or contact a website. Country names follow the bundled world map. These links do not imply national ALS coverage or enable an in-app download adapter. Restart the app after updating links.
A data frame of country, country_code, source_id, name, url, updated_on and notes. The initial records are the packaged external portals.
country_links()country_links()
Create an ALS download planning report
create_als_report(...)create_als_report(...)
... |
Arguments passed to als_report(). |
The generated report path, invisibly.
# Render a local planning report from synthetic metadata; no downloads. # Rendering can take more than 5 seconds and requires Pandoc. if (requireNamespace("rmarkdown", quietly = TRUE) && rmarkdown::pandoc_available()) { index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) output_dir <- tempfile("als-report-") report <- create_als_report(tiles, output_dir, format = "html") basename(report) file.exists(report) unlink(output_dir, recursive = TRUE) }# Render a local planning report from synthetic metadata; no downloads. # Rendering can take more than 5 seconds and requires Pandoc. if (requireNamespace("rmarkdown", quietly = TRUE) && rmarkdown::pandoc_available()) { index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) output_dir <- tempfile("als-report-") report <- create_als_report(tiles, output_dir, format = "html") basename(report) file.exists(report) unlink(output_dir, recursive = TRUE) }
Download selected airborne laser scanning files
download_als_data(...)download_als_data(...)
... |
Arguments passed to download_tiles(). |
A transfer status table, as returned by download_tiles().
# Requires an interactive session, Internet and your own polygon file. # Provider availability and original tile sizes vary; allow more than 5 seconds. if (interactive()) { aoi <- read_aoi(file.choose()) tiles <- find_tiles(aoi, provider = "usgs3dep") if (nrow(tiles) > 0L) { output_dir <- tempfile("als-download-") result <- download_als_data(tiles[1, ], output_dir = output_dir, workers = 1) result[, c("status", "path")] # The downloaded file and its manifest remain in output_dir for inspection. } }# Requires an interactive session, Internet and your own polygon file. # Provider availability and original tile sizes vary; allow more than 5 seconds. if (interactive()) { aoi <- read_aoi(file.choose()) tiles <- find_tiles(aoi, provider = "usgs3dep") if (nrow(tiles) > 0L) { output_dir <- tempfile("als-download-") result <- download_als_data(tiles[1, ], output_dir = output_dir, workers = 1) result[, c("status", "path")] # The downloaded file and its manifest remain in output_dir for inspection. } }
Download selected tiles with resumable transfer records
download_tiles( tiles, output_dir, workers = 1L, mode = c("local", "hosted"), provider_limit = 2L, retries = 2L, timeout = 600, progress_dir = NULL )download_tiles( tiles, output_dir, workers = 1L, mode = c("local", "hosted"), provider_limit = 2L, retries = 2L, timeout = 600, progress_dir = NULL )
tiles |
An |
output_dir |
Explicit writable destination directory. A directory is created only when this function is called. |
workers |
Requested transfer workers. Defaults to one for scripted use. |
mode |
|
provider_limit |
Provider concurrency ceiling; defaults to two until an operator has verified the provider's applicable terms. |
retries |
Number of retries for transient failures. Authentication and rate-limit responses are not retried automatically. |
timeout |
Per-transfer timeout in seconds. |
progress_dir |
Optional directory for per-tile progress records. |
Uses future.apply::future_lapply() and restores the caller's future
plan. Resume requires both a completed sidecar record and a matching file
checksum. HTTP status, reported length and LAS signature are checked;
complete point-stream decompression is not verified. Existing untracked
destination files are never overwritten. Credentials are not written to
the exported manifest. Large datasets should be downloaded locally.
A data frame with one row per asset, transfer status, canonical source URL, byte count, checksum and local path. Failed tiles remain in the result.
# Requires an interactive session, Internet and your own polygon file. # Provider availability and original tile sizes vary; allow more than 5 seconds. if (interactive()) { aoi <- read_aoi(file.choose()) tiles <- find_tiles(aoi, provider = "usgs3dep") if (nrow(tiles) > 0L) { output_dir <- tempfile("als-download-") result <- download_tiles(tiles[1, ], output_dir = output_dir, workers = 1) result[, c("status", "path")] # The downloaded file and its manifest remain in output_dir for inspection. } }# Requires an interactive session, Internet and your own polygon file. # Provider availability and original tile sizes vary; allow more than 5 seconds. if (interactive()) { aoi <- read_aoi(file.choose()) tiles <- find_tiles(aoi, provider = "usgs3dep") if (nrow(tiles) > 0L) { output_dir <- tempfile("als-download-") result <- download_tiles(tiles[1, ], output_dir = output_dir, workers = 1) result[, c("status", "path")] # The downloaded file and its manifest remain in output_dir for inspection. } }
Plan download concurrency
download_worker_policy( mode, available_cores = NA_integer_, requested = NULL, provider_limit = Inf, jobs = Inf )download_worker_policy( mode, available_cores = NA_integer_, requested = NULL, provider_limit = Inf, jobs = Inf )
mode |
Deployment mode: |
available_cores |
Available logical CPU cores. Missing values use one. |
requested |
User-selected worker count, or |
provider_limit |
Maximum simultaneous transfers allowed by the provider. |
jobs |
Number of pending tile transfers. |
Hosted mode uses one worker. Local mode leaves four available cores unused when possible and initially recommends at most ten workers. During automated package checks callers must explicitly request no more than two.
A list containing recommended, maximum, requested and effective counts.
download_worker_policy("local", available_cores = 8) download_worker_policy("hosted", available_cores = 16, requested = 4)download_worker_policy("local", available_cores = 8) download_worker_policy("hosted", available_cores = 16, requested = 4)
Extract acquisition years and retain their evidence
extract_als_dates(tiles, lookup = TRUE, lookup_budget = 60)extract_als_dates(tiles, lookup = TRUE, lookup_budget = 60)
tiles |
An ALS asset table. |
lookup |
Whether to consult linked provider metadata. |
lookup_budget |
Maximum elapsed seconds before starting more metadata lookups. |
The table with acquisition_year, source, precision, scope and status. Missing values remain NA. Filename years are labelled unverified references.
# Synthetic catalogue values, read locally without contacting their URLs. index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) dated <- extract_als_dates(tiles, lookup = FALSE) dated[, c("acquisition_year", "date_source", "date_status")]# Synthetic catalogue values, read locally without contacting their URLs. index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) dated <- extract_als_dates(tiles, lookup = FALSE) dated[, c("acquisition_year", "date_source", "date_status")]
Find airborne laser scanning data
find_als_data( aoi, provider = c("usgs3dep", "planetary", "opentopography", "contributed", "ahn6", "swisstopo", "ignfr", "canelevation"), start = NULL, end = NULL, tile_index_dir = NULL, max_items = 10000L )find_als_data( aoi, provider = c("usgs3dep", "planetary", "opentopography", "contributed", "ahn6", "swisstopo", "ignfr", "canelevation"), start = NULL, end = NULL, tile_index_dir = NULL, max_items = 10000L )
aoi |
Polygon input accepted by |
provider |
Either |
start, end
|
Optional inclusive acquisition dates in |
tile_index_dir |
Directory of OpenTopography |
max_items |
Maximum number of tiles to return. An incomplete result raises an error instead of silently reporting partial coverage. |
An sf asset table including acquisition evidence and file sizes when retrievable. The download summary is available with summarize_als_download().
# Read a small synthetic catalogue supplied with the package; no Internet. index_dir <- system.file("extdata", "example-index", package = "ALSdownloadeR") index <- read_tile_index(file.path(index_dir, "demo.tiles.geojson")) aoi <- read_aoi(sf::st_geometry(index)) # Search the local demonstration index and inspect the matching record. tiles <- find_als_data(aoi, provider = "contributed", tile_index_dir = index_dir) tiles[, c("tile_id", "acquired_start", "acquired_end", "size_bytes")] # The example.org URLs are placeholders: do not download these demo records.# Read a small synthetic catalogue supplied with the package; no Internet. index_dir <- system.file("extdata", "example-index", package = "ALSdownloadeR") index <- read_tile_index(file.path(index_dir, "demo.tiles.geojson")) aoi <- read_aoi(sf::st_geometry(index)) # Search the local demonstration index and inspect the matching record. tiles <- find_als_data(aoi, provider = "contributed", tile_index_dir = index_dir) tiles[, c("tile_id", "acquired_start", "acquired_end", "size_bytes")] # The example.org URLs are placeholders: do not download these demo records.
Find point-cloud tiles intersecting an AOI
find_tiles( aoi, provider = c("usgs3dep", "planetary", "opentopography", "contributed", "ahn6", "swisstopo", "ignfr", "canelevation"), start = NULL, end = NULL, tile_index_dir = NULL, max_items = 10000L )find_tiles( aoi, provider = c("usgs3dep", "planetary", "opentopography", "contributed", "ahn6", "swisstopo", "ignfr", "canelevation"), start = NULL, end = NULL, tile_index_dir = NULL, max_items = 10000L )
aoi |
Polygon input accepted by |
provider |
Either |
start, end
|
Optional inclusive acquisition dates in |
tile_index_dir |
Directory of OpenTopography |
max_items |
Maximum number of tiles to return. An incomplete result raises an error instead of silently reporting partial coverage. |
Network access occurs only when this function is explicitly called for a remote source. OpenTopography searches the packaged, audited airborne-LiDAR registry by default and fetches matching provider indexes with SHA-256 verification. An explicit local index directory overrides that route in the R API. Public tile downloads do not require an API key. Asset licenses vary per dataset.
An sf table of assets with stable identifiers, canonical URLs,
acquisition dates, citation information and tile geometry in EPSG:4326.
campaign_id contains the reported 3DEP project or IGN mission identifier.
campaign_group and campaign_basis also describe fallback groups from
recognized project directories, delivery blocks or datasets. Fallback
groups do not establish distinct flight dates.
# Read a small synthetic catalogue supplied with the package; no Internet. index_dir <- system.file("extdata", "example-index", package = "ALSdownloadeR") index <- read_tile_index(file.path(index_dir, "demo.tiles.geojson")) aoi <- read_aoi(sf::st_geometry(index)) # Search the local demonstration index and inspect the matching record. tiles <- find_tiles(aoi, provider = "contributed", tile_index_dir = index_dir) tiles[, c("tile_id", "acquired_start", "acquired_end", "size_bytes")] # The example.org URLs are placeholders: do not download these demo records.# Read a small synthetic catalogue supplied with the package; no Internet. index_dir <- system.file("extdata", "example-index", package = "ALSdownloadeR") index <- read_tile_index(file.path(index_dir, "demo.tiles.geojson")) aoi <- read_aoi(sf::st_geometry(index)) # Search the local demonstration index and inspect the matching record. tiles <- find_tiles(aoi, provider = "contributed", tile_index_dir = index_dir) tiles[, c("tile_id", "acquired_start", "acquired_end", "size_bytes")] # The example.org URLs are placeholders: do not download these demo records.
Retrieve sizes of ALS files without downloading point clouds
get_als_file_sizes(tiles, timeout = 15, budget = 60, connections = 4L)get_als_file_sizes(tiles, timeout = 15, budget = 60, connections = 4L)
tiles |
An ALS asset table. |
timeout |
Maximum seconds per HTTP request. |
budget |
Maximum seconds for each batch of requests. |
connections |
Maximum simultaneous connections (1 to 8). |
The asset table with size_bytes and size provenance/status. NA sizes are not zero. Requests use HEAD and, when necessary, a bounded byte range.
# Synthetic catalogue values, read locally without contacting their URLs. index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) # Sizes are already recorded, so no HTTP lookup is needed. sized <- get_als_file_sizes(tiles) sized[, c("size_bytes", "size_source", "size_status")]# Synthetic catalogue values, read locally without contacting their URLs. index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) # Sizes are already recorded, so no HTTP lookup is needed. sized <- get_als_file_sizes(tiles) sized[, c("size_bytes", "size_source", "size_status")]
Rebuild an inbox contribution in the private review queue
import_zenodo_inbox(fields, queue)import_zenodo_inbox(fields, queue)
fields |
Named list of fields received through the configured submission inbox. Untrusted metadata are re-fetched from Zenodo; links are not followed unless they exactly match a file in that record. |
queue |
Administrator-controlled persistent private queue directory. |
This maintainer operation supports the link-only Formspree fields generated by ALSdownloadeR. It retrieves Zenodo metadata and, for polygon coverage, one bounded boundary file. It never downloads point clouds. Access to the inbox is configured separately; no inbox API key is bundled.
Pending proposal ID. Repeated imports are deduplicated. No approval or publication is performed.
# Maintainer-only: requires an actual inbox export, Internet and a private queue. # The JSON file must contain the named fields received by the submission inbox. ## Not run: fields <- jsonlite::read_json(file.choose(), simplifyVector = TRUE) queue <- readline("Private review queue directory: ") id <- import_zenodo_inbox(fields, queue) zenodo_submissions(queue) ## End(Not run)# Maintainer-only: requires an actual inbox export, Internet and a private queue. # The JSON file must contain the named fields received by the submission inbox. ## Not run: fields <- jsonlite::read_json(file.choose(), simplifyVector = TRUE) queue <- readline("Private review queue directory: ") id <- import_zenodo_inbox(fields, queue) zenodo_submissions(queue) ## End(Not run)
Inspect a public Zenodo record without downloading point clouds
inspect_zenodo(link)inspect_zenodo(link)
link |
Published Zenodo record URL, DOI or numeric record ID. |
Only retrieves a bounded JSON metadata response from zenodo.org. Publication dates are never treated as acquisition dates. No catalogue changes.
Metadata including authors, licence, description, file sizes and links.
# Requires Internet and a published, openly accessible Zenodo record. if (interactive()) { link <- readline("Published Zenodo record URL or DOI: ") metadata <- inspect_zenodo(link) metadata[c("title", "doi", "license_url")] }# Requires Internet and a published, openly accessible Zenodo record. if (interactive()) { link <- readline("Published Zenodo record URL or DOI: ") metadata <- inspect_zenodo(link) metadata[c("title", "doi", "license_url")] }
Launch the ALSdownloadeR Shiny application
launch_app( mode = c("local", "hosted"), tile_index_dir = NULL, provider_limit = 2L, host = "127.0.0.1", port = NULL, launch.browser = interactive(), submission_dir = NULL, reviewer = NULL )launch_app( mode = c("local", "hosted"), tile_index_dir = NULL, provider_limit = 2L, host = "127.0.0.1", port = NULL, launch.browser = interactive(), submission_dir = NULL, reviewer = NULL )
mode |
|
tile_index_dir |
Optional administrator-supplied OpenTopography or contributed index directory. Not exposed as a server path control in hosted mode. |
provider_limit |
Transfer concurrency ceiling after checking provider terms. Defaults to two; hosted mode always uses one. |
host, port
|
Bind address and optional port passed to |
launch.browser |
Whether to open a browser. Defaults to interactive use. |
submission_dir |
Optional private directory for Zenodo proposals and approved indexes. No directory is created until a proposal is submitted. |
reviewer |
Optional trusted maintainer name; enables private review UI
only in local mode with email-link authentication configured by
|
Launch is explicit: loading the package does not start a browser,
contact providers, change the working directory or install packages.
Background transfer processes are terminated when the owning session ends.
Optional browser submissions use option ALSdownloadeR.formspree, a list
with endpoint (a public https://formspree.io/f/ form URL) and attachments
(FALSE by default; TRUE requires a file-upload plan). Alternatively set
environment variable ALS_FORMSPREE_ENDPOINT for links-only submissions.
The community form is the default when no local submission directory is set.
Set option ALSdownloadeR.formspree = FALSE to disable remote submission.
An explicitly configured transport takes precedence over the local queue button. It requires
explicit submission and Internet access, but no contributor account.
Service quotas apply; receiving a proposal never approves its publication.
Invisibly, the return value of shiny::runApp(). Runs until stopped.
if (interactive()) launch_app()if (interactive()) launch_app()
Prepare a Zenodo contribution for maintainer review
prepare_zenodo_submission( link, boundary, acquired = "", platform = "ALS", email = "" )prepare_zenodo_submission( link, boundary, acquired = "", platform = "ALS", email = "" )
link |
Public Zenodo DOI or record link. |
boundary |
GeoJSON, GeoPackage, zipped Shapefile or sf polygons. For multiple assets include file_key with exact Zenodo filenames. |
acquired |
Collection year, year range or YYYY-MM-DD / YYYY-MM-DD; blank means unknown and never substitutes the publication date. |
platform |
ALS or UAV-LiDAR, confirmed by the contributor. |
email |
Optional private contact email, excluded from approved indexes. |
A pending proposal; no files are published and no point clouds read.
# Requires Internet and coverage polygons matching the files in your record. # This prepares a proposal but does not submit it or approve its publication. if (interactive()) { link <- readline("Published Zenodo record URL or DOI: ") boundary <- read_aoi(file.choose()) proposal <- prepare_zenodo_submission(link, boundary, acquired = "", platform = "ALS") proposal$id }# Requires Internet and coverage polygons matching the files in your record. # This prepares a proposal but does not submit it or approve its publication. if (interactive()) { link <- readline("Published Zenodo record URL or DOI: ") boundary <- read_aoi(file.choose()) proposal <- prepare_zenodo_submission(link, boundary, acquired = "", platform = "ALS") proposal$id }
Make a bounded point-cloud preview
preview_points(points, max_points = 100000L)preview_points(points, max_points = 100000L)
points |
A data frame or matrix with numeric |
max_points |
Maximum displayed points, between one and one million. |
Sampling is deterministic and affects only the returned preview. The source cloud is not modified. Elevation is not normalized canopy height.
A data frame of sampled coordinates with an origin attribute.
Coordinates are translated to a local origin for display precision.
An optional numeric Classification column is retained as an aligned
classification attribute; missing or invalid codes become NA.
Optional numeric Intensity is retained as an aligned intensity
attribute. No classification or intensity is inferred.
preview_points(data.frame(X = 1:10, Y = 1:10, Z = 11:20), 5)preview_points(data.frame(X = 1:10, Y = 1:10, Z = 11:20), 5)
Download one remote tile temporarily and read a bounded preview
preview_remote_tile( tile, max_bytes = 1024 * 1024^2, path = tempfile(fileext = ".laz"), reader = function(path) read_preview(path, 100000L), progress = NULL, zip_member = NULL, max_uncompressed_bytes = 2 * 1024^3 )preview_remote_tile( tile, max_bytes = 1024 * 1024^2, path = tempfile(fileext = ".laz"), reader = function(path) read_preview(path, 100000L), progress = NULL, zip_member = NULL, max_uncompressed_bytes = 2 * 1024^3 )
tile |
A single-row tile data frame, as returned by |
max_bytes |
Maximum known HTTP file size accepted for the temporary download, in bytes. |
path |
Temporary local path for the downloaded file. Removed after
|
reader |
Function called with |
progress |
Optional function receiving short preview-stage messages. |
zip_member |
Optional exact LAS/LAZ member name when a ZIP contains multiple point clouds. A single point cloud is selected automatically. |
max_uncompressed_bytes |
Maximum total uncompressed ZIP size, in bytes. |
A temporary, single-file preview; never persists a cloud in the
source catalog. Exported (rather than internal-only) so a background
callr::r_bg() worker can call it by namespace-qualified name – a
plain closure passed as a callr argument can lose access to sibling
package-internal helpers it calls, such as require_data_terms().
Whatever reader returns.
# Requires an interactive session, Internet and your own polygon file. # Provider availability and original tile sizes vary; allow more than 5 seconds. if (interactive() && requireNamespace("lidR", quietly = TRUE)) { aoi <- read_aoi(file.choose()) tiles <- find_tiles(aoi, provider = "usgs3dep") if (nrow(tiles) > 0L) { # Downloads one original tile temporarily (up to 10 MiB here). points <- preview_remote_tile(tiles[1, ], max_bytes = 10 * 1024^2) head(points) } }# Requires an interactive session, Internet and your own polygon file. # Provider availability and original tile sizes vary; allow more than 5 seconds. if (interactive() && requireNamespace("lidR", quietly = TRUE)) { aoi <- read_aoi(file.choose()) tiles <- find_tiles(aoi, provider = "usgs3dep") if (nrow(tiles) > 0L) { # Downloads one original tile temporarily (up to 10 MiB here). points <- preview_remote_tile(tiles[1, ], max_bytes = 10 * 1024^2) head(points) } }
Inspect provider access and implementation status
provider_catalog()provider_catalog()
A data frame with provider identifiers, access notes, source links, and whether a tile-search adapter is implemented. Implemented does not mean that every dataset or endpoint is currently available.
provider_catalog()provider_catalog()
Read and validate a polygon AOI
read_aoi(x, layer = NULL)read_aoi(x, layer = NULL)
x |
An |
layer |
Layer name for a multi-layer GeoPackage. Required when there is more than one layer. |
Zipped Shapefiles must contain one Shapefile with a declared CRS. Archives with unsafe paths or more than 200 MB uncompressed are rejected. No coordinate reference system is guessed.
An sf polygon object in EPSG:4326. Empty geometries are removed.
ring <- matrix(c(0,0, 1,0, 1,1, 0,1, 0,0), ncol = 2, byrow = TRUE) aoi <- read_aoi(sf::st_sfc(sf::st_polygon(list(ring)), crs = 4326))ring <- matrix(c(0,0, 1,0, 1,1, 0,1, 0,0), ncol = 2, byrow = TRUE) aoi <- read_aoi(sf::st_sfc(sf::st_polygon(list(ring)), crs = 4326))
Read a decimated, spatially windowed preview for the forest close-up viewer
read_forest_preview( path, percent = 2, window = 100, center_x = 50, center_y = 50, voxel = 0, xy_units = "auto", z_units = "auto" )read_forest_preview( path, percent = 2, window = 100, center_x = 50, center_y = 50, voxel = 0, xy_units = "auto", z_units = "auto" )
path |
Local LAS/LAZ file path. |
percent |
Approximate percentage of source points the reader keeps, between 0.1 and 100. The reader pool is also capped at 750,000 points. |
window, center_x, center_y, voxel
|
Display windowing and optional
voxel thinning; see |
xy_units, z_units
|
Source horizontal and elevation units: |
Requires the optional package 'lidR'. Exported so a background
callr::r_bg() worker can call it by namespace-qualified name; see
preview_remote_tile() for why.
The same translated coordinate table as preview_points(), with
a display_note attribute describing the sampling actually used.
# Use a small LAS/LAZ example distributed with the optional lidR package. if (requireNamespace("lidR", quietly = TRUE)) { path <- system.file("extdata", "MixedConifer.laz", package = "lidR") points <- read_forest_preview(path, percent = 1) head(points) attr(points, "origin") attr(points, "units") }# Use a small LAS/LAZ example distributed with the optional lidR package. if (requireNamespace("lidR", quietly = TRUE)) { path <- system.file("extdata", "MixedConifer.laz", package = "lidR") points <- read_forest_preview(path, percent = 1) head(points) attr(points, "origin") attr(points, "units") }
Read a small preview from a local LAS or LAZ file
read_preview(path, max_points = 100000L, xy_units = "auto", z_units = "auto")read_preview(path, max_points = 100000L, xy_units = "auto", z_units = "auto")
path |
Local point-cloud filename. |
max_points |
Maximum preview size, between one and one million. |
xy_units, z_units
|
Source horizontal and elevation units: |
Requires the optional package 'lidR'. Reader-side decimation limits retained points before they enter R. The file may still need to be scanned in full; this function is not a remote COPC range reader.
The same translated coordinate table as preview_points().
# Use a small LAS/LAZ example distributed with the optional lidR package. if (requireNamespace("lidR", quietly = TRUE)) { path <- system.file("extdata", "MixedConifer.laz", package = "lidR") points <- read_preview(path, max_points = 1000) head(points) attr(points, "origin") attr(points, "units") }# Use a small LAS/LAZ example distributed with the optional lidR package. if (requireNamespace("lidR", quietly = TRUE)) { path <- system.file("extdata", "MixedConifer.laz", package = "lidR") points <- read_preview(path, max_points = 1000) head(points) attr(points, "origin") attr(points, "units") }
Read a contributed aerial LiDAR tile index
read_tile_index(path)read_tile_index(path)
path |
Local GeoJSON index, at most 5 MiB and 10,000 polygons. |
Reads metadata only. Does not contact asset URLs or approve a source. Required properties are tile_id, dataset, url, acquired_start, acquired_end, platform, license_url and citation. Dates may be null when unknown. Platform must be ALS or UAV-LiDAR. Coordinates must be EPSG:4326. Assets must be direct HTTPS LAS/LAZ files or Zenodo record ZIP files. ZIP files are downloaded intact and require local extraction for preview.
An sf tile table accepted by download_tiles().
read_tile_index(system.file("extdata", "contribution-template.geojson", package = "ALSdownloadeR"))read_tile_index(system.file("extdata", "contribution-template.geojson", package = "ALSdownloadeR"))
Accept or reject a queued Zenodo contribution
review_zenodo_submission( queue, id, decision = c("approve", "reject"), reviewer, confirmed = FALSE, reason = "" )review_zenodo_submission( queue, id, decision = c("approve", "reject"), reviewer, confirmed = FALSE, reason = "" )
queue |
Administrator-controlled private queue directory. |
id |
Proposal ID. |
decision |
approve or reject. |
reviewer |
Maintainer name for the audit record. |
confirmed |
Explicit confirmation of coverage/file mapping, dates, aerial LiDAR content, attribution and licence suitability. Required to approve. |
reason |
Optional private review note. |
Approval re-fetches Zenodo metadata and rejects changed records. Only approved indexes under queue/approved participate in catalogue search. Never downloads point clouds. Expose this operation only to trusted maintainers.
Path to an approved index, or invisibly NULL on rejection.
# Maintainer-only example: records a real rejection in an existing private queue. # Requires a pending proposal and an explicit review decision; not run automatically. ## Not run: queue <- readline("Private review queue directory: ") zenodo_submissions(queue) id <- readline("ID of the proposal you have reviewed: ") reviewer <- readline("Your maintainer name: ") review_zenodo_submission(queue, id, decision = "reject", reviewer = reviewer, reason = "Coverage or metadata needs correction.") ## End(Not run)# Maintainer-only example: records a real rejection in an existing private queue. # Requires a pending proposal and an explicit review decision; not run automatically. ## Not run: queue <- readline("Private review queue directory: ") zenodo_submissions(queue) id <- readline("ID of the proposal you have reviewed: ") reviewer <- readline("Your maintainer name: ") review_zenodo_submission(queue, id, decision = "reject", reviewer = reviewer, reason = "Coverage or metadata needs correction.") ## End(Not run)
Submit a proposal to a private local review queue
submit_zenodo(proposal, queue)submit_zenodo(proposal, queue)
proposal |
Result of prepare_zenodo_submission(). |
queue |
Administrator-controlled private queue directory. |
Does not activate coverage or download data. Optional administrator
configuration in option ALSdownloadeR.submission_mail enables notifications;
see the notification setup guide in the repository documentation.
Proposal ID. Identical metadata/coverage proposals are deduplicated.
# Requires a real record, matching coverage and an administrator-owned queue. # Run only when intending to submit; configured notifications may send email. ## Not run: link <- readline("Published Zenodo record URL or DOI: ") boundary <- read_aoi(file.choose()) proposal <- prepare_zenodo_submission(link, boundary, acquired = "", platform = "ALS") queue <- readline("Private review queue directory: ") id <- submit_zenodo(proposal, queue) zenodo_submissions(queue) ## End(Not run)# Requires a real record, matching coverage and an administrator-owned queue. # Run only when intending to submit; configured notifications may send email. ## Not run: link <- readline("Published Zenodo record URL or DOI: ") boundary <- read_aoi(file.choose()) proposal <- prepare_zenodo_submission(link, boundary, acquired = "", platform = "ALS") queue <- readline("Private review queue directory: ") id <- submit_zenodo(proposal, queue) zenodo_submissions(queue) ## End(Not run)
Summarize an ALS data selection
summarize_als_data(tiles)summarize_als_data(tiles)
tiles |
An ALS asset table. |
Counts and total download size; incomplete totals remain NA.
# Synthetic catalogue values, read locally without contacting their URLs. index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) summarize_als_data(tiles) # Unknown sizes remain unknown rather than being counted as zero. tiles$size_bytes <- NA_real_ summarize_als_data(tiles)# Synthetic catalogue values, read locally without contacting their URLs. index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) summarize_als_data(tiles) # Unknown sizes remain unknown rather than being counted as zero. tiles$size_bytes <- NA_real_ summarize_als_data(tiles)
Summarize the total download size of a selection
summarize_als_download(tiles)summarize_als_download(tiles)
tiles |
An ALS asset table, optionally enriched with get_als_file_sizes(). |
A one-row data frame with file count, known bytes, missing sizes and complete total bytes (NA when any size is missing). GB uses 10^9 bytes.
# Synthetic catalogue values, read locally without contacting their URLs. index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) summarize_als_download(tiles) # Unknown sizes remain unknown rather than being counted as zero. tiles$size_bytes <- NA_real_ summarize_als_download(tiles)# Synthetic catalogue values, read locally without contacting their URLs. index <- system.file("extdata", "example-index", "demo.tiles.geojson", package = "ALSdownloadeR") tiles <- read_tile_index(index) summarize_als_download(tiles) # Unknown sizes remain unknown rather than being counted as zero. tiles$size_bytes <- NA_real_ summarize_als_download(tiles)
Add or update an external ALS source link for a country
update_country_link( country, url, updated_on, source_id = "country_portal", name = "ALS source portal", notes = "External access; consult source coverage and terms.", path = country_links_path() )update_country_link( country, url, updated_on, source_id = "country_portal", name = "ALS source portal", notes = "External access; consult source coverage and terms.", path = country_links_path() )
country |
Country name (case-insensitive) or numeric country code from
the bundled world map, for example |
url |
An HTTPS source portal URL. It is recorded, not fetched or verified. |
updated_on |
Date supplied by the maintainer, in |
source_id |
Stable source identifier within a country. Use an existing identifier from country_links() to replace that source's URL. |
name |
Display name for the portal. |
notes |
Coverage and access notes. A regional portal is not national coverage. |
path |
Registry file. Defaults to the package's user configuration directory;
override with option |
Updates only the matching country/source pair; other entries remain.
Prior revisions are retained in the registry and the previous file is saved
with a .bak suffix. A lock rejects simultaneous writers. Registered links
appear in the yellow External Access map layer and source catalogue after
restarting the app, including countries with separate red survey footprints.
No package installation files are modified. Share the registry path with
the app process to use the same links in a hosted installation.
The updated current country-link table, invisibly.
registry <- tempfile(fileext=".rds") update_country_link("Italy", "https://example.org/lidar", "2026-09-22", name="Example portal (not a verified source)", path=registry) country_links(path=registry) unlink(c(registry, paste0(registry, ".bak")))registry <- tempfile(fileext=".rds") update_country_link("Italy", "https://example.org/lidar", "2026-09-22", name="Example portal (not a verified source)", path=registry) country_links(path=registry) unlink(c(registry, paste0(registry, ".bak")))
List pending and reviewed Zenodo contributions
zenodo_submissions(queue)zenodo_submissions(queue)
queue |
Administrator-controlled private queue directory. |
A table of request IDs, DOI, title and status. Private contacts are omitted.
# A new private queue has no submissions; no network or files are created. queue <- tempfile("als-review-") zenodo_submissions(queue)# A new private queue has no submissions; no network or files are created. queue <- tempfile("als-review-") zenodo_submissions(queue)