int process(char *fname, int components, int z_lookup, unsigned char *startbuf, unsigned char *endbuf, int z_draw, int x_draw, int y_draw, struct graphics *gc, int mapbits, int metabits, int dump, int gps, struct color_range *colors, int xoff, int yoff) { int bytes = bytesfor(mapbits, metabits, components, z_lookup); int ret = 0; char fn[strlen(fname) + 1 + 5 + 1 + 5 + 1]; struct tilecontext tc; tc.z = z_draw; tc.x = x_draw; tc.y = y_draw; tc.xoff = xoff; tc.yoff = yoff; if (components == 1) { sprintf(fn, "%s/1,0", fname); } else { sprintf(fn, "%s/%d,%d", fname, components, z_lookup); } int fd = open(fn, O_RDONLY); if (fd < 0) { // perror(fn); return ret; } struct stat st; if (fstat(fd, &st) < 0) { perror("stat"); exit(EXIT_FAILURE); } unsigned char *map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); if (map == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } gSortBytes = bytes; unsigned char *start = search(startbuf, map, st.st_size / bytes, bytes, bufcmp); unsigned char *end = search(endbuf, map, st.st_size / bytes, bytes, bufcmp); end += bytes; // points to the last value in range; need the one after that if (memcmp(start, startbuf, bytes) < 0) { start += bytes; // if not exact match, points to element before match } int step = 1; double brush = 1; double thick = line_thick; double bright1; if (components == 1) { bright1 = dot_bright; if (z_draw > dot_base) { step = 1; brush = exp(log(2.0) * (z_draw - dot_base)); bright1 *= exp(log(dot_ramp) * (z_draw - dot_base)); } else { step = floor(exp(log(exponent) * (dot_base - z_draw)) + .5); bright1 *= exp(log(dot_ramp) * (z_draw - dot_base)); bright1 = bright1 * step / (1 << (dot_base - z_draw)); } bright1 /= point_size; brush *= point_size; } else { bright1 = dot_bright * line_per_dot / line_thick; if (line_ramp >= 1) { thick *= exp(log(line_ramp) * (z_draw - dot_base)); bright1 *= exp(log(dot_ramp / line_ramp) * (z_draw - dot_base)); } else { bright1 *= exp(log(dot_ramp) * (z_draw - dot_base)); } } if (mercator >= 0) { double lat, lon; tile2latlon((x_draw + .5) * (1LL << (32 - z_draw)), (y_draw + .5) * (1LL << (32 - z_draw)), 32, &lat, &lon); double rat = cos(lat * M_PI / 180); double base = cos(mercator * M_PI / 180); brush /= rat * rat / (base * base); } if (dump) { step = 1; } else { // Align to step size so each zoom is a superset of the previous start = (start - map + (step * bytes - 1)) / (step * bytes) * (step * bytes) + map; } double size = cloudsize(z_draw, x_draw, y_draw); int innerstep = 1; long long todo = 0; size *= tilesize; // convert to pixels if (circle > 0) { // An additional 4 zoom levels without skipping // XXX Why 4? if (step > 1 && size > .0625) { innerstep = step; step = 1; } } const double b = brush * (tilesize / 256.0) * (tilesize / 256.0); for (; start < end; start += step * bytes) { unsigned int x[components], y[components]; double xd[components], yd[components]; int k; unsigned long long meta = 0; buf2xys(start, mapbits, metabits, z_lookup, components, x, y, &meta); if (meta > maxmeta) { continue; } if (!dump && z_draw >= mapbits / 2 - 8) { // Add noise below the bottom of the file resolution // so that it looks less gridded when overzoomed int j; for (j = 0; j < components; j++) { int noisebits = 32 - mapbits / 2; int i; for (i = 0; i < noisebits; i++) { x[j] |= ((y[j] >> (2 * noisebits - 1 - i)) & 1) << i; y[j] |= ((x[j] >> (2 * noisebits - 1 - i)) & 1) << i; } } } double hue = -1; if (metabits > 0 && colors->active) { hue = (((double) meta - colors->meta1) / (colors->meta2 - colors->meta1) * (colors->hue2 - colors->hue1) + colors->hue1) / 360; if (hue < -2) { hue = -1; } else { while (hue < 0) { hue++; } while (hue > 1) { hue--; } } } double bright = bright1; double bb = b; if (metabright) { bright *= meta; } if (metabrush) { bb = bb * meta; } for (k = 0; k < components; k++) { wxy2fxy(x[k], y[k], &xd[k], &yd[k], z_draw, x_draw, y_draw); } if (dump) { int should = 0; if (components == 1) { should = 1; } else { for (k = 1; k < components; k++) { double x1 = xd[k - 1]; double y1 = yd[k - 1]; double x2 = xd[k]; double y2 = yd[k]; if (clip(&x1, &y1, &x2, &y2, 0, 0, 1, 1)) { should = 1; break; } } } if (should) { dump_out(dump, x, y, components, metabits, meta); } } else if (components == 1) { if (!antialias) { xd[0] = ((int) (xd[0] * tilesize) + .5) / tilesize; yd[0] = ((int) (yd[0] * tilesize) + .5) / tilesize; } if (circle > 0) { if (size < .5) { if (bb <= 1) { drawPixel((xd[0] * tilesize - .5) + xoff, (yd[0] * tilesize - .5) + yoff, gc, bright * bb * meta / innerstep, hue, meta, &tc); } else { drawBrush((xd[0] * tilesize) + xoff, (yd[0] * tilesize) + yoff, gc, bright * meta / innerstep, bb, hue, meta, gaussian, &tc); ret = 1; } } else { double xc = (xd[0] * tilesize) + xoff; double yc = (yd[0] * tilesize) + yoff; if (xc + size >= 0 && yc + size >= 0 && xc - size <= tilesize && yc - size <= tilesize) { srand(x[0] * 37 + y[0]); for (todo += meta; todo > 0; todo -= innerstep) { double r = sqrt(((double) (rand() & (INT_MAX - 1))) / (INT_MAX)); double ang = ((double) (rand() & (INT_MAX - 1))) / (INT_MAX) * 2 * M_PI; double xp = xc + size * r * cos(ang); double yp = yc + size * r * sin(ang); if (bb <= 1) { drawPixel(xp - .5, yp - .5, gc, bright * bb, hue, meta, &tc); } else { drawBrush(xp, yp, gc, bright, bb, hue, meta, gaussian, &tc); ret = 1; } } } } } else { if (bb <= 1) { drawPixel((xd[0] * tilesize - .5) + xoff, (yd[0] * tilesize - .5) + yoff, gc, bright * bb, hue, meta, &tc); } else { drawBrush((xd[0] * tilesize) + xoff, (yd[0] * tilesize) + yoff, gc, bright, bb, hue, meta, gaussian, &tc); ret = 1; } } } else { for (k = 1; k < components; k++) { double bright1 = bright; long long xk1 = x[k - 1]; long long xk = x[k]; if (gps) { double xdist = (long long) x[k] - (long long) x[k - 1]; double ydist = (long long) y[k] - (long long) y[k - 1]; double dist = sqrt(xdist * xdist + ydist * ydist); double min = gps_dist; min = min * exp(log(gps_ramp) * (gps_base - z_draw)); if (dist > min) { bright1 /= (dist / min); } if (bright1 < .0025) { continue; } } double thick1 = thick * tilesize / 256.0; if (xk - xk1 >= (1LL << 31)) { wxy2fxy(xk - (1LL << 32), y[k], &xd[k], &yd[k], z_draw, x_draw, y_draw); drawClip(xd[k - 1] * tilesize + xoff, yd[k - 1] * tilesize + yoff, xd[k] * tilesize + xoff, yd[k] * tilesize + yoff, gc, bright1, hue, meta, antialias, thick1, &tc); wxy2fxy(x[k], y[k], &xd[k], &yd[k], z_draw, x_draw, y_draw); wxy2fxy(xk1 + (1LL << 32), y[k - 1], &xd[k - 1], &yd[k - 1], z_draw, x_draw, y_draw); drawClip(xd[k - 1] * tilesize + xoff, yd[k - 1] * tilesize + yoff, xd[k] * tilesize + xoff, yd[k] * tilesize + yoff, gc, bright1, hue, meta, antialias, thick1, &tc); wxy2fxy(x[k - 1], y[k - 1], &xd[k - 1], &yd[k - 1], z_draw, x_draw, y_draw); } else if (xk1 - xk >= (1LL << 31)) { wxy2fxy(xk1 - (1LL << 32), y[k - 1], &xd[k - 1], &yd[k - 1], z_draw, x_draw, y_draw); drawClip(xd[k - 1] * tilesize + xoff, yd[k - 1] * tilesize + yoff, xd[k] * tilesize + xoff, yd[k] * tilesize + yoff, gc, bright1, hue, meta, antialias, thick1, &tc); wxy2fxy(x[k - 1], y[k - 1], &xd[k - 1], &yd[k - 1], z_draw, x_draw, y_draw); wxy2fxy(xk + (1LL << 32), y[k], &xd[k], &yd[k], z_draw, x_draw, y_draw); drawClip(xd[k - 1] * tilesize + xoff, yd[k - 1] * tilesize + yoff, xd[k] * tilesize + xoff, yd[k] * tilesize + yoff, gc, bright1, hue, meta, antialias, thick1, &tc); wxy2fxy(x[k], y[k], &xd[k], &yd[k], z_draw, x_draw, y_draw); } else { drawClip(xd[k - 1] * tilesize + xoff, yd[k - 1] * tilesize + yoff, xd[k] * tilesize + xoff, yd[k] * tilesize + yoff, gc, bright1, hue, meta, antialias, thick1, &tc); } } } }
int process(char *fname, int components, int z_lookup, unsigned char *startbuf, unsigned char *endbuf, int z_draw, int x_draw, int y_draw, double *image, double *cx, double *cy, int mapbits, int metabits, int dump, int gps, int colors) { int bytes = bytesfor(mapbits, metabits, components, z_lookup); int ret = 0; char fn[strlen(fname) + 1 + 5 + 1 + 5 + 1]; if (components == 1) { sprintf(fn, "%s/1,0", fname); } else { sprintf(fn, "%s/%d,%d", fname, components, z_lookup); } int fd = open(fn, O_RDONLY); if (fd < 0) { perror(fn); return ret; } struct stat st; if (fstat(fd, &st) < 0) { perror("stat"); exit(EXIT_FAILURE); } unsigned char *map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); if (map == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } gSortBytes = bytes; unsigned char *start = search(startbuf, map, st.st_size / bytes, bytes, bufcmp); unsigned char *end = search(endbuf, map, st.st_size / bytes, bytes, bufcmp); end += bytes; // points to the last value in range; need the one after that if (memcmp(start, startbuf, bytes) < 0) { start += bytes; // if not exact match, points to element before match } int step = 1; double brush = 1; double bright1; if (components == 1) { bright1 = dot_bright; if (z_draw > dot_base) { step = 1; brush = 1 << (multiplier * (z_draw - dot_base)); } else { step = 1 << (multiplier * (dot_base - z_draw)); } bright1 *= exp(log(dot_ramp) * (z_draw - dot_base)); } else { bright1 = dot_bright * line_per_dot; bright1 *= exp(log(dot_ramp) * (z_draw - dot_base)); } if (dump) { step = 1; } else { // Align to step size so each zoom is a superset of the previous start = (start - map) / (step * bytes) * (step * bytes) + map; } for (; start < end; start += step * bytes) { unsigned int x[components], y[components]; double xd[components], yd[components]; int k; unsigned int meta = 0; buf2xys(start, mapbits, metabits, z_lookup, components, x, y, &meta); if (!dump && z_draw >= mapbits / 2 - 8) { // Add noise below the bottom of the file resolution // so that it looks less gridded when overzoomed int j; for (j = 0; j < components; j++) { int noisebits = 32 - mapbits / 2; int i; for (i = 0; i < noisebits; i++) { x[j] |= ((y[j] >> (2 * noisebits - 1 - i)) & 1) << i; y[j] |= ((x[j] >> (2 * noisebits - 1 - i)) & 1) << i; } } } double hue = -1; if (metabits > 0 && colors > 0) { hue = (double) meta / colors; } double bright = bright1; if (mercator >= 0) { double lat, lon; tile2latlon(x[0], y[0], 32, &lat, &lon); double rat = cos(lat * M_PI / 180); double base = cos(mercator * M_PI / 180); bright /= rat * rat / (base * base); } for (k = 0; k < components; k++) { wxy2fxy(x[k], y[k], &xd[k], &yd[k], z_draw, x_draw, y_draw); } if (dump) { int should = 0; if (components == 1) { should = 1; } else { for (k = 1; k < components; k++) { if (drawClip(xd[k - 1], yd[k - 1], xd[k], yd[k], NULL, NULL, NULL, 0, 0, 0)) { should = 1; break; } } } if (should) { for (k = 0; k < components; k++) { double lat, lon; tile2latlon(x[k], y[k], 32, &lat, &lon); printf("%lf,%lf ", lat, lon); } if (metabits != 0) { printf("%d:%d ", metabits, meta); } printf("// "); for (k = 0; k < components; k++) { printf("%08x %08x ", x[k], y[k]); } printf("\n"); } } else if (components == 1) { if (!antialias) { xd[0] = (int) xd[0] + .5; yd[0] = (int) yd[0] + .5; } if (brush <= 1) { drawPixel(xd[0] - .5, yd[0] - .5, image, cx, cy, bright * brush, hue); } else { drawBrush(xd[0], yd[0], image, cx, cy, bright, brush, hue); ret = 1; } } else { for (k = 1; k < components; k++) { double bright1 = bright; long long xk1 = x[k - 1]; long long xk = x[k]; if (gps) { double xdist = (long long) x[k] - (long long) x[k - 1]; double ydist = (long long) y[k] - (long long) y[k - 1]; double dist = sqrt(xdist * xdist + ydist * ydist); double min = gps_dist; min = min * exp(log(gps_ramp) * (gps_base - z_draw)); if (dist > min) { bright1 /= (dist / min); } if (bright1 < .0025) { continue; } } if (xk - xk1 >= (1LL << 31)) { wxy2fxy(xk - (1LL << 32), y[k], &xd[k], &yd[k], z_draw, x_draw, y_draw); drawClip(xd[k - 1], yd[k - 1], xd[k], yd[k], image, cx, cy, bright1, hue, antialias); wxy2fxy(x[k], y[k], &xd[k], &yd[k], z_draw, x_draw, y_draw); wxy2fxy(xk1 + (1LL << 32), y[k - 1], &xd[k - 1], &yd[k - 1], z_draw, x_draw, y_draw); drawClip(xd[k - 1], yd[k - 1], xd[k], yd[k], image, cx, cy, bright1, hue, antialias); wxy2fxy(x[k - 1], y[k - 1], &xd[k - 1], &yd[k - 1], z_draw, x_draw, y_draw); } else if (xk1 - xk >= (1LL << 31)) { wxy2fxy(xk1 - (1LL << 32), y[k - 1], &xd[k - 1], &yd[k - 1], z_draw, x_draw, y_draw); drawClip(xd[k - 1], yd[k - 1], xd[k], yd[k], image, cx, cy, bright1, hue, antialias); wxy2fxy(x[k - 1], y[k - 1], &xd[k - 1], &yd[k - 1], z_draw, x_draw, y_draw); wxy2fxy(xk + (1LL << 32), y[k], &xd[k], &yd[k], z_draw, x_draw, y_draw); drawClip(xd[k - 1], yd[k - 1], xd[k], yd[k], image, cx, cy, bright1, hue, antialias); wxy2fxy(x[k], y[k], &xd[k], &yd[k], z_draw, x_draw, y_draw); } else { drawClip(xd[k - 1], yd[k - 1], xd[k], yd[k], image, cx, cy, bright1, hue, antialias); } } } }