Observed since 20 Oct, 17:33 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
KyFromAbove LiDAR, DEM, and orthoimagery data access for Python
KyFromAbove LiDAR, DEM, orthoimagery, and oblique imagery data access for Python.
Kentucky's KyFromAbove program provides statewide 2ft DEMs, 3-inch orthoimagery, 3-inch oblique imagery, and COPC LiDAR point clouds — all publicly available on S3 with a STAC API for discovery. abovepy gives you Pythonic access to all of it, plus server-side terrain analysis via TiTiler. No credentials required.
pip install abovepy
Optional extras:
pip install abovepy[lidar] # COPC/LAZ point cloud support
pip install abovepy[viz] # leafmap + matplotlib visualization
pip install abovepy[all] # Everything
import abovepy
# Find DEM tiles covering Franklin County
tiles = abovepy.search(county="Franklin", product="dem_phase3")
print(tiles)
tiles = abovepy.search(
bbox=(-84.9, 38.15, -84.8, 38.25),
product="dem_phase3"
)
paths = abovepy.download(tiles, output_dir="./data")
vrt = abovepy.mosaic(paths, output="frankfort.vrt")
# 500-foot radius around a point (uses EPSG:3089 for accurate measurement)
tiles = abovepy.search(
point=(-84.87, 38.20),
buffer_feet=500,
product="dem_phase3"
)
from shapely.geometry import LineString
# Search along a road centerline with 200ft buffer on each side
road = LineString([(-84.90, 38.20), (-84.85, 38.19), (-84.82, 38.21)])
tiles = abovepy.search(geometry=road, buffer_feet=200, product="ortho_phase3")
data, profile = abovepy.read(
tiles.iloc[0].asset_url,
bbox=(-84.85, 38.18, -84.82, 38.21)
)
result = abovepy.search(county="Pike", product="dem_phase3")
# Check for data quality issues
warnings = result.validate()
for w in warnings:
print(f"Warning: {w}")
# Warning: 3 tile(s) (12%) have no acquisition date metadata.
# Generate source documentation for deliverables
prov = result.provenance()
print(prov["source_program"]) # KyFromAbove
print(prov["acquisition_period"]) # 2022-2025
print(prov["native_crs"]) # EPSG:3089
print(prov["tile_count"]) # 42
print(prov["estimated_size_mb"]) # 210.0
print(abovepy.info())
# product display_name format resolution phase crs
# dem_phase1 DEM Phase 1 (5ft) COG 5ft 1 EPSG:3089
# dem_phase2 DEM Phase 2 (2ft) COG 2ft 2 EPSG:3089
# dem_phase3 DEM Phase 3 (2ft) COG 2ft 3 EPSG:3089
# ortho_phase1 Orthoimagery Phase 1 ... COG 6in 1 EPSG:3089
# ...plus oblique products
Generate hillshade, slope, and contour tiles directly from the TiTiler-pgSTAC server — no downloads needed:
from abovepy.titiler import hillshade_tile_url, slope_tile_url, contour_tile_url
# Hillshade TileJSON URL — use in MapLibre/Leaflet/leafmap
url = hillshade_tile_url(bbox=(-84.9, 38.15, -84.8, 38.25))
# Slope in degrees
url = slope_tile_url(bbox=(-84.9, 38.15, -84.8, 38.25))
# Contour lines every 50ft
url = contour_tile_url(bbox=(-84.9, 38.15, -84.8, 38.25), increment=50)
# Display a hillshade map in Jupyter (requires pip install abovepy[viz])
m = abovepy.show("dem_phase3", county="Franklin", algorithm="hillshade")
m # renders interactive leafmap
Register a search with TiTiler-pgSTAC to get a shareable tile URL:
search_id = abovepy.register_search("dem_phase3", bbox=(-84.9, 38.15, -84.8, 38.25))
from abovepy.searches import search_tile_url
url = search_tile_url(search_id) # stable TileJSON URL
Access Phase 3 oblique imagery from 4 camera directions (backward, forward, left, right):
from abovepy.obliques import list_oblique_seasons, search_obliques
seasons = list_oblique_seasons()
frames = search_obliques(direction="bwd", season=seasons[-1], max_items=10)
# Each frame has: frame_id, tif_url, json_url, season, direction
Compare 5ft Phase 1 vs 2ft Phase 3 resolution from the same tile in Frankfort:

Compute a hillshade directly from a cloud-hosted DEM tile — no download required:

Read just the pixels you need with a bounding box:

Pull 3-inch true-color imagery of the Kentucky State Capitol:

Relative Elevation Model showing height above the Kentucky River in Frankfort:

Estimate cut volume for an active mine permit in Perry County using DEM differencing:

Visualize tile coverage for Franklin County:

Compare Phase 1 vs Phase 3 DEM over a Pike County mining area to detect terrain change:

Simulate rising water levels on a DEM — watch the Kentucky River floodplain fill:


Compute slope and aspect from DEM for terrain analysis:

Overlay 10ft/50ft contour lines on a shaded relief map:

Extract a cross-valley transect showing the Kentucky River valley profile:

Side-by-side ortho imagery across phases showing development over time:

Map DEM tile coverage across five Central Kentucky counties:

Combine ortho, DEM, hillshade, and slope for a single area:

One tile from each product type - DEM Phase 1/2/3 and Ortho Phase 3:

Server-side DEM elevation, hillshade, and ortho previews generated from TiTiler-pgSTAC:

Four-direction oblique frame coverage summarized for rapid site inspection:

See examples/scripts/ for the full source code behind each image and demo.
| Product | Resolution | Format | Collection ID |
|---|---|---|---|
dem_phase1 | 5ft | COG | dem-phase1 |
dem_phase2 | 2ft | COG | dem-phase2 |
dem_phase3 | 2ft | COG | dem-phase3 |
ortho_phase1 | 6 inch | COG | orthos-phase1 |
ortho_phase2 | 6 inch | COG | orthos-phase2 |
ortho_phase3 | 3 inch | COG | orthos-phase3 |
laz_phase1 | Varies | LAZ | laz-phase1 |
laz_phase2 | Varies | COPC | laz-phase2 |
laz_phase3 | Varies | COPC | laz-phase3 |
oblique_phase3_bwd | 3 inch | COG | obliques-phase3* |
oblique_phase3_fwd | 3 inch | COG | obliques-phase3* |
oblique_phase3_left | 3 inch | COG | obliques-phase3* |
oblique_phase3_right | 3 inch | COG | obliques-phase3* |
* Oblique STAC collection pending — use search_obliques() for S3-based discovery.
All data is natively in EPSG:3089 (Kentucky Single Zone, US feet). abovepy accepts bounding boxes in EPSG:4326 by default.
An ArcGIS Pro Python Toolbox is included in arcgis/AbovePro.pyt with tools for:
See ArcGIS Pro Toolbox Guide for installation and usage.
AboveQGIS is a QGIS Processing toolbox plugin with 6 tools:
abovepy.export.to_stl()Install via Plugins > Manage and Install Plugins or from the QGIS Plugin Repository. The plugin auto-installs abovepy on first run.
Tools appear under Plugins > AboveQGIS — KyFromAbove and in the Processing Toolbox.
KyFromAbove provides pre-built 3-inch ortho mosaics for all 120 counties. Stream them directly without downloading:
import abovepy
# Get the S3 URL for Franklin County's ortho mosaic
url = abovepy.county_mosaic_url("Franklin")
# Or for ArcGIS users
url = abovepy.county_mosaic_url("Franklin", fmt="tpkx")
In QGIS, use Plugins > AboveQGIS > Load County Ortho Mosaic to stream directly into your project.
abovepy generates TiTiler-compatible URLs for web map integration:
from abovepy.titiler import cog_tile_url, collection_tile_url, hillshade_tile_url
# Individual COG via standalone TiTiler
url = cog_tile_url(tiles.iloc[0].asset_url)
# Entire collection via TiTiler-pgSTAC (no individual URLs needed)
url = collection_tile_url("dem_phase3", bbox=(-84.9, 38.15, -84.8, 38.25))
# Server-side hillshade
url = hillshade_tile_url(bbox=(-84.9, 38.15, -84.8, 38.25))
# Use any of these with MapLibre GL JS, Leaflet, or leafmap
KyFromAbove TiTiler endpoints are used by default. A docker-compose.yml for local TiTiler is in examples/.
abovepy includes geometry utilities that work natively in Kentucky State Plane (EPSG:3089, Northing/Easting in US Survey Feet) — the coordinate system surveyors and engineers actually use:
from abovepy import buffer_feet, corridor_buffer
from shapely.geometry import Point, LineString
# Buffer a survey point by 500 feet using State Plane coordinates
site = Point(1_600_000, 312_000) # Easting, Northing in feet
area = buffer_feet(site, 500.0, input_crs="EPSG:3089")
# Create a corridor polygon from a road centerline (200ft each side)
road = LineString([(1_599_000, 312_000), (1_601_000, 312_500)])
corridor = corridor_buffer(road, 400.0, input_crs="EPSG:3089")
# Also works with WGS84 — reprojects to EPSG:3089 internally
site_wgs84 = Point(-84.87, 38.20)
area = buffer_feet(site_wgs84, 500.0) # input_crs defaults to EPSG:4326
abovepy includes a full CLI for terminal workflows:
# Search with feet-based buffer
abovepy search --point=-84.87,38.20 --buffer-feet 500 -p dem_phase3
# Get provenance metadata as JSON
abovepy search --county Franklin -p dem_phase3 --format provenance
# Estimate download size
abovepy estimate --county Franklin -p ortho_phase3
# Download tiles (concurrent, resumable)
abovepy download --county Franklin -p dem_phase3 -o ./data --workers 8
# Generate a hillshade tile URL
abovepy tile-url --bbox=-84.9,38.15,-84.8,38.25 --algorithm hillshade
For power users who need the full pystac-client:
client = abovepy.KyFromAboveClient()
stac_client = client.get_stac_client()
# Full pystac-client API
results = stac_client.search(
collections=["dem-phase3"],
bbox=(-84.9, 38.15, -84.8, 38.25),
datetime="2022-01-01/..",
).item_collection()
rio cogeo validate to check internal tiling, overviews, and compression.https://spved5ihrl.execute-api.us-west-2.amazonaws.com/s3://kyfromabove/ (public, us-west-2)GPL-3.0 — see LICENSE.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 2.1.3 | 1 Apr 2026 | 23 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 17:33 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:76f83b65020c354b90d1f382f4f2a7ef52ec41c55e2e7bd6c8b686466cd72993