summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <github@kkaefer.com>2014-01-08 14:32:58 +0100
committerKonstantin Käfer <github@kkaefer.com>2014-01-08 14:32:58 +0100
commit7526d681e287264d4b4f7b81e3f7cd68dae97bfb (patch)
tree88d1d2b26292225dcc647dacea9e0b52fded102b
parent7253f808c6eda60fc76547faf165b329a1fd99bc (diff)
downloadqtlocation-mapboxgl-7526d681e287264d4b4f7b81e3f7cd68dae97bfb.tar.gz
calculate proper tile position
-rw-r--r--include/llmr/map/map.hpp7
-rw-r--r--include/llmr/map/transform.hpp32
-rw-r--r--include/llmr/renderer/painter.hpp8
-rw-r--r--macosx/main.mm11
-rw-r--r--src/map/map.cpp33
-rw-r--r--src/map/tile.cpp39
-rw-r--r--src/map/transform.cpp82
-rw-r--r--src/renderer/painter.cpp32
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);