int mapzen_init()
{
- TangramView::initNetworkRequests();
int ret = mapzen_init_queue();
return ret;
int mapzen_shutdown()
{
- TangramView::deinitNetworkRequests();
int ret = mapzen_deinit_queue();
return ret;
#pragma once
-#include <vector>
#include <string>
+#include <vector>
namespace Tangram {
std::string getAsString(const std::string& key) const;
- const bool getAsString(const std::string& key, std::string& value) const;
+ bool getAsString(const std::string& key, std::string& value) const;
std::string toJson() const;
+++ /dev/null
-#pragma once
-
-#include "tangram.h"
-#include <cmath>
-#include <functional>
-
-namespace Tangram {
-
-using EaseCb = std::function<void (float)>;
-
-template<typename T>
-T ease(T _start, T _end, float _t, EaseType _e) {
- float f = _t;
- switch (_e) {
- case EaseType::cubic: f = (-2 * f + 3) * f * f; break;
- case EaseType::quint: f = (6 * f * f - 15 * f + 10) * f * f * f; break;
- case EaseType::sine: f = 0.5 - 0.5 * cos(M_PI * f); break;
- default: break;
- }
- return _start + (_end - _start) * f;
-}
-
-struct Ease {
- float t;
- float d;
- EaseCb cb;
-
- Ease() : t(0), d(0), cb([](float) {}) {}
- Ease(float _duration, EaseCb _cb) : t(-1), d(_duration), cb(_cb) {}
-
- bool finished() const { return t >= d; }
-
- void update(float _dt) {
- t = t < 0 ? 0 : std::fmin(t + _dt, d);
- cb(std::fmin(1, t / d));
- }
-};
-
-}
#pragma once
+#include <functional>
#include <string>
-#include <cstring>
#include <vector>
-#include <algorithm>
-#include <functional>
-#include <cstdio>
-/* Print a formatted message to the console
- *
- * Uses printf syntax to write a string to stderr (or logcat, on Android)
- */
-void logMsg(const char* fmt, ...);
+namespace Tangram {
-/* Function type for a mapReady callback*/
+// Function type for a mapReady callback
using MapReady = std::function<void(void*)>;
-/* Request that a new frame be rendered by the windowing system
- */
-void requestRender();
+// Function type for receiving data from a successful network request
+using UrlCallback = std::function<void(std::vector<char>&&)>;
+
+using FontSourceLoader = std::function<std::vector<char>()>;
+
+struct FontSourceHandle {
+ FontSourceHandle(std::string _path) : path(_path) {}
+ FontSourceHandle(FontSourceLoader _loader) : load(_loader) {}
-/* If called with 'true', the windowing system will re-draw frames continuously;
- * otherwise new frames will only be drawn when 'requestRender' is called.
- */
-void setContinuousRendering(bool _isContinuous);
+ std::string path;
+ FontSourceLoader load;
+};
-bool isContinuousRendering();
+// Print a formatted message to the console
+// Uses printf syntax to write a string to stderr (or logcat, on Android)
+void logMsg(const char* fmt, ...);
-/* get system path of a font file */
-std::string systemFontPath(const std::string& _name, const std::string& _weight, const std::string& _face);
+void initGLExtensions();
-/* Read a file as a string
- *
- * Opens the file at the _path and returns a string with its contents.
- * If the file cannot be found or read, the returned string is empty.
- */
-std::string stringFromFile(const char* _path);
+// Set the priority of the current thread. Priority is equivalent to pthread niceness
+void setCurrentThreadPriority(int priority);
-/* Read a file into memory
- *
- * Opens the file at _path then allocates and returns a pointer to memory
- * containing the contents of the file. The size of the memory in bytes is written to _size.
- * If the file cannot be read, nothing is allocated and nullptr is returned.
- */
-unsigned char* bytesFromFile(const char* _path, size_t& _size);
+class Platform {
-/* Function type for receiving data from a successful network request */
-using UrlCallback = std::function<void(std::vector<char>&&)>;
+public:
-/* Start retrieving data from a URL asynchronously
- *
- * When the request is finished, the callback @_callback will be
- * run with the data that was retrieved from the URL @_url
- */
-bool startUrlRequest(const std::string& _url, UrlCallback _callback);
+ Platform();
+ virtual ~Platform();
-/* Stop retrieving data from a URL that was previously requested
- */
-void cancelUrlRequest(const std::string& _url);
+ // Request that a new frame be rendered by the windowing system
+ virtual void requestRender() const = 0;
+ // If called with 'true', the windowing system will re-draw frames continuously;
+ // otherwise new frames will only be drawn when 'requestRender' is called.
+ virtual void setContinuousRendering(bool _isContinuous);
-/* Set the priority of the current thread. Priority is equivalent
- * to pthread niceness.
- */
-void setCurrentThreadPriority(int priority);
+ virtual bool isContinuousRendering() const;
-/* Get the font fallback ordered by importance, 0 being the first fallback
- * (e.g. the fallback more willing resolve the glyph codepoint)
- */
-std::string systemFontFallbackPath(int _importance, int _weightHint);
+ virtual std::string resolveAssetPath(const std::string& path) const;
-void initGLExtensions();
+ // Read a file as a string
+ // Opens the file at the _path and returns a string with its contents.
+ // If the file cannot be found or read, the returned string is empty.
+ virtual std::string stringFromFile(const char* _path) const;
+
+ // Read a file into memory
+ // Opens the file at _path then allocates and returns a pointer to memory
+ // containing the contents of the file. The size of the memory in bytes is written to _size.
+ // If the file cannot be read, nothing is allocated and nullptr is returned.
+ virtual std::vector<char> bytesFromFile(const char* _path) const;
+
+ // Start retrieving data from a URL asynchronously
+ // When the request is finished, the callback _callback will be
+ // run with the data that was retrieved from the URL _url
+ virtual bool startUrlRequest(const std::string& _url, UrlCallback _callback) = 0;
+
+ // Stop retrieving data from a URL that was previously requested
+ virtual void cancelUrlRequest(const std::string& _url) = 0;
+
+ virtual std::vector<char> systemFont(const std::string& _name, const std::string& _weight, const std::string& _face) const;
+
+ virtual std::vector<FontSourceHandle> systemFontFallbacksHandle() const;
+
+protected:
+
+ bool bytesFromFileSystem(const char* _path, std::function<char*(size_t)> _allocator) const;
+
+private:
+
+ bool m_continuousRendering;
+
+};
+
+} // namespace Tangram
+#if 0
#pragma once
#include "platform.h"
-#include <functional>
-#include <Evas_GL.h>
bool shouldRender();
-void setRenderCallbackFunction(std::function<void()> callback);
-
void initUrlRequests(const char* proxyAddress);
void stopUrlRequests();
-void setEvasGlAPI(Evas_GL_API* glApi);
+#endif
+
+#pragma once
+
+#include "platform.h"
+#include "urlClient.h"
+
+#include <functional>
+#include <Evas_GL.h>
+
+typedef struct _FcConfig FcConfig;
+
+namespace Tangram {
+
+void setEvasGlAPI(Evas_GL_API *glApi);
+
+class TizenPlatform : public Platform {
+
+public:
+
+ TizenPlatform();
+ TizenPlatform(UrlClient::Options urlClientOptions);
+ ~TizenPlatform() override;
+ void requestRender() const override;
+ bool startUrlRequest(const std::string& _url, UrlCallback _callback) override;
+ void cancelUrlRequest(const std::string& _url) override;
+
+
+ std::vector<FontSourceHandle> systemFontFallbacksHandle() const override;
+
+ std::vector<char> systemFont(const std::string& _name, const std::string& _weight,
+ const std::string& _face) const override;
+
+ void setRenderCallbackFunction(std::function<void()> callback);
+
+
+protected:
+
+ void initPlatformFontSetup() const;
+
+ std::string fontPath(const std::string& _name, const std::string& _weight,
+ const std::string& _face) const;
+
+ UrlClient m_urlClient;
+
+ std::function<void()> m_renderCallbackFunction = nullptr;
+
+ mutable bool m_update = false;
+
+ mutable std::vector<std::string> m_fallbackFonts;
+ mutable FcConfig* m_fcConfig = nullptr;
+
+};
+
+} // namespace Tangram
#pragma once
-#include "properties.h"
-#include "types.h"
+#include "data/properties.h"
+#include "util/types.h"
+
+#include <array>
#include <functional>
#include <memory>
#include <string>
namespace Tangram {
-class DataSource;
+class Platform;
+class TileSource;
+
+enum LabelType {
+ icon,
+ text,
+};
+
+struct FeaturePickResult {
+ FeaturePickResult(std::shared_ptr<Properties> _properties,
+ std::array<float, 2> _position)
+ : properties(_properties), position(_position) {}
-struct TouchItem {
std::shared_ptr<Properties> properties;
- float position[2];
- float distance;
+ std::array<float, 2> position;
+};
+
+// Returns a pointer to the selected feature pick result or null, only valid on the callback scope
+using FeaturePickCallback = std::function<void(const FeaturePickResult*)>;
+
+struct LabelPickResult {
+ LabelPickResult(LabelType _type, LngLat _coordinates, FeaturePickResult _touchItem)
+ : type(_type),
+ coordinates(_coordinates),
+ touchItem(_touchItem) {}
+
+ LabelType type;
+ LngLat coordinates;
+ FeaturePickResult touchItem;
};
+// Returns a pointer to the selected label pick result or null, only valid on the callback scope
+using LabelPickCallback = std::function<void(const LabelPickResult*)>;
+
+struct MarkerPickResult {
+ MarkerPickResult(MarkerID _id, LngLat _coordinates, std::array<float, 2> _position)
+ : id(_id), coordinates(_coordinates), position(_position) {}
+
+ MarkerID id;
+ LngLat coordinates;
+ std::array<float, 2> position;
+};
+
+// Returns a pointer to the selected marker pick result or null, only valid on the callback scope
+using MarkerPickCallback = std::function<void(const MarkerPickResult*)>;
+
struct SceneUpdate {
std::string path;
std::string value;
+ SceneUpdate(std::string p, std::string v) : path(p), value(v) {}
+ SceneUpdate() {}
+};
+
+enum Error {
+ scene_update_path_not_found,
+ scene_update_path_yaml_syntax_error,
+ scene_update_value_yaml_syntax_error,
+};
+
+struct SceneUpdateError {
+ SceneUpdate update;
+ Error error;
};
+using SceneUpdateErrorCallback = std::function<void(const SceneUpdateError&)>;
+
+// Function type for a mapReady callback
+using MapReady = std::function<void(void*)>;
+
enum class EaseType : char {
linear = 0,
cubic,
};
class Map {
+
public:
// Create an empty map object. To display a map, call either loadScene() or loadSceneAsync().
- Map();
+ Map(std::shared_ptr<Platform> _platform);
~Map();
// Load the scene at the given absolute file path asynchronously
- void loadSceneAsync(const char* _scenePath, bool _useScenePosition = false,
- std::function<void(void*)> _platformCallback = {}, void *_cbData = nullptr,
- const std::vector<SceneUpdate>& sceneUpdates = {});
+ // Any pending scene update will be cleared
+ void loadSceneAsync(const char* _scenePath,
+ bool _useScenePosition = false,
+ MapReady _onMapReady = nullptr,
+ void *_onMapReadyUserData = nullptr,
+ const std::vector<SceneUpdate>& sceneUpdates = {},
+ SceneUpdateErrorCallback _onSceneUpdateError = nullptr);
// Load the scene at the given absolute file path synchronously
- void loadScene(const char* _scenePath, bool _useScenePosition = false,
- const std::vector<SceneUpdate>& sceneUpdates = {});
+ // Any pending scene update will be cleared
+ void loadScene(const char* _scenePath,
+ bool _useScenePosition = false,
+ const std::vector<SceneUpdate>& sceneUpdates = {},
+ SceneUpdateErrorCallback _onSceneUpdateError = nullptr);
// Request an update to the scene configuration; the path is a series of yaml keys
// separated by a '.' and the value is a string of yaml to replace the current value
void queueSceneUpdate(const std::vector<SceneUpdate>& sceneUpdates);
// Apply all previously requested scene updates
- void applySceneUpdates();
+ void applySceneUpdates(SceneUpdateErrorCallback _onSceneUpdateError = nullptr);
+
+ // Set an MBTiles SQLite database file for a DataSource in the scene.
+ void setMBTiles(const char* _dataSourceName, const char* _mbtilesFilePath);
// Initialize graphics resources; OpenGL context must be created prior to calling this
void setupGL();
// Gets the viewport width in physical pixels (framebuffer size)
int getViewportWidth();
- // Set the ratio of hardware pixels to logical pixels (defaults to 1.0)
+ // Set the ratio of hardware pixels to logical pixels (defaults to 1.0);
+ // this operation can be slow, so only perform this when necessary.
void setPixelScale(float _pixelsPerPoint);
// Gets the pixel scale
// point is not visible on the screen, otherwise returns true
bool lngLatToScreenPosition(double _lng, double _lat, double* _x, double* _y);
- // Add a data source for adding drawable map data, which will be styled
+ // Add a tile source for adding drawable map data, which will be styled
// according to the scene file using the provided data source name;
- void addDataSource(std::shared_ptr<DataSource> _source);
+ void addTileSource(std::shared_ptr<TileSource> _source);
- // Remove a data source from the map; returns true if the source was found
+ // Remove a tile source from the map; returns true if the source was found
// and removed, otherwise returns false.
- bool removeDataSource(DataSource& _source);
+ bool removeTileSource(TileSource& _source);
- void clearDataSource(DataSource& _source, bool _data, bool _tiles);
+ void clearTileSource(TileSource& _source, bool _data, bool _tiles);
// Add a marker object to the map and return an ID for it; an ID of 0 indicates an invalid marker;
// the marker will not be drawn until both styling and geometry are set using the functions below.
// Set the styling for a marker object; _styling is a string of YAML that specifies a 'draw rule'
// according to the scene file syntax; returns true if the marker ID was found and successfully
// updated, otherwise returns false.
- bool markerSetStyling(MarkerID _marker, const char* _styling);
+ bool markerSetStylingFromString(MarkerID _marker, const char* _styling);
+
+ // Set an explicit draw group for a marker object; _path is a '.' delimited path to a draw rule
+ // in the current scene. The Marker will be styled using the draw rule specified at this path;
+ // returns true if the marker ID was found and successfully updated, otherwise returns false.
+ bool markerSetStylingFromPath(MarkerID _marker, const char* _path);
// Set a bitmap to use as the image for a point marker; _data is a buffer of RGBA pixel data with
// length of _width * _height; pixels are in row-major order beginning from the bottom-left of the
// efficiency, but can cause errors if your application code makes OpenGL calls (false by default)
void useCachedGlState(bool _use);
- const std::vector<TouchItem>& pickFeaturesAt(float _x, float _y);
+ // Set the radius in logical pixels to use when picking features on the map (default is 0.5).
+ void setPickRadius(float _radius);
+
+ // Create a query to select a feature marked as 'interactive'. The query runs on the next frame.
+ // Calls _onFeaturePickCallback once the query has completed, and returns the FeaturePickResult
+ // with its associated properties or null if no feature was found.
+ void pickFeatureAt(float _x, float _y, FeaturePickCallback _onFeaturePickCallback);
+
+ // Create a query to select a label created for a feature marked as 'interactive'. The query runs
+ // on the next frame.
+ // Calls _onLabelPickCallback once the query has completed, and returns the LabelPickResult
+ // with its associated properties or null if no label was found.
+ void pickLabelAt(float _x, float _y, LabelPickCallback _onLabelPickCallback);
+
+ // Create a query to select a marker that is 'interactive'. The query runs on the next frame.
+ // Calls _onLMarkerPickCallback once the query has completed, and returns the MarkerPickResult
+ // with its associated properties or null if no marker was found.
+ void pickMarkerAt(float _x, float _y, MarkerPickCallback _onMarkerPickCallback);
// Run this task asynchronously to Tangram's main update loop.
void runAsyncTask(std::function<void()> _task);
+ // Send a signal to Tangram that the platform received a memory warning
+ void onMemoryWarning();
+
+ std::shared_ptr<Platform>& getPlatform();
+
private:
class Impl;
std::unique_ptr<Impl> impl;
+
+protected:
+
+ std::shared_ptr<Platform> platform;
+
};
enum DebugFlags {
tangram_infos, // Various text tangram debug info printed on the screen
draw_all_labels, // Draw all labels
tangram_stats, // Tangram frame graph stats
+ selection_buffer, // Render selection framebuffer
};
// Set debug features on or off using a boolean (see debug.h)
void toggleDebugFlag(DebugFlags _flag);
}
-
--- /dev/null
+#pragma once
+
+#include "platform.h"
+#include <condition_variable>
+#include <functional>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <vector>
+
+namespace Tangram {
+
+class UrlClient {
+
+public:
+
+ struct Options {
+ uint32_t numberOfThreads = 4;
+ uint32_t connectionTimeoutMs = 3000;
+ uint32_t requestTimeoutMs = 30000;
+ std::string proxyAddress;
+ };
+
+ struct Response {
+ std::vector<char> data;
+ bool successful = false;
+ bool canceled = false;
+ };
+
+ UrlClient(Options options);
+ ~UrlClient();
+
+ bool addRequest(const std::string& url, UrlCallback onComplete);
+
+ void cancelRequest(const std::string& url);
+
+private:
+ struct Request {
+ std::string url;
+ UrlCallback callback;
+ };
+
+ struct Task {
+ Request request;
+ Response response;
+ };
+
+ void curlLoop(uint32_t index);
+
+ std::vector<std::thread> m_threads;
+ std::vector<Task> m_tasks;
+ std::vector<Request> m_requests;
+ std::condition_variable m_requestCondition;
+ std::mutex m_requestMutex;
+ Options m_options;
+ bool m_keepRunning = false;
+};
+
+} // namespace Tangram
// Nothing to do.
}
-void TangramView::initNetworkRequests() {
- char* proxyAddress = NULL;
- get_proxy_address(&proxyAddress);
-
- initUrlRequests(proxyAddress);
-
- g_free(proxyAddress);
-}
-
-void TangramView::deinitNetworkRequests() {
- stopUrlRequests();
-}
-
mapzen_error_e TangramView::create(maps_view_h view, maps_plugin_map_view_ready_cb callback, const char* providerKey)
{
if (!view) {
return error;
}
- setRenderCallbackFunction([=](){
- ecore_main_loop_thread_safe_call_async(&renderingCb, m_image);
- });
-
m_readyCb = callback;
// TODO: What to do for multiple instances
- setEvasGlAPI(m_api);
+ Tangram::setEvasGlAPI(m_api);
+
+ Tangram::UrlClient::Options urlOptions;
+ char* proxyAddress = NULL;
+ get_proxy_address(&proxyAddress);
+ urlOptions.proxyAddress = proxyAddress;
+ g_free(proxyAddress);
+
+ auto platform = std::shared_ptr<Tangram::TizenPlatform>(new Tangram::TizenPlatform(urlOptions));
+ //auto platform = std::make_shared<Tangram::TizenPlatform>();
+
+ platform->setRenderCallbackFunction([=](){
+ ecore_main_loop_thread_safe_call_async(&renderingCb, m_image);
+ });
// Set up the tangram map.
- m_map = new Tangram::Map();
+ m_map = new Tangram::Map(platform);
float scaleFactor = elm_config_scale_get();
MAPS_LOGD("evas_gl_context_create() set PixelScale %f", scaleFactor);
}
if (m_map) {
- setRenderCallbackFunction(nullptr);
+ static_cast<Tangram::TizenPlatform*>(m_map->getPlatform().get())->setRenderCallbackFunction(nullptr);
removeAllObjects();
delete m_map;
m_map = nullptr;
m_map->setPosition(m_lng, m_lat);
}
- requestRender();
+ m_map->getPlatform()->requestRender();
return MAPZEN_ERROR_NONE;
}
std::snprintf(styleString, sizeof(styleString), styleFormat, int(scaledWidth), int(scaledHeight), anchor.c_str());
MAPS_LOGD("Marker Style String: %s", styleString);
- m_map->markerSetStyling(tvMarker, styleString);
+ m_map->markerSetStylingFromString(tvMarker, styleString);
error = maps_view_object_marker_get_coordinates(object, &mapsCoord);
if (error != MAPS_ERROR_NONE) { break; }
MAPS_LOGD("Polyline Style String: %s", styleString);
- m_map->markerSetStyling(tvMarker, styleString);
+ m_map->markerSetStylingFromString(tvMarker, styleString);
error = maps_view_object_polyline_foreach_point(object, emplaceCoord, &coords);
if (error != MAPS_ERROR_NONE) { break; }
MAPS_LOGD("Polygon Style String: %s", styleString);
- m_map->markerSetStyling(tvMarker, styleString);
+ m_map->markerSetStylingFromString(tvMarker, styleString);
error = maps_view_object_polygon_foreach_point(object, emplaceCoord, &coords);
if (error != MAPS_ERROR_NONE) { break; }
#include <mutex>
#include "mapzen_types.h"
-#include "tangram/types.h"
+#include "tangram/util/types.h"
namespace Tangram {
class Map;
mapzen_error_e onViewObject(maps_view_h view, const maps_view_object_h object, maps_view_object_operation_e operation);
mapzen_error_e captureSnapshot(maps_view_h view, void **data, int *width, int *height, maps_view_colorspace_type_e *cs);
- static void initNetworkRequests();
- static void deinitNetworkRequests();
-
int getWidth() { return m_w; }
int getHeight() { return m_h; }