Created
September 14, 2013 15:00
-
-
Save dinnouti/6562701 to your computer and use it in GitHub Desktop.
Load points from NASA FIRMS into a SQL Database via ArcGIS 10.2. NASA only keeps 15 days of FIRMS data hence the reason to keep the CSV file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; configuration file | |
[test] | |
logging_file = D:/firecast_data/script_logs/firms_log.txt | |
;1 = file , 2 = stdout | |
logging_streaming = 1 | |
; ftp information | |
ftp_host = <ftp host address> | |
ftp_remote_path = <path in the remote FTP server> | |
ftp_username = | |
ftp_password = | |
ftp_local_path = <local path where the CSV will be stored> | |
; CSV file format | |
fai_latitude = 0 | |
fai_longitude = 1 | |
fai_brightness = 2 | |
fai_scan = 3 | |
fai_track = 4 | |
fai_acq_date = 5 | |
fai_acq_time = 6 | |
fai_satellite = 7 | |
fai_confidence = 8 | |
fai_version = 9 | |
fai_bright_t31 = 10 | |
fai_frp = 11 | |
; ArcGIS | |
arcgis_sde_firms = D:/<somefolder>/<sde file>.sde/<database> | |
[production] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/python | |
# load points from firms | |
import sys | |
###### | |
from ConfigParser import SafeConfigParser | |
cfg = SafeConfigParser() | |
cfg.read('D:/<path to the ini file>/loadPointsFromFirms.ini') | |
###### | |
import argparse | |
parser = argparse.ArgumentParser(description='Import fire points from FIRMS FTP and load into ArcGIS') | |
parser.add_argument('-i', dest='serverInstance', action='store',choices={'test','production','dev'}, required=True, help='Server instance') | |
parser.add_argument('-d', dest='date', action='store', required=True, help='Day to run the process format: YYYY/MM/DD or "yesterday"') | |
args = parser.parse_args() | |
serverInstance = args.serverInstance | |
downloadDate = args.date | |
# TODO: move the logging stream to a CLI parameter | |
###### | |
import logging | |
log = logging.getLogger(__file__) | |
log.setLevel(logging.DEBUG) | |
if int(cfg.get(serverInstance, 'logging_streaming')) == 1: | |
fh = logging.FileHandler(cfg.get(serverInstance, 'logging_file')) | |
else: | |
fh = logging.StreamHandler() | |
fh.setLevel(logging.DEBUG) | |
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') | |
fh.setFormatter(formatter) | |
log.addHandler(fh) | |
##### Testing date arguments | |
import datetime | |
from datetime import date, timedelta, datetime | |
import time | |
if downloadDate == 'yesterday': | |
yesterday = date.today() - timedelta(1) | |
downloadDate = yesterday.strftime('%Y-%m-%d') | |
if len(downloadDate.split('-')) != 3: | |
log.error('date is in the wrong format: %s' % downloadDate) | |
sys.exit() | |
log.info('---- new batch of FIRMS points ----') | |
log.info('processing date: %s' % downloadDate) | |
downloadDateArr = downloadDate.split('-') | |
#### FTP | |
# stores the CSV file locally and loads latter in the code, b/c FIRMS only stores the last 30 days, and easy from troubleshooting | |
import ftplib | |
import os | |
import socket | |
# open FTP connection | |
try: | |
f = ftplib.FTP(cfg.get(serverInstance, 'ftp_host'),cfg.get(serverInstance, 'ftp_username'), cfg.get(serverInstance, 'ftp_password')) | |
except Exception as e: | |
log.error('cannot login to ftp: %s' % cfg.get(serverInstance, 'ftp_host')) | |
log.error(e) | |
sys.exit() | |
log.info('connected to ftp: %s' % cfg.get(serverInstance, 'ftp_host')) | |
# changing directory | |
try: | |
f.cwd(cfg.get(serverInstance, 'ftp_remote_path')) | |
except Exception as e: | |
f.quit() | |
log.error('cannot CD to %s ' % cfg.get(serverInstance, 'ftp_remote_path')) | |
log.error(e) | |
sys.exit() | |
log.info('CD to %s ' % cfg.get(serverInstance, 'ftp_remote_path')) | |
# generating the filename - it uses julian date, 2013-06-03 = 154 | |
try: | |
julianDay = date(int(downloadDateArr[0]), int(downloadDateArr[1]), int(downloadDateArr[2])).strftime('%j') | |
except Exception as e: | |
f.quit() | |
log.error('converting julian date from %s ' % downloadDateArr) | |
log.error(e) | |
sys.exit() | |
log.debug('Julian day since begin of the year: %s' % julianDay) | |
remoteFilename = 'Global_MCD14DL_'+ downloadDateArr[0] + julianDay +'.txt' | |
log.info('remote filename: %s' % remoteFilename) | |
localFilename = cfg.get(serverInstance, 'ftp_local_path') + remoteFilename | |
log.info('local filename: %s' % localFilename) | |
# check if the file exists on the FTP site | |
try: | |
fileSize = f.size(remoteFilename) | |
except Exception as e: | |
f.quit() | |
log.error('File doesnt exist in the FTP: ' + remoteFilename) | |
log.error(e) | |
sys.exit() | |
# downloading file | |
try: | |
f.retrbinary('RETR %s' % remoteFilename, open(localFilename, 'wb').write) | |
except Exception as e: | |
# os.unlink(localFilename) | |
f.quit() | |
log.error('cannot download: %s' % remoteFilename) | |
log.error(e) | |
sys.exit() | |
log.info('donwloaded: %s' % remoteFilename) | |
f.quit() | |
log.info('closing connection to ftp') | |
#### Parsing from File to Array | |
log.info('parsing: %s' % localFilename) | |
fai_latitude = int(cfg.get(serverInstance, 'fai_latitude')) | |
fai_longitude = int(cfg.get(serverInstance, 'fai_longitude')) | |
fai_brightness = int(cfg.get(serverInstance, 'fai_brightness')) | |
fai_scan = int(cfg.get(serverInstance, 'fai_scan')) | |
fai_track = int(cfg.get(serverInstance, 'fai_track')) | |
fai_acq_date = int(cfg.get(serverInstance, 'fai_acq_date')) | |
fai_acq_time = int(cfg.get(serverInstance, 'fai_acq_time')) | |
fai_satellite = int(cfg.get(serverInstance, 'fai_satellite')) | |
fai_confidence = int(cfg.get(serverInstance, 'fai_confidence')) | |
fai_version = int(cfg.get(serverInstance, 'fai_version')) | |
fai_bright_t31 = int(cfg.get(serverInstance, 'fai_bright_t31')) | |
fai_frp = int(cfg.get(serverInstance, 'fai_frp')) | |
f = open(localFilename,'r') | |
lstFires = f.readlines() | |
aFires = [] | |
for fire in lstFires: | |
lstValues = fire.split(',') | |
if lstValues[0] == 'latitude': | |
log.debug('skipping the file header: %s' % lstValues) | |
continue | |
zeroError = True | |
try: | |
latitude = float(lstValues[fai_latitude]) | |
longitude = float(lstValues[fai_longitude]) | |
brightness = float(lstValues[fai_brightness]) | |
scan = float(lstValues[fai_scan]) | |
track = float(lstValues[fai_track]) | |
acq_date = lstValues[fai_acq_date] | |
acq_time = lstValues[fai_acq_time] | |
satellite = lstValues[fai_satellite] | |
confidence = int(lstValues[fai_confidence]) | |
version = float(lstValues[fai_version]) | |
bright_t31 = float(lstValues[fai_bright_t31]) | |
frp = float(lstValues[fai_frp].rstrip('\n')) | |
except Exception as e: | |
log.error('Error parsing: %s' % lstValues) | |
log.error(e) | |
zeroError = False | |
if zeroError: | |
aFires.append([latitude, longitude, brightness, scan,track,acq_date,acq_time,satellite,confidence,version,bright_t31,frp]) | |
f.close() | |
log.info('numero of points parsed to an array: %s' % len(aFires)) | |
########## loading to ArcGIS | |
import math | |
import arcpy | |
log.info('sde workspace: %s' % cfg.get(serverInstance, 'arcgis_sde_firms')) | |
arcpy.env.workspace = cfg.get(serverInstance, 'arcgis_sde_firms') | |
totalPointsImported = 0 | |
try: | |
### with arcpy.da.InsertCursor(arcpy.env.workspace, fieldsToUpdate) as cursor: | |
cursor = arcpy.da.InsertCursor(arcpy.env.workspace, ("SHAPE@XY", "brightness", "track", "acq_date", "satellite", "confidence", "version", "bright_t31", "frp")) | |
for aFire in aFires: | |
totalPointsImported += 1 | |
### convert from WGS to mercator | |
wgsX_lon = aFire[fai_longitude] | |
wgsY_lat = aFire[fai_latitude] | |
mercatorX_lon = 6378137.0 * wgsX_lon * 0.017453292519943295 | |
mercatorY_lat = 3189068.5 * math.log((1.0 + math.sin(wgsY_lat * 0.017453292519943295)) / (1.0 - math.sin(wgsY_lat * 0.017453292519943295))) | |
### log.info('long %s lat %s' % (aFire[fai_longitude],aFire[fai_latitude])) | |
row_values = ((mercatorX_lon, mercatorY_lat) ,aFire[fai_brightness], aFire[fai_track], aFire[fai_acq_date], aFire[fai_satellite], aFire[fai_confidence], aFire[fai_version], aFire[fai_bright_t31], aFire[fai_frp]) | |
cursor.insertRow(row_values) | |
del cursor | |
except Exception as e: | |
log.error(e) | |
log.error(arcpy.GetMessages()) | |
sys.exit() | |
log.info('summary') | |
log.info('today date: %s' % date.today().strftime('%Y-%m-%d %H:%M:%S')) | |
log.info('processing date: %s' % downloadDate) | |
log.info('total points imported into ArcGIS %s from %s' % (totalPointsImported, downloadDate)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment