#!/usr/bin/python
'''
ACIS-WS Sample Code --> Spatial summary of grid data
Sum of daily July precipitation projected for 2040
over the state California
using climate model: CRCM + CGCM3 (grid number 6).
For more information: http://rcc-acis.org/docs_webservices.html
The result is climate map (.png) showing sum of precipitation
in July at each California gridpoint.
'''
#######################################
#Import modules required by Acis
import json, requests, sys
#######################################
#######################################
#Import plotting tools
import cairo
import base64
from cStringIO import StringIO
#######################################
#Set Acis data server
base_url = "https://data.rcc-acis.org/"
#######################################
#Acis WebServices functions
#######################################
def make_request(url,params) :
try:
response = requests.post(url, data={'params': json.dumps(params)}, headers={"Accept":"application/json"})
return response.json()
except:
print ("Error making ACIS Web Services call")
sys.exit()
def GridData(params):
return make_request(base_url+"GridData",params)
##################################################
#Map code using Cairo
#http://cairoplot.sourceforge.net/tutorials.html
###################################################
def place_text(ctx,txt,j='l',v='b') :
_,_,w,h,_,_ = ctx.text_extents(txt)
if v == 'b' : h = 0
elif v == 'm' : h = h/2
elif v == 't' : h = h
if j == 'l' : w = 0
elif j == 'c' : w = -w/2
elif j == 'r' : w = -w
ctx.rel_move_to(w,h)
ctx.show_text(txt)
def add_legend(ctx,image_info) :
#ctx.set_matrix(cairo.Matrix(yy=-1,y0=height))
if image_info['size'][0]<301:
ctx.set_font_size(8.)
w = image_info['size'][0]/(len(image_info['cmap']) + 3)
elif image_info['size'][0]>300 and image_info['size'][0]<501:
ctx.set_font_size(10.)
w = image_info['size'][0]/(len(image_info['cmap'])+2)
else:
ctx.set_font_size(12.)
w = image_info['size'][0]/(len(image_info['cmap'])+2)
for idx,color in enumerate(image_info['cmap']) :
ctx.rectangle(idx*w,0,w,10)
ctx.set_source_rgb(int(color[1:3],16)/255.,int(color[3:5],16)/255.,int(color[5:7],16)/255.)
ctx.fill_preserve()
ctx.set_source_rgb(0,0,0)
ctx.stroke()
for idx,value in enumerate(image_info['levels']) :
ctx.move_to((idx+1)*w,10)
ctx.rel_line_to(0,5)
ctx.rel_move_to(-2,3)
if value >0.0 and value < 1.0:
place_text(ctx,'%.2f'%(value),j='c',v='t')
else:
place_text(ctx,'%d'%(value),j='c',v='t')
ctx.stroke()
def build_figure(image_info, out_name):
image_offset=0
image_padding = 0,150
img_buf = StringIO(image_info['data'][21:].decode('base64'))
img_buf.seek(0)
# create input image
in_img = cairo.ImageSurface.create_from_png(img_buf)
size = height,width = in_img.get_height(),in_img.get_width()
pad_w,pad_h = image_padding
# create output image
out_img = cairo.ImageSurface(cairo.FORMAT_ARGB32,
width+pad_w, height+pad_h+image_offset)
ctx = cairo.Context(out_img)
# set background color
ctx.set_source_rgb(255,239,213)
ctx.paint()
# place image
ctx.set_source_surface(in_img,pad_w/2,image_offset)
ctx.paint()
# frame image
ctx.set_line_width(1.0)
ctx.set_source_rgb(0,0,0)
ctx.rectangle(pad_w/2,image_offset,width,height)
ctx.stroke()
ctx.set_matrix(cairo.Matrix(x0=15+25,y0=image_offset+height+80))
ctx.set_matrix(cairo.Matrix(x0=15+25,
y0=image_offset+height+30))
add_legend(ctx,image_info)
out_buf = open(out_name,'w')
out_img.write_to_png(out_buf)
###################################################
#M A I N
###################################################
if __name__ == "__main__":
#Set parameters for data request
#levels = [0.2*i for i in range(15)]
params = {
"state":"ca",
"sdate":"20400701",
"edate":"20400731",
"grid":"6",
"output":"json",
"elems":[{"name":"pcpn","smry":"sum","smry_only":1}],
"image":{
"proj":"lcc",
"overlays":"state",
"interp":"cspline",
"cmap":"rainbow",
"width":350
#"levels":levels
}
}
#Obtain data
data = GridData(params)
#Generate png output
build_figure(data, 'CA_pcpn_map.png')