mirror of
https://github.com/consbio/mbtileserver.git
synced 2024-09-11 07:15:24 +03:00
ENH: Add auto-detection of tile size and return blank PNG of same size (#155)
This commit is contained in:
parent
85eee9b020
commit
c4e7d1f8b5
@ -7,6 +7,8 @@
|
||||
- added support for specifying host IP address to listen on using the `--host`
|
||||
option (#138).
|
||||
- switched basemaps to [Stamen map tiles](http://maps.stamen.com/) (#148)
|
||||
- added auto-detection of tile size and return blank tile of same size
|
||||
(if available) for image tilesets when tile is not found (#155).
|
||||
|
||||
## 0.8.2
|
||||
|
||||
|
2
go.mod
2
go.mod
@ -1,7 +1,7 @@
|
||||
module github.com/consbio/mbtileserver
|
||||
|
||||
require (
|
||||
github.com/brendan-ward/mbtiles-go v0.1.1-0.20220505234122-e9589dbaa0da
|
||||
github.com/brendan-ward/mbtiles-go v0.1.1-0.20220830154734-a6cb9b848bab
|
||||
github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d // indirect
|
||||
github.com/evalphobia/logrus_sentry v0.8.2
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
|
4
go.sum
4
go.sum
@ -68,8 +68,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/brendan-ward/mbtiles-go v0.1.1-0.20220505234122-e9589dbaa0da h1:UTmXm7fCvJbBnxoewyzAUX/FpA1MSnAagCSqtCom9vY=
|
||||
github.com/brendan-ward/mbtiles-go v0.1.1-0.20220505234122-e9589dbaa0da/go.mod h1:PjU6MOcQtVNQbHT42VnBVLQh4pze1Hy+6AkwRoW4BBY=
|
||||
github.com/brendan-ward/mbtiles-go v0.1.1-0.20220830154734-a6cb9b848bab h1:/+iZRJ5VeHYqgQQtfiAaP6niUH+2zSfox6QetbqB6eI=
|
||||
github.com/brendan-ward/mbtiles-go v0.1.1-0.20220830154734-a6cb9b848bab/go.mod h1:PjU6MOcQtVNQbHT42VnBVLQh4pze1Hy+6AkwRoW4BBY=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d h1:S2NE3iHSwP0XV47EEXL8mWmRdEfGscSJ+7EgePNgt0s=
|
||||
|
@ -421,7 +421,7 @@ func (ts *Tileset) arcgisTileHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if data == nil || len(data) <= 1 {
|
||||
// Return blank PNG for all image types
|
||||
w.Header().Set("Content-Type", "image/png")
|
||||
_, err = w.Write(BlankPNG())
|
||||
_, err = w.Write(BlankPNG(ts.tilesize))
|
||||
|
||||
if err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -1,18 +1,37 @@
|
||||
package handlers
|
||||
|
||||
// BlankPNG returns bytes of a blank PNG, for the request handlers to return
|
||||
// when an image tile is not available.
|
||||
func BlankPNG() []byte {
|
||||
return []byte{
|
||||
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49,
|
||||
0x48, 0x44, 0x52, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x3,
|
||||
0x0, 0x0, 0x0, 0x66, 0xbc, 0x3a, 0x25, 0x0, 0x0, 0x0, 0x3, 0x50, 0x4c,
|
||||
0x54, 0x45, 0x0, 0x0, 0x0, 0xa7, 0x7a, 0x3d, 0xda, 0x0, 0x0, 0x0, 0x1,
|
||||
0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0, 0x0, 0x0,
|
||||
0x1f, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xed, 0xc1, 0x1, 0xd, 0x0,
|
||||
0x0, 0x0, 0xc2, 0x20, 0xfb, 0xa7, 0x36, 0xc7, 0x37, 0x60, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x7, 0x21, 0x0, 0x0, 0x1, 0xa7,
|
||||
0x57, 0x29, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae,
|
||||
0x42, 0x60, 0x82,
|
||||
// BlankPNG returns bytes of a blank PNG of the requested size, falling back to
|
||||
// 256px if a suitable size is not available.
|
||||
// Used for the request handlers to return when an image tile is not available.
|
||||
// Images created with https://png-pixel.com/ then minified using tinypng.com
|
||||
func BlankPNG(tilesize uint32) []byte {
|
||||
switch tilesize {
|
||||
case 512:
|
||||
return []byte{
|
||||
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd,
|
||||
0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1,
|
||||
0x3, 0x0, 0x0, 0x0, 0xce, 0xb6, 0x46, 0xb9, 0x0, 0x0, 0x0, 0x3, 0x50,
|
||||
0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xa7, 0x7a, 0x3d, 0xda, 0x0, 0x0,
|
||||
0x0, 0x1, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0,
|
||||
0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xc1, 0x1,
|
||||
0x1, 0x0, 0x0, 0x0, 0x82, 0xa0, 0xfe, 0xaf, 0x6e, 0x88, 0xc0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0xe2, 0xe, 0x82, 0x0, 0x0, 0x1, 0x1, 0xf5, 0x37, 0x5e,
|
||||
0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
|
||||
}
|
||||
default: // 256
|
||||
return []byte{
|
||||
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd,
|
||||
0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1,
|
||||
0x3, 0x0, 0x0, 0x0, 0x66, 0xbc, 0x3a, 0x25, 0x0, 0x0, 0x0, 0x3, 0x50,
|
||||
0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xa7, 0x7a, 0x3d, 0xda, 0x0, 0x0,
|
||||
0x0, 0x1, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0,
|
||||
0x0, 0x0, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xed, 0xc1, 0x1,
|
||||
0xd, 0x0, 0x0, 0x0, 0xc2, 0x20, 0xfb, 0xa7, 0x36, 0xc7, 0x37, 0x60,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0x7, 0x21, 0x0, 0x0,
|
||||
0x1, 0xa7, 0x57, 0x29, 0xd7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e,
|
||||
0x44, 0xae, 0x42, 0x60, 0x82,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,35 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_BlankPNG(t *testing.T) {
|
||||
blankPNG := BlankPNG()
|
||||
b64 := base64.StdEncoding.EncodeToString(blankPNG)
|
||||
expected := "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAB9JREFUaN7twQENAAAAwiD7pzbHN2AAAAAAAAAAAHEHIQAAAadXKdcAAAAASUVORK5CYII="
|
||||
if b64 != expected {
|
||||
t.Error("BlankPNG returned unexpected value (base64):", b64)
|
||||
tests := []struct {
|
||||
tilesize uint32
|
||||
data string
|
||||
}{
|
||||
{
|
||||
// tilesize not detected, defaults to 256
|
||||
tilesize: 0, data: "89504e470d0a1a0a0000000d494844520000010000000100010300000066bc3a2500000003504c5445000000a77a3dda0000000174524e530040e6d8660000001f4944415468deedc1010d000000c220fba736c737600000000000000000710721000001a75729d70000000049454e44ae426082",
|
||||
},
|
||||
{
|
||||
// not available, defaults to 256
|
||||
tilesize: 128, data: "89504e470d0a1a0a0000000d494844520000010000000100010300000066bc3a2500000003504c5445000000a77a3dda0000000174524e530040e6d8660000001f4944415468deedc1010d000000c220fba736c737600000000000000000710721000001a75729d70000000049454e44ae426082",
|
||||
},
|
||||
{
|
||||
tilesize: 256, data: "89504e470d0a1a0a0000000d494844520000010000000100010300000066bc3a2500000003504c5445000000a77a3dda0000000174524e530040e6d8660000001f4944415468deedc1010d000000c220fba736c737600000000000000000710721000001a75729d70000000049454e44ae426082",
|
||||
},
|
||||
{
|
||||
tilesize: 512, data: "89504e470d0a1a0a0000000d4948445200000200000002000103000000ceb646b900000003504c5445000000a77a3dda0000000174524e530040e6d866000000364944415478daedc1010100000082a0feaf6e88c00000000000000000000000000000000000000000000000000000000000000000e20e8200000101f5375e0000000049454e44ae426082",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
blankPNG := hex.EncodeToString(BlankPNG(tc.tilesize))
|
||||
if blankPNG != tc.data {
|
||||
t.Error("BlankPNG returned unexpected value for size ", tc.tilesize, " :", blankPNG)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ type Tileset struct {
|
||||
id string
|
||||
name string
|
||||
tileformat mbtiles.TileFormat
|
||||
tilesize uint32
|
||||
published bool
|
||||
locked bool
|
||||
router *http.ServeMux
|
||||
@ -51,6 +52,7 @@ func newTileset(svc *ServiceSet, filename, id, path string) (*Tileset, error) {
|
||||
id: id,
|
||||
name: name,
|
||||
tileformat: db.GetTileFormat(),
|
||||
tilesize: db.GetTileSize(),
|
||||
published: true,
|
||||
}
|
||||
|
||||
@ -136,6 +138,10 @@ func (ts *Tileset) TileJSON(svcURL string, query string) (map[string]interface{}
|
||||
"name": ts.name,
|
||||
}
|
||||
|
||||
if ts.tilesize > 0 {
|
||||
out["tilesize"] = ts.tilesize
|
||||
}
|
||||
|
||||
metadata, err := db.ReadMetadata()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -213,7 +219,7 @@ func (ts *Tileset) tileHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if ts == nil || !ts.published {
|
||||
// In order to not break any requests from when this tileset was published
|
||||
// return the appropriate not found handler for the original tile format.
|
||||
tileNotFoundHandler(w, r, ts.tileformat)
|
||||
tileNotFoundHandler(w, r, ts.tileformat, ts.tilesize)
|
||||
return
|
||||
}
|
||||
|
||||
@ -249,7 +255,7 @@ func (ts *Tileset) tileHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
if data == nil || len(data) <= 1 {
|
||||
tileNotFoundHandler(w, r, ts.tileformat)
|
||||
tileNotFoundHandler(w, r, ts.tileformat, ts.tilesize)
|
||||
return
|
||||
}
|
||||
|
||||
@ -322,13 +328,13 @@ func (ts *Tileset) previewHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// tileNotFoundHandler is an http.HandlerFunc that writes the default response
|
||||
// for a non-existing tile of type f to w
|
||||
func tileNotFoundHandler(w http.ResponseWriter, r *http.Request, f mbtiles.TileFormat) {
|
||||
func tileNotFoundHandler(w http.ResponseWriter, r *http.Request, f mbtiles.TileFormat, tilesize uint32) {
|
||||
switch f {
|
||||
case mbtiles.PNG, mbtiles.JPG, mbtiles.WEBP:
|
||||
// Return blank PNG for all image types
|
||||
w.Header().Set("Content-Type", "image/png")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(BlankPNG())
|
||||
w.Write(BlankPNG(tilesize))
|
||||
case mbtiles.PBF:
|
||||
// Return 204
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
|
Loading…
Reference in New Issue
Block a user