calculate proper tile position

This commit is contained in:
Konstantin Käfer
2014-01-08 14:32:58 +01:00
parent 7253f808c6
commit 7526d681e2
8 changed files with 165 additions and 77 deletions

View File

@@ -6,17 +6,25 @@
using namespace llmr;
map::map(class platform *platform, class painter *painter)
map::map(class platform *platform)
: platform(platform),
painter(painter),
transform(new class transform()) {
transform(new class transform()),
painter(new class painter(platform, transform)) {
painter->setTransform(transform);
transform->setLonLat(13, 50);
transform->setZoom(3);
tiles.push_back(new class tile(1, 0, 0));
platform->request(tiles.back());
tile *tile = new class tile(0, 0, 0);
tiles.push_back(tile);
platform->request(tile);
tiles.push_back(new class tile(1, 1, 0));
platform->request(tiles.back());
tiles.push_back(new class tile(1, 0, 1));
platform->request(tiles.back());
tiles.push_back(new class tile(1, 1, 1));
platform->request(tiles.back());
}
@@ -24,6 +32,15 @@ map::~map() {
delete transform;
}
void map::setup() {
painter->setup();
}
void map::resize(uint32_t width, uint32_t height) {
transform->width = width;
transform->height = height;
platform->restart();
}
void map::moveBy(double dx, double dy) {
transform->moveBy(dx, dy);
@@ -61,4 +78,4 @@ void map::tileFailed(tile *tile) {
fprintf(stderr, "[%8zx] tile failed to load %d/%d/%d\n",
std::hash<std::thread::id>()(std::this_thread::get_id()),
tile->z, tile->x, tile->y);
}
}

View File

@@ -25,25 +25,20 @@ void tile::setData(uint8_t *data, uint32_t bytes) {
bool tile::parse()
{
fprintf(stderr, "[%8zx] parsing tile\n",
std::hash<std::thread::id>()(std::this_thread::get_id())
);
fprintf(stderr, "[%p] parsing tile...\n", this);
// try {
pbf tile(data, bytes);
while (tile.next()) {
if (tile.tag == 3) { // layer
uint32_t bytes = (uint32_t)tile.varint();
parseLayer(tile.data, bytes);
tile.skipBytes(bytes);
} else {
tile.skip();
}
pbf tile(data, bytes);
while (tile.next()) {
if (tile.tag == 3) { // layer
uint32_t bytes = (uint32_t)tile.varint();
parseLayer(tile.data, bytes);
tile.skipBytes(bytes);
} else {
tile.skip();
}
// } catch (std::exception& ex) {
// std::cerr << ex.what();
// return false;
// }
}
fprintf(stderr, "[%p] parsing tile...done\n", this);
loaded = true;
return true;
@@ -69,15 +64,15 @@ void tile::parseFeature(const uint8_t *data, uint32_t bytes) {
pbf feature(data, bytes);
while (feature.next()) {
if (feature.tag == 1) {
uint32_t id = feature.varint();
/*uint32_t id =*/ feature.varint();
} else if (feature.tag == 2) {
const uint8_t *tag_end = feature.data + feature.varint();
while (feature.data < tag_end) {
uint32_t key = feature.varint();
uint32_t value = feature.varint();
/*uint32_t key =*/ feature.varint();
/*uint32_t value =*/ feature.varint();
}
} else if (feature.tag == 3) {
uint32_t type = feature.varint();
/*uint32_t type =*/ feature.varint();
} else if (feature.tag == 4) {
uint32_t bytes = (uint32_t)feature.varint();
loadGeometry(feature.data, bytes);

View File

@@ -1,12 +1,27 @@
#include <llmr/map/transform.hpp>
#include <llmr/util/mat4.h>
#include <cmath>
#include <cstdio>
using namespace llmr;
transform::transform()
: x(0.0f),
y(0.0f),
scale(1.0f) {
const double MAXEXTENT = 20037508.34;
const double D2R = M_PI / 180.0;
const double R2D = 180.0 / M_PI;
const double A = 6378137;
transform::transform()
:
width(0),
height(0),
x(0),
y(0),
angle(0.0),
scale(1.0) {
setScale(scale);
}
void transform::moveBy(double dx, double dy) {
@@ -16,6 +31,61 @@ void transform::moveBy(double dx, double dy) {
void transform::scaleBy(double ds, double cx, double cy) {
scale *= ds;
x = x * ds + cx * (1 - ds);
y = y * ds + cy * (1 - ds);
x = x * ds + (cx - width / 2) * (1.0 - ds);
y = y * ds + (cy - height / 2) * (1.0 - ds);
}
// void transform::setAngle(double _angle) {
// angle = _angle;
// }
void transform::setScale(double new_scale) {
const double factor = new_scale / scale;
x *= factor;
y *= factor;
scale = new_scale;
const double s = scale * size;
zc = s / 2;
Bc = s / 360;
Cc = s / (2 * M_PI);
}
void transform::setZoom(double zoom) {
setScale(pow(2.0, zoom));
}
void transform::setLonLat(double lon, double lat) {
const double f = fmin(fmax(sin(D2R * lat), -0.9999), 0.9999);
x = -round(lon * Bc);
y = round(0.5 * Cc * log((1 + f) / (1 - f)));
fprintf(stderr, "pos: %f/%f\n", x, y);
}
void transform::getLonLat(double& lon, double& lat) const {
lon = -x / Bc;
lat = R2D * (2 * atan(exp(y / Cc)) - 0.5 * M_PI);
}
double transform::pixel_x() const {
const double center = (width - scale * size) / 2;
return center + x;
}
double transform::pixel_y() const {
const double center = (height - scale * size) / 2;
return center + y;
}
void transform::matrixFor(float matrix[16], uint32_t tile_z, uint32_t tile_x, uint32_t tile_y) const {
const double tile_scale = pow(2, tile_z);
const double tile_size = scale * size / tile_scale;
mat4_identity(matrix);
mat4_translate(matrix, matrix, pixel_x(), pixel_y(), -1);
mat4_translate(matrix, matrix, tile_x * tile_size, tile_y * tile_size, 0);
// TODO: Get rid of the 8 (scaling from 4096 to 512 px tile size);
mat4_scale(matrix, matrix, scale / tile_scale / 8, scale / tile_scale / 8, 1);
}

View File

@@ -25,20 +25,14 @@ GLfloat fill_vertices[] = {
};
painter::painter(class platform *platform)
painter::painter(class platform *platform, class transform *transform)
: platform(platform),
transform(NULL),
width(0),
height(0),
transform(transform),
currentShader(NULL),
fillShader(NULL) {
}
void painter::setTransform(class transform *transform) {
this->transform = transform;
}
void painter::setup() {
setupShaders();
@@ -86,29 +80,15 @@ void painter::teardown() {
}
void painter::resize(GLuint new_width, GLuint new_height) {
if (width == new_width && height == new_height) {
return;
}
fprintf(stderr, "changing viewport size to %d/%d\n", new_width, new_height);
width = new_width;
height = new_height;
}
void painter::changeMatrix() {
void painter::changeMatrix(tile *tile) {
assert(transform);
assert(width);
assert(height);
// Initialize projection matrix
float projMatrix[16];
mat4_ortho(projMatrix, 0, width, height, 0, 1, 10);
mat4_ortho(projMatrix, 0, transform->width, transform->height, 0, 1, 10);
float mvMatrix[16];
mat4_identity(mvMatrix);
mat4_translate(mvMatrix, mvMatrix, transform->x, transform->y, -1);
mat4_scale(mvMatrix, mvMatrix, transform->scale / 8, transform->scale / 8, 1);
transform->matrixFor(mvMatrix, tile->z, tile->x, tile->y);
mat4_multiply(matrix, projMatrix, mvMatrix);
}
@@ -119,7 +99,7 @@ void painter::clear() {
}
void painter::render(tile *tile) {
changeMatrix();
changeMatrix(tile);
glDisable(GL_STENCIL_TEST);
glEnable(GL_BLEND);