Skip to content

Commit

Permalink
add show specific tile to show [#21]
Browse files Browse the repository at this point in the history
  • Loading branch information
bdon committed Oct 14, 2022
1 parent 82c42cd commit 971ddd6
Showing 1 changed file with 81 additions and 29 deletions.
110 changes: 81 additions & 29 deletions pmtiles/show.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
package pmtiles

import (
"bytes"
"context"
"flag"
"fmt"
"github.com/dustin/go-humanize"
"gocloud.dev/blob"
"io"
"log"
"os"
"strconv"
)

func Show(logger *log.Logger, args []string) error {
cmd := flag.NewFlagSet("upload", flag.ExitOnError)
cmd := flag.NewFlagSet("show", flag.ExitOnError)
cmd.Parse(args)
bucketURL := cmd.Arg(0)
file := cmd.Arg(1)
arg_z := cmd.Arg(2)
arg_x := cmd.Arg(3)
arg_y := cmd.Arg(4)

if bucketURL == "" || file == "" {
return fmt.Errorf("USAGE: show BUCKET_URL KEY")
}

ctx := context.Background()
bucket, err := blob.OpenBucket(ctx, bucketURL)
Expand All @@ -35,35 +45,77 @@ func Show(logger *log.Logger, args []string) error {
r.Close()

header := deserialize_header(b[0:HEADERV3_LEN_BYTES])
var tile_type string
switch header.TileType {
case Mvt:
tile_type = "Vector Protobuf (MVT)"
case Png:
tile_type = "Raster PNG"
case Jpeg:
tile_type = "Raster Jpeg"
case Webp:
tile_type = "Raster WebP"
default:
tile_type = "Unknown"
}
fmt.Printf("total size: %s\n", humanize.Bytes(uint64(r.Size())))
fmt.Printf("tile type: %s\n", tile_type)
fmt.Printf("bounds: %f,%f %f,%f\n", float64(header.MinLonE7)/10000000, float64(header.MinLatE7)/10000000, float64(header.MaxLonE7)/10000000, float64(header.MaxLatE7)/10000000)
fmt.Printf("min zoom: %d\n", header.MinZoom)
fmt.Printf("max zoom: %d\n", header.MaxZoom)
fmt.Printf("center: %f,%f\n", float64(header.CenterLonE7)/10000000, float64(header.CenterLatE7)/10000000)
fmt.Printf("center zoom: %d\n", header.CenterZoom)
fmt.Printf("addressed tiles count: %d\n", header.AddressedTilesCount)
fmt.Printf("tile entries count: %d\n", header.TileEntriesCount)
fmt.Printf("tile contents count: %d\n", header.TileContentsCount)
fmt.Printf("clustered: %t\n", header.Clustered)

// entries := deserialize_entries(bytes.NewBuffer(b[header.RootOffset:header.RootOffset+header.RootLength]))
// for _, entry := range entries {
// fmt.Println(entry)
// }
if arg_z == "" {
var tile_type string
switch header.TileType {
case Mvt:
tile_type = "Vector Protobuf (MVT)"
case Png:
tile_type = "Raster PNG"
case Jpeg:
tile_type = "Raster Jpeg"
case Webp:
tile_type = "Raster WebP"
default:
tile_type = "Unknown"
}
fmt.Printf("total size: %s\n", humanize.Bytes(uint64(r.Size())))
fmt.Printf("tile type: %s\n", tile_type)
fmt.Printf("bounds: %f,%f %f,%f\n", float64(header.MinLonE7)/10000000, float64(header.MinLatE7)/10000000, float64(header.MaxLonE7)/10000000, float64(header.MaxLatE7)/10000000)
fmt.Printf("min zoom: %d\n", header.MinZoom)
fmt.Printf("max zoom: %d\n", header.MaxZoom)
fmt.Printf("center: %f,%f\n", float64(header.CenterLonE7)/10000000, float64(header.CenterLatE7)/10000000)
fmt.Printf("center zoom: %d\n", header.CenterZoom)
fmt.Printf("addressed tiles count: %d\n", header.AddressedTilesCount)
fmt.Printf("tile entries count: %d\n", header.TileEntriesCount)
fmt.Printf("tile contents count: %d\n", header.TileContentsCount)
fmt.Printf("clustered: %t\n", header.Clustered)
} else {
// write the tile to stdout

z, _ := strconv.ParseUint(arg_z, 10, 8)
x, _ := strconv.ParseUint(arg_x, 10, 32)
y, _ := strconv.ParseUint(arg_y, 10, 32)
tile_id := ZxyToId(uint8(z), uint32(x), uint32(y))

dir_offset := header.RootOffset
dir_length := header.RootLength

for depth := 0; depth <= 3; depth++ {
r, err := bucket.NewRangeReader(ctx, file, int64(dir_offset), int64(dir_length), nil)
if err != nil {
return fmt.Errorf("Network error")
}
defer r.Close()
b, err := io.ReadAll(r)
if err != nil {
return fmt.Errorf("I/O Error")
}
directory := deserialize_entries(bytes.NewBuffer(b))
entry, ok := find_tile(directory, tile_id)
if ok {
if entry.RunLength > 0 {
tile_r, err := bucket.NewRangeReader(ctx, file, int64(header.TileDataOffset+entry.Offset), int64(entry.Length), nil)
if err != nil {
return fmt.Errorf("Network error")
}
defer tile_r.Close()
tile_b, err := io.ReadAll(tile_r)
if err != nil {
return fmt.Errorf("I/O Error")
}
os.Stdout.Write(tile_b)
break
} else {
dir_offset = header.LeafDirectoryOffset + entry.Offset
dir_length = uint64(entry.Length)
}
} else {
fmt.Println("Tile not found in archive.")
return nil
}
}
}
return nil
}

0 comments on commit 971ddd6

Please sign in to comment.