diff options
-rw-r--r-- | CMakeLists.txt | 11 | ||||
-rw-r--r-- | include/llmr/map/map.hpp | 10 | ||||
-rw-r--r-- | include/llmr/map/settings.hpp | 23 | ||||
-rw-r--r-- | include/llmr/map/transform.hpp | 2 | ||||
-rw-r--r-- | include/llmr/util/string.hpp | 19 | ||||
-rw-r--r-- | macosx/CMakeLists.txt | 23 | ||||
-rw-r--r-- | macosx/Info.plist.in | 36 | ||||
-rw-r--r-- | macosx/main.mm | 39 | ||||
-rw-r--r-- | macosx/settings.hpp | 18 | ||||
-rw-r--r-- | macosx/settings.mm | 62 | ||||
-rw-r--r-- | src/map/map.cpp | 62 | ||||
-rw-r--r-- | src/map/transform.cpp | 22 |
12 files changed, 280 insertions, 47 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index fa5ddfdfab..2919943c69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,16 @@ cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) project(llmr) + +set(VERSION_MAJOR "0") +set(VERSION_MINOR "0") +set(VERSION_PATCH "1") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11") add_subdirectory(src) -add_subdirectory(macosx) + + +if(APPLE) + add_subdirectory(macosx) +endif(APPLE) diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index 0947daafb1..37fd9ab1e6 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -5,6 +5,7 @@ #include "../renderer/painter.hpp" #include "transform.hpp" #include <llmr/map/tile.hpp> +#include "settings.hpp" #include <forward_list> @@ -12,10 +13,11 @@ namespace llmr { class map { public: - map(); + map(settings *settings); ~map(); void setup(); + void loadSettings(); void resize(uint32_t width, uint32_t height); /* callback */ @@ -34,6 +36,8 @@ public: // void setZoom(double zoom); // void setLonLatZoom(double lon, double lat, double zoom); + void toggleDebug(); + private: bool findLoadedChildren(const tile_id& id, int32_t maxCoveringZoom, std::forward_list<tile_id>& retain); bool findLoadedParent(const tile_id& id, int32_t minCoveringZoom, std::forward_list<tile_id>& retain); @@ -41,7 +45,11 @@ private: tile::ptr addTile(const tile_id& id); tile::ptr hasTile(const tile_id& id); + + void update(); + private: + settings *settings; transform *transform; painter *painter; diff --git a/include/llmr/map/settings.hpp b/include/llmr/map/settings.hpp new file mode 100644 index 0000000000..d7ebb55ede --- /dev/null +++ b/include/llmr/map/settings.hpp @@ -0,0 +1,23 @@ +#ifndef LLMR_MAP_SETTINGS +#define LLMR_MAP_SETTINGS + +namespace llmr { + +class settings { +public: + virtual void save() = 0; + +public: + // position + double longitude = 0; + double latitude = 0; + double scale = 0; + double angle = 0; + + // debug + bool debug = false; +}; + +} + +#endif diff --git a/include/llmr/map/transform.hpp b/include/llmr/map/transform.hpp index 4ff7ba7fd4..cf1ae6fff3 100644 --- a/include/llmr/map/transform.hpp +++ b/include/llmr/map/transform.hpp @@ -29,6 +29,8 @@ public: // Getters void matrixFor(float matrix[16], const vec3<int32_t>& id) const; int32_t getZoom() const; + double getScale() const; + double getAngle() const; void getLonLat(double& lon, double& lat) const; diff --git a/include/llmr/util/string.hpp b/include/llmr/util/string.hpp new file mode 100644 index 0000000000..4e7ae6d4b9 --- /dev/null +++ b/include/llmr/util/string.hpp @@ -0,0 +1,19 @@ +#ifndef LLMR_UTIL_STRING +#define LLMR_UTIL_STRING + +#include <string> + +namespace llmr { +namespace util { + +template<typename... Args> +inline std::string sprintf(const char *msg, Args... args) { + char res[1024]; + int len = snprintf(res, sizeof(res), msg, args...); + return std::string(res, len); +} + +} +} + +#endif diff --git a/macosx/CMakeLists.txt b/macosx/CMakeLists.txt index 2a839c0c1d..0ac0d4e441 100644 --- a/macosx/CMakeLists.txt +++ b/macosx/CMakeLists.txt @@ -9,6 +9,7 @@ PKG_SEARCH_MODULE(GLFW REQUIRED glfw3) SET(macosx_SOURCES main.mm + settings.mm ) SET(macosx_HEADERS @@ -23,10 +24,30 @@ LINK_DIRECTORIES( ${GLFW_LIBRARY_DIRS} ) -ADD_EXECUTABLE(macosx +# Define some settings for the Bundle +set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}) +set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.mapbox.llmr.native") +set(MACOSX_BUNDLE_ICON_FILE "macosx.icns") +set(MACOSX_BUNDLE_INFO_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") +set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") +set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") +set(MACOSX_BUNDLE_BUNDLE_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") +set(MACOSX_BUNDLE_COPYRIGHT "(c) 2014 Mapbox") + +# Add Mac OS X specific icon +#list(APPEND macosx_RESOURCES ../resources/macosx.icns) + +# Ensures that resources end up in the Resources folder +set_source_files_properties(${macosx_RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + +add_executable(macosx MACOSX_BUNDLE ${macosx_SOURCES} + ${macosx_RESOURCES} ) + +set_target_properties(macosx PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/macosx/Info.plist.in) + TARGET_LINK_LIBRARIES(macosx llmr ${COCOA_LIBRARY} diff --git a/macosx/Info.plist.in b/macosx/Info.plist.in new file mode 100644 index 0000000000..a77546b82f --- /dev/null +++ b/macosx/Info.plist.in @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> + <key>CFBundleGetInfoString</key> + <string>${MACOSX_BUNDLE_INFO_STRING}</string> + <key>CFBundleIconFile</key> + <string>${MACOSX_BUNDLE_ICON_FILE}</string> + <key>CFBundleIdentifier</key> + <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleLongVersionString</key> + <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> + <key>CFBundleName</key> + <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> + <key>CFBundleSignature</key> + <string>LLMR</string> + <key>CFBundleVersion</key> + <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> + <key>CSResourcesFileMapped</key> + <true/> + <key>NSHumanReadableCopyright</key> + <string>${MACOSX_BUNDLE_COPYRIGHT}</string> + <key>NSHighResolutionCapable</key> + <true/> +</dict> +</plist>
\ No newline at end of file diff --git a/macosx/main.mm b/macosx/main.mm index ba75d1b35c..80a7df00d4 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -1,8 +1,10 @@ #include <llmr/llmr.hpp> #include <GLFW/glfw3.h> #import <Foundation/Foundation.h> +#import <AppKit/AppKit.h> #include <llmr/platform/platform.hpp> #include <llmr/map/tile.hpp> +#include "settings.hpp" class MapView { public: @@ -11,7 +13,8 @@ public: tracking(false), rotating(false), last_click(-1), - map(new llmr::map()) { + settings(new llmr::macosx_settings()), + map(new llmr::map(settings)) { } void init() { @@ -32,18 +35,16 @@ public: glfwMakeContextCurrent(window); - int stencil_bits = glfwGetWindowAttrib(window, GLFW_STENCIL_BITS); - fprintf(stderr, "stencil bits: %d\n", stencil_bits); - + settings->load(); map->setup(); - int width, height; glfwGetWindowSize(window, &width, &height); map->resize(width, height); glfwSwapInterval(1); + map->loadSettings(); glfwSetCursorPosCallback(window, mousemove); glfwSetMouseButtonCallback(window, mouseclick); @@ -56,28 +57,27 @@ public: } static void character(GLFWwindow *window, unsigned int codepoint) { - MapView *view = (MapView *)glfwGetWindowUserPointer(window); - switch (codepoint) { - case L'n': - case L'N': - view->map->resetNorth(); - break; - case L'r': - case L'R': - view->map->resetPosition(); - break; - } + } static void key(GLFWwindow *window, int key, int scancode, int action, int mods) { - // MapView *view = (MapView *)glfwGetWindowUserPointer(window); + MapView *view = (MapView *)glfwGetWindowUserPointer(window); if (action == GLFW_RELEASE) { switch (key) { case GLFW_KEY_ESCAPE: glfwSetWindowShouldClose(window, true); break; + case GLFW_KEY_TAB: + view->map->toggleDebug(); + break; + case GLFW_KEY_R: + if (!mods) view->map->resetPosition(); + break; + case GLFW_KEY_N: + if (!mods) view->map->resetNorth(); + break; } } } @@ -195,6 +195,7 @@ public: double last_click; GLFWwindow *window; + llmr::macosx_settings *settings; llmr::map *map; }; @@ -210,9 +211,7 @@ void restart(void *) { void request(void *, tile::ptr tile) { assert((bool)tile); - // fprintf(stderr, "request %d/%d/%d\n", tile->z, tile->x, tile->y); - // fprintf(stderr, "requesting tile\n"); // NSString *urlTemplate = @"http://api.tiles.mapbox.com/v3/mapbox.mapbox-streets-v4/%d/%d/%d.vector.pbf"; NSString *urlTemplate = @"http://localhost:3333/gl/tiles/plain/%d-%d-%d.vector.pbf"; NSString *urlString = [NSString @@ -248,8 +247,6 @@ void request(void *, tile::ptr tile) { return; } } - - fprintf(stderr, "[%s] status code %d\n", [urlString UTF8String], code); } dispatch_async(dispatch_get_main_queue(), ^ { diff --git a/macosx/settings.hpp b/macosx/settings.hpp new file mode 100644 index 0000000000..7c23f829ea --- /dev/null +++ b/macosx/settings.hpp @@ -0,0 +1,18 @@ +#ifndef LLMR_MACOSX_SETTINGS +#define LLMR_MACOSX_SETTINGS + +#include <llmr/map/settings.hpp> + +namespace llmr { + +class macosx_settings : public settings { +public: + macosx_settings(); + virtual void save(); + virtual void load(); + virtual void clear(); +}; + +} + +#endif diff --git a/macosx/settings.mm b/macosx/settings.mm new file mode 100644 index 0000000000..31395781ff --- /dev/null +++ b/macosx/settings.mm @@ -0,0 +1,62 @@ +#import <Foundation/Foundation.h> + +#include "settings.hpp" + + +using namespace llmr; + +macosx_settings::macosx_settings() { + NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: + + // position + [NSNumber numberWithDouble:longitude], @"longitude", + [NSNumber numberWithDouble:latitude], @"latitude", + [NSNumber numberWithDouble:scale], @"scale", + [NSNumber numberWithDouble:angle], @"angle", + + // debug + [NSNumber numberWithBool:debug], @"debug", + + nil + ]; + + [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; +} + +void macosx_settings::load() { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + // position + longitude = [defaults doubleForKey:@"longitude"]; + latitude = [defaults doubleForKey:@"latitude"]; + scale = [defaults doubleForKey:@"scale"]; + angle = [defaults doubleForKey:@"angle"]; + + // debug + debug = [defaults boolForKey:@"debug"]; +} + +void macosx_settings::save() { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: + + // position + [NSNumber numberWithDouble:longitude], @"longitude", + [NSNumber numberWithDouble:latitude], @"latitude", + [NSNumber numberWithDouble:scale], @"scale", + [NSNumber numberWithDouble:angle], @"angle", + + // debug + [NSNumber numberWithBool:debug], @"debug", + + nil + ]; + [defaults setPersistentDomain:appDefaults forName:[[NSBundle mainBundle] bundleIdentifier]]; + + [defaults synchronize]; +} + +void macosx_settings::clear() { + // TODO +} diff --git a/src/map/map.cpp b/src/map/map.cpp index 5f9e0b7eda..4c05b8f3dc 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -10,14 +10,12 @@ using namespace llmr; -map::map() - : transform(new class transform()), +map::map(class settings *settings) + : settings(settings), + transform(new class transform()), painter(new class painter(transform)), min_zoom(0), max_zoom(14) { - - // transform->setLonLat(13, 50); - // transform->setZoom(3); } map::~map() { @@ -28,45 +26,77 @@ void map::setup() { painter->setup(); } +void map::loadSettings() { + transform->setAngle(settings->angle); + transform->setScale(settings->scale); + transform->setLonLat(settings->longitude, settings->latitude); + update(); +} + void map::resize(uint32_t width, uint32_t height) { transform->width = width; transform->height = height; - updateTiles(); - platform::restart(this); + update(); } void map::moveBy(double dx, double dy) { transform->moveBy(dx, dy); - updateTiles(); - platform::restart(this); + update(); + + transform->getLonLat(settings->longitude, settings->latitude); + settings->save(); } void map::scaleBy(double ds, double cx, double cy) { transform->scaleBy(ds, cx, cy); - updateTiles(); - platform::restart(this); + update(); + + transform->getLonLat(settings->longitude, settings->latitude); + settings->scale = transform->getScale(); + settings->save(); } void map::rotateBy(double cx, double cy, double sx, double sy, double ex, double ey) { transform->rotateBy(cx, cy, sx, sy, ex, ey); - updateTiles(); - platform::restart(this); + update(); + + settings->angle = transform->getAngle(); + settings->save(); } void map::resetNorth() { transform->setAngle(0); - updateTiles(); - platform::restart(this); + update(); + + settings->angle = transform->getAngle(); + settings->save(); } void map::resetPosition() { transform->setAngle(0); transform->setLonLat(0, 0); transform->setZoom(0); + update(); + + transform->getLonLat(settings->longitude, settings->latitude); + settings->scale = transform->getScale(); + settings->angle = transform->getAngle(); + settings->save(); +} + +void map::toggleDebug() { + settings->debug = !settings->debug; + update(); + + settings->save(); +} + +void map::update() { updateTiles(); platform::restart(this); } + tile::ptr map::hasTile(const tile_id& id) { for (tile::ptr& tile : tiles) { if (tile->id == id) { @@ -238,7 +268,7 @@ bool map::render() { void map::tileLoaded(tile::ptr tile) { // std::cerr << "loaded " << tile->toString() << std::endl; - platform::restart(this); + update(); } void map::tileFailed(tile::ptr tile) { diff --git a/src/map/transform.cpp b/src/map/transform.cpp index d7c189003b..3c028be149 100644 --- a/src/map/transform.cpp +++ b/src/map/transform.cpp @@ -36,21 +36,22 @@ void transform::moveBy(double dx, double dy) { void transform::scaleBy(double ds, double cx, double cy) { // clamp scale to min/max values - const double new_scale = scale * ds; + double new_scale = scale * ds; if (new_scale < min_scale) { ds = min_scale / scale; + new_scale = min_scale; } else if (new_scale > max_scale) { ds = max_scale / scale; + new_scale = max_scale; } + setScale(new_scale); + + // Correct for non-center scaling location. const double dx = (cx - width / 2) * (1.0 - ds); const double dy = (cy - height / 2) * (1.0 - ds); - const double fx = cos(angle) * dx + sin(angle) * dy; - const double fy = cos(angle) * dy + sin(-angle) * dx; - - scale *= ds; - x = (x * ds) + fx; - y = (y * ds) + fy; + x += cos(angle) * dx + sin(angle) * dy; + y += cos(angle) * dy + sin(-angle) * dx; } @@ -154,6 +155,13 @@ int32_t transform::getZoom() const { return floor(log(scale) / M_LN2); } +double transform::getScale() const { + return scale; +} + +double transform::getAngle() const { + return angle; +} void transform::mapCornersToBox(uint32_t z, box& b) const { const double ref_scale = pow(2, z); |