This repository has been archived by the owner on Aug 30, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathosm_render.cpp
115 lines (100 loc) · 5.47 KB
/
osm_render.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "osm_render.h"
#include "gfx_2d.h"
// #include <stdio.h>
// Memory estimation in bytes:
// 256*256*2=131.072
// 2x2 = 524.288
// 3x3 = 1.179.648
// 4x4 = 2.097.152
// 5x5 = 3.276.800
Graphics2D *getTile(BufferedTile **buffer, uint8_t bufferLength, loadTile loadTileFn, uint32_t tileX, uint32_t tileY,
uint8_t tileZ) {
// return buffered tile
for (uint16_t i = 0; i < bufferLength; i++) {
if (buffer[i] != NULL && buffer[i]->hasTile(tileX, tileY, tileZ)) {
return buffer[i]->getGraphics();
}
}
// find oldest tile
unsigned long oldestTimeStamp = 4294967295;
uint16_t oldestIndex = 0;
for (uint16_t i = 0; i < bufferLength; i++) {
if (buffer[i] != NULL && buffer[i]->getLastUsed() < oldestTimeStamp) {
oldestTimeStamp = buffer[i]->getLastUsed();
oldestIndex = i;
}
}
// overwrite withe new tile
buffer[oldestIndex]->loadTile(loadTileFn, tileX, tileY, tileZ);
// return fresh tile
return buffer[oldestIndex]->getGraphics();
}
void drawTilesBuffered(BufferedTile **buffer, uint8_t n, Graphics2D *target, //
loadTile loadTileFn, float lat, float lon, uint8_t z) {
// TODO: proxy loadTileFn and reuse buffered tile if present
float tileX = lon2tilex(lon, z);
float tileY = lat2tiley(lat, z);
uint16_t zoom = z;
int32_t tposX = target->getWidth() / 2 - tileOffset(tileX);
int32_t tposY = target->getHeight() / 2 - tileOffset(tileY);
// getTile(buffer, n, loadTileFn, tileX, tileY, zoom)->fillFrame(0, 0, 255, 255, rgb565(255, 0, 0));
target->drawGraphics2D(tposX, tposY, getTile(buffer, n, loadTileFn, tileX, tileY, zoom));
// TODO below is not optimal, we have cases where nothing needs to be drawn
if (tileOffset(tileX) < 128 && tileOffset(tileY) < 128) {
// top left (first tile is bot right)
target->drawGraphics2D(tposX - TILE_W, tposY /* */, getTile(buffer, n, loadTileFn, tileX - 1, tileY, zoom));
target->drawGraphics2D(tposX - TILE_W, tposY - TILE_H, getTile(buffer, n, loadTileFn, tileX - 1, tileY - 1, zoom));
target->drawGraphics2D(tposX /* */, tposY - TILE_H, getTile(buffer, n, loadTileFn, tileX, tileY - 1, zoom));
} else if (tileOffset(tileX) < 128 && tileOffset(tileY) >= 128) {
// bot left (first tile is top right)
target->drawGraphics2D(tposX - TILE_W, tposY /* */, getTile(buffer, n, loadTileFn, tileX - 1, tileY, zoom));
target->drawGraphics2D(tposX - TILE_W, tposY + TILE_H, getTile(buffer, n, loadTileFn, tileX - 1, tileY + 1, zoom));
target->drawGraphics2D(tposX /* */, tposY + TILE_H, getTile(buffer, n, loadTileFn, tileX, tileY + 1, zoom));
} else if (tileOffset(tileX) >= 128 && tileOffset(tileY) >= 128) {
// bot right (first tile is top left)
target->drawGraphics2D(tposX /* */, tposY + TILE_H, getTile(buffer, n, loadTileFn, tileX, tileY + 1, zoom));
target->drawGraphics2D(tposX + TILE_W, tposY + TILE_H, getTile(buffer, n, loadTileFn, tileX + 1, tileY + 1, zoom));
target->drawGraphics2D(tposX + TILE_W, tposY /* */, getTile(buffer, n, loadTileFn, tileX + 1, tileY, zoom));
} else {
// top right (first tile is bot left)
target->drawGraphics2D(tposX + TILE_W, tposY /* */, getTile(buffer, n, loadTileFn, tileX + 1, tileY, zoom));
target->drawGraphics2D(tposX + TILE_W, tposY - TILE_H, getTile(buffer, n, loadTileFn, tileX + 1, tileY - 1, zoom));
target->drawGraphics2D(tposX /* */, tposY - TILE_H, getTile(buffer, n, loadTileFn, tileX, tileY - 1, zoom));
}
}
void drawTiles(Graphics2D *target, loadTile loadTileFn, float lat, float lon, uint8_t z) {
float tileX = lon2tilex(lon, z);
float tileY = lat2tiley(lat, z);
uint16_t zoom = z;
int32_t tposX = target->getWidth() / 2 - tileOffset(tileX);
int32_t tposY = target->getHeight() / 2 - tileOffset(tileY);
// target->fill(rgb565(0, 0, 0));
loadTileFn(target, zoom, tileX, tileY, tposX, tposY);
// target->drawFrame(tposX, tposY, 256, 256, rgb565(255, 0, 0));
// TODO below is not optimal, we have cases where nothing needs to be drawn
if (tileOffset(tileX) < 128 && tileOffset(tileY) < 128) {
// top left (first tile is bot right)
loadTileFn(target, zoom, tileX - 1, tileY, tposX - TILE_W, tposY);
loadTileFn(target, zoom, tileX - 1, tileY - 1, tposX - TILE_W, tposY - TILE_H);
loadTileFn(target, zoom, tileX, tileY - 1, tposX, tposY - TILE_H);
// target->drawFrame(200, 200, 10, 10, rgb565(255, 0, 0));
} else if (tileOffset(tileX) < 128 && tileOffset(tileY) >= 128) {
// bot left (first tile is top right)
loadTileFn(target, zoom, tileX - 1, tileY, tposX - TILE_W, tposY);
loadTileFn(target, zoom, tileX - 1, tileY + 1, tposX - TILE_W, tposY + TILE_H);
loadTileFn(target, zoom, tileX, tileY + 1, tposX, tposY + TILE_H);
// target->drawFrame(200, 40, 10, 10, rgb565(255, 0, 0));
} else if (tileOffset(tileX) >= 128 && tileOffset(tileY) >= 128) {
// bot right (first tile is top left)
loadTileFn(target, zoom, tileX, tileY + 1, tposX, tposY + TILE_H);
loadTileFn(target, zoom, tileX + 1, tileY + 1, tposX + TILE_W, tposY + TILE_H);
loadTileFn(target, zoom, tileX + 1, tileY, tposX + TILE_W, tposY);
// target->drawFrame(40, 40, 10, 10, rgb565(255, 0, 0));
} else {
// top right (first tile is bot left)
loadTileFn(target, zoom, tileX + 1, tileY, tposX + TILE_W, tposY);
loadTileFn(target, zoom, tileX + 1, tileY - 1, tposX + TILE_W, tposY - TILE_H);
loadTileFn(target, zoom, tileX, tileY - 1, tposX, tposY - TILE_H);
// target->drawFrame(40, 200, 10, 10, rgb565(255, 0, 0));
}
}