2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "here_view.h"
18 #include <Elementary.h>
20 using namespace HERE_PLUGIN_NAMESPACE_PREFIX;
22 static const char SIG_LOADED[] = "loaded";
25 HERE_PLUGIN_BEGIN_NAMESPACE
38 __isInitialized = false;
54 here_error_e HereView::init(maps_view_h view, maps_plugin_map_view_ready_cb callback)
57 return HERE_ERROR_INVALID_PARAMETER;
59 __idler = ecore_idler_add(__idlerCb, (void*)view);
61 here_error_e error = HERE_ERROR_NONE;
62 int error2 = MAPS_ERROR_NONE;
65 error2 = maps_view_get_viewport(view, &__img);
66 if (error2 != MAPS_ERROR_NONE) break;
68 error2 = maps_view_get_screen_location(view, &__x, &__y, &__w, &__h);
69 if (error2 != MAPS_ERROR_NONE) break;
72 if (error != HERE_ERROR_NONE) break;
74 error = initOpenGLSurface(view);
75 if (error != HERE_ERROR_NONE) break;
77 error = initMap(view, callback);
80 if (error == HERE_ERROR_NONE && error2 != MAPS_ERROR_NONE)
81 error = (here_error_e)ConvertToHereError(error2);
86 here_error_e HereView::initOpenGL()
88 __cfg = evas_gl_config_new();
90 MAPS_LOGE("evas_gl_config_new() failed");
91 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
94 __cfg->color_format = EVAS_GL_RGBA_8888; // Surface Color Format
95 __cfg->depth_bits = EVAS_GL_DEPTH_NONE; // Surface Depth Format
96 __cfg->stencil_bits = EVAS_GL_STENCIL_NONE; // Surface Stencil Format
97 __cfg->options_bits = EVAS_GL_OPTIONS_DIRECT; // Configuration options (here, no extra options)
99 __gl = evas_gl_new(evas_object_evas_get(__img));
101 MAPS_LOGE("evas_gl_new() failed");
102 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
105 __api = evas_gl_api_get(__gl);
107 MAPS_LOGE("evas_gl_api_get() failed");
108 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
111 __ctx = evas_gl_context_create(__gl, NULL);
113 MAPS_LOGE("evas_gl_context_create() failed");
114 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
117 return HERE_ERROR_NONE;
120 here_error_e HereView::initOpenGLSurface(maps_view_h view)
122 if (!view || !__gl || !__cfg || !__img || !__ctx)
123 return HERE_ERROR_INVALID_PARAMETER;
125 evas_object_image_pixels_get_callback_set(__img, NULL, NULL);
128 evas_object_image_native_surface_set(__img, NULL);
129 evas_gl_surface_destroy(__gl, __sfc);
135 evas_object_image_size_set(__img, __w, __h);
137 Evas_Native_Surface ns;
138 __sfc = evas_gl_surface_create(__gl, __cfg, __w, __h);
140 MAPS_LOGE("evas_gl_surface_create() failed");
141 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
144 if (!evas_gl_native_surface_get(__gl, __sfc, &ns)) {
145 evas_gl_make_current(__gl, NULL, NULL);
146 evas_gl_surface_destroy(__gl, __sfc);
148 MAPS_LOGE("evas_gl_native_surface_get() faile");
149 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
152 evas_object_image_native_surface_set(__img, &ns);
153 evas_object_image_pixels_get_callback_set(__img, __pixelGetCb, view);
154 __isInitialized = true;
156 return HERE_ERROR_NONE;
159 here_error_e HereView::initMap(maps_view_h view, maps_plugin_map_view_ready_cb callback)
162 return HERE_ERROR_INVALID_PARAMETER;
164 __map = new (std::nothrow) GeoTiledMap();
166 return HERE_ERROR_OUT_OF_MEMORY;
168 __readyCb = callback;
170 __map->SetReadyMapSignal((GeoTiledMap::ReadyMapSignalFunctor)__readyMapCb, (void *)view);
171 __map->SetEvasGlApi(__api);
172 __map->SetMapSize(Dimension(__w, __h));
174 __visualObjects.set(__map, evas_object_evas_get(__img));
176 return HERE_ERROR_NONE;
179 here_error_e HereView::close(maps_view_h view)
182 return HERE_ERROR_INVALID_PARAMETER;
184 __isInitialized = false;
186 __visualObjects.set(NULL, NULL);
189 evas_object_image_pixels_get_callback_set(__img, NULL, NULL);
192 ecore_idler_del(__idler);
195 __map->SetUpdateMapSignal(NULL);
202 evas_gl_make_current(__gl, __sfc, __ctx);
205 evas_object_image_native_surface_set(__img, NULL);
206 evas_gl_surface_destroy(__gl, __sfc);
210 evas_gl_context_destroy(__gl, __ctx);
217 evas_gl_config_free(__cfg);
219 return HERE_ERROR_NONE;
222 void HereView::__readyMapCb(void *data)
225 int maps_error = maps_view_get_maps_plugin_view_handle((maps_view_h)data, (void**)&hv);
226 if (maps_error != MAPS_ERROR_NONE || !hv) return;
232 void HereView::__pixelGetCb(void *data, Evas_Object *obj)
235 int maps_error = maps_view_get_maps_plugin_view_handle(data, (void**)&hv);
236 if (maps_error != MAPS_ERROR_NONE || !hv ||
237 !hv->__map || !hv->__gl || !hv->__sfc || !hv->__ctx) return;
239 evas_gl_make_current(hv->__gl, hv->__sfc, hv->__ctx);
240 hv->__map->PaintMap(hv->__w, hv->__h);
243 void HereView::__renderingCb(void *data)
246 evas_object_image_pixels_dirty_set((Evas_Object*)data, EINA_TRUE);
249 void HereView::setMapType(maps_view_h view)
254 /* When the theme is changed, clear cache */
255 maps_view_type_e map_type;
256 maps_view_get_type(view, &map_type);
258 bool buildings_enabled = false;
259 maps_view_get_buildings_enabled(view, &buildings_enabled);
261 bool traffic_enabled = false;
262 maps_view_get_traffic_enabled(view, &traffic_enabled);
264 bool public_transit_enabled = false;
265 maps_view_get_public_transit_enabled(view, &public_transit_enabled);
267 GeoTiledMap::MapType hereMapType = HereUtils::Convert(map_type, buildings_enabled,
268 traffic_enabled, public_transit_enabled);
270 if (hereMapType != __map->GetMapType())
272 MAPS_LOGD("Clear cache, because map type is changed.");
274 #ifdef TIZEN_SUPPORT_TILE_FILE_CACHE
275 __map->ClearTileFileCache();
277 __map->SetMapType(hereMapType);
281 here_error_e HereView::renderMap(maps_view_h view, const maps_coordinates_h coord, double zoom, double angle)
284 return HERE_ERROR_INVALID_PARAMETER;
286 if (!__isInitialized || !__map || !__api)
287 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
294 maps_view_get_screen_location(view, &x, &y, &w, &h);
298 if (x != __x || y != __y || w != __w || h != __h) {
304 __api->glViewport(0, 0, __w, __h);
305 __map->SetMapSize(Dimension(__w, __h));
306 initOpenGLSurface(view);
310 GeoTiledMap::UpdateMapSignalFunctor callback = std::tr1::bind(&__renderingCb, __img);
311 __map->SetUpdateMapSignal(callback);
314 if (__map->GetZoomLevel() != zoom) {
315 __map->SetZoomLevel(zoom, false);
319 if (__map->GetAngle() != angle) {
320 __map->SetAngle(angle);
325 maps_coordinates_get_latitude(coord, &lat);
326 maps_coordinates_get_longitude(coord, &lng);
328 GeoCoordinates geoCoord(lat, lng);
329 __map->SetCenter(geoCoord);
331 return HERE_ERROR_NONE;
334 here_error_e HereView::moveCenter(maps_view_h view, int delta_x, int delta_y)
337 return HERE_ERROR_INVALID_PARAMETER;
339 if (!__isInitialized || !__map)
340 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
342 if (delta_x == 0 && delta_y == 0)
343 return HERE_ERROR_NONE;
345 __map->Pan(delta_x, delta_y);
347 return HERE_ERROR_NONE;
350 here_error_e HereView::getCenter(maps_view_h view, maps_coordinates_h *center)
352 if (!view || !center)
353 return HERE_ERROR_INVALID_PARAMETER;
355 if (!__isInitialized || !__map)
356 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
358 GeoCoordinates geoCoord = __map->GetCenter();
359 if (*center == NULL) {
360 maps_coordinates_create(geoCoord.GetLatitude(), geoCoord.GetLongitude(), center);
362 maps_coordinates_set_latitude(*center, geoCoord.GetLatitude());
363 maps_coordinates_set_longitude(*center, geoCoord.GetLongitude());
366 return HERE_ERROR_NONE;
369 here_error_e HereView::setScalebarEnabled(maps_view_h view, bool enable)
372 return HERE_ERROR_INVALID_PARAMETER;
374 if (!__isInitialized || !__map)
375 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
377 __map->SetScalebar(enable);
379 return HERE_ERROR_NONE;
382 here_error_e HereView::getScalebarEnabled(maps_view_h view, bool *enabled)
384 if (!view || !enabled)
385 return HERE_ERROR_INVALID_PARAMETER;
387 if (!__isInitialized || !__map)
388 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
390 *enabled = __map->GetScalebar();
391 return HERE_ERROR_NONE;
394 here_error_e HereView::convertScreenToGeolocation(maps_view_h view, int x, int y, maps_coordinates_h *coord)
397 return HERE_ERROR_INVALID_PARAMETER;
399 if (!__isInitialized || !__map)
400 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
402 Tizen::Maps::Point point(x, y);
403 GeoCoordinates geoCoord = __map->ScreenPositionToCoordinate(point);
404 double lat = geoCoord.GetLatitude();
405 double lng = geoCoord.GetLongitude();
407 int error = maps_coordinates_create(lat, lng, coord);
408 if (error != MAPS_ERROR_NONE)
409 return (here_error_e)ConvertToHereError(error);
411 return HERE_ERROR_NONE;
414 here_error_e HereView::convertGeolocationToScreen(maps_view_h view, const maps_coordinates_h coord, int *x, int *y)
416 if (!view || !x || !y)
417 return HERE_ERROR_INVALID_PARAMETER;
419 if (!__isInitialized || !__map)
420 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
423 maps_coordinates_get_latitude(coord, &lat);
424 maps_coordinates_get_longitude(coord, &lng);
425 GeoCoordinates geoCoord(lat, lng);
426 Tizen::Maps::Point point = __map->CoordinateToScreenPosition(geoCoord);
431 return HERE_ERROR_NONE;
434 here_error_e HereView::getMinZoomLevel(maps_view_h view, int *zoom)
437 return HERE_ERROR_INVALID_PARAMETER;
439 if (!__isInitialized || !__map)
440 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
442 *zoom = (int)__map->GetMinimumZoomLevel();
444 return HERE_ERROR_NONE;
447 here_error_e HereView::getMaxZoomLevel(maps_view_h view, int *zoom)
450 return HERE_ERROR_INVALID_PARAMETER;
452 if (!__isInitialized || !__map)
453 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
455 *zoom = (int)__map->GetMaximumZoomLevel();
457 return HERE_ERROR_NONE;
460 here_error_e HereView::onViewObject(maps_view_h view, const maps_view_object_h object, maps_view_object_operation_e operation)
462 if (!view || !object ||
463 operation < MAPS_VIEW_OBJECT_ADD || operation > MAPS_VIEW_OBJECT_REMOVE)
464 return HERE_ERROR_INVALID_PARAMETER;
466 if (!__isInitialized || !__map)
467 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
469 if (__map->GetRootPixmap())
470 __processViewObject(view, object, operation);
472 __pendingObjects.push_back(std::make_pair(object, operation));
474 return HERE_ERROR_NONE;
477 Eina_Bool HereView::__idlerCb(void *data)
480 int maps_error = maps_view_get_maps_plugin_view_handle(data, (void**)&hv);
481 if (maps_error != MAPS_ERROR_NONE || !hv) return true;
482 if (!hv->__map || !hv->__map->GetRootPixmap()) return true;
484 while (hv->__pendingObjects.size()) {
485 PendingObject pending = hv->__pendingObjects.front();
486 hv->__pendingObjects.pop_front();
487 maps_view_object_h object = pending.first;
488 maps_view_object_operation_e operation = pending.second;
490 __processViewObject(data, object, operation);
495 void HereView::__processViewObject(maps_view_h view, const maps_view_object_h object, maps_view_object_operation_e operation)
498 int maps_error = maps_view_get_maps_plugin_view_handle(view, (void**)&hv);
499 if (maps_error != MAPS_ERROR_NONE || !hv) return;
501 maps_view_object_type_e type;
502 maps_view_object_get_type(object, &type);
504 if (type < MAPS_VIEW_OBJECT_POLYLINE || type > MAPS_VIEW_OBJECT_MARKER) return;
505 if (operation < MAPS_VIEW_OBJECT_ADD || operation > MAPS_VIEW_OBJECT_REMOVE) return;
507 const char *oper_str[20] = { "ADD", "SET_VISIBLE", "MOVE", "CHANGE", "REMOVE"};
508 const char *type_str[20] = { "POLYLINE", "POLYGON", "MARKER", "ROUTE", "UNKNOWN"};
510 MAPS_LOGD("type=%s, operation=%s, object=%p",
511 (type >= MAPS_VIEW_OBJECT_POLYLINE && type <= MAPS_VIEW_OBJECT_MARKER) ? type_str[type] : "?",
512 (operation >= MAPS_VIEW_OBJECT_ADD && operation <= MAPS_VIEW_OBJECT_REMOVE) ? oper_str[operation] : "?",
517 case MAPS_VIEW_OBJECT_ADD: hv->__visualObjects.add(object); break;
518 case MAPS_VIEW_OBJECT_SET_VISIBLE: hv->__visualObjects.setVisible(object); break;
519 case MAPS_VIEW_OBJECT_CHANGE: hv->__visualObjects.update(object); break;
520 case MAPS_VIEW_OBJECT_REMOVE: hv->__visualObjects.remove(object); break;
525 here_error_e HereView::captureSnapshot(maps_view_h view, void **data, int *width, int *height,
526 maps_view_colorspace_type_e *cs)
528 if (!__isInitialized || !__map || __w <= 0 || __h <= 0)
529 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
531 int sizeOfLine = (__w * 4);
532 unsigned char *readData = (unsigned char*)malloc(sizeOfLine * __h);
534 return HERE_ERROR_OUT_OF_MEMORY;
536 *data = (void*)malloc(sizeOfLine * __h);
539 return HERE_ERROR_OUT_OF_MEMORY;
542 __pixelGetCb(view, NULL);
543 __api->glReadPixels(0, 0, __w, __h, GL_RGBA, GL_UNSIGNED_BYTE, readData);
544 for(int i = 0; i < __h; i++)
545 memcpy((unsigned char*)*data + sizeOfLine * i, readData + sizeOfLine * (__h - i - 1), sizeOfLine);
550 *cs = MAPS_VIEW_COLORSPACE_RGBA8888;
552 return HERE_ERROR_NONE;
555 here_error_e HereView::getViewScale(maps_view_h view, double *scale)
558 return HERE_ERROR_INVALID_PARAMETER;
560 if (!__isInitialized || !__map)
561 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
563 *scale = __map->GetScale();
565 return HERE_ERROR_NONE;
568 here_error_e HereView::setViewScale(maps_view_h view, double scale)
571 return HERE_ERROR_INVALID_PARAMETER;
573 if (!__isInitialized || !__map)
574 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
576 __map->SetScale(scale);
578 return HERE_ERROR_NONE;
581 HERE_PLUGIN_END_NAMESPACE