mirror of
https://bitbucket.org/s_l_teichmann/mtsatellite
synced 2024-11-09 11:40:23 +01:00
129 lines
3.3 KiB
Go
129 lines
3.3 KiB
Go
|
// Copyright 2014 by Sascha L. Teichmann
|
||
|
// Use of this source code is governed by the MIT license
|
||
|
// that can be found in the LICENSE file.
|
||
|
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"flag"
|
||
|
"fmt"
|
||
|
"image"
|
||
|
"image/png"
|
||
|
"log"
|
||
|
"net/http"
|
||
|
"path/filepath"
|
||
|
"strconv"
|
||
|
|
||
|
"bytes"
|
||
|
|
||
|
"bitbucket.org/s_l_teichmann/mtredisalize/common"
|
||
|
|
||
|
"github.com/gorilla/mux"
|
||
|
"github.com/nfnt/resize"
|
||
|
)
|
||
|
|
||
|
func toUint(s string) uint {
|
||
|
var err error
|
||
|
var x int
|
||
|
if x, err = strconv.Atoi(s); err != nil {
|
||
|
log.Printf("WARN: Cannot convert to int: %s", err)
|
||
|
return 0
|
||
|
}
|
||
|
return uint(x)
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
var (
|
||
|
port int
|
||
|
host string
|
||
|
webDir string
|
||
|
mapDir string
|
||
|
)
|
||
|
flag.IntVar(&port, "port", 8808, "port of the web server")
|
||
|
flag.IntVar(&port, "p", 8808, "port of the web server (shorthand)")
|
||
|
flag.StringVar(&host, "host", "localhost", "address to bind")
|
||
|
flag.StringVar(&host, "h", "localhost", "address to bind (shorthand)")
|
||
|
flag.StringVar(&webDir, "web", "web", "static served web files.")
|
||
|
flag.StringVar(&webDir, "w", "web", "static served web files (shorthand)")
|
||
|
flag.StringVar(&mapDir, "map", "map", "directory of prerendered tiles")
|
||
|
flag.StringVar(&mapDir, "m", "map", "directory of prerendered tiles (shorthand)")
|
||
|
|
||
|
flag.Parse()
|
||
|
|
||
|
r := mux.NewRouter()
|
||
|
r.HandleFunc("/map/{z:[0-9]+}/{x:[0-9]+}/{y:[0-9]+}.png", func(rw http.ResponseWriter, r *http.Request) {
|
||
|
vars := mux.Vars(r)
|
||
|
xs := vars["x"]
|
||
|
ys := vars["y"]
|
||
|
zs := vars["z"]
|
||
|
x, y, z := toUint(xs), toUint(ys), toUint(zs)
|
||
|
if z < 9 {
|
||
|
filename := fmt.Sprintf("%d/%d/%d.png", z, x, y)
|
||
|
http.ServeFile(rw, r, filepath.Join(mapDir, filename))
|
||
|
return
|
||
|
}
|
||
|
if z > 16 {
|
||
|
z = 16
|
||
|
}
|
||
|
//fmt.Printf("x %d\n", x)
|
||
|
//fmt.Printf("y %d\n", y)
|
||
|
//fmt.Printf("z %d\n", z)
|
||
|
tx := x >> (z - 8)
|
||
|
ty := y >> (z - 8)
|
||
|
rx := x & ^(^uint(0) << (z - 8))
|
||
|
ry := y & ^(^uint(0) << (z - 8))
|
||
|
|
||
|
parts := uint(1) << (z - 8)
|
||
|
//fmt.Printf("z %d\n", z)
|
||
|
//fmt.Printf("parts %d\n", parts)
|
||
|
|
||
|
w := uint(256) / parts
|
||
|
xo := w * rx
|
||
|
yo := w * (parts - 1 - ry)
|
||
|
//fmt.Printf("w %d\n", w)
|
||
|
//fmt.Printf("xo %d\n", xo)
|
||
|
//fmt.Printf("yo %d\n", yo)
|
||
|
//fmt.Printf("rx %d\n", rx)
|
||
|
//fmt.Printf("ry %d\n", ry)
|
||
|
|
||
|
baseTile := filepath.Join(mapDir, fmt.Sprintf("8/%d/%d.png", tx, ty))
|
||
|
img := common.LoadPNG(baseTile)
|
||
|
|
||
|
type subImage interface {
|
||
|
image.Image
|
||
|
SubImage(image.Rectangle) image.Image
|
||
|
}
|
||
|
var si subImage
|
||
|
var ok bool
|
||
|
if si, ok = img.(subImage); !ok {
|
||
|
// Should not happen.
|
||
|
http.ServeFile(rw, r, filepath.Join(mapDir, baseTile))
|
||
|
return
|
||
|
}
|
||
|
|
||
|
img = si.SubImage(image.Rect(int(xo), int(yo), int(xo+w), int(yo+w)))
|
||
|
//fmt.Printf("%s\n", img.Bounds())
|
||
|
img = resize.Resize(256, 256, img, resize.NearestNeighbor)
|
||
|
|
||
|
var buf bytes.Buffer
|
||
|
if err := png.Encode(&buf, img); err != nil {
|
||
|
http.ServeFile(rw, r, filepath.Join(mapDir, baseTile))
|
||
|
return
|
||
|
}
|
||
|
b := buf.Bytes()
|
||
|
rw.Header().Set("Content-Type", "image/png")
|
||
|
// Don't set the content length to use chunked mode.
|
||
|
// rw.Header().Set("Content-Length", strconv.Itoa(len(b)))
|
||
|
if _, err := rw.Write(b); err != nil {
|
||
|
log.Printf("WARM: sending image failed: %s", err)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
r.PathPrefix("/").Handler(http.FileServer(http.Dir(webDir)))
|
||
|
http.Handle("/", r)
|
||
|
addr := fmt.Sprintf("%s:%d", host, port)
|
||
|
if err := http.ListenAndServe(addr, nil); err != nil {
|
||
|
log.Fatalf("Starting server failed: %s\n", err)
|
||
|
}
|
||
|
}
|