@@ -28,6 +28,7 @@ pub struct PmTilesStreamWriter<W: Write + Seek> {
28
28
29
29
pub ( crate ) trait WriteTo {
30
30
fn write_to < W : Write > ( & self , writer : & mut W ) -> std:: io:: Result < ( ) > ;
31
+
31
32
fn write_compressed_to < W : Write > (
32
33
& self ,
33
34
writer : & mut W ,
@@ -43,6 +44,7 @@ pub(crate) trait WriteTo {
43
44
}
44
45
Ok ( ( ) )
45
46
}
47
+
46
48
fn write_compressed_to_counted < W : Write > (
47
49
& self ,
48
50
writer : & mut Counter < W > ,
@@ -52,6 +54,7 @@ pub(crate) trait WriteTo {
52
54
self . write_compressed_to ( writer, compression) ?;
53
55
Ok ( writer. writer_bytes ( ) - pos)
54
56
}
57
+
55
58
fn compressed_size ( & self , compression : Compression ) -> PmtResult < usize > {
56
59
let mut devnull = Counter :: new ( std:: io:: sink ( ) ) ;
57
60
self . write_compressed_to ( & mut devnull, compression) ?;
@@ -73,6 +76,7 @@ impl PmTilesWriter {
73
76
TileType :: Mvt => Compression :: Gzip ,
74
77
_ => Compression :: None ,
75
78
} ;
79
+ #[ allow( clippy:: excessive_precision, clippy:: unreadable_literal) ]
76
80
let header = Header {
77
81
version : 3 ,
78
82
root_offset : HEADER_SIZE as u64 ,
@@ -93,9 +97,9 @@ impl PmTilesWriter {
93
97
min_zoom : 0 ,
94
98
max_zoom : 22 ,
95
99
min_longitude : -180.0 ,
96
- min_latitude : -85.0 ,
100
+ min_latitude : -85.051129 ,
97
101
max_longitude : 180.0 ,
98
- max_latitude : 85.0 ,
102
+ max_latitude : 85.051129 ,
99
103
center_zoom : 0 ,
100
104
center_longitude : 0.0 ,
101
105
center_latitude : 0.0 ,
@@ -105,30 +109,35 @@ impl PmTilesWriter {
105
109
metadata : "{}" . to_string ( ) ,
106
110
}
107
111
}
112
+
108
113
/// Set the compression for metadata and directories.
109
114
#[ must_use]
110
115
pub fn internal_compression ( mut self , compression : Compression ) -> Self {
111
116
self . header . internal_compression = compression;
112
117
self
113
118
}
119
+
114
120
/// Set the compression for tile data.
115
121
#[ must_use]
116
122
pub fn tile_compression ( mut self , compression : Compression ) -> Self {
117
123
self . header . tile_compression = compression;
118
124
self
119
125
}
126
+
120
127
/// Set the minimum zoom level of the tiles
121
128
#[ must_use]
122
129
pub fn min_zoom ( mut self , level : u8 ) -> Self {
123
130
self . header . min_zoom = level;
124
131
self
125
132
}
133
+
126
134
/// Set the maximum zoom level of the tiles
127
135
#[ must_use]
128
136
pub fn max_zoom ( mut self , level : u8 ) -> Self {
129
137
self . header . max_zoom = level;
130
138
self
131
139
}
140
+
132
141
/// Set the bounds of the tiles
133
142
#[ must_use]
134
143
pub fn bounds ( mut self , min_lon : f32 , min_lat : f32 , max_lon : f32 , max_lat : f32 ) -> Self {
@@ -138,19 +147,22 @@ impl PmTilesWriter {
138
147
self . header . max_longitude = max_lon;
139
148
self
140
149
}
150
+
141
151
/// Set the center zoom level.
142
152
#[ must_use]
143
153
pub fn center_zoom ( mut self , level : u8 ) -> Self {
144
154
self . header . center_zoom = level;
145
155
self
146
156
}
157
+
147
158
/// Set the center position.
148
159
#[ must_use]
149
160
pub fn center ( mut self , lon : f32 , lat : f32 ) -> Self {
150
161
self . header . center_latitude = lat;
151
162
self . header . center_longitude = lon;
152
163
self
153
164
}
165
+
154
166
/// Set the metadata, which must contain a valid JSON object.
155
167
///
156
168
/// If the tile type has a value of MVT Vector Tile, the object must contain a key of `vector_layers` as described in the `TileJSON` 3.0 specification.
@@ -159,6 +171,7 @@ impl PmTilesWriter {
159
171
self . metadata = metadata. to_string ( ) ;
160
172
self
161
173
}
174
+
162
175
/// Create a new `PMTiles` writer.
163
176
pub fn create < W : Write + Seek > ( self , writer : W ) -> PmtResult < PmTilesStreamWriter < W > > {
164
177
let mut out = Counter :: new ( BufWriter :: new ( writer) ) ;
@@ -194,8 +207,10 @@ impl PmTilesWriter {
194
207
Ok ( writer)
195
208
}
196
209
}
210
+
197
211
impl < W : Write + Seek > PmTilesStreamWriter < W > {
198
- /// Add tile to writer
212
+ /// Add tile to writer.
213
+ ///
199
214
/// Tiles are deduplicated and written to output.
200
215
/// `tile_id` should be increasing.
201
216
pub fn add_tile ( & mut self , tile_id : u64 , data : & [ u8 ] ) -> PmtResult < ( ) > {
@@ -215,7 +230,7 @@ impl<W: Write + Seek> PmTilesStreamWriter<W> {
215
230
216
231
self . n_addressed_tiles += 1 ;
217
232
if !is_first
218
- && compare_blobs ( & self . prev_tile_data , data)
233
+ && self . prev_tile_data == data
219
234
&& tile_id == last_entry. tile_id + u64:: from ( last_entry. run_length )
220
235
{
221
236
last_entry. run_length += 1 ;
@@ -285,6 +300,7 @@ impl<W: Write + Seek> PmTilesStreamWriter<W> {
285
300
leaf_size += leaf_size / 5 ; // go-pmtiles: leaf_size *= 1.2
286
301
}
287
302
}
303
+
288
304
fn build_roots_leaves ( & self , leaf_size : usize ) -> PmtResult < ( Directory , usize ) > {
289
305
let mut root_dir = Directory :: with_capacity ( self . entries . len ( ) / leaf_size) ;
290
306
let mut offset = 0 ;
@@ -302,6 +318,7 @@ impl<W: Write + Seek> PmTilesStreamWriter<W> {
302
318
let num_leaves = root_dir. entries ( ) . len ( ) ;
303
319
Ok ( ( root_dir, num_leaves) )
304
320
}
321
+
305
322
fn dir_size ( & self , entries : & [ DirEntry ] ) -> PmtResult < usize > {
306
323
let dir = Directory :: from_entries ( entries) ;
307
324
dir. compressed_size ( self . header . internal_compression )
@@ -333,10 +350,6 @@ impl<W: Write + Seek> PmTilesStreamWriter<W> {
333
350
}
334
351
}
335
352
336
- fn compare_blobs ( a : & [ u8 ] , b : & [ u8 ] ) -> bool {
337
- a. len ( ) == b. len ( ) && a. iter ( ) . zip ( b. iter ( ) ) . all ( |( a, b) | a == b)
338
- }
339
-
340
353
fn into_u32 ( v : usize ) -> PmtResult < u32 > {
341
354
v. try_into ( ) . map_err ( |_| PmtError :: IndexEntryOverflow )
342
355
}
@@ -395,8 +408,14 @@ mod tests {
395
408
assert_eq ! ( header_in. center_zoom, header_out. center_zoom) ;
396
409
assert_eq ! ( header_in. center_latitude, header_out. center_latitude) ;
397
410
assert_eq ! ( header_in. center_longitude, header_out. center_longitude) ;
398
- assert_eq ! ( header_in. min_latitude, header_out. min_latitude) ;
399
- assert_eq ! ( header_in. max_latitude, header_out. max_latitude) ;
411
+ assert_eq ! (
412
+ header_in. min_latitude. round( ) ,
413
+ header_out. min_latitude. round( )
414
+ ) ;
415
+ assert_eq ! (
416
+ header_in. max_latitude. round( ) ,
417
+ header_out. max_latitude. round( )
418
+ ) ;
400
419
assert_eq ! ( header_in. min_longitude, header_out. min_longitude) ;
401
420
assert_eq ! ( header_in. max_longitude, header_out. max_longitude) ;
402
421
assert_eq ! ( header_in. clustered, header_out. clustered) ;
0 commit comments