#ifndef LLMR_MAP_TRANSFORM #define LLMR_MAP_TRANSFORM #include #include #include #include #include #include namespace llmr { struct box; class Transform : private util::noncopyable { public: Transform(); // Animations bool needsAnimation() const; void updateAnimations(double time); void cancelAnimations(); // Map view changes. // Note: width * ratio does not necessarily equal fb_width void resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width, uint16_t fb_height); // Relative changes void moveBy(double dx, double dy, double duration = 0); void scaleBy(double ds, double cx = -1, double cy = -1, double duration = 0); void rotateBy(double sx, double sy, double ex, double ey, double duration = 0); // Absolute changes void setScale(double scale, double cx = -1, double cy = -1, double duration = 0); void setAngle(double angle, double duration = 0); void setZoom(double zoom, double duration = 0); void setLonLat(double lon, double lat, double duration = 0); void setLonLatZoom(double lon, double lat, double zoom, double duration = 0); // Getters void matrixFor(mat4& matrix, const Tile::ID& id) const; float getZoom() const; float getNormalizedZoom() const; int32_t getIntegerZoom() const; double getScale() const; double getAngle() const; void getLonLat(double& lon, double& lat) const; void getLonLatZoom(double& lon, double& lat, double& zoom) const; // Animations void startPanning(); void stopPanning(); void startRotating(); void stopRotating(); void startScaling(); void stopScaling(); box cornersToBox(uint32_t z) const; // More getters inline uint16_t getWidth() const { return width; } inline uint16_t getHeight() const { return height; } inline uint16_t getFramebufferWidth() const { return fb_width; } inline uint16_t getFramebufferHeight() const { return fb_height; } inline float getPixelRatio() const { return pixelRatio; } private: void setScaleXY(double new_scale, double xn, double yn, double duration = 0); double pixel_x() const; double pixel_y() const; private: // logical dimensions uint16_t width = 0; uint16_t height = 0; // physical (framebuffer) dimensions uint16_t fb_width = 0; uint16_t fb_height = 0; float pixelRatio = 1; public: bool rotating = false; bool scaling = false; bool panning = false; private: double x = 0, y = 0; // pixel values of the map center in the current scale double angle = 0; double scale = 1; double min_scale = pow(2, 0); double max_scale = pow(2, 20); // cache values for spherical mercator math double zc, Bc, Cc; std::forward_list> animations; std::shared_ptr scale_timeout; std::shared_ptr rotate_timeout; std::shared_ptr pan_timeout; }; } #endif