Implement fetaure request issue #17

mtseeder and mtwebmapper got an option to set the background color where no nodes are generated, yet.
This commit is contained in:
Sascha L. Teichmann
2016-04-23 16:45:33 +02:00
parent 0030f7bc02
commit 0db9b519a6
10 changed files with 130 additions and 45 deletions

View File

@ -5,6 +5,7 @@
package main
import (
"image/color"
"log"
"os"
"path/filepath"
@ -39,7 +40,7 @@ func createBaseLevel(
address string,
xMin, yMin, zMin, xMax, yMax, zMax int,
transparent bool, transparentDim float32,
colorsFile, outDir string,
colorsFile string, bg color.RGBA, outDir string,
numWorkers int) (err error) {
var colors *common.Colors
@ -65,7 +66,7 @@ func createBaseLevel(
}
done.Add(1)
btc := common.NewBaseTileCreator(
client, colors,
client, colors, bg,
int16(yMin), int16(yMax),
transparent, baseDir, false)
go createTiles(btc, jobs, &done)

View File

@ -7,6 +7,7 @@ package main
import (
"flag"
"fmt"
"image/color"
"log"
"bitbucket.org/s_l_teichmann/mtsatellite/common"
@ -19,6 +20,7 @@ func main() {
xMin, yMin, zMin int
xMax, yMax, zMax int
colorsFile string
bgColor string
outDir string
numWorkers int
skipBaseLevel bool
@ -28,6 +30,8 @@ func main() {
version bool
)
defaultBgColor := common.ColorToHex(common.BackgroundColor)
flag.IntVar(&port, "port", 6379, "port to of mtredisalize server")
flag.IntVar(&port, "p", 6379, "port to of mtredisalize server (shorthand)")
flag.StringVar(&host, "host", "localhost", "host to mtredisalize server")
@ -38,6 +42,8 @@ func main() {
flag.IntVar(&zMin, "zmin", -1933, "z min of the area to tile")
flag.IntVar(&zMax, "zmax", 1932, "z max of the area to tile")
flag.StringVar(&colorsFile, "colors", "colors.txt", "definition of colors")
flag.StringVar(&bgColor, "background", defaultBgColor, "background color")
flag.StringVar(&bgColor, "bg", defaultBgColor, "background color (shorthand)")
flag.StringVar(&outDir, "output-dir", "map", "directory with the resulting image tree")
flag.StringVar(&outDir, "o", "map", "directory with the resulting image tree")
flag.IntVar(&numWorkers, "workers", 1, "number of workers")
@ -62,6 +68,13 @@ func main() {
common.PrintVersionAndExit()
}
var bg color.RGBA
var err error
if bg, err = common.ParseColor(bgColor); err != nil {
log.Printf("WARN: Cannot parse background color '%s': %s\n", bgColor, err)
bg = common.BackgroundColor
}
if !skipBaseLevel {
td := common.Clamp32f(float32(transparentDim/100.0), 0.0, 1.0)
address := fmt.Sprintf("%s:%d", host, port)
@ -69,14 +82,15 @@ func main() {
address,
xMin, yMin, zMin, xMax, yMax, zMax,
transparent, td,
colorsFile,
colorsFile, bg,
outDir,
numWorkers); err != nil {
log.Fatalf("Creating base level tiles failed: %s", err)
}
}
if !skipPyramid {
if err := createPyramid(outDir, numWorkers); err != nil {
pc := pyramidCreator{numWorkers: numWorkers, outDir: outDir, bg: bg}
if err := pc.create(); err != nil {
log.Fatalf("Creating pyramid tiles failed: %s", err)
}
}

View File

@ -6,6 +6,7 @@ package main
import (
"image"
"image/color"
"image/draw"
"io/ioutil"
"log"
@ -21,6 +22,12 @@ import (
"github.com/bamiaux/rez"
)
type pyramidCreator struct {
numWorkers int
outDir string
bg color.RGBA
}
func findMaxDir(files []os.FileInfo) (min, max int) {
min, max = math.MaxInt32, math.MinInt32
for _, file := range files {
@ -64,7 +71,10 @@ type pyramidJob struct {
dst string
}
func createParentLevel(oldDir string, jobs chan pyramidJob) (newDir string, err error) {
func (pc *pyramidCreator) createParentLevel(
oldDir string,
jobs chan pyramidJob) (newDir string, err error) {
oldName := filepath.Base(oldDir)
var oldLevel int
@ -155,11 +165,14 @@ var dps = [4]image.Point{
image.Pt(256, 256),
image.Pt(256, 0)}
func fuseTile(scratch, resized *image.RGBA, conv rez.Converter, job *pyramidJob) error {
func (pc *pyramidCreator) fuseTile(
scratch, resized *image.RGBA,
conv rez.Converter,
job *pyramidJob) error {
for i, path := range job.src {
img := common.LoadPNG(path)
img := common.LoadPNG(path, pc.bg)
sr := clipRect(img.Bounds())
r := sr.Sub(sr.Min).Add(dps[i])
@ -176,7 +189,7 @@ func fuseTile(scratch, resized *image.RGBA, conv rez.Converter, job *pyramidJob)
return common.SaveAsPNG(job.dst, resized)
}
func fuseTiles(jobs chan pyramidJob, done *sync.WaitGroup) {
func (pc *pyramidCreator) fuseTiles(jobs chan pyramidJob, done *sync.WaitGroup) {
defer done.Done()
scratch := image.NewRGBA(image.Rect(0, 0, 512, 512))
resized := image.NewRGBA(image.Rect(0, 0, 256, 256))
@ -194,41 +207,41 @@ func fuseTiles(jobs chan pyramidJob, done *sync.WaitGroup) {
}
for job := range jobs {
if err := fuseTile(scratch, resized, conv, &job); err != nil {
if err := pc.fuseTile(scratch, resized, conv, &job); err != nil {
log.Printf("WARN: Writing image failed: %s\n", err)
}
}
}
func createPyramid(outDir string, numWorker int) (err error) {
func (pc *pyramidCreator) create() (err error) {
for oldDir := filepath.Join(outDir, baseLevelDir); oldDir != ""; {
if oldDir, err = createLevel(oldDir, numWorker); err != nil {
for oldDir := filepath.Join(pc.outDir, baseLevelDir); oldDir != ""; {
if oldDir, err = pc.createLevel(oldDir); err != nil {
return
}
}
return
}
func createLevel(oldDir string, numWorker int) (newDir string, err error) {
func (pc *pyramidCreator) createLevel(oldDir string) (string, error) {
jobs := make(chan pyramidJob)
var done sync.WaitGroup
for i := 0; i < numWorker; i++ {
for i := 0; i < pc.numWorkers; i++ {
done.Add(1)
go fuseTiles(jobs, &done)
go pc.fuseTiles(jobs, &done)
}
newDir, err = createParentLevel(oldDir, jobs)
newDir, err := pc.createParentLevel(oldDir, jobs)
close(jobs)
if err != nil {
return
return newDir, err
}
done.Wait()
return
return newDir, err
}