… | |
… | |
206 | |
206 | |
207 | my $torad = (atan2 1,0) / 90; |
207 | my $torad = (atan2 1,0) / 90; |
208 | |
208 | |
209 | my $boxes = int 6378 * 2 * 2 * (atan2 1,0) / $km; # equator radius / cell size |
209 | my $boxes = int 6378 * 2 * 2 * (atan2 1,0) / $km; # equator radius / cell size |
210 | |
210 | |
211 | open my $fh, "<:perlio", $ARGV[0]; |
211 | open my $fh, "<:perlio", $ARGV[0] |
|
|
212 | or die "$ARGV[0]: $!\n"; |
212 | |
213 | |
213 | my @grid; |
214 | my @grid; |
214 | |
215 | |
215 | while (<$fh>) { |
216 | while (<$fh>) { |
216 | my ($lat, $lon, $w, $payload) = $extract->() |
217 | my ($lat, $lon, $w, $payload) = $extract->() |
… | |
… | |
228 | |
229 | |
229 | # we use 16 bit for lat/lon, 8 bi8t for the weight, BER-id, counted name and CC |
230 | # we use 16 bit for lat/lon, 8 bi8t for the weight, BER-id, counted name and CC |
230 | push @{ $grid[$y][$x] }, pack "s< s< C C/a*", $lat * 32767 / 90, $lon * 32767 / 180, $w, $payload; |
231 | push @{ $grid[$y][$x] }, pack "s< s< C C/a*", $lat * 32767 / 90, $lon * 32767 / 180, $w, $payload; |
231 | } |
232 | } |
232 | |
233 | |
233 | my ($max, $sum, $cnt); |
234 | ############################################################################# |
|
|
235 | # write gridded data out |
234 | |
236 | |
235 | open my $cdb, ">", $ARGV[1] |
237 | open my $cdb, ">", $ARGV[1] |
236 | or die; |
238 | or die "$ARGV[1]: $!\n"; |
237 | Geo::LatLon2Place::cdb_make_start fileno $cdb |
239 | Geo::LatLon2Place::cdb_make_start fileno $cdb |
238 | and die "cdb_make_start failure"; |
240 | and die "cdb_make_start failure"; |
239 | |
241 | |
240 | Geo::LatLon2Place::cdb_make_add "", pack "a4VVV", "SRGL", 2, $km, $boxes; |
242 | Geo::LatLon2Place::cdb_make_add "", pack "a4VVVV", "SRGL", 2, $km, $boxes, time; |
241 | |
243 | |
242 | for my $y (0 .. $#grid) { |
244 | ############################################################################# |
|
|
245 | # now we walk the grid using a hilbert curve to increase locality when querying |
|
|
246 | |
|
|
247 | my ($max, $sum, $cnt); # statistics |
|
|
248 | |
|
|
249 | my ($x, $y) = (-1, 0); |
|
|
250 | |
|
|
251 | sub step { # move one step into $_[0] direction: 0 x++, 1 y++, 2 x--, 3 y-- |
|
|
252 | ($_[0] & 1 ? $y : $x) += 1 - ($_[0] & 2); |
|
|
253 | |
|
|
254 | # write cell at $x,$y, if any |
243 | my $r = $grid[$y]; |
255 | my $c = $grid[$y][$x] |
244 | for my $x (0 .. $#$r) { |
256 | or return; |
245 | my $c = $r->[$x] |
|
|
246 | or next; |
|
|
247 | |
257 | |
|
|
258 | undef $grid[$y][$x]; # for paranoia check |
|
|
259 | |
248 | # statistics |
260 | # statistics |
249 | $sum += scalar @$c; |
261 | $sum += scalar @$c; |
250 | $cnt++; |
262 | $cnt++; |
251 | $max = [(scalar @$c), $x, $y] if @$c > $max->[0]; |
263 | $max = [(scalar @$c), $x, $y] if @$c > $max->[0]; |
252 | |
264 | |
253 | Geo::LatLon2Place::cdb_make_add |
265 | Geo::LatLon2Place::cdb_make_add |
254 | +(pack "s< s<", $x, $y), |
266 | +(pack "s< s<", $x, $y), |
255 | +(join "", @$c) |
267 | +(join "", @$c) |
256 | and "cdb_make_add failure"; |
268 | and "cdb_make_add failure"; |
257 | } |
|
|
258 | } |
269 | } |
|
|
270 | |
|
|
271 | sub hilbert; |
|
|
272 | sub hilbert { # order dir rot |
|
|
273 | my $order = $_[0] >> 1 |
|
|
274 | or return; |
|
|
275 | |
|
|
276 | hilbert $order, $_[1] + $_[2], -$_[2]; step $_[1] + $_[2]; |
|
|
277 | hilbert $order, $_[1] , $_[2]; step $_[1] ; |
|
|
278 | hilbert $order, $_[1] , $_[2]; step $_[1] - $_[2]; |
|
|
279 | hilbert $order, $_[1] - $_[2], -$_[2]; |
|
|
280 | } |
|
|
281 | |
|
|
282 | step 0; # move to 0,0 |
|
|
283 | hilbert @grid * 2, 0, 1; |
|
|
284 | |
|
|
285 | # paranoia-check, make sure we wrote out all cells |
|
|
286 | for (@grid) { |
|
|
287 | grep $_, @$_ |
|
|
288 | and die; |
|
|
289 | } |
|
|
290 | |
|
|
291 | ############################################################################# |
259 | |
292 | |
260 | Geo::LatLon2Place::cdb_make_finish |
293 | Geo::LatLon2Place::cdb_make_finish |
261 | and die "cdb_make_finish failed"; |
294 | and die "cdb_make_finish failed"; |
262 | close $cdb; |
295 | close $cdb; |
263 | |
296 | |