Overview
Kentucky STAC is the QGIS successor to two ArcGIS Pro add-ins — kyfromabove-stac-addin
(imagery & elevation) and kylidar-addin (LiDAR) — merged into a single tabbed dock panel.
The plugin adds one dock, Kentucky STAC, with two tabs: Imagery / DEM and LiDAR Pointcloud. Both work the same way: set an area of interest, pick one or more collections, search, then add results to the map, download them, or export them for use outside QGIS.
Installation
The plugin targets QGIS's own bundled Python, GDAL and PDAL — no separate package manager or virtual environment is involved.
Requirements
- QGIS 3.44 LTR, installed via OSGeo4W (minimum tested version 3.34).
- QGIS 4.2 (Qt6) is supported too: search, streaming, downloads, mosaics, Virtual Point Clouds and clipping were all exercised on 4.2.3 in automated runs. The 3.44 LTR remains the build used day to day.
- PDAL, bundled with OSGeo4W, is required for point cloud AOI clipping and is already on
PATHinside a normal OSGeo4W install.
Install the plugin
The source is on GitHub at
ianhorn/kentucky-stac
(git clone https://github.com/ianhorn/kentucky-stac.git); the plugin is the kentucky_stac/ folder.
Copy (or symlink/junction, for development) the kentucky_stac/ folder into your QGIS
profile's plugin directory:
%APPDATA%\QGIS\QGIS3\profiles\default\python\plugins\kentucky_stac
Then enable it from Plugins → Manage and Install Plugins → Installed, and open it from Plugins → Kentucky STAC (or the toolbar icon). While developing, the Plugin Reloader plugin picks up code changes without restarting QGIS.
Area of interest
Every search is scoped to an area of interest (AOI), set with the tools at the top of the dock, shared by both tabs.
Point / Line / Polygon
Click to place vertices; right-click to finish a line or polygon (a point finishes on the first click). Backspace undoes the last vertex, Esc cancels.
Select features
Click, or drag a box over, existing vector features on the map — their combined outline becomes the AOI.
Current extent
Uses whatever area the map canvas is currently showing as a rectangular AOI.
Clear
Clears the AOI and any feature selection.
Each drawing/selection tool is one-shot: once it successfully sets an AOI, it deactivates itself (its toolbar button un-highlights) rather than staying armed, since a new AOI always replaces the old one outright. Clear and Current extent also release a tool that was armed but never used.
Searching
Each tab lists the collections available for its kind of data (imagery/DEM phases, or LiDAR phases) as a checklist.
- Collections start unchecked — pick one or more before searching.
- Select All / Clear Selection toggle every collection at once.
- Search area of interest runs the STAC search, scoped to the checked collections and the current AOI.
Filters
The collapsed Filters section above the search button narrows a search; its header shows how many are active, and Reset filters clears them all. Sort and Max tiles sit on the same row as the Filters header, so they are always visible.
- From / To — only tiles captured in that date range (the end day is included).
- Max cloud cover — imagery tabs only. Tiles that report no cloud cover (radar, elevation, aerial imagery) are kept. Some servers (Earth Search, for one) can only apply this strictly, which also hides tiles without cloud data; the plugin tells you when that happens.
- Sort — by capture date, newest or oldest first. With more matches than the limit, “Newest first” keeps the latest. A server that can’t sort is sorted here instead.
- Max tiles — the most tiles fetched per source (default 20; raise it to see more of a big result).
Large catalogs such as Sentinel-2 are much faster with a date range. If a server can’t return a big page, the plugin retries with smaller pages automatically.
Other STAC APIs (experimental)
Besides the built-in KyFromAbove catalog, the dock can search any public STAC API — picked from STAC Index or typed in by URL.
- Sources... (above the tabs) opens the source list. Choose a catalog from the STAC Index dropdown (which fills in a name and URL), or type an API base URL yourself.
- Add searches the new API alongside the current sources; Replace all sources searches only it. Picking KyFromAbove from the dropdown is the way back to the default.
- Another source's collections are labeled
Title · Source namein the checklist and in the results. While any source other than KyFromAbove is active, the two tabs are renamed Raster and Point Cloud. Raster has the imagery/DEM actions and Point Cloud has the same actions as the LiDAR tab (streaming, download, Virtual Point Clouds with their options, clipping to the AOI, Export as script). Another source’s collections are listed on both tabs, since they can’t be classified reliably: pick a point cloud collection on Point Cloud, anything else on Raster. With KyFromAbove alone the tabs are called Imagery / DEM and LiDAR Pointcloud, and its own collections stay on their matching tab. - Each source loads and searches independently: an unreachable API is reported, but doesn't stop the others.
- The source list is remembered between QGIS sessions.
- Use the API’s base URL, the one that answers
/collections, not its browser documentation page (for examplehttps://landsatlook.usgs.gov/stac-server, not.../stac-server/api.html). - Some catalogs list tiles whose files need a login, such as USGS Landsat Look, whose files redirect to a USGS sign-in page. The plugin can’t sign in, so those tiles can’t be streamed or downloaded; use an open copy of the data instead (Landsat is also on Microsoft Planetary Computer).
Other APIs implement STAC differently, so thumbnails, adding to the map, or downloads may not work for
every one. Files at s3:// addresses (common outside KyFromAbove) are handled for you:
public ones are downloaded and streamed through their https address. Files on Azure Blob Storage, which is
how Microsoft Planetary Computer serves its assets, are signed automatically with a free SAS token from the
Planetary Computer’s token service (cached until shortly before it expires). Private and requester-pays buckets
(e.g. NAIP on Earth Search) need your own AWS credentials, set as the AWS_ACCESS_KEY_ID /
AWS_SECRET_ACCESS_KEY environment variables or in ~/.aws/credentials
(restart QGIS after setting them). With credentials found, files are read through GDAL’s signed S3
access, and for requester-pays buckets the transfer charges go to your AWS account. Add as server mosaic uses KyFromAbove’s titiler-pgstac server for KyFromAbove tiles. For
tiles from another source it uses KyFromAbove’s shared plain titiler unless you set your own, which is
encouraged: set it under Sources... → Tile server.... This is experimental.
Two kinds of server work, and the plugin works out which yours is:
- titiler-pgstac connected to that API’s catalog — one mosaic layer per collection.
- A plain titiler — one layer per tile (up to 50 at a time), each reading the tile’s own file. No catalog connection needed.
The server must be able to read the files: public https is fine; s3:// files need the server to have its own
AWS access. The dialog’s i button explains this.
Results list
Each matching tile is shown as a card: a checkbox, the tile id, collection, capture date, file size (once known), coordinate reference system, and — for LiDAR — its point count, next to a thumbnail preview.
Hover for the raw JSON. Rest the mouse on a tile for half a second and a card opens beside the panel with that tile’s STAC item exactly as the catalog returned it: properties, assets, links. It stays open while the mouse is over the tile or the card, so you can scroll it, select and copy text, and click any URL.
| Field | Notes |
|---|---|
| Size | Blank until you download or check sizes — the catalog doesn't carry file size up front. |
| Projection | A plain EPSG:N for imagery/DEM. LiDAR tiles have a compound
horizontal+vertical CRS with no single EPSG code, so it's shown as EPSG:horizontal/EPSG:vertical
(e.g. EPSG:6473/EPSG:6360 for NAD83(2011) Kentucky Single Zone + NAVD88 height). |
| Points | LiDAR tiles only, from the catalog's own point count — not re-derived. |
Check tiles directly in the list, or use Select All / Clear Selection above the results. The checkbox and the tree's own row selection stay in sync either way.
Imagery / DEM actions
Add selected to map
Streams the selected COG tiles directly as map layers — no download.
Download selected…
Downloads the selected tiles to a folder you choose, after checking their total size.
Export VRT
Stitches the selected tiles into a GDAL virtual raster, one per collection, and adds it to the map.
Export as MosaicJSON…
Writes a MosaicJSON file per collection — a portable index that titiler, rio-tiler or cogeo-mosaic can read directly, with no GDAL or server round trip involved.
Add as server mosaic
Registers a titiler-pgstac search restricted to the selected tiles and streams it — a precise crop of the statewide mosaic, with no download or local stitching.
Export as script…
Saves a Jupyter notebook, Python script or shell script that downloads the selected tiles outside QGIS. See Export as script.
LiDAR actions
Add selected to map
Streams selected COPC tiles directly. Plain LAZ/LAS tiles (Phase 1) can't be streamed this way — download them instead.
Download selected…
Downloads the selected point cloud tiles to a folder you choose.
Add selected as Virtual Point Cloud
Combines the selected COPC tiles into one Virtual Point Cloud (.vpc) layer, streamed directly from their remote URLs — no download, no local file beyond the small index itself.
Export as script…
Saves a Jupyter notebook, Python script or shell script that downloads the selected tiles outside QGIS. See Export as script.
Add downloaded files to the map (unchecked by default) adds files after a download completes; two or more LiDAR tiles are combined into one Virtual Point Cloud layer automatically.
Virtual point cloud options
With Add downloaded files to the map ticked and two or more tiles selected, clicking Download selected… first asks for the options of QGIS’s Build virtual point cloud algorithm. They are remembered between sessions:
- Calculate boundary polygons — store each tile’s exact data outline, not just its rectangle.
- Calculate statistics — store the range of each attribute so styling works straight away.
- Build overview point cloud — also write a thinned overview (every 1000th point) next to the
.vpc.
With all three unchecked (the default) the index is built instantly from the catalog’s metadata. Any option makes QGIS read every point of every tile in the background, which takes longer. The options are not offered for Add selected as Virtual Point Cloud, which streams: the algorithm has to read every point, and it never finished over https.
Export as script
Both tabs have an Export as script… button. Select tiles, click it, pick a format, and choose where to save. The script downloads those tiles’ main files (the COG, or the COPC/LAZ file) outside QGIS.
- Jupyter notebook (.ipynb) — separate cells for settings, the tile list, the helper functions and the download.
- Python script (.py) — standard library only. Set
DESTandWORKERSat the top. - Shell script (.sh) — bash and curl. Usage:
./download_tiles.sh [folder];JOBS=8sets how many download at once.
All three skip files that already exist, turn s3:// addresses into https, and fetch a Planetary Computer
SAS token when they run for Azure files (a token expires within the hour, so it can’t be saved in the script).
Files that aren’t public, such as a private S3 bucket, need their own credentials, which the scripts don’t handle.
Clip to area of interest
Unchecked by default. When enabled with a polygon AOI, output is cropped to the AOI's actual shape instead of the tiles' full rectangular extent.
| Context | Mechanism |
|---|---|
| Imagery/DEM — Export VRT | A GDAL warp cutline; pixels outside the AOI become nodata. |
| LiDAR — Download selected | A PDAL filters.crop pipeline, one crop stage per AOI part (merged if the AOI is multi-part), run per tile before combining into a VPC. |
Known issues
"Preferred Transformation Not Available" dialog
The first time QGIS needs to reproject between Kentucky's state plane CRS and WGS84, it may show a
dialog saying the preferred transform needs a grid file, us_noaa_kyhpgn.tif, that isn't
installed, and offers a 4 m-accuracy fallback instead of the preferred 2 m.
To stop seeing it: download the grid from
cdn.proj.org/us_noaa_kyhpgn.tif (a direct file,
not a page), then either use the dialog's own Install … from Folder button, or
drop it into your OSGeo4W install's PROJ data directory (%OSGEO4W_ROOT%\share\proj\) so
it's available to every tool using that PROJ install, not just QGIS.
Help & feedback
Help (top of the dock) opens this page. Feedback offers two ways to reach the developer: Report an Issue on GitHub opens a pre-filled issue in your browser (needs a free GitHub account; public), or Send Feedback Directly sends a private message with no account needed. Your email is optional, only if you want a reply. Both attach the plugin, QGIS and operating system versions automatically.
Where this came from
Kentucky STAC consolidates two separate ArcGIS Pro add-ins built for the same Kentucky From Above catalog — one for imagery/elevation, one for LiDAR — into a single cross-platform QGIS plugin with one shared area-of-interest workflow instead of two separate tools.
The originals are kyfromabove-stac-addin (imagery & elevation) and kylidar-addin (LiDAR); this plugin lives at ianhorn/kentucky-stac.
Licensed GPL-2.0-or-later.