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;
55 void HereView::TerminateService(void)
58 MAPS_LOGD("close HereView");
64 here_error_e HereView::init(maps_view_h view, maps_plugin_map_view_ready_cb callback)
67 return HERE_ERROR_INVALID_PARAMETER;
69 __idler = ecore_idler_add(__idlerCb, (void*)view);
71 here_error_e error = HERE_ERROR_NONE;
72 int error2 = MAPS_ERROR_NONE;
75 error2 = maps_view_get_viewport(view, &__img);
76 if (error2 != MAPS_ERROR_NONE) break;
78 error2 = maps_view_get_screen_location(view, &__x, &__y, &__w, &__h);
79 if (error2 != MAPS_ERROR_NONE) break;
82 if (error != HERE_ERROR_NONE) break;
84 error = initOpenGLSurface(view);
85 if (error != HERE_ERROR_NONE) break;
87 error = initMap(view, callback);
90 if (error == HERE_ERROR_NONE && error2 != MAPS_ERROR_NONE)
91 error = (here_error_e)ConvertToHereError(error2);
96 here_error_e HereView::initOpenGL()
98 __cfg = evas_gl_config_new();
100 MAPS_LOGE("evas_gl_config_new() failed");
101 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
104 __cfg->color_format = EVAS_GL_RGBA_8888; // Surface Color Format
105 __cfg->depth_bits = EVAS_GL_DEPTH_NONE; // Surface Depth Format
106 __cfg->stencil_bits = EVAS_GL_STENCIL_NONE; // Surface Stencil Format
107 __cfg->options_bits = EVAS_GL_OPTIONS_DIRECT; // Configuration options (here, no extra options)
109 __gl = evas_gl_new(evas_object_evas_get(__img));
111 MAPS_LOGE("evas_gl_new() failed");
112 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
115 __api = evas_gl_api_get(__gl);
117 MAPS_LOGE("evas_gl_api_get() failed");
118 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
121 __ctx = evas_gl_context_create(__gl, NULL);
123 MAPS_LOGE("evas_gl_context_create() failed");
124 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
127 return HERE_ERROR_NONE;
130 here_error_e HereView::initOpenGLSurface(maps_view_h view)
132 if (!view || !__gl || !__cfg || !__img || !__ctx)
133 return HERE_ERROR_INVALID_PARAMETER;
135 evas_object_image_pixels_get_callback_set(__img, NULL, NULL);
138 evas_object_image_native_surface_set(__img, NULL);
139 evas_gl_surface_destroy(__gl, __sfc);
145 evas_object_image_size_set(__img, __w, __h);
147 Evas_Native_Surface ns;
148 __sfc = evas_gl_surface_create(__gl, __cfg, __w, __h);
150 MAPS_LOGE("evas_gl_surface_create() failed");
151 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
154 if (!evas_gl_native_surface_get(__gl, __sfc, &ns)) {
155 evas_gl_make_current(__gl, NULL, NULL);
156 evas_gl_surface_destroy(__gl, __sfc);
158 MAPS_LOGE("evas_gl_native_surface_get() faile");
159 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
162 evas_object_image_native_surface_set(__img, &ns);
163 evas_object_image_pixels_get_callback_set(__img, __pixelGetCb, view);
164 __isInitialized = true;
166 return HERE_ERROR_NONE;
169 here_error_e HereView::initMap(maps_view_h view, maps_plugin_map_view_ready_cb callback)
172 return HERE_ERROR_INVALID_PARAMETER;
174 __map = new (std::nothrow) GeoTiledMap();
176 return HERE_ERROR_OUT_OF_MEMORY;
178 __readyCb = callback;
180 __map->SetReadyMapSignal((GeoTiledMap::ReadyMapSignalFunctor)__readyMapCb, (void *)view);
181 __map->SetEvasGlApi(__api);
182 __map->SetMapSize(Dimension(__w, __h));
184 __visualObjects.set(__map, evas_object_evas_get(__img));
186 return HERE_ERROR_NONE;
189 here_error_e HereView::close(maps_view_h view)
193 __isInitialized = false;
196 __visualObjects.set(NULL, NULL);
199 evas_object_image_pixels_get_callback_set(__img, NULL, NULL);
202 ecore_idler_del(__idler);
207 __map->SetUpdateMapSignal(NULL);
214 evas_gl_make_current(__gl, __sfc, __ctx);
217 evas_object_image_native_surface_set(__img, NULL);
218 evas_gl_surface_destroy(__gl, __sfc);
222 evas_gl_context_destroy(__gl, __ctx);
229 evas_gl_config_free(__cfg);
231 return HERE_ERROR_NONE;
234 void HereView::__readyMapCb(void *data)
237 int maps_error = maps_view_get_maps_plugin_view_handle((maps_view_h)data, (void**)&hv);
238 if (maps_error != MAPS_ERROR_NONE || !hv) return;
244 void HereView::__pixelGetCb(void *data, Evas_Object *obj)
247 int maps_error = maps_view_get_maps_plugin_view_handle(data, (void**)&hv);
248 if (maps_error != MAPS_ERROR_NONE || !hv ||
249 !hv->__map || !hv->__gl || !hv->__sfc || !hv->__ctx) return;
251 evas_gl_make_current(hv->__gl, hv->__sfc, hv->__ctx);
252 hv->__map->PaintMap(hv->__w, hv->__h);
255 void HereView::__renderingCb(void *data)
258 evas_object_image_pixels_dirty_set((Evas_Object*)data, EINA_TRUE);
261 void HereView::setMapType(maps_view_h view)
266 /* When the theme is changed, clear cache */
267 maps_view_type_e map_type;
268 maps_view_get_type(view, &map_type);
270 bool buildings_enabled = false;
271 maps_view_get_buildings_enabled(view, &buildings_enabled);
273 bool traffic_enabled = false;
274 maps_view_get_traffic_enabled(view, &traffic_enabled);
276 bool public_transit_enabled = false;
277 maps_view_get_public_transit_enabled(view, &public_transit_enabled);
279 GeoTiledMap::MapType hereMapType = HereUtils::Convert(map_type, buildings_enabled,
280 traffic_enabled, public_transit_enabled);
282 if (hereMapType != __map->GetMapType())
284 MAPS_LOGD("Clear cache, because map type is changed.");
286 #ifdef TIZEN_SUPPORT_TILE_FILE_CACHE
287 __map->ClearTileFileCache();
289 __map->SetMapType(hereMapType);
293 here_error_e HereView::renderMap(maps_view_h view, const maps_coordinates_h coord, double zoom, double angle)
296 return HERE_ERROR_INVALID_PARAMETER;
298 if (!__isInitialized || !__map || !__api)
299 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
306 maps_view_get_screen_location(view, &x, &y, &w, &h);
310 if (x != __x || y != __y || w != __w || h != __h) {
316 __api->glViewport(0, 0, __w, __h);
317 __map->SetMapSize(Dimension(__w, __h));
318 initOpenGLSurface(view);
322 GeoTiledMap::UpdateMapSignalFunctor callback = std::tr1::bind(&__renderingCb, __img);
323 __map->SetUpdateMapSignal(callback);
326 if (__map->GetZoomLevel() != zoom) {
327 __map->SetZoomLevel(zoom, false);
331 if (__map->GetAngle() != angle) {
332 __map->SetAngle(angle);
337 maps_coordinates_get_latitude(coord, &lat);
338 maps_coordinates_get_longitude(coord, &lng);
340 GeoCoordinates geoCoord(lat, lng);
341 __map->SetCenter(geoCoord);
343 return HERE_ERROR_NONE;
346 here_error_e HereView::moveCenter(maps_view_h view, int delta_x, int delta_y)
349 return HERE_ERROR_INVALID_PARAMETER;
351 if (!__isInitialized || !__map)
352 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
354 if (delta_x == 0 && delta_y == 0)
355 return HERE_ERROR_NONE;
357 __map->Pan(delta_x, delta_y);
359 return HERE_ERROR_NONE;
362 here_error_e HereView::getCenter(maps_view_h view, maps_coordinates_h *center)
364 if (!view || !center)
365 return HERE_ERROR_INVALID_PARAMETER;
367 if (!__isInitialized || !__map)
368 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
370 GeoCoordinates geoCoord = __map->GetCenter();
371 if (*center == NULL) {
372 maps_coordinates_create(geoCoord.GetLatitude(), geoCoord.GetLongitude(), center);
374 maps_coordinates_set_latitude(*center, geoCoord.GetLatitude());
375 maps_coordinates_set_longitude(*center, geoCoord.GetLongitude());
378 return HERE_ERROR_NONE;
381 here_error_e HereView::setScalebarEnabled(maps_view_h view, bool enable)
384 return HERE_ERROR_INVALID_PARAMETER;
386 if (!__isInitialized || !__map)
387 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
389 __map->SetScalebar(enable);
391 return HERE_ERROR_NONE;
394 here_error_e HereView::getScalebarEnabled(maps_view_h view, bool *enabled)
396 if (!view || !enabled)
397 return HERE_ERROR_INVALID_PARAMETER;
399 if (!__isInitialized || !__map)
400 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
402 *enabled = __map->GetScalebar();
403 return HERE_ERROR_NONE;
406 here_error_e HereView::convertScreenToGeolocation(maps_view_h view, int x, int y, maps_coordinates_h *coord)
409 return HERE_ERROR_INVALID_PARAMETER;
411 if (!__isInitialized || !__map)
412 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
414 Tizen::Maps::Point point(x, y);
415 GeoCoordinates geoCoord = __map->ScreenPositionToCoordinate(point);
416 double lat = geoCoord.GetLatitude();
417 double lng = geoCoord.GetLongitude();
419 int error = maps_coordinates_create(lat, lng, coord);
420 if (error != MAPS_ERROR_NONE)
421 return (here_error_e)ConvertToHereError(error);
423 return HERE_ERROR_NONE;
426 here_error_e HereView::convertGeolocationToScreen(maps_view_h view, const maps_coordinates_h coord, int *x, int *y)
428 if (!view || !x || !y)
429 return HERE_ERROR_INVALID_PARAMETER;
431 if (!__isInitialized || !__map)
432 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
435 maps_coordinates_get_latitude(coord, &lat);
436 maps_coordinates_get_longitude(coord, &lng);
437 GeoCoordinates geoCoord(lat, lng);
438 Tizen::Maps::Point point = __map->CoordinateToScreenPosition(geoCoord);
443 return HERE_ERROR_NONE;
446 here_error_e HereView::getMinZoomLevel(maps_view_h view, int *zoom)
449 return HERE_ERROR_INVALID_PARAMETER;
451 if (!__isInitialized || !__map)
452 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
454 *zoom = (int)__map->GetMinimumZoomLevel();
456 return HERE_ERROR_NONE;
459 here_error_e HereView::getMaxZoomLevel(maps_view_h view, int *zoom)
462 return HERE_ERROR_INVALID_PARAMETER;
464 if (!__isInitialized || !__map)
465 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
467 *zoom = (int)__map->GetMaximumZoomLevel();
469 return HERE_ERROR_NONE;
472 here_error_e HereView::onViewObject(maps_view_h view, const maps_view_object_h object, maps_view_object_operation_e operation)
474 if (!view || !object ||
475 operation < MAPS_VIEW_OBJECT_ADD || operation > MAPS_VIEW_OBJECT_REMOVE)
476 return HERE_ERROR_INVALID_PARAMETER;
478 if (!__isInitialized || !__map)
479 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
481 if (__map->GetRootPixmap())
482 __processViewObject(view, object, operation);
484 __pendingObjects.push_back(std::make_pair(object, operation));
486 return HERE_ERROR_NONE;
489 Eina_Bool HereView::__idlerCb(void *data)
492 int maps_error = maps_view_get_maps_plugin_view_handle(data, (void**)&hv);
493 if (maps_error != MAPS_ERROR_NONE || !hv) return ECORE_CALLBACK_CANCEL;
494 if (hv->__isShutdown) return ECORE_CALLBACK_CANCEL;
495 if (!hv->__map || !hv->__map->GetRootPixmap()) return ECORE_CALLBACK_RENEW;
497 while (hv->__pendingObjects.size()) {
498 PendingObject pending = hv->__pendingObjects.front();
499 hv->__pendingObjects.pop_front();
500 maps_view_object_h object = pending.first;
501 maps_view_object_operation_e operation = pending.second;
503 __processViewObject(data, object, operation);
505 return ECORE_CALLBACK_RENEW;
508 void HereView::__processViewObject(maps_view_h view, const maps_view_object_h object, maps_view_object_operation_e operation)
511 int maps_error = maps_view_get_maps_plugin_view_handle(view, (void**)&hv);
512 if (maps_error != MAPS_ERROR_NONE || !hv) return;
514 maps_view_object_type_e type;
515 maps_view_object_get_type(object, &type);
517 if (type < MAPS_VIEW_OBJECT_POLYLINE || type > MAPS_VIEW_OBJECT_MARKER) return;
518 if (operation < MAPS_VIEW_OBJECT_ADD || operation > MAPS_VIEW_OBJECT_REMOVE) return;
520 const char *oper_str[20] = { "ADD", "SET_VISIBLE", "MOVE", "CHANGE", "REMOVE"};
521 const char *type_str[20] = { "POLYLINE", "POLYGON", "MARKER", "ROUTE", "UNKNOWN"};
523 MAPS_LOGD("type=%s, operation=%s, object=%p",
524 (type >= MAPS_VIEW_OBJECT_POLYLINE && type <= MAPS_VIEW_OBJECT_MARKER) ? type_str[type] : "?",
525 (operation >= MAPS_VIEW_OBJECT_ADD && operation <= MAPS_VIEW_OBJECT_REMOVE) ? oper_str[operation] : "?",
530 case MAPS_VIEW_OBJECT_ADD: hv->__visualObjects.add(object); break;
531 case MAPS_VIEW_OBJECT_SET_VISIBLE: hv->__visualObjects.setVisible(object); break;
532 case MAPS_VIEW_OBJECT_CHANGE: hv->__visualObjects.update(object); break;
533 case MAPS_VIEW_OBJECT_REMOVE: hv->__visualObjects.remove(object); break;
538 here_error_e HereView::captureSnapshot(maps_view_h view, void **data, int *width, int *height,
539 maps_view_colorspace_type_e *cs)
541 if (!__isInitialized || !__map || __w <= 0 || __h <= 0)
542 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
544 int sizeOfLine = (__w * 4);
545 unsigned char *readData = (unsigned char*)malloc(sizeOfLine * __h);
547 return HERE_ERROR_OUT_OF_MEMORY;
549 *data = (void*)malloc(sizeOfLine * __h);
552 return HERE_ERROR_OUT_OF_MEMORY;
555 __pixelGetCb(view, NULL);
556 __api->glReadPixels(0, 0, __w, __h, GL_RGBA, GL_UNSIGNED_BYTE, readData);
557 for(int i = 0; i < __h; i++)
558 memcpy((unsigned char*)*data + sizeOfLine * i, readData + sizeOfLine * (__h - i - 1), sizeOfLine);
563 *cs = MAPS_VIEW_COLORSPACE_RGBA8888;
565 return HERE_ERROR_NONE;
568 here_error_e HereView::getViewScale(maps_view_h view, double *scale)
571 return HERE_ERROR_INVALID_PARAMETER;
573 if (!__isInitialized || !__map)
574 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
576 *scale = __map->GetScale();
578 return HERE_ERROR_NONE;
581 here_error_e HereView::setViewScale(maps_view_h view, double scale)
584 return HERE_ERROR_INVALID_PARAMETER;
586 if (!__isInitialized || !__map)
587 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
589 __map->SetScale(scale);
591 return HERE_ERROR_NONE;
594 HERE_PLUGIN_END_NAMESPACE