@@ -6,46 +6,68 @@ import (
66 "os"
77)
88
9+ // A program that creates the smallest meaningful PMTiles archive,
10+ // consisting of a purple square at tile 0,0,0 (the entire earth).
11+ // Uses only two library functions, SerializeHeader and SerializeEntries.
912func main () {
10- PINK := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/D/PwAHAwL/qGeMxAAAAABJRU5ErkJggg=="
11- CYAN := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P//PwAGBAL/VJiKjgAAAABJRU5ErkJggg=="
13+ outfile , _ := os . Create ( "minimal.pmtiles" )
14+ defer outfile . Close ()
1215
13- pink , _ := base64 . StdEncoding . DecodeString ( PINK )
14- cyan , _ := base64 .StdEncoding .DecodeString (CYAN )
16+ // A solid purple PNG with 50% opacity.
17+ png , _ := base64 .StdEncoding .DecodeString ("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mM0NLxTDwADmAG/Djok1gAAAABJRU5ErkJggg==" )
1518
16- outfile , _ := os .Create ("output.pmtiles" )
19+ // Create an entry with TileID=0 (z=0, x=0, y=0), Offset=0, Length=len(png), and RunLength=1.
20+ entries := []pmtiles.EntryV3 {{0 , 0 , uint32 (len (png )), 1 }}
1721
18- var h pmtiles.HeaderV3
19- var entries []pmtiles.EntryV3
20- entries = append (entries , pmtiles.EntryV3 {1 , uint64 (len (cyan )), uint32 (len (pink )), 1 })
21- entries = append (entries , pmtiles.EntryV3 {2 , 0 , uint32 (len (cyan )), 1 })
22+ // Create the bytes of the root directory.
2223 dir := pmtiles .SerializeEntries (entries , pmtiles .NoCompression )
24+
25+ // the JSON metadata is the empty object.
26+ metadata := "{}"
27+
28+ // here we set the data of the header (the first 127 bytes)
29+ var h pmtiles.HeaderV3
2330 h .SpecVersion = 3
24- h .RootOffset = 127
31+
32+ // the root directory follows the header.
33+ h .RootOffset = pmtiles .HeaderV3LenBytes
2534 h .RootLength = uint64 (len (dir ))
26- h .MetadataOffset = uint64 (127 + len (dir ))
27- h .MetadataLength = 2
35+
36+ // the JSON metadata follows the root directory.
37+ h .MetadataOffset = h .RootOffset + uint64 (len (dir ))
38+ h .MetadataLength = uint64 (len (metadata ))
39+
40+ // there are no leaves, but set the offset to the right place and length=0.
2841 h .LeafDirectoryOffset = h .MetadataOffset + h .MetadataLength
2942 h .LeafDirectoryLength = 0
43+
44+ // the tile data follows the JSON metadata.
3045 h .TileDataOffset = h .LeafDirectoryOffset
31- h .TileDataLength = uint64 (len (pink ) + len (cyan ))
32- h .AddressedTilesCount = 2
33- h .TileEntriesCount = 2
34- h .TileContentsCount = 2
35- h .InternalCompression = 1
36- h .TileCompression = 1
37- h .TileType = 2
38- h .MinZoom = 1
39- h .CenterZoom = 1
40- h .MaxZoom = 1
46+ h .TileDataLength = uint64 (len (png ))
47+
48+ // set statistics
49+ h .AddressedTilesCount = 1
50+ h .TileEntriesCount = 1
51+ h .TileContentsCount = 1
52+
53+ // since we store a PNG, the tile data should not be interpreted as compressed.
54+ h .InternalCompression = pmtiles .NoCompression
55+ h .TileCompression = pmtiles .NoCompression
56+ h .TileType = pmtiles .Png
57+
58+ // set the zoom and geographic bounds.
59+ h .MinZoom = 0
60+ h .CenterZoom = 0
61+ h .MaxZoom = 0
4162 h .MinLatE7 = - 85 * 10000000
4263 h .MaxLatE7 = 85 * 10000000
4364 h .MinLonE7 = - 180 * 10000000
4465 h .MaxLonE7 = 180 * 10000000
4566
4667 outfile .Write (pmtiles .SerializeHeader (h ))
68+
69+ // write the directory, JSON metadata and tile data.
4770 outfile .Write (dir )
48- outfile .Write ([]byte ("{}" ))
49- outfile .Write (cyan )
50- outfile .Write (pink )
71+ outfile .Write ([]byte (metadata ))
72+ outfile .Write (png )
5173}
0 commit comments