#!/usr/bin/python2

import os
import sys
import urllib
import json
import time

CRSLIST_URL="https://spatialreference.org/crslist.json"
WKT_URL_TEMPLATE="https://spatialreference.org/ref/%s/%s/prettywkt2.txt"
PROJ4_URL_TEMPLATE="https://spatialreference.org/ref/%s/%s/proj4.txt"



auth_names = {
    "NKG":"Nordic Geodetic Commission",
    "EPSG":"European Petroleum Survey Group",
    "OGC":"Open Geospatial Consortium",
    "IGNF":"Institut Geographique National de France",
    "IAU_2015" : "International Astronomical Union",
    "ESRI":"Esri",
    "USER":"_Defined_by_user"
}

def getdata(url):
    f = urllib.urlopen(url)
    data = f.read()
    f.close()
    return data

def writefile(pathname,data):
    f = open(pathname,"wt")
    f.write(data)
    f.close()
    
def generatecrss(datadir, authority,crss):
    authorityid = authority.lower()
    authdir = os.path.join(datadir,authorityid)
    crssdir = os.path.join(authdir,"crs")
    if not os.path.isdir(crssdir):
        os.makedirs(crssdir)
    print "Processing authority ",authority
    
    crs_csv = open(os.path.join(authdir,"crs.csv"),"wt")
    crs_csv.write("#id,description,eastBoundLongitude,southBoundLatitude,westBoundLongitude,northBoundLatitude,areaName\n");
            
    counter = 0
    downloads = 0
    total = 0
    for crs in crss:
        if crs["auth_name"]==authority:
            total+=1
    for crs in crss:
        if crs["auth_name"]==authority:
            print "%s:%s (%s/%s)" % (authority,crs["code"],counter,total),
            code = crs["code"].lower()   
            print " add to csv",
            line = u"%s,%s,%3.3f,%3.3f,%3.3f,%3.3f,%s\n" % (
                    crs["code"],
                    crs["name"].replace(",","\\x2c"),
                    crs["area_of_use"][0],
                    crs["area_of_use"][1],
                    crs["area_of_use"][2],
                    crs["area_of_use"][3],
                    crs["area_of_use"][4].replace(",","\\x2c")
                )
            crs_csv.write(line.encode("utf-8"))
            crs_csv.flush()

            wkt_file = os.path.join(crssdir,code)+".wkt"
            if not os.path.exists(wkt_file) :
                print " downloading wkt",
                crs_wkt = getdata(WKT_URL_TEMPLATE % (authorityid,crs["code"]))
                writefile(wkt_file, crs_wkt)
                downloads+=1
            else:
                print " from cache",
            #proj4_file = os.path.join(crssdir,code)+".proj4"
            #if not os.path.exists(proj4_file) :
            #    print " downloading proj4",
            #    crs_proj4 = getdata(PROJ4_URL_TEMPLATE % (authorityid,crs["code"]))
            #    writefile(proj4_file, crs_proj4)
            #    downloads+=1
            print
            if downloads >= 40 :
                downloads = 0
                print "(sleep 0.5min)"
                time.sleep(0.5*60)
            counter+=1
                
    crs_csv.close()

def getauthorities(crss):
    l = set()
    for crs in crss:
        l.add(crs["auth_name"])
    l.add("USER")
    authorities = []
    authorities.extend(l)
    authorities.sort()
    return authorities

def generateauthorities(datadir,authorities):
    if not os.path.isdir(datadir):
        os.makedirs(datadir)
    auth_csv = open(os.path.join(datadir,"authorities.csv"),"wt")
    auth_csv.write("#Id,Name,Description\n");
    for auth in authorities:
        auth_csv.write("%s,%s,%s\n" % (auth.lower(),auth,auth_names.get(auth,auth)))
    auth_csv.close()

def main():
    datadir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))),"data","authorities")

    print "\nDownload CRS from spatialreference"
    print "Downloading CRS json"
    crss_json = getdata(CRSLIST_URL)
    crss = json.loads(crss_json)
    auths = getauthorities(crss)
    print "Generating auhorities file"
    generateauthorities(datadir,auths)
    retry = True
    while retry:
        try:
            for auth in auths:
                generatecrss(datadir,auth,crss)
            retry = False
        except IOError as e:
            retry = True
            print "(sleep 3min)"
            time.sleep(60*3)
            
if __name__ == "__main__":
    main()
    
