Skip to content

Instantly share code, notes, and snippets.

@dinnouti
Created September 14, 2013 15:00
Show Gist options
  • Save dinnouti/6562701 to your computer and use it in GitHub Desktop.
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.
; 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]
#! /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