Dette datasettet inneholder luftfoto fra National Agricultural Imagery Program (NAIP).
NAIP leverer høyoppløselige luftfoto for hele USA. Dette programmet administreres av Aerial Field Photography Office (AFPO) i US Department of Agriculture (USDA). Data er tilgjengelige fra 2010 til i dag.
Lagringsressurser
Data lagres i skyoptimaliserte GeoTIFF-filer i Azure Blob Storage i det østamerikanske datasenteret i følgende blob-beholder:
https://naipblobs.blob.core.windows.net/naip
Innenfor den beholderen, organiseres data etter:
v002/[state]/[year]/[state]_[resolution]_[year]/[quadrangle]/filename
… for eksempel:
v002/al/2015/al_100cm_2015/30086/m_3008601_ne_16_1_20150804.tif
Flere detaljer om disse feltene:
- År: Firesifret år. Bilder samles inn i hver delstat hvert 3–5 år, der hvert aktuelle år inneholder noen (men ikke alle) delstater. Alabama har for eksempel data i 2011 og 2013, men ikke i 2012, mens California har data i 2012, men ikke 2011 eller 2013. Esri gir informasjon om NAIP-dekning i deres interaktive årlige NAIP-dekningskart.
- Delstat: Delstatskode på to bokstaver.
- Oppløsning: Strengspesifikasjon av bildeoppløsning, som har variert gjennom NAIP’s historie. Avhengig av år og dato, kan dette være “50 cm”, “60 cm” eller “100 cm”.
- Firkant: USGS-kvadratidentifikator, som spesifiserer et 7,5 minutt x 7,5 minutts område.
Filer lagres som skyoptimaliserte GeoTIFF-bilder, med en .TIF-utvidelse. Disse filene ble produsert (fra det originale, USDA-medfølgende formatet) og organisert av Esri.
Små miniatyrbilder er også tilgjengelige for hvert bilde. Erstatt “.TIF” med “.200.jpg” for å hente miniatyrbildet. Eksempel:
https://naipblobs.blob.core.windows.net/naip/v002/al/2013/al_100cm_2013/30086/m_3008601_ne_16_1_20130928.200.jpg
Et fullstendig eksempel på tilgang til og innføring av NAIP-bilde i Python, er tilgjengelig i notatboken under “datatilgang”.
Vi leverer også et skrivebeskyttet SAS-token (delt tilgangssignatur) for å gi tilgang til NAIP-data via, f.eks., BlobFuse, som lar deg sette inn blob-beholdere som stasjoner:
st=2019-07-18T03%3A53%3A22Z&se=2035-07-19T03%3A53%3A00Z&sp=rl&sv=2018-03-28&sr=c&sig=2RIXmLbLbiagYnUd49rgx2kOXKyILrJOgafmkODhRAQ%3D
Monteringsinstruksjoner for Linux er her.
NAIP-data kan bruke hundrevis av terrabytes, så storskalabehandling utføres best i Azure-datasenteret i øst-USA, der bildene er lagret. Hvis du bruker NAIP-data for miljøvitenskapsprogrammer, vurder å søke om et AI for Earth-stipend for å støtte dine databehandlingskrav.
Indeks
En liste over alle NAIP-filer er tilgjengelig her, som en komprimert .CSV-fil:
https://naipblobs.blob.core.windows.net/naip-index/naip_v002_index.zip
Vi har også et rtree-objekt for å støtte spatiale spørsmål for Python-brukere. Se notatbok for utvalg for detaljer.
Data finner man også her.
Hvor ble det av .MRF-filene?
I juni 2020 oppdaterte vi hele NAIP-arkivet vårt, sånn at det forbedrer både dekning og vedlikeholdbarhet. Vi byttet også fra .MRF-format til skyoptimalisert GeoTIFF, og gjorde noen forandringer i banestrukturen. .MRF-filene er midlertidig fremdeles tilgjengelige i en annen beholder. Hvis de er viktige for arbeidet ditt og du trenger tilgang, kan du kontakte aiforearthdatasets@microsoft.com
.
Fint bilde
Bilde i 1m-oppløsning av området bær Microsoft’s Redmond-campus i 2017.
Kontakt
For spørsmål om datasettet kontakt aiforearthdatasets@microsoft.com
.
Access
Available in | When to use |
---|---|
Azure Notebooks | Quickly explore the dataset with Jupyter notebooks hosted on Azure or your local machine. |
Select your preferred service:
Azure Notebooks
# Standard packages
import tempfile
import warnings
import urllib
import shutil
import os
# Less standard, but still pip- or conda-installable
import matplotlib.pyplot as plt
import numpy as np
import rasterio
import re
import rtree
import shapely
import pickle
# pip install progressbar2, not progressbar
import progressbar
from geopy.geocoders import Nominatim
from rasterio.windows import Window
from tqdm import tqdm
latest_wkid = 3857
crs = "EPSG:4326"
# Storage locations are documented at http://aka.ms/ai4edata-naip
# The(preferred) copy of NAIP in the West Europe Azure region
blob_root = 'https://naipeuwest.blob.core.windows.net/naip'
# NAIP is also available in the East US Azure region
# blob_root = 'https://naipblobs.blob.core.windows.net/naip'
index_files = ["tile_index.dat", "tile_index.idx", "tiles.p"]
index_blob_root = re.sub('/naip$','/naip-index/rtree/',blob_root)
temp_dir = os.path.join(tempfile.gettempdir(),'naip')
os.makedirs(temp_dir,exist_ok=True)
# Spatial index that maps lat/lon to NAIP tiles; we'll load this when we first
# need to access it.
index = None
# URL where we've stashed a geojson file with the boundaries of Maryland. Why do we
# need the boundaries of Maryland? It's a surprise, you'll have to keep reading to find
# out.
maryland_boundary_url = 'https://ai4edatasetspublicassets.blob.core.windows.net/assets/maryland.json'
warnings.filterwarnings("ignore")
%matplotlib inline
class DownloadProgressBar():
"""
https://stackoverflow.com/questions/37748105/how-to-use-progressbar-module-with-urlretrieve
"""
def __init__(self):
self.pbar = None
def __call__(self, block_num, block_size, total_size):
if not self.pbar:
self.pbar = progressbar.ProgressBar(max_value=total_size)
self.pbar.start()
downloaded = block_num * block_size
if downloaded < total_size:
self.pbar.update(downloaded)
else:
self.pbar.finish()
class NAIPTileIndex:
"""
Utility class for performing NAIP tile lookups by location.
"""
tile_rtree = None
tile_index = None
base_path = None
def __init__(self, base_path=None):
if base_path is None:
base_path = temp_dir
os.makedirs(base_path,exist_ok=True)
for file_path in index_files:
download_url(index_blob_root + file_path, base_path + '/' + file_path,
progress_updater=DownloadProgressBar())
self.base_path = base_path
self.tile_rtree = rtree.index.Index(base_path + "/tile_index")
self.tile_index = pickle.load(open(base_path + "/tiles.p", "rb"))
def lookup_tile(self, lat, lon):
""""
Given a lat/lon coordinate pair, return the list of NAIP tiles that contain
that location.
Returns a list of COG file paths.
"""
point = shapely.geometry.Point(float(lon),float(lat))
intersected_indices = list(self.tile_rtree.intersection(point.bounds))
intersected_files = []
tile_intersection = False
for idx in intersected_indices:
intersected_file = self.tile_index[idx][0]
intersected_geom = self.tile_index[idx][1]
if intersected_geom.contains(point):
tile_intersection = True
intersected_files.append(intersected_file)
if not tile_intersection and len(intersected_indices) > 0:
print('''Error: there are overlaps with tile index,
but no tile completely contains selection''')
return None
elif len(intersected_files) <= 0:
print("No tile intersections")
return None
else:
return intersected_files
def download_url(url, destination_filename=None, progress_updater=None, force_download=False):
"""
Download a URL to a temporary file
"""
# This is not intended to guarantee uniqueness, we just know it happens to guarantee
# uniqueness for this application.
if destination_filename is None:
url_as_filename = url.replace('://', '_').replace('/', '_')
destination_filename = \
os.path.join(temp_dir,url_as_filename)
if (not force_download) and (os.path.isfile(destination_filename)):
print('Bypassing download of already-downloaded file {}'.format(os.path.basename(url)))
return destination_filename
print('Downloading file {} to {}'.format(os.path.basename(url),destination_filename),end='')
urllib.request.urlretrieve(url, destination_filename, progress_updater)
assert(os.path.isfile(destination_filename))
nBytes = os.path.getsize(destination_filename)
print('...done, {} bytes.'.format(nBytes))
return destination_filename
def display_naip_tile(filename):
"""
Display a NAIP tile using rasterio.
"""
# NAIP tiles are enormous; downsize for plotting in this notebook
dsfactor = 10
with rasterio.open(filename) as raster:
# NAIP imagery has four channels: R, G, B, IR
#
# Stack RGB channels into an image; we won't try to render the IR channel
#
# rasterio uses 1-based indexing for channels.
h = int(raster.height/dsfactor)
w = int(raster.width/dsfactor)
print('Resampling to {},{}'.format(h,w))
r = raster.read(1, out_shape=(1, h, w))
g = raster.read(2, out_shape=(1, h, w))
b = raster.read(3, out_shape=(1, h, w))
rgb = np.dstack((r,g,b))
fig = plt.figure(figsize=(7.5, 7.5), dpi=100, edgecolor='k')
plt.imshow(rgb)
raster.close()
def get_coordinates_from_address(address):
"""
Look up the lat/lon coordinates for an address.
"""
geolocator = Nominatim(user_agent="NAIP")
location = geolocator.geocode(address)
print('Retrieving location for address:\n{}'.format(location.address))
return location.latitude, location.longitude
# Tiles are stored at:
#
# [blob root]/v002/[state]/[year]/[state]_[resolution]_[year]/[quadrangle]/filename
year = '2015'
state = 'al'
resolution = '100cm'
quadrangle = '30086'
filename = 'm_3008601_ne_16_1_20150804.tif'
tile_url = blob_root + '/v002/' + state + '/' + year + '/' + state + '_' + resolution + \
'_' + year + '/' + quadrangle + '/' + filename
print(tile_url)
# Download the image
image_filename = download_url(tile_url,progress_updater=DownloadProgressBar())
# Plot the image
print('Reading file:\n{}'.format(os.path.basename(image_filename)))
assert os.path.isfile(image_filename)
display_naip_tile(image_filename)
if index is None:
index = NAIPTileIndex()
lat = 47.645950
lon = -122.136980
naip_files = index.lookup_tile(lat, lon)
print('\nList of available naip files for this location:\n')
for file in naip_files:
print(file)
print('')
# Choose the latest NAIP tile from this location
#
# Images are indexed in reverse-chronological order, so zero is the