diff options
author | Konstantin Käfer <github@kkaefer.com> | 2014-01-08 14:32:58 +0100 |
---|---|---|
committer | Konstantin Käfer <github@kkaefer.com> | 2014-01-08 14:32:58 +0100 |
commit | 7526d681e287264d4b4f7b81e3f7cd68dae97bfb (patch) | |
tree | 88d1d2b26292225dcc647dacea9e0b52fded102b | |
parent | 7253f808c6eda60fc76547faf165b329a1fd99bc (diff) | |
download | qtlocation-mapboxgl-7526d681e287264d4b4f7b81e3f7cd68dae97bfb.tar.gz |
calculate proper tile position
-rw-r--r-- | include/llmr/map/map.hpp | 7 | ||||
-rw-r--r-- | include/llmr/map/transform.hpp | 32 | ||||
-rw-r--r-- | include/llmr/renderer/painter.hpp | 8 | ||||
-rw-r--r-- | macosx/main.mm | 11 | ||||
-rw-r--r-- | src/map/map.cpp | 33 | ||||
-rw-r--r-- | src/map/tile.cpp | 39 | ||||
-rw-r--r-- | src/map/transform.cpp | 82 | ||||
-rw-r--r-- | src/renderer/painter.cpp | 32 |
8 files changed, 166 insertions, 78 deletions
diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index e19236f12e..7940eb32c1 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -11,9 +11,12 @@ class tile; class map { public: - map(class platform *platform, class painter *painter); + map(class platform *platform); ~map(); + void setup(); + void resize(uint32_t width, uint32_t height); + /* callback */ bool render(); void moveBy(double dx, double dy); @@ -23,8 +26,8 @@ public: private: platform *platform; - painter *painter; transform *transform; + painter *painter; std::vector<tile *> tiles; }; diff --git a/include/llmr/map/transform.hpp b/include/llmr/map/transform.hpp index 26a6683f20..57d5379bfc 100644 --- a/include/llmr/map/transform.hpp +++ b/include/llmr/map/transform.hpp @@ -1,6 +1,8 @@ #ifndef LLMR_MAP_TRANSFORM #define LLMR_MAP_TRANSFORM +#include <cstdint> + namespace llmr { class tile; @@ -9,12 +11,40 @@ class transform { public: transform(); + // Relative changes void moveBy(double dx, double dy); void scaleBy(double ds, double cx, double cy); + // Absolute changes + void setScale(double scale); + void setZoom(double zoom); + void setLonLat(double lon, double lat); + // void setAngle(double angle); + + + // Getters + void matrixFor(float matrix[16], uint32_t z, uint32_t x, uint32_t y) const; + void getLonLat(double& lon, double& lat) const; + +private: + double pixel_x() const; + double pixel_y() const; + public: - double x, y; + // double x, y; + uint32_t width; + uint32_t height; + + +private: + double x, y; // spherical mercator meters of the view center + double angle; double scale; + + + const int32_t size = 512; + + double zc, Bc, Cc; }; } diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 6c75171846..21dec5e075 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -12,12 +12,10 @@ class tile; class painter { public: - painter(class platform *platform); + painter(class platform *platform, class transform *tranform); void setup(); void teardown(); - - void resize(uint32_t new_width, uint32_t new_height); void viewport(); @@ -25,18 +23,16 @@ public: void render(tile *tile); void switchShader(Shader *shader, float matrix[16]); - void setTransform(transform *transform); private: void setupShaders(); - void changeMatrix(); + void changeMatrix(tile *tile); public: private: platform *platform; transform *transform; - uint32_t width, height; float matrix[16]; Shader *currentShader; diff --git a/macosx/main.mm b/macosx/main.mm index caa56d999e..864803354a 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -10,8 +10,7 @@ public: dirty(true), tracking(false), platform(new llmr::platform(this)), - painter(new llmr::painter(platform)), - map(new llmr::map(platform, painter)) { + map(new llmr::map(platform)) { if (!glfwInit()) { fprintf(stderr, "Failed to initialize glfw\n"); exit(1); @@ -26,12 +25,12 @@ public: glfwMakeContextCurrent(window); - painter->setup(); + map->setup(); int width, height; glfwGetWindowSize(window, &width, &height); - painter->resize(width, height); + map->resize(width, height); glfwSwapInterval(1); @@ -68,7 +67,7 @@ public: static void resize(GLFWwindow *window, int width, int height) { MapView *view = (MapView *)glfwGetWindowUserPointer(window); - view->painter->resize(width, height); + view->map->resize(width, height); } static void mouseclick(GLFWwindow *window, int button, int action, int modifiers) { @@ -125,7 +124,6 @@ public: ~MapView() { delete map; - delete painter; delete platform; glfwTerminate(); } @@ -137,7 +135,6 @@ public: GLFWwindow *window; llmr::platform *platform; - llmr::painter *painter; llmr::map *map; }; diff --git a/src/map/map.cpp b/src/map/map.cpp index 397ba384d8..e01a9fc98f 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -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); -}
\ No newline at end of file +} diff --git a/src/map/tile.cpp b/src/map/tile.cpp index ce56cd6134..6216c55caa 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -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()) - ); - - // 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(); - } + fprintf(stderr, "[%p] parsing tile...\n", this); + + 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); diff --git a/src/map/transform.cpp b/src/map/transform.cpp index 61d982192d..4fcac6892b 100644 --- a/src/map/transform.cpp +++ b/src/map/transform.cpp @@ -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); } diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 1a3fde50ab..696e6a8625 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -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); |