0c9aa0d1621303a6eecd26e7ad4860ab2124bbca
[platform/core/location/maps-plugin-here.git] / src / here_view.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "here_view.h"
18 #include <Elementary.h>
19
20 using namespace HERE_PLUGIN_NAMESPACE_PREFIX;
21
22 static const char SIG_LOADED[] = "loaded";
23
24
25 HERE_PLUGIN_BEGIN_NAMESPACE
26
27 GLData *HereView::m_pImpl = NULL;
28
29 HereView::HereView(void *pCbFunc, void *pUserData, int nReqId)
30 {
31         m_pCbFunc = pCbFunc;
32         m_pUserData = pUserData;
33         m_nReqId = nReqId;
34 }
35
36 HereView::~HereView()
37 {
38 }
39
40 GLData* HereView::GetImplHandler()
41 {
42         return m_pImpl;
43 }
44
45 here_error_e HereView::Init(maps_view_h hView, maps_plugin_map_view_ready_cb pCbFunc)
46 {
47         if (!hView)
48                 return HERE_ERROR_INVALID_PARAMETER;
49
50         if (m_pImpl)
51                 return HERE_ERROR_INVALID_OPERATION;
52
53         if (!m_pImpl)
54         {
55                 m_pImpl = new (std::nothrow) GLData();
56
57                 if (!m_pImpl)
58                         return HERE_ERROR_INVALID_PARAMETER;
59
60                 m_pImpl->idler = ecore_idler_add(__idlerCb, (void*)m_pImpl);
61                 m_pImpl->readyCb = NULL;
62         }
63
64         here_error_e error = HERE_ERROR_NONE;
65         int error2 = MAPS_ERROR_NONE;
66
67         do {
68                 error2 = maps_view_get_viewport(hView, &m_pImpl->img);
69                 if (error2 != MAPS_ERROR_NONE) break;
70
71                 error2 = maps_view_get_screen_location(hView, &m_pImpl->x, &m_pImpl->y, &m_pImpl->w, &m_pImpl->h);
72                 if (error2 != MAPS_ERROR_NONE) break;
73
74                 m_pImpl->hView = hView;
75
76                 error = InitOpenGL(m_pImpl);
77                 if (error != HERE_ERROR_NONE) break;
78
79                 error = InitOpenGLSurface(m_pImpl);
80                 if (error != HERE_ERROR_NONE) break;
81
82                 error = InitMap(m_pImpl, pCbFunc);
83         } while(0);
84
85         if (error == HERE_ERROR_NONE && error2 != MAPS_ERROR_NONE)
86                 error = (here_error_e)ConvertToHereError(error2);
87
88         return error;
89 }
90
91 here_error_e HereView::InitOpenGL(GLData *gld)
92 {
93         if (!gld)
94                 return HERE_ERROR_INVALID_PARAMETER;
95
96
97         gld->cfg = evas_gl_config_new();
98         if (!gld->cfg)
99         {
100                 MAPS_LOGE("evas_gl_config_new() failed");
101                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
102         }
103
104         gld->cfg->color_format = EVAS_GL_RGBA_8888;    // Surface Color Format
105         gld->cfg->depth_bits   = EVAS_GL_DEPTH_NONE;   // Surface Depth Format
106         gld->cfg->stencil_bits = EVAS_GL_STENCIL_NONE; // Surface Stencil Format
107         gld->cfg->options_bits = EVAS_GL_OPTIONS_DIRECT; // Configuration options (here, no extra options)
108
109         gld->gl = evas_gl_new(evas_object_evas_get(gld->img));
110         if (!gld->gl)
111         {
112                 MAPS_LOGE("evas_gl_new() failed");
113                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
114         }
115
116         gld->api = evas_gl_api_get(gld->gl);
117         if (!gld->api)
118         {
119                 MAPS_LOGE("evas_gl_api_get() failed");
120                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
121         }
122
123         gld->ctx = evas_gl_context_create(gld->gl, NULL);
124         if (!gld->ctx)
125         {
126                 MAPS_LOGE("evas_gl_context_create() failed");
127                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
128         }
129
130         return HERE_ERROR_NONE;
131 }
132
133 here_error_e HereView::InitOpenGLSurface(GLData *gld)
134 {
135         if (!gld || !gld->gl || !gld->cfg || !gld->img || !gld->ctx)
136                 return HERE_ERROR_INVALID_PARAMETER;
137
138
139         evas_object_image_pixels_get_callback_set(gld->img, NULL, NULL);
140
141         if (gld->sfc)
142         {
143                 evas_object_image_native_surface_set(gld->img, NULL);
144                 evas_gl_surface_destroy(gld->gl, gld->sfc);
145         }
146
147         m_pImpl->w = MAX(m_pImpl->w, 1);
148         m_pImpl->h = MAX(m_pImpl->h, 1);
149
150         evas_object_image_size_set(gld->img, gld->w, gld->h);
151
152         Evas_Native_Surface ns;
153         gld->sfc = evas_gl_surface_create(gld->gl, gld->cfg, gld->w, gld->h);
154         if (!gld->sfc)
155         {
156                 MAPS_LOGE("evas_gl_surface_create() failed");
157                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
158         }
159
160         if (!evas_gl_native_surface_get(gld->gl, gld->sfc, &ns))
161         {
162                 evas_gl_make_current(gld->gl, NULL, NULL);
163                 evas_gl_surface_destroy(gld->gl, gld->sfc);
164                 gld->sfc = NULL;
165                 MAPS_LOGE("evas_gl_native_surface_get() faile");
166                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
167         }
168
169         evas_object_image_native_surface_set(gld->img, &ns);
170
171         evas_object_image_pixels_get_callback_set(gld->img, __pixelGetCb, this);
172
173         gld->isInitialized = true;
174         //MAPS_LOGD("initializing is Done!!!");
175
176         return HERE_ERROR_NONE;
177 }
178
179 here_error_e HereView::InitMap(GLData *gld, maps_plugin_map_view_ready_cb pCbFunc)
180 {
181         if (!gld)
182                 return HERE_ERROR_INVALID_PARAMETER;
183
184         gld->map = new (std::nothrow) GeoTiledMap();
185
186         if (!gld->map)
187                 return HERE_ERROR_OUT_OF_MEMORY;
188
189         gld->readyCb = pCbFunc;
190
191         gld->map->SetReadyMapSignal((GeoTiledMap::ReadyMapSignalFunctor)__readyCb);
192
193         gld->map->SetEvasGlApi(gld->api);
194
195         MAPS_LOGD("gld->api=%p, m_pImpl->api=%p", gld->api, m_pImpl->api);
196
197         gld->map->SetMapSize(Dimension(gld->w,gld->h));
198
199         //gld->map->SetUpdateMapSignal(RenderingCb, this);
200
201         m_pImpl->visualObjects.set(gld->map, evas_object_evas_get(gld->img));
202
203         return HERE_ERROR_NONE;
204 }
205
206 here_error_e HereView::Close()
207 {
208         if (m_pImpl)
209         {
210                 m_pImpl->isInitialized = false;
211
212                 if (m_pImpl->map)
213                 {
214                         m_pImpl->map->SetUpdateMapSignal(NULL);
215                 }
216
217                 m_pImpl->visualObjects.set(NULL, NULL);
218
219                 if (m_pImpl->img)
220                 {
221                         evas_object_image_pixels_get_callback_set(m_pImpl->img, NULL, NULL);
222                 }
223
224                 if (m_pImpl->idler)
225                 {
226                         ecore_idler_del(m_pImpl->idler);
227                         m_pImpl->idler = NULL;
228                 }
229
230                 if (m_pImpl->map)
231                 {
232                         m_pImpl->map->SetUpdateMapSignal(NULL);
233                         delete m_pImpl->map;
234                         m_pImpl->map = NULL;
235                 }
236
237                 if (m_pImpl->gl)
238                 {
239                         evas_gl_make_current(m_pImpl->gl, m_pImpl->sfc, m_pImpl->ctx);
240
241                         if (m_pImpl->sfc)
242                         {
243                                 evas_object_image_native_surface_set(m_pImpl->img, NULL);
244                                 evas_gl_surface_destroy(m_pImpl->gl, m_pImpl->sfc);
245                                 m_pImpl->sfc = NULL;
246                         }
247
248                         if (m_pImpl->ctx)
249                         {
250                                 evas_gl_context_destroy(m_pImpl->gl, m_pImpl->ctx);
251                                 m_pImpl->ctx = NULL;
252                         }
253
254                         evas_gl_free(m_pImpl->gl);
255                         m_pImpl->gl = NULL;
256                 }
257
258                 if (m_pImpl->cfg)
259                 {
260                         evas_gl_config_free(m_pImpl->cfg);
261                         m_pImpl->cfg = NULL;
262                 }
263
264                 delete m_pImpl;
265                 m_pImpl = NULL;
266         }
267
268         return HERE_ERROR_NONE;
269 }
270
271 void HereView::__readyCb()
272 {
273         if (m_pImpl->readyCb)
274                 m_pImpl->readyCb(m_pImpl->hView);
275 }
276
277 void HereView::__pixelGetCb(void *data, Evas_Object *obj)
278 {
279         if (!m_pImpl || !m_pImpl->map) return;
280         if (!m_pImpl->gl || !m_pImpl->sfc || !m_pImpl->ctx) return;
281
282         evas_gl_make_current(m_pImpl->gl, m_pImpl->sfc, m_pImpl->ctx);
283         m_pImpl->map->PaintMap(m_pImpl->w, m_pImpl->h);
284 }
285
286 void HereView::__renderingCb(void *data)
287 {
288         if (!data) return;
289         evas_object_image_pixels_dirty_set((Evas_Object*)data, EINA_TRUE);
290 }
291
292 void HereView::__setMapType()
293 {
294         /* When the theme is changed, clear cache */
295         maps_view_type_e map_type;
296         maps_view_get_type(m_pImpl->hView, &map_type);
297
298         bool buildings_enabled = false;
299         maps_view_get_buildings_enabled(m_pImpl->hView, &buildings_enabled);
300
301         bool traffic_enabled = false;
302         maps_view_get_traffic_enabled(m_pImpl->hView, &traffic_enabled);
303
304         bool public_transit_enabled = false;
305
306         GeoTiledMap::MapType hereMapType = HereUtils::Convert(map_type, buildings_enabled,
307                                                 traffic_enabled, public_transit_enabled);
308
309         if (hereMapType != m_pImpl->map->GetMapType())
310         {
311                 MAPS_LOGD("Clear cache, because map type is changed.");
312                 m_pImpl->map->ClearCache();
313 #ifdef TIZEN_SUPPORT_TILE_FILE_CACHE
314                 m_pImpl->map->ClearTileFileCache();
315 #endif
316                 m_pImpl->map->SetMapType(hereMapType);
317         }
318 }
319
320 here_error_e HereView::RenderMap(const maps_coordinates_h mapsCoord, double dZoom, double dAngle)
321 {
322
323         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map || !m_pImpl->api)
324                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
325
326         if (!mapsCoord)
327                 return HERE_ERROR_INVALID_PARAMETER;
328
329         /* set map type */
330         __setMapType();
331
332         /* resize window */
333         int x, y, w, h;
334         maps_view_get_screen_location(m_pImpl->hView, &x, &y, &w, &h);
335         m_pImpl->w = MAX(m_pImpl->w, 1);
336         m_pImpl->h = MAX(m_pImpl->h, 1);
337
338         if (x != m_pImpl->x || y != m_pImpl->y || w != m_pImpl->w || h != m_pImpl->h)
339         {
340                 m_pImpl->x = x;
341                 m_pImpl->y = y;
342                 m_pImpl->w = w;
343                 m_pImpl->h = h;
344
345                 m_pImpl->api->glViewport(0, 0, m_pImpl->w, m_pImpl->h);
346                 m_pImpl->map->SetMapSize(Dimension(m_pImpl->w,m_pImpl->h));
347                 InitOpenGLSurface(m_pImpl);
348         }
349
350         /* callback */
351         GeoTiledMap::UpdateMapSignalFunctor callback = std::tr1::bind(&__renderingCb, m_pImpl->img);
352         m_pImpl->map->SetUpdateMapSignal(callback);
353
354         /* zoom level */
355         if (m_pImpl->map->GetZoomLevel() != dZoom)
356         {
357                 m_pImpl->zoom = dZoom;
358                 m_pImpl->map->SetZoomLevel(dZoom, false);
359         }
360
361         /* angle */
362         if (m_pImpl->angle != dAngle) {
363                 m_pImpl->angle = dAngle;
364                 m_pImpl->map->SetAngle(dAngle);
365         }
366
367         /* center */
368         double lat, lng;
369         maps_coordinates_get_latitude(mapsCoord, &lat);
370         maps_coordinates_get_longitude(mapsCoord, &lng);
371
372         GeoCoordinates geoCoord(lat, lng);
373         m_pImpl->lat = lat;
374         m_pImpl->lng = lng;
375         m_pImpl->map->SetCenter(geoCoord);
376
377         return HERE_ERROR_NONE;
378 }
379
380 here_error_e HereView::RenderMapByArea(const maps_area_h hArea, double dZoom, double dAngle)
381 {
382         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map || !m_pImpl->map->GetRootPixmap() || !m_pImpl->api)
383                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
384
385         if (!hArea)
386                 return HERE_ERROR_INVALID_PARAMETER;
387
388         return HERE_ERROR_NONE;
389 }
390
391 here_error_e HereView::MoveCenter(int delta_x, int delta_y)
392 {
393         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map || !m_pImpl->map->GetRootPixmap() || !m_pImpl->api)
394                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
395
396         if (delta_x == 0 && delta_y == 0)
397                 return HERE_ERROR_NONE;
398
399         m_pImpl->map->Pan(delta_x, delta_y);
400
401         return HERE_ERROR_NONE;
402 }
403
404 here_error_e HereView::SetScalebar(bool enable)
405 {
406         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map)
407                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
408
409         m_pImpl->map->SetScalebar(enable);
410
411         return HERE_ERROR_NONE;
412 }
413
414 here_error_e HereView::GetScalebar(bool *enabled)
415 {
416         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map || !enabled)
417                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
418
419         *enabled = m_pImpl->map->GetScalebar();
420         return HERE_ERROR_NONE;
421 }
422
423 here_error_e HereView::DrawMap(Evas* pCanvas, int x, int y, int nWidth, int nHeight)
424 {
425         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map || !m_pImpl->map->GetRootPixmap() || !m_pImpl->api)
426                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
427
428         if (!pCanvas || nWidth <= 0 || nHeight <= 0)
429                 return HERE_ERROR_INVALID_PARAMETER;
430
431         if (m_pImpl->w <= 0 || m_pImpl->h <= 0)
432                 return HERE_ERROR_INVALID_PARAMETER;
433
434         unsigned char* srcimg_data = (unsigned char*)malloc(m_pImpl->w*m_pImpl->h*4);
435         if (!srcimg_data)
436                 return HERE_ERROR_OUT_OF_MEMORY;
437
438         Evas_Object *dstimg = evas_object_image_filled_add(pCanvas);
439         if (!dstimg)
440         {
441                 g_free(srcimg_data);
442                 return HERE_ERROR_INVALID_OPERATION;
443         }
444
445         unsigned char *dstimg_data = (unsigned char *)evas_object_image_data_get(dstimg, EINA_TRUE);
446         if (!dstimg_data)
447         {
448                 g_free(srcimg_data);
449                 return HERE_ERROR_INVALID_OPERATION;
450         }
451
452         int w = nWidth;
453         int h = nHeight;
454
455         if (m_pImpl->w < w) w = m_pImpl->w;
456         if (m_pImpl->h < h) h = m_pImpl->h;
457
458         m_pImpl->api->glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, srcimg_data);
459
460         try {
461                 for (int i = 0; i < h; i++)
462                         memcpy(dstimg_data+(i*w), srcimg_data+(i*m_pImpl->w+x), w*4);
463         }
464         catch (std::exception &e) {
465                 MAPS_LOGD("Exception caught: %s", e.what());
466         }
467         g_free(srcimg_data);
468
469         return HERE_ERROR_NONE;
470 }
471
472 here_error_e HereView::GetCenter(maps_coordinates_h *center)
473 {
474         if (!center)
475                 return HERE_ERROR_INVALID_PARAMETER;
476
477         GeoCoordinates geoCoord = m_pImpl->map->GetCenter();
478
479         if (*center == NULL)
480         {
481                 maps_coordinates_create(geoCoord.GetLatitude(), geoCoord.GetLongitude(), center);
482         }
483         else
484         {
485                 maps_coordinates_set_latitude(*center, geoCoord.GetLatitude());
486                 maps_coordinates_set_longitude(*center, geoCoord.GetLongitude());
487         }
488
489         return HERE_ERROR_NONE;
490 }
491
492 here_error_e HereView::ScreenToGeolocation(int x, int y, maps_coordinates_h *mapsCoord)
493 {
494         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map)
495                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
496
497         if (!mapsCoord)
498                 return HERE_ERROR_INVALID_PARAMETER;
499
500         Tizen::Maps::Point mapsPoint(x, y);
501         GeoCoordinates hereCoord = m_pImpl->map->ScreenPositionToCoordinate(mapsPoint);
502         double lat = hereCoord.GetLatitude();
503         double lng = hereCoord.GetLongitude();
504
505 #if 1
506         int error = maps_coordinates_create(lat, lng, mapsCoord);
507         if (error != MAPS_ERROR_NONE)
508                 return (here_error_e)ConvertToHereError(error);
509 #else
510         maps_coordinates_h __mapsCoord;
511         int error = maps_coordinates_create(lat, lng, &__mapsCoord);
512         if (error != MAPS_ERROR_NONE)
513                 return (here_error_e)ConvertToHereError(error);
514
515         if (*mapsCoord) {
516                 /* maps_coord is already allocated in heap memory */
517                 maps_coordinates_get_latitude(__mapsCoord, &lat);
518                 maps_coordinates_get_longitude(__mapsCoord, &lng);
519                 maps_coordinates_set_latitude(*mapsCoord, lat);
520                 maps_coordinates_set_longitude(*mapsCoord, lng);
521         } else {
522                 /* maps_coord is not allocated yet */
523                 maps_coordinates_clone(__mapsCoord, mapsCoord);
524         }
525         maps_coordinates_destroy(__mapsCoord);
526 #endif
527
528         return HERE_ERROR_NONE;
529 }
530
531 here_error_e HereView::GeolocationToScreen(const maps_coordinates_h mapsCoord, int *x, int *y)
532 {
533         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map)
534                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
535
536         if (!x || !y)
537                 return HERE_ERROR_INVALID_PARAMETER;
538
539         double lat, lng;
540         maps_coordinates_get_latitude(mapsCoord, &lat);
541         maps_coordinates_get_longitude(mapsCoord, &lng);
542         GeoCoordinates hereCoord(lat, lng);
543         Tizen::Maps::Point mapsPoint = m_pImpl->map->CoordinateToScreenPosition(hereCoord);
544
545         *x = mapsPoint.x;
546         *y = mapsPoint.y;
547
548         return HERE_ERROR_NONE;
549 }
550
551 here_error_e HereView::GetMinZoomLevel(int *nMinZoomLevel)
552 {
553         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map)
554                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
555
556         if (!nMinZoomLevel)
557                 return HERE_ERROR_INVALID_PARAMETER;
558
559         *nMinZoomLevel = (int)m_pImpl->map->GetMinimumZoomLevel();
560
561         return HERE_ERROR_NONE;
562 }
563
564 here_error_e HereView::GetMaxZoomLevel(int *nMaxZoomLevel)
565 {
566         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map)
567                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
568
569         if (!nMaxZoomLevel)
570                 return HERE_ERROR_INVALID_PARAMETER;
571
572         *nMaxZoomLevel = (int)m_pImpl->map->GetMaximumZoomLevel();
573
574         return HERE_ERROR_NONE;
575 }
576
577 here_error_e HereView::OnViewObject(const maps_view_object_h object, maps_view_object_operation_e operation)
578 {
579         if (!m_pImpl || !m_pImpl->isInitialized || !m_pImpl->map)
580                 return HERE_ERROR_SERVICE_NOT_AVAILABLE;
581
582         if (!object || operation < MAPS_VIEW_OBJECT_ADD || operation > MAPS_VIEW_OBJECT_REMOVE)
583                 return HERE_ERROR_INVALID_PARAMETER;
584
585         if (m_pImpl->map->GetRootPixmap())
586                 __processViewObject(object, operation);
587         else
588                 m_pImpl->pendingObjects.push_back(std::make_pair(object, operation));
589
590         return HERE_ERROR_NONE;
591 }
592
593 Eina_Bool HereView::__idlerCb(void *data)
594 {
595         GLData *pImpl = (GLData*)data;
596
597         if (!pImpl || !pImpl->map || !pImpl->map->GetRootPixmap()) return true;
598
599         while (pImpl->pendingObjects.size())
600         {
601                 PendingObject pending = pImpl->pendingObjects.front();
602                 pImpl->pendingObjects.pop_front();
603                 maps_view_object_h object = pending.first;
604                 maps_view_object_operation_e operation = pending.second;
605
606                 __processViewObject(object, operation);
607         }
608
609         return true;
610 }
611
612 void HereView::__processViewObject(const maps_view_object_h object, maps_view_object_operation_e operation)
613 {
614         maps_view_object_type_e type;
615         maps_view_object_get_type(object, &type);
616
617         if (type < MAPS_VIEW_OBJECT_POLYLINE || type > MAPS_VIEW_OBJECT_MARKER) return;
618         if (operation < MAPS_VIEW_OBJECT_ADD || operation > MAPS_VIEW_OBJECT_REMOVE) return;
619
620         const char *oper_str[20] = { "ADD", "SET_VISIBLE", "MOVE", "CHANGE", "REMOVE"};
621         const char *type_str[20] = { "POLYLINE", "POLYGON", "MARKER", "ROUTE", "UNKNOWN"};
622
623         MAPS_LOGD("type=%s, operation=%s, object=%p",
624                 (type >= MAPS_VIEW_OBJECT_POLYLINE && type <= MAPS_VIEW_OBJECT_MARKER) ? type_str[type] : "?",
625                 (operation >= MAPS_VIEW_OBJECT_ADD && operation <= MAPS_VIEW_OBJECT_REMOVE) ? oper_str[operation] : "?",
626                 object);
627
628         switch(operation)
629         {
630         case MAPS_VIEW_OBJECT_ADD:                      m_pImpl->visualObjects.add(object); break;
631         case MAPS_VIEW_OBJECT_SET_VISIBLE:      m_pImpl->visualObjects.setVisible(object); break;
632         case MAPS_VIEW_OBJECT_CHANGE:                   m_pImpl->visualObjects.update(object); break;
633         case MAPS_VIEW_OBJECT_REMOVE:                   m_pImpl->visualObjects.remove(object); break;
634         default:                        break;
635         }
636 }
637
638 HERE_PLUGIN_END_NAMESPACE