shithub: map

ref: a0578c7de4163344d936ea78191a836556495bba
dir: /tile.c/

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include "dat.h"
#include "fns.h"

extern int tilesize;

static double
asinh(double x)
{
	if (isNaN(x))
		x = 1.;
	double s = sqrt(x*x + 1);
	return log(x + s);
}

static int
lon2tilex(double lon, int z, int *offset)
{
	double tile = (lon + 180.0) / 360.0 * (1<<z);
	int t = floor(tile);
	*offset = (tile - t) * tilesize;
	return t;
}

static int
lat2tiley(double lat, int z, int *offset)
{
	double latrad = lat * PI/180.0;
	double tile = (1.0 - asinh(tan(latrad)) / PI) / 2.0 * (1<<z);
	int t = floor(tile);
	*offset = (tile - t) * tilesize;
	return t;
}

static double
tilex2lon(double x, int z)
{
	return x / (double)(1<<z) * 360.0 - 180.0;
}

static double
tiley2lat(double y, int z)
{
	double n = PI - 2.0 * PI * y / (double)(1<<z);
	return 180.0 / PI * atan(0.5 * (exp(n) - exp(-n)));
}

void
tile2gps(double *x, double *y, int z)
{
	if (x) *x = tilex2lon(*x, z);
	if (y) *y = tiley2lat(*y, z);
}

GBundle
getbundle(GPos pos, int z, Point *offset)
{
	GBundle ret;
	if (z < 0)
		z = 0;
	ret.x = lon2tilex(pos.lon, z, &offset->x);
	ret.y = lat2tiley(pos.lat, z, &offset->y);
	ret.z = z;
	debugprint("bundle for %f,%f = %d, %d, %d\n",
		pos.lon, pos.lat, ret.z, ret.x, ret.y);
	return ret;
}