Add a C implementation of QuadTile.iterate_tiles_for_area
This commit is contained in:
parent
d49e3b0f09
commit
254fc8ebbc
2 changed files with 127 additions and 26 deletions
|
@ -1,6 +1,60 @@
|
|||
#include "ruby.h"
|
||||
#include "quad_tile.h"
|
||||
|
||||
typedef struct {
|
||||
unsigned int *tilev;
|
||||
unsigned int tilec;
|
||||
} tilelist_t;
|
||||
|
||||
static tilelist_t tilelist_for_area(unsigned int minx, unsigned int miny, unsigned int maxx, unsigned int maxy)
|
||||
{
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
tilelist_t tl;
|
||||
unsigned int maxtilec;
|
||||
|
||||
maxtilec = 256;
|
||||
|
||||
tl.tilev = malloc(maxtilec * sizeof(unsigned int));
|
||||
tl.tilec = 0;
|
||||
|
||||
for (x = minx; x <= maxx; x++)
|
||||
{
|
||||
for (y = miny; y <= maxy; y++)
|
||||
{
|
||||
if (tl.tilec == maxtilec)
|
||||
{
|
||||
maxtilec = maxtilec * 2;
|
||||
|
||||
tl.tilev = realloc(tl.tilev, maxtilec * sizeof(unsigned int));
|
||||
}
|
||||
|
||||
tl.tilev[tl.tilec++] = xy2tile(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return tl;
|
||||
}
|
||||
|
||||
static int tile_compare(const void *ap, const void *bp)
|
||||
{
|
||||
unsigned int a = *(unsigned int *)ap;
|
||||
unsigned int b = *(unsigned int *)bp;
|
||||
|
||||
if (a < b)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (a > b)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE tile_for_point(VALUE self, VALUE lat, VALUE lon)
|
||||
{
|
||||
unsigned int x = lon2x(NUM2DBL(lon));
|
||||
|
@ -15,18 +69,17 @@ static VALUE tiles_for_area(VALUE self, VALUE minlat, VALUE minlon, VALUE maxlat
|
|||
unsigned int maxx = lon2x(NUM2DBL(maxlon));
|
||||
unsigned int miny = lat2y(NUM2DBL(minlat));
|
||||
unsigned int maxy = lat2y(NUM2DBL(maxlat));
|
||||
tilelist_t tl = tilelist_for_area(minx, miny, maxx, maxy);
|
||||
VALUE tiles = rb_ary_new();
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int t;
|
||||
|
||||
for (x = minx; x <= maxx; x++)
|
||||
for (t = 0; t < tl.tilec; t++)
|
||||
{
|
||||
for (y = miny; y <= maxy; y++)
|
||||
{
|
||||
rb_ary_push(tiles, UINT2NUM(xy2tile(x, y)));
|
||||
}
|
||||
rb_ary_push(tiles, UINT2NUM(tl.tilev[tl.tilec]));
|
||||
}
|
||||
|
||||
free(tl.tilev);
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
|
@ -35,6 +88,53 @@ static VALUE tile_for_xy(VALUE self, VALUE x, VALUE y)
|
|||
return UINT2NUM(xy2tile(NUM2UINT(x), NUM2UINT(y)));
|
||||
}
|
||||
|
||||
static VALUE iterate_tiles_for_area(VALUE self, VALUE minlat, VALUE minlon, VALUE maxlat, VALUE maxlon)
|
||||
{
|
||||
unsigned int minx = lon2x(NUM2DBL(minlon));
|
||||
unsigned int maxx = lon2x(NUM2DBL(maxlon));
|
||||
unsigned int miny = lat2y(NUM2DBL(minlat));
|
||||
unsigned int maxy = lat2y(NUM2DBL(maxlat));
|
||||
tilelist_t tl = tilelist_for_area(minx, miny, maxx, maxy);
|
||||
|
||||
if (tl.tilec > 0)
|
||||
{
|
||||
unsigned int first;
|
||||
unsigned int last;
|
||||
unsigned int t;
|
||||
VALUE a = rb_ary_new();
|
||||
|
||||
qsort(tl.tilev, tl.tilec, sizeof(unsigned int), tile_compare);
|
||||
|
||||
first = last = tl.tilev[0];
|
||||
|
||||
for (t = 1; t < tl.tilec; t++)
|
||||
{
|
||||
unsigned int tile = tl.tilev[t];
|
||||
|
||||
if (tile == last + 1)
|
||||
{
|
||||
last = tile;
|
||||
}
|
||||
else
|
||||
{
|
||||
rb_ary_store(a, 0, UINT2NUM(first));
|
||||
rb_ary_store(a, 1, UINT2NUM(last));
|
||||
rb_yield(a);
|
||||
|
||||
first = last = tile;
|
||||
}
|
||||
}
|
||||
|
||||
rb_ary_store(a, 0, UINT2NUM(first));
|
||||
rb_ary_store(a, 1, UINT2NUM(last));
|
||||
rb_yield(a);
|
||||
}
|
||||
|
||||
free(tl.tilev);
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
void Init_quad_tile_so(void)
|
||||
{
|
||||
VALUE m = rb_define_module("QuadTile");
|
||||
|
@ -42,6 +142,7 @@ void Init_quad_tile_so(void)
|
|||
rb_define_module_function(m, "tile_for_point", tile_for_point, 2);
|
||||
rb_define_module_function(m, "tiles_for_area", tiles_for_area, 4);
|
||||
rb_define_module_function(m, "tile_for_xy", tile_for_xy, 2);
|
||||
rb_define_module_function(m, "iterate_tiles_for_area", iterate_tiles_for_area, 4);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue