#pragma once
#include "properties.h"
+#include "types.h"
#include <functional>
#include <memory>
#include <string>
};
class Map {
-
public:
// Create an empty map object. To display a map, call either loadScene() or loadSceneAsync().
void clearDataSource(DataSource& _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.
+ MarkerID markerAdd();
+
+ // Remove a marker object from the map; returns true if the marker ID was found and successfully
+ // removed, otherwise returns false.
+ bool markerRemove(MarkerID _marker);
+
+ // 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);
+
+ // Set the geometry of a marker to a point at the given coordinates; markers can have their
+ // geometry set multiple times with possibly different geometry types; returns true if the
+ // marker ID was found and successfully updated, otherwise returns false.
+ bool markerSetPoint(MarkerID _marker, LngLat _lngLat);
+
+ // Set the geometry of a marker to a point at the given coordinates; if the marker was previously
+ // set to a point, this eases the position over the given duration in seconds with the given EaseType;
+ // returns true if the marker ID was found and successfully updated, otherwise returns false.
+ bool markerSetPointEased(MarkerID _marker, LngLat _lngLat, float _duration, EaseType _ease);
+
+ // Set the geometry of a marker to a polyline along the given coordinates; _coordinates is a
+ // pointer to a sequence of _count LngLats; markers can have their geometry set multiple times
+ // with possibly different geometry types; returns true if the marker ID was found and
+ // successfully updated, otherwise returns false.
+ bool markerSetPolyline(MarkerID _marker, LngLat* _coordinates, int _count);
+
+ // Set the geometry of a marker to a polygon with the given coordinates; _counts is a pointer
+ // to a sequence of _rings integers and _coordinates is a pointer to a sequence of LngLats with
+ // a total length equal to the sum of _counts; for each integer n in _counts, a polygon is created
+ // by taking the next n LngLats from _coordinates, with winding order and internal polygons
+ // behaving according to the GeoJSON specification; markers can have their geometry set multiple
+ // times with possibly different geometry types; returns true if the marker ID was found and
+ // successfully updated, otherwise returns false.
+ bool markerSetPolygon(MarkerID _marker, LngLat* _coordinates, int* _counts, int _rings);
+
+ // Set the visibility of a marker object; returns true if the marker ID was found and successfully
+ // updated, otherwise returns false.
+ bool markerSetVisible(MarkerID _marker, bool _visible);
+
+ // Remove all marker objects from the map; Any marker IDs previously returned from 'markerAdd'
+ // are invalidated after this.
+ void markerRemoveAll();
+
// Respond to a tap at the given screen coordinates (x right, y down)
void handleTapGesture(float _posX, float _posY);
class Impl;
std::unique_ptr<Impl> impl;
-
};
enum DebugFlags {
tile_infos, // Debug tile infos
labels, // Debug label bounding boxes
tangram_infos, // Various text tangram debug info printed on the screen
- all_labels, // Draw all labels
+ draw_all_labels, // Draw all labels
tangram_stats, // Tangram frame graph stats
};
#include "tangram_view.hpp"
#include "tangram/tangram.h"
#include "tangram/platform_tizen.h"
+#include <Elementary.h>
+
+#include <string>
+#include <cstdio>
#define NORMAL_SCENE_FILE_PATH "/usr/share/maps/mapzen/scenes/bubble-wrap/bubble-wrap.yaml"
#define TERRAIN_SCENE_FILE_PATH "/usr/share/maps/mapzen/scenes/walkabout-style/walkabout-style.yaml"
// Set up the tangram map.
m_map = new Tangram::Map();
+
+ float scaleFactor = elm_config_scale_get();
+ MAPS_LOGD("evas_gl_context_create() set PixelScale %f", scaleFactor);
+ m_map->setPixelScale(scaleFactor);
+
m_map->loadScene(NORMAL_SCENE_FILE_PATH);
// Make the GL context current and perform GL setup.
evas_gl_make_current(m_gl, m_surface, m_context);
m_map->setupGL();
+
m_map->resize(m_w, m_h);
readyMapCb((void*)view);
}
if (m_map) {
+ removeAllObjects();
delete m_map;
m_map = nullptr;
}
mapzen_error_e TangramView::onViewObject(maps_view_h view, const maps_view_object_h object, maps_view_object_operation_e operation)
{
- // TODO
- return MAPZEN_ERROR_SERVICE_NOT_AVAILABLE;
+ if (!view || !object || operation < MAPS_VIEW_OBJECT_ADD || operation > MAPS_VIEW_OBJECT_REMOVE) {
+ return MAPZEN_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!m_isInitialized || !m_map) {
+ return MAPZEN_ERROR_SERVICE_NOT_AVAILABLE;
+ }
+
+ return processViewObject(view, object, operation);
+}
+
+mapzen_error_e TangramView::processViewObject(maps_view_h view, const maps_view_object_h object, maps_view_object_operation_e operation)
+{
+ mapzen_error_e error = MAPZEN_ERROR_NONE;
+
+ TangramView *tv = nullptr;
+ int maps_error = maps_view_get_maps_plugin_view_handle(view, (void**)&tv);
+ if (maps_error != MAPS_ERROR_NONE || !tv) { return MAPZEN_ERROR_INVALID_PARAMETER; }
+
+ maps_view_object_type_e type = MAPS_VIEW_OBJECT_POLYLINE;
+ maps_view_object_get_type(object, &type);
+
+ if (type < MAPS_VIEW_OBJECT_POLYLINE || type > MAPS_VIEW_OBJECT_MARKER) { return MAPZEN_ERROR_INVALID_PARAMETER; }
+ if (operation < MAPS_VIEW_OBJECT_ADD || operation > MAPS_VIEW_OBJECT_REMOVE) { return MAPZEN_ERROR_INVALID_PARAMETER; }
+
+ auto& mapViewObjs = tv->mapViewObjects();
+ auto& mutex = tv->viewObjectMutex();
+ MapViewObjects::iterator iter;
+ MapViewObjects::iterator end;
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ iter = mapViewObjs.find(object);
+ end = mapViewObjs.end();
+ }
+
+ switch(operation) {
+ case MAPS_VIEW_OBJECT_ADD:
+ error = tv->addObject(object);
+ break;
+ case MAPS_VIEW_OBJECT_SET_VISIBLE:
+ if (iter != end) {
+ error = tv->setObjectVisible(object, iter->second);
+ }
+ break;
+ case MAPS_VIEW_OBJECT_CHANGE:
+ if (iter != end) {
+ error = tv->updateObject(object, iter->second);
+ }
+ break;
+ case MAPS_VIEW_OBJECT_REMOVE:
+ error = tv->removeObject(object);
+ break;
+ default: break;
+ }
+
+ const char *oper_str[20] = { "ADD", "SET_VISIBLE", "MOVE", "CHANGE", "REMOVE"};
+ const char *type_str[20] = { "POLYLINE", "POLYGON", "MARKER", "UNKNOWN"};
+
+ MAPS_LOGD("Done Processing View Object: type=%s, operation=%s, object=%p",
+ (type >= MAPS_VIEW_OBJECT_POLYLINE && type <= MAPS_VIEW_OBJECT_MARKER) ? type_str[type] : "?",
+ (operation >= MAPS_VIEW_OBJECT_ADD && operation <= MAPS_VIEW_OBJECT_REMOVE) ? oper_str[operation] : "?",
+ object);
+
+ if (error != MAPZEN_ERROR_NONE) {
+ MAPS_LOGD("Something went wrong in processing this ViewObject operation");
+ }
+
+ return error;
+}
+
+mapzen_error_e TangramView::addObject(maps_view_object_h object)
+{
+ if (!object || !m_map) { return MAPZEN_ERROR_INVALID_PARAMETER; }
+
+ mapzen_error_e error = MAPZEN_ERROR_NONE;
+ Tangram::MarkerID tvMarker = 0;
+ maps_view_object_type_e type = MAPS_VIEW_OBJECT_POLYLINE;
+
+ maps_view_object_get_type(object, &type);
+
+ MapViewObjects::iterator iter;
+ MapViewObjects::iterator end;
+
+ switch(type) {
+ case MAPS_VIEW_OBJECT_MARKER:
+ case MAPS_VIEW_OBJECT_POLYGON:
+ case MAPS_VIEW_OBJECT_POLYLINE:
+ {
+ std::lock_guard<std::mutex> lock(m_viewObjectMutex);
+ iter = m_mapViewObjs.find(object);
+ end = m_mapViewObjs.end();
+ }
+ if (iter == end) {
+ tvMarker = m_map->markerAdd();
+ if (tvMarker) {
+ error = updateObject(object, tvMarker);
+ if (error == MAPZEN_ERROR_NONE) {
+ std::lock_guard<std::mutex> lock(m_viewObjectMutex);
+ m_mapViewObjs.insert(std::make_pair(object, tvMarker));
+ } else {
+ m_map->markerRemove(tvMarker);
+ tvMarker = 0;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return error;
+}
+
+mapzen_error_e TangramView::setObjectVisible(maps_view_object_h object, Tangram::MarkerID tvMarker)
+{
+ if (!object || !tvMarker || !m_map) { return MAPZEN_ERROR_INVALID_PARAMETER; }
+
+ bool visible = true;
+ maps_view_object_get_visible(object, &visible);
+
+ m_map->markerSetVisible(tvMarker, visible);
+ return MAPZEN_ERROR_NONE;
+}
+
+mapzen_error_e TangramView::updateObject(maps_view_object_h object, Tangram::MarkerID tvMarker)
+{
+ if (!object || !tvMarker || !m_map) { return MAPZEN_ERROR_INVALID_PARAMETER; }
+
+ int error = MAPS_ERROR_NONE;
+ maps_view_object_type_e type = MAPS_VIEW_OBJECT_POLYLINE;
+
+ maps_view_object_get_type(object, &type);
+
+ std::string styleString = "";
+
+ Tangram::Coordinates coords = {};
+ unsigned char r = 0, g = 0, b = 0, a = 0;
+
+ switch(type) {
+ case MAPS_VIEW_OBJECT_MARKER:
+ {
+ // TODO: distinguish between MAPS_VIEW_MARKER_PIN and MAPS_VIEW_MARKER_STICKER (pin vs billboard?)
+ // TODO: use image passed with the view object, not available in tangram yet!
+ maps_coordinates_h mapsCoord = nullptr;
+ double lat = 0.0, lng = 0.0;
+ int markerWidth = 0, markerHeight = 0;
+
+ const char* styleFormat = "{ style: 'ux-icons-overlay', sprite: 'ux-search-active', size: [%dpx, %dpx], collide: false, anchor: top, transition: { [show, hide]: { time: 0s } } }";
+
+ error = maps_view_object_marker_get_size(object, &markerWidth, &markerHeight);
+ if (error != MAPS_ERROR_NONE) { break; }
+
+ int sz = std::snprintf(nullptr, 0, styleFormat, markerWidth, markerHeight);
+ styleString.resize(sz+1);
+ std::snprintf(&styleString[0], styleString.size(), styleFormat, markerWidth, markerHeight);
+
+ m_map->markerSetStyling(tvMarker, styleString.c_str());
+
+ error = maps_view_object_marker_get_coordinates(object, &mapsCoord);
+ if (error != MAPS_ERROR_NONE) { break; }
+
+ error = maps_coordinates_get_longitude(mapsCoord, &lng);
+ if (error != MAPS_ERROR_NONE) {
+ maps_coordinates_destroy(mapsCoord);
+ break;
+ }
+
+ error = maps_coordinates_get_latitude(mapsCoord, &lat);
+ if (error != MAPS_ERROR_NONE) {
+ maps_coordinates_destroy(mapsCoord);
+ break;
+ }
+
+ maps_coordinates_destroy(mapsCoord);
+ m_map->markerSetPoint(tvMarker, Tangram::LngLat(lng, lat));
+ }
+ break;
+ case MAPS_VIEW_OBJECT_POLYLINE:
+ {
+ int width = 0;
+ const char* styleFormat = "{ style: 'ux-route-line-overlay', color: [%d, %d, %d, %d], width: %dpx, order: 500 }";
+
+ error = maps_view_object_polyline_get_color(object, &r, &g, &b, &a);
+ if (error != MAPS_ERROR_NONE) { break; }
+
+ error = maps_view_object_polyline_get_width(object, &width);
+ if (error != MAPS_ERROR_NONE) { break; }
+
+ int sz = std::snprintf(nullptr, 0, styleFormat, r, g, b, a, width);
+ styleString.resize(sz+1);
+ std::snprintf(&styleString[0], styleString.size(), styleFormat, r, g, b, a, width);
+
+ m_map->markerSetStyling(tvMarker, styleString.c_str());
+
+ error = maps_view_object_polyline_foreach_point(object, emplaceCoord, &coords);
+ if (error != MAPS_ERROR_NONE) { break; }
+
+ m_map->markerSetPolyline(tvMarker, coords.data(), static_cast<int>(coords.size()));
+ }
+ break;
+ case MAPS_VIEW_OBJECT_POLYGON:
+ {
+ const char* styleFormat = "{ style: 'polygons', color: [%d, %d, %d, %d] }";
+
+ error = maps_view_object_polygon_get_fill_color(object, &r, &g, &b, &a);
+ if (error != MAPS_ERROR_NONE) { break; }
+
+ int sz = std::snprintf(nullptr, 0, styleFormat, r, g, b, a);
+ styleString.resize(sz+1);
+ std::snprintf(&styleString[0], styleString.size(), styleFormat, r, g, b, a);
+
+ m_map->markerSetStyling(tvMarker, styleString.c_str());
+
+ error = maps_view_object_polygon_foreach_point(object, emplaceCoord, &coords);
+ if (error != MAPS_ERROR_NONE) { break; }
+
+ int count = (int)coords.size();
+ m_map->markerSetPolygon(tvMarker, coords.data(), &count, 1);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return (mapzen_error_e)convert_maps_error_to_mapzen_error(error);
+}
+
+mapzen_error_e TangramView::removeObject(maps_view_object_h object)
+{
+ if (!object || !m_map) { return MAPZEN_ERROR_INVALID_PARAMETER; }
+
+ mapzen_error_e error = MAPZEN_ERROR_NONE;
+
+ std::lock_guard<std::mutex> lock(m_viewObjectMutex);
+ auto iter = m_mapViewObjs.find(object);
+ if (iter != m_mapViewObjs.end()) {
+ if (iter->second) {
+ m_map->markerRemove(iter->second);
+ }
+ iter = m_mapViewObjs.erase(iter);
+ error = MAPZEN_ERROR_NONE;
+ }
+
+ return error;
+}
+
+void TangramView::removeAllObjects()
+{
+ std::lock_guard<std::mutex> lock(m_viewObjectMutex);
+ m_mapViewObjs.clear();
+ m_map->markerRemoveAll();
+}
+
+bool TangramView::emplaceCoord(int index, maps_coordinates_h coordinate, void *user_data)
+{
+ if (!coordinate || !user_data) { return false; }
+
+ int error = 0;
+ double lng = 0.0, lat = 0.0;
+
+ error = maps_coordinates_get_longitude(coordinate, &lng);
+ if (error != MAPS_ERROR_NONE) {
+ MAPS_LOGD("Not able to extract longitude from coordiate");
+ return false;
+ }
+ error = maps_coordinates_get_latitude(coordinate, &lat);
+ if (error != MAPS_ERROR_NONE) {
+ MAPS_LOGD("Not able to extract longitude from coordiate");
+ return false;
+ }
+
+ MAPS_LOGD("[%d] %f, %f", index+1, lng, lat);
+
+ Tangram::Coordinates *coords = static_cast<Tangram::Coordinates*>(user_data);
+ coords->emplace_back(lng, lat);
+ return true;
}
mapzen_error_e TangramView::captureSnapshot(maps_view_h view, void **data, int *width, int *height, maps_view_colorspace_type_e *cs)