KyFromAbove LiDAR, DEM, and orthoimagery data access for Python
Project description
abovepy
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.
Install
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
Quick Start
Search by county name
import abovepy
# Find DEM tiles covering Franklin County
tiles = abovepy.search(county="Franklin", product="dem_phase3")
print(tiles)
Search by bounding box
tiles = abovepy.search(
bbox=(-84.9, 38.15, -84.8, 38.25),
product="dem_phase3"
)
Download tiles
paths = abovepy.download(tiles, output_dir="./data")
Mosaic into a single raster
vrt = abovepy.mosaic(paths, output="frankfort.vrt")
Search by point with feet-based buffer
# 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"
)
Corridor search
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")
Stream without downloading
data, profile = abovepy.read(
tiles.iloc[0].asset_url,
bbox=(-84.85, 38.18, -84.82, 38.21)
)
Data quality validation
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.
Provenance 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
Explore available products
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
Terrain analysis (server-side)
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)
Interactive notebook maps
# Display a hillshade map in Jupyter (requires pip install abovepy[viz])
m = abovepy.show("dem_phase3", county="Franklin", algorithm="hillshade")
m # renders interactive leafmap
Persistent virtual mosaics
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
Oblique imagery
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
Examples
DEM Phase Comparison
Compare 5ft Phase 1 vs 2ft Phase 3 resolution from the same tile in Frankfort:
Hillshade from Streamed DEM
Compute a hillshade directly from a cloud-hosted DEM tile — no download required:
Streamed DEM Window
Read just the pixels you need with a bounding box:
Ortho RGB Extract
Pull 3-inch true-color imagery of the Kentucky State Capitol:
Kentucky River REM
Relative Elevation Model showing height above the Kentucky River in Frankfort:
Mine Volume Estimate
Estimate cut volume for an active mine permit in Perry County using DEM differencing:
Search Results Map
Visualize tile coverage for Franklin County:
DEM Change Detection
Compare Phase 1 vs Phase 3 DEM over a Pike County mining area to detect terrain change:
Flood Inundation Simulation
Simulate rising water levels on a DEM — watch the Kentucky River floodplain fill:
Slope & Aspect Analysis
Compute slope and aspect from DEM for terrain analysis:
Elevation Contours over Hillshade
Overlay 10ft/50ft contour lines on a shaded relief map:
Elevation Profile
Extract a cross-valley transect showing the Kentucky River valley profile:
Land Use Change
Side-by-side ortho imagery across phases showing development over time:
Multi-County Tile Coverage
Map DEM tile coverage across five Central Kentucky counties:
Multi-Product Site Assessment
Combine ortho, DEM, hillshade, and slope for a single area:
Product Gallery
One tile from each product type - DEM Phase 1/2/3 and Ortho Phase 3:
pgSTAC Terrain Previews
Server-side DEM elevation, hillshade, and ortho previews generated from TiTiler-pgSTAC:
Oblique Site Inspection
Four-direction oblique frame coverage summarized for rapid site inspection:
See examples/scripts/ for the full source code behind each image and demo.
Available Products
| 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.
ArcGIS Pro Toolbox
An ArcGIS Pro Python Toolbox is included in arcgis/AbovePro.pyt with tools for:
- Find KyFromAbove Tiles — draw extent, pick product, see available tiles
- Download Tiles — download with progress tracking
- Download and Load — download + add to map in one step
- DEM Hillshade — automated DEM → hillshade workflow
- County Download — download by county name dropdown
See ArcGIS Pro Toolbox Guide for installation and usage.
Web Visualization
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/.
Kentucky Engineering Geometry
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
Command-Line Interface
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
Advanced: Direct STAC Access
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()
Related Resources
- kyfromabove-on-aws-examples — Foundational examples for accessing KyFromAbove data on AWS using tile index GeoPackages and boto3. Great reference for understanding the raw S3 data structure that abovepy wraps.
- kyfromabove-gisconference2025-workshop — 2025 KY GIS Conference workshop covering STAC API access from Python, ArcGIS Pro, and QGIS. Includes building height estimation from COPC LiDAR, DEM change detection, and MosaicJSON workflows.
- KyFromAbove — Official program site from the Kentucky Division of Geographic Information.
- STAC Browser — Browse the KyFromAbove STAC catalog interactively.
Data Source
- STAC API:
https://spved5ihrl.execute-api.us-west-2.amazonaws.com/ - S3 Bucket:
s3://kyfromabove/(public, us-west-2) - AWS Open Data Registry: KyFromAbove
License
GPL-3.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file abovepy-2.1.0.tar.gz.
File metadata
- Download URL: abovepy-2.1.0.tar.gz
- Upload date:
- Size: 50.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30c00c068a2a883c494a41ee1c23c44bd2a6500f4ebaa6917e5de88e72cf4ceb
|
|
| MD5 |
4ff53a94b7aea9dd5827791fba08ffc3
|
|
| BLAKE2b-256 |
9cb7a843ed4a782c881260765e7083db532e233f901ef4e03cbb8d74fc418149
|
File details
Details for the file abovepy-2.1.0-py3-none-any.whl.
File metadata
- Download URL: abovepy-2.1.0-py3-none-any.whl
- Upload date:
- Size: 65.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c963adba436dcb07143a8056484f9832451af13f6c9210ec91bd599402bf69a5
|
|
| MD5 |
825c8b084be7a23ad8ed161aff40ba4f
|
|
| BLAKE2b-256 |
30aca31fd83b408b31cbbfaa2db75328a9564c5f6710859b221f19b6354de5c5
|