Skip to content

Instantly share code, notes, and snippets.

@prl900
Created April 12, 2018 06:55
Show Gist options
  • Save prl900/7a598b7bb24b8524ba1eca19980e6f33 to your computer and use it in GitHub Desktop.
Save prl900/7a598b7bb24b8524ba1eca19980e6f33 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/gob"
"fmt"
"image"
"image/png"
"net/http"
"strconv"
"github.com/prl900/geowarp"
"github.com/prl900/image/tiff"
"cloud.google.com/go/storage"
"golang.org/x/net/context"
"google.golang.org/appengine"
"google.golang.org/appengine/log"
"google.golang.org/appengine/urlfetch"
)
const (
sinuProj = "+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs "
bktName = "terrascope-io.appspot.com"
indexURL = "https://index-dot-terrascope-io.appspot.com/"
)
var modisGeot = []float64{-20015109.3539999984204769, 463.3127165279165069, 0.0, 10007554.677005993, 0.0, -463.3127165279165069}
func ReadObject(ctx context.Context, bktName, oName string) (image.Image, error) {
client, err := storage.NewClient(ctx)
if err != nil {
return nil, err
}
rc, err := client.Bucket(bktName).Object(oName).NewReader(ctx)
if err != nil {
return nil, err
}
defer rc.Close()
log.Debugf(ctx, "Before ReadAll")
im, err := tiff.Decode(rc)
if err != nil {
return nil, err
}
log.Debugf(ctx, "After ReadAll")
return im, nil
}
func Burn(ctx context.Context, canvasRaster16 geowarp.GrayGeoRaster16, obj string) error {
im, err := ReadObject(ctx, bktName, obj)
if err != nil {
return err
}
geoIm := im.(*geowarp.GrayGeoRaster16)
geoIm.Proj4 = sinuProj
modisRaster16 := geowarp.GrayGeoRaster16{geoIm.Gray16, sinuProj, geoIm.GeoTrans, 0}
modisRaster16.Warp(canvasRaster16)
return nil
}
func handle(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
w.Header().Set("Content-Type", "text/plain")
log.Debugf(ctx, "Request started")
q := r.URL.Query()
xSize, err := strconv.Atoi(q.Get("xsize"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
ySize, err := strconv.Atoi(q.Get("ysize"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
x0, err := strconv.ParseFloat(q.Get("x0"), 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
y0, err := strconv.ParseFloat(q.Get("y0"), 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
res, err := strconv.ParseFloat(q.Get("res"), 64)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
client := urlfetch.Client(ctx)
url := fmt.Sprintf("%s?xsize=%d&ysize=%d&x0=%f&y0=%f&res=%f", indexURL, xSize, ySize, x0, y0, res)
resp, err := client.Get(url)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer resp.Body.Close()
var objs []string
err = gob.NewDecoder(resp.Body).Decode(&objs)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
canvasIm16 := image.NewGray16(image.Rect(0, 0, xSize, ySize))
geotCanvas := []float64{x0, res, 0, y0, 0, -1 * res}
canvasRaster16 := geowarp.GrayGeoRaster16{canvasIm16, "", geotCanvas, 0}
for _, obj := range objs {
err := Burn(ctx, canvasRaster16, obj)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
log.Debugf(ctx, "Object: %s has been read", obj)
}
log.Debugf(ctx, "Encoding started")
w.Header().Set("Content-Type", "image/png")
err = png.Encode(w, canvasRaster16)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
log.Debugf(ctx, "Encoding finished")
}
func main() {
http.HandleFunc("/", handle)
appengine.Main()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment