mirror of
https://bitbucket.org/s_l_teichmann/mtsatellite
synced 2025-06-28 14:16:24 +02:00
mtwebmapper: First version of pyramid tile updater. Needs testing.
This commit is contained in:
@ -8,7 +8,6 @@ import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
@ -129,17 +128,5 @@ func (btc *BaseTileCreator) CreateTile(x, z int16, i, j int) error {
|
||||
return SaveAsPNG(path, image)
|
||||
}
|
||||
|
||||
// Try to make creation of update "atomic" by first writing to tmp file
|
||||
// and rename the tmp file to the original one afterwards.
|
||||
pathTmp := path + "tmp"
|
||||
pathTmpPre := pathTmp
|
||||
tc := 0
|
||||
for _, err := os.Stat(pathTmp); err == nil; _, err = os.Stat(pathTmp) {
|
||||
pathTmp = fmt.Sprintf("%s%d", pathTmpPre, tc)
|
||||
tc++
|
||||
}
|
||||
if err := SaveAsPNG(pathTmp, image); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Rename(pathTmp, path)
|
||||
return SaveAsPNGAtomic(path, image)
|
||||
}
|
||||
|
@ -6,12 +6,35 @@ package common
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"image"
|
||||
"image/png"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var rand uint32
|
||||
var randmu sync.Mutex
|
||||
|
||||
func reseed() uint32 {
|
||||
return uint32(time.Now().UnixNano() + int64(os.Getpid()))
|
||||
}
|
||||
|
||||
func nextSuffix() string {
|
||||
randmu.Lock()
|
||||
r := rand
|
||||
if r == 0 {
|
||||
r = reseed()
|
||||
}
|
||||
r = r*1664525 + 1013904223 // constants from Numerical Recipes
|
||||
rand = r
|
||||
randmu.Unlock()
|
||||
return strconv.Itoa(int(1e9 + r%1e9))[1:]
|
||||
}
|
||||
|
||||
func SaveAsPNG(path string, img image.Image) (err error) {
|
||||
var file *os.File
|
||||
if file, err = os.Create(path); err != nil {
|
||||
@ -24,6 +47,38 @@ func SaveAsPNG(path string, img image.Image) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func tmpName(tmpl string) (string, error) {
|
||||
tmpPre := tmpl + ".tmp"
|
||||
nconflict := 0
|
||||
for i := 0; i < 10000; i++ {
|
||||
tmp := tmpPre + nextSuffix()
|
||||
if _, err := os.Stat(tmp); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return tmp, nil
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
if nconflict++; nconflict > 10 {
|
||||
nconflict = 0
|
||||
rand = reseed()
|
||||
}
|
||||
}
|
||||
return "", errors.New("Cannot create temp name")
|
||||
}
|
||||
|
||||
func SaveAsPNGAtomic(path string, img image.Image) (err error) {
|
||||
|
||||
var tmpPath string
|
||||
if tmpPath, err = tmpName(path); err != nil {
|
||||
return
|
||||
}
|
||||
// Still a bit racy
|
||||
if err = SaveAsPNG(tmpPath, img); err != nil {
|
||||
return
|
||||
}
|
||||
return os.Rename(tmpPath, path)
|
||||
}
|
||||
|
||||
func LoadPNG(path string) image.Image {
|
||||
var err error
|
||||
var file *os.File
|
||||
|
Reference in New Issue
Block a user