-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.go
130 lines (104 loc) · 2.59 KB
/
app.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"errors"
"fmt"
"github.com/codegangsta/cli"
"io/ioutil"
"os"
"time"
)
var hosts = map[string]string{
"mapbox": "",
"openstreetmap": "http://a.tile.openstreetmap.org//{{.Z}}/{{.X}}/{{.Y}}.png",
"googlemaps": "",
}
func main() {
app := cli.NewApp()
app.Name = "mapsnap"
app.Usage = "Download map tiles and join them"
app.Flags = []cli.Flag{
cli.StringFlag{"host", "mapbox", "Host for maps. Supported: mapbox,google,openstreetmap"},
cli.IntFlag{"z", 0, "Z coordinate/Zoom factor"},
}
app.Action = func(c *cli.Context) {
points, filename := parseArgs(c)
z, host := parseFlags(c)
// Transform points into coordinates and create
// Value matrix
tiles := CreateMatrix(points)
// Info time
fmt.Printf("Dimension x: %d, y: %d \n", tiles.width(), tiles.height())
fmt.Printf("Number of tiles to download: %d\n", tiles.size())
// Move to temp and remember home
script_dir, _ := os.Getwd()
temp := initTemp()
// Create job channel
jobs := make(chan Downloadjob, int(tiles.size()))
done := make(chan bool, int(tiles.size()))
// Create workers
for i := 0; i < 4; i++ {
go Downloader(i, jobs, done)
}
// Send jobs
for dx := tiles.TL.x; dx < tiles.TR.x; dx++ {
for dy := tiles.BL.y; dy < tiles.TL.y; dy++ {
jobs <- Downloadjob{point{dx, dy}, coord(z), host, 0}
}
}
close(jobs)
// count finished
start := time.Now()
for i := 0; i < int(tiles.size()); i++ {
<-done
fmt.Printf("Finished: %d ~~ Speed: %.3f tiles/second \r", i, float64(i)/time.Since(start).Seconds())
}
img := Join(tiles)
os.Chdir(script_dir)
Save(img, filename)
os.Remove(temp)
}
app.Run(os.Args)
}
func bailout(err error) {
fmt.Println(err)
os.Exit(1)
}
func parseArgs(c *cli.Context) ([2]string, string) {
// Well defined rectangle
if len(c.Args()) < 2 {
bailout(errors.New("Incorrect point definition: Define points like this '10,10 20,34'"))
cli.ShowAppHelp(c)
}
// Output file
var outfile string
if len(c.Args()) < 3 {
outfile := fmt.Sprintf("__%s_%s.png", c.Args()[0], c.Args()[1])
fmt.Printf("Output filename not specified using %s", outfile)
} else {
outfile = c.Args()[2]
}
return [2]string{c.Args()[0], c.Args()[1]}, outfile
}
func parseFlags(c *cli.Context) (int, string) {
var z int
if c.Int("z") != 0 {
z = c.Int("z")
} else {
bailout(errors.New("Missing z"))
cli.ShowAppHelp(c)
z = 0
}
host := "openstreetmap"
return z, host
}
/**
* Create temp dir and go there
*/
func initTemp() string {
temp, err := ioutil.TempDir("", "mapTiles")
if err != nil {
bailout(err)
}
os.Chdir(temp)
return temp
}