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;
59 here_error_e HereView::Init(maps_view_h hView, maps_plugin_map_view_ready_cb pCbFunc)
62 return HERE_ERROR_INVALID_PARAMETER;
64 __idler = ecore_idler_add(__idlerCb, (void*)hView);
66 here_error_e error = HERE_ERROR_NONE;
67 int error2 = MAPS_ERROR_NONE;
70 error2 = maps_view_get_viewport(hView, &__img);
71 if (error2 != MAPS_ERROR_NONE) break;
73 error2 = maps_view_get_screen_location(hView, &__x, &__y, &__w, &__h);
74 if (error2 != MAPS_ERROR_NONE) break;
76 error = __initOpenGL();
77 if (error != HERE_ERROR_NONE) break;
79 error = __initOpenGLSurface(hView);
80 if (error != HERE_ERROR_NONE) break;
82 error = __initMap(hView, pCbFunc);
85 if (error == HERE_ERROR_NONE && error2 != MAPS_ERROR_NONE)
86 error = (here_error_e)ConvertToHereError(error2);
91 here_error_e HereView::__initOpenGL()
93 __cfg = evas_gl_config_new();
95 MAPS_LOGE("evas_gl_config_new() failed");
96 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
99 __cfg->color_format = EVAS_GL_RGBA_8888; // Surface Color Format
100 __cfg->depth_bits = EVAS_GL_DEPTH_NONE; // Surface Depth Format
101 __cfg->stencil_bits = EVAS_GL_STENCIL_NONE; // Surface Stencil Format
102 __cfg->options_bits = EVAS_GL_OPTIONS_DIRECT; // Configuration options (here, no extra options)
104 __gl = evas_gl_new(evas_object_evas_get(__img));
106 MAPS_LOGE("evas_gl_new() failed");
107 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
110 __api = evas_gl_api_get(__gl);
112 MAPS_LOGE("evas_gl_api_get() failed");
113 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
116 __ctx = evas_gl_context_create(__gl, NULL);
118 MAPS_LOGE("evas_gl_context_create() failed");
119 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
122 return HERE_ERROR_NONE;
125 here_error_e HereView::__initOpenGLSurface(maps_view_h hView)
127 if (!hView || !__gl || !__cfg || !__img || !__ctx)
128 return HERE_ERROR_INVALID_PARAMETER;
130 evas_object_image_pixels_get_callback_set(__img, NULL, NULL);
133 evas_object_image_native_surface_set(__img, NULL);
134 evas_gl_surface_destroy(__gl, __sfc);
140 evas_object_image_size_set(__img, __w, __h);
142 Evas_Native_Surface ns;
143 __sfc = evas_gl_surface_create(__gl, __cfg, __w, __h);
145 MAPS_LOGE("evas_gl_surface_create() failed");
146 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
149 if (!evas_gl_native_surface_get(__gl, __sfc, &ns)) {
150 evas_gl_make_current(__gl, NULL, NULL);
151 evas_gl_surface_destroy(__gl, __sfc);
153 MAPS_LOGE("evas_gl_native_surface_get() faile");
154 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
157 evas_object_image_native_surface_set(__img, &ns);
158 evas_object_image_pixels_get_callback_set(__img, __pixelGetCb, hView);
159 __isInitialized = true;
161 return HERE_ERROR_NONE;
164 here_error_e HereView::__initMap(maps_view_h hView, maps_plugin_map_view_ready_cb pCbFunc)
167 return HERE_ERROR_INVALID_PARAMETER;
169 __map = new (std::nothrow) GeoTiledMap();
171 return HERE_ERROR_OUT_OF_MEMORY;
175 __map->SetReadyMapSignal((GeoTiledMap::ReadyMapSignalFunctor)__readyMapCb, (void *)hView);
176 __map->SetEvasGlApi(__api);
177 __map->SetMapSize(Dimension(__w,__h));
179 __visualObjects.set(__map, evas_object_evas_get(__img));
181 return HERE_ERROR_NONE;
184 here_error_e HereView::Close(maps_view_h hView)
187 return HERE_ERROR_INVALID_PARAMETER;
189 __isInitialized = false;
191 __visualObjects.set(NULL, NULL);
194 evas_object_image_pixels_get_callback_set(__img, NULL, NULL);
197 ecore_idler_del(__idler);
200 __map->SetUpdateMapSignal(NULL);
207 evas_gl_make_current(__gl, __sfc, __ctx);
210 evas_object_image_native_surface_set(__img, NULL);
211 evas_gl_surface_destroy(__gl, __sfc);
214 evas_gl_context_destroy(__gl, __ctx);
221 evas_gl_config_free(__cfg);
223 return HERE_ERROR_NONE;
226 void HereView::__readyMapCb(void *data)
229 int maps_error = maps_view_get_maps_plugin_view_handle((maps_view_h)data, (void**)&hv);
230 if (maps_error != MAPS_ERROR_NONE || !hv) return;
236 void HereView::__pixelGetCb(void *data, Evas_Object *obj)
239 int maps_error = maps_view_get_maps_plugin_view_handle(data, (void**)&hv);
240 if (maps_error != MAPS_ERROR_NONE || !hv ||
241 !hv->__map || !hv->__gl || !hv->__sfc || !hv->__ctx) return;
243 evas_gl_make_current(hv->__gl, hv->__sfc, hv->__ctx);
244 hv->__map->PaintMap(hv->__w, hv->__h);
247 void HereView::__renderingCb(void *data)
250 evas_object_image_pixels_dirty_set((Evas_Object*)data, EINA_TRUE);
253 void HereView::__setMapType(maps_view_h hView)
258 /* When the theme is changed, clear cache */
259 maps_view_type_e map_type;
260 maps_view_get_type(hView, &map_type);
262 bool buildings_enabled = false;
263 maps_view_get_buildings_enabled(hView, &buildings_enabled);
265 bool traffic_enabled = false;
266 maps_view_get_traffic_enabled(hView, &traffic_enabled);
268 bool public_transit_enabled = false;
269 maps_view_get_public_transit_enabled(hView, &public_transit_enabled);
271 GeoTiledMap::MapType hereMapType = HereUtils::Convert(map_type, buildings_enabled,
272 traffic_enabled, public_transit_enabled);
274 if (hereMapType != __map->GetMapType())
276 MAPS_LOGD("Clear cache, because map type is changed.");
278 #ifdef TIZEN_SUPPORT_TILE_FILE_CACHE
279 __map->ClearTileFileCache();
281 __map->SetMapType(hereMapType);
285 here_error_e HereView::RenderMap(maps_view_h hView, const maps_coordinates_h mapsCoord, double dZoom, double dAngle)
287 if (!hView || !mapsCoord)
288 return HERE_ERROR_INVALID_PARAMETER;
290 if (!__isInitialized || !__map || !__api)
291 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
298 maps_view_get_screen_location(hView, &x, &y, &w, &h);
302 if (x != __x || y != __y || w != __w || h != __h)
309 __api->glViewport(0, 0, __w, __h);
310 __map->SetMapSize(Dimension(__w,__h));
311 __initOpenGLSurface(hView);
315 GeoTiledMap::UpdateMapSignalFunctor callback = std::tr1::bind(&__renderingCb, __img);
316 __map->SetUpdateMapSignal(callback);
319 if (__map->GetZoomLevel() != dZoom)
322 __map->SetZoomLevel(dZoom, false);
326 if (__angle != dAngle) {
328 __map->SetAngle(dAngle);
333 maps_coordinates_get_latitude(mapsCoord, &lat);
334 maps_coordinates_get_longitude(mapsCoord, &lng);
336 GeoCoordinates geoCoord(lat, lng);
339 __map->SetCenter(geoCoord);
341 return HERE_ERROR_NONE;
344 here_error_e HereView::RenderMapByArea(maps_view_h hView, const maps_area_h hArea, double dZoom, double dAngle)
346 if (!hView || !hArea)
347 return HERE_ERROR_INVALID_PARAMETER;
349 if (!__isInitialized || !__map)
350 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
352 return HERE_ERROR_NONE;
355 here_error_e HereView::MoveCenter(maps_view_h hView, int delta_x, int delta_y)
358 return HERE_ERROR_INVALID_PARAMETER;
360 if (!__isInitialized || !__map)
361 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
363 if (delta_x == 0 && delta_y == 0)
364 return HERE_ERROR_NONE;
366 __map->Pan(delta_x, delta_y);
368 return HERE_ERROR_NONE;
371 here_error_e HereView::GetCenter(maps_view_h hView, maps_coordinates_h *center)
373 if (!hView || !center)
374 return HERE_ERROR_INVALID_PARAMETER;
376 if (!__isInitialized || !__map)
377 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
379 GeoCoordinates geoCoord = __map->GetCenter();
380 if (*center == NULL) {
381 maps_coordinates_create(geoCoord.GetLatitude(), geoCoord.GetLongitude(), center);
383 maps_coordinates_set_latitude(*center, geoCoord.GetLatitude());
384 maps_coordinates_set_longitude(*center, geoCoord.GetLongitude());
387 return HERE_ERROR_NONE;
390 here_error_e HereView::SetScalebar(maps_view_h hView, bool enable)
393 return HERE_ERROR_INVALID_PARAMETER;
395 if (!__isInitialized || !__map)
396 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
398 __map->SetScalebar(enable);
400 return HERE_ERROR_NONE;
403 here_error_e HereView::GetScalebar(maps_view_h hView, bool *enabled)
405 if (!hView || !enabled)
406 return HERE_ERROR_INVALID_PARAMETER;
408 if (!__isInitialized || !__map)
409 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
411 *enabled = __map->GetScalebar();
412 return HERE_ERROR_NONE;
415 here_error_e HereView::DrawMap(maps_view_h hView, Evas* pCanvas, int x, int y, int nWidth, int nHeight)
417 if (!hView || !pCanvas || nWidth <= 0 || nHeight <= 0)
418 return HERE_ERROR_INVALID_PARAMETER;
420 if (!__isInitialized || !__map || !__map->GetRootPixmap() || !__api || __w <= 0 || __h <= 0)
421 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
423 unsigned char* srcimg_data = (unsigned char*)malloc(__w * __h * 4);
425 return HERE_ERROR_OUT_OF_MEMORY;
427 Evas_Object *dstimg = evas_object_image_filled_add(pCanvas);
430 return HERE_ERROR_INVALID_OPERATION;
433 unsigned char *dstimg_data = (unsigned char *)evas_object_image_data_get(dstimg, EINA_TRUE);
436 return HERE_ERROR_INVALID_OPERATION;
442 if (__w < w) w = __w;
443 if (__h < h) h = __h;
445 __api->glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, srcimg_data);
448 for(int i = 0; i < h; i++)
449 memcpy(dstimg_data+(i*w), srcimg_data+(i * w + x), w * 4);
451 catch(std::exception &e) {
452 MAPS_LOGD("Exception caught: %s", e.what());
456 return HERE_ERROR_NONE;
459 here_error_e HereView::ScreenToGeolocation(maps_view_h hView, int x, int y, maps_coordinates_h *mapsCoord)
461 if (!hView || !mapsCoord)
462 return HERE_ERROR_INVALID_PARAMETER;
464 if (!__isInitialized || !__map)
465 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
467 Tizen::Maps::Point mapsPoint(x, y);
468 GeoCoordinates hereCoord = __map->ScreenPositionToCoordinate(mapsPoint);
469 double lat = hereCoord.GetLatitude();
470 double lng = hereCoord.GetLongitude();
472 int error = maps_coordinates_create(lat, lng, mapsCoord);
473 if (error != MAPS_ERROR_NONE)
474 return (here_error_e)ConvertToHereError(error);
476 return HERE_ERROR_NONE;
479 here_error_e HereView::GeolocationToScreen(maps_view_h hView, const maps_coordinates_h mapsCoord, int *x, int *y)
481 if (!hView || !x || !y)
482 return HERE_ERROR_INVALID_PARAMETER;
484 if (!__isInitialized || !__map)
485 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
488 maps_coordinates_get_latitude(mapsCoord, &lat);
489 maps_coordinates_get_longitude(mapsCoord, &lng);
490 GeoCoordinates hereCoord(lat, lng);
491 Tizen::Maps::Point mapsPoint = __map->CoordinateToScreenPosition(hereCoord);
496 return HERE_ERROR_NONE;
499 here_error_e HereView::GetMinZoomLevel(maps_view_h hView, int *nMinZoomLevel)
501 if (!hView || !nMinZoomLevel)
502 return HERE_ERROR_INVALID_PARAMETER;
504 if (!__isInitialized || !__map)
505 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
507 *nMinZoomLevel = (int)__map->GetMinimumZoomLevel();
509 return HERE_ERROR_NONE;
512 here_error_e HereView::GetMaxZoomLevel(maps_view_h hView, int *nMaxZoomLevel)
514 if (!hView || !nMaxZoomLevel)
515 return HERE_ERROR_INVALID_PARAMETER;
517 if (!__isInitialized || !__map)
518 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
520 *nMaxZoomLevel = (int)__map->GetMaximumZoomLevel();
522 return HERE_ERROR_NONE;
525 here_error_e HereView::OnViewObject(maps_view_h hView, const maps_view_object_h object, maps_view_object_operation_e operation)
527 if (!hView || !object ||
528 operation < MAPS_VIEW_OBJECT_ADD || operation > MAPS_VIEW_OBJECT_REMOVE)
529 return HERE_ERROR_INVALID_PARAMETER;
531 if (!__isInitialized || !__map)
532 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
534 if (__map->GetRootPixmap())
535 __processViewObject(hView, object, operation);
537 __pendingObjects.push_back(std::make_pair(object, operation));
539 return HERE_ERROR_NONE;
542 Eina_Bool HereView::__idlerCb(void *data)
545 int maps_error = maps_view_get_maps_plugin_view_handle(data, (void**)&hv);
546 if (maps_error != MAPS_ERROR_NONE || !hv) return true;
547 if (!hv->__map || !hv->__map->GetRootPixmap()) return true;
549 while (hv->__pendingObjects.size()) {
550 PendingObject pending = hv->__pendingObjects.front();
551 hv->__pendingObjects.pop_front();
552 maps_view_object_h object = pending.first;
553 maps_view_object_operation_e operation = pending.second;
555 __processViewObject(data, object, operation);
560 void HereView::__processViewObject(maps_view_h hView, const maps_view_object_h object, maps_view_object_operation_e operation)
563 int maps_error = maps_view_get_maps_plugin_view_handle(hView, (void**)&hv);
564 if (maps_error != MAPS_ERROR_NONE || !hv) return;
566 maps_view_object_type_e type;
567 maps_view_object_get_type(object, &type);
569 if (type < MAPS_VIEW_OBJECT_POLYLINE || type > MAPS_VIEW_OBJECT_MARKER) return;
570 if (operation < MAPS_VIEW_OBJECT_ADD || operation > MAPS_VIEW_OBJECT_REMOVE) return;
572 const char *oper_str[20] = { "ADD", "SET_VISIBLE", "MOVE", "CHANGE", "REMOVE"};
573 const char *type_str[20] = { "POLYLINE", "POLYGON", "MARKER", "ROUTE", "UNKNOWN"};
575 MAPS_LOGD("type=%s, operation=%s, object=%p",
576 (type >= MAPS_VIEW_OBJECT_POLYLINE && type <= MAPS_VIEW_OBJECT_MARKER) ? type_str[type] : "?",
577 (operation >= MAPS_VIEW_OBJECT_ADD && operation <= MAPS_VIEW_OBJECT_REMOVE) ? oper_str[operation] : "?",
582 case MAPS_VIEW_OBJECT_ADD: hv->__visualObjects.add(object); break;
583 case MAPS_VIEW_OBJECT_SET_VISIBLE: hv->__visualObjects.setVisible(object); break;
584 case MAPS_VIEW_OBJECT_CHANGE: hv->__visualObjects.update(object); break;
585 case MAPS_VIEW_OBJECT_REMOVE: hv->__visualObjects.remove(object); break;
590 HERE_PLUGIN_END_NAMESPACE