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_objects.h"
18 #include "here_utils.h"
20 #include <graphic/Grp_Util.h>
21 #include <maps/GeoMapObjectMarker.h>
22 #include <maps/GeoMapObjectPolygon.h>
23 #include <maps/GeoMapObjectPolyline.h>
26 using namespace HERE_PLUGIN_NAMESPACE_PREFIX;
28 HERE_PLUGIN_BEGIN_NAMESPACE
30 HereViewObjects::HereViewObjects()
32 pthread_mutex_init(&__mutex, NULL);
35 HereViewObjects::~HereViewObjects()
37 pthread_mutex_destroy(&__mutex);
40 void HereViewObjects::set(GeoTiledMap *map, Evas *evas)
42 if (!map && !evas) removeAll();
47 here_error_e HereViewObjects::add(maps_view_object_h hObj)
49 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
51 here_error_e error = HERE_ERROR_INVALID_PARAMETER;
52 if (__currentObjects.find(hObj) == __currentObjects.end())
55 if (error == HERE_ERROR_NONE) __invalidate(hObj);
59 here_error_e HereViewObjects::__add(maps_view_object_h hObj)
61 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
62 if (!__map) return HERE_ERROR_INVALID_OPERATION;
64 here_error_e error = HERE_ERROR_NONE;
65 GeoMapObject *hereObject = NULL;
66 maps_view_object_type_e type;
67 maps_view_object_get_type(hObj, &type);
71 case MAPS_VIEW_OBJECT_MARKER:
72 hereObject = new (std::nothrow) GeoMapObjectMarker;
73 error = __updateMarker(hObj, (GeoMapObjectMarker*)hereObject);
76 case MAPS_VIEW_OBJECT_POLYGON:
77 hereObject = new (std::nothrow) GeoMapObjectPolygon;
78 error = __updatePolygon(hObj, (GeoMapObjectPolygon*)hereObject);
81 case MAPS_VIEW_OBJECT_POLYLINE:
82 hereObject = new (std::nothrow) GeoMapObjectPolyline;
83 error = __updatePolyline(hObj, (GeoMapObjectPolyline*)hereObject);
85 #ifdef TIZEN_3_0_NEXT_MS
86 case MAPS_VIEW_OBJECT_ROUTE:
87 for (int i=0; i < 2; i++)
89 hereObject = new (std::nothrow) GeoMapObjectPolyline;
92 __map->AddObject(hereObject);
93 error = __updateRoute(hObj);
94 if (error != HERE_ERROR_NONE) break;
95 pthread_mutex_lock(&__mutex);
96 __currentObjects.insert(std::make_pair(hObj, (GeoMapObjectPolyline*)hereObject));
97 pthread_mutex_unlock(&__mutex);
100 hereObject = new (std::nothrow) GeoMapObjectMarker;
103 __map->AddObject(hereObject);
104 error = __updateRoute(hObj);
105 if (error != HERE_ERROR_NONE) break;
106 pthread_mutex_lock(&__mutex);
107 __currentObjects.insert(std::make_pair(hObj, (GeoMapObjectMarker*)hereObject));
108 pthread_mutex_unlock(&__mutex);
112 #endif /* TIZEN_3_0_NEXT_MS */
114 error = HERE_ERROR_INVALID_PARAMETER;
118 if (error != HERE_ERROR_NONE)
120 if (hereObject) delete hereObject;
124 #ifdef TIZEN_3_0_NEXT_MS
125 if (hereObject && type != MAPS_VIEW_OBJECT_ROUTE)
128 #endif /* TIZEN_3_0_NEXT_MS */
130 __map->AddObject(hereObject);
131 pthread_mutex_lock(&__mutex);
132 __currentObjects.insert(std::make_pair(hObj, hereObject));
133 pthread_mutex_unlock(&__mutex);
139 here_error_e HereViewObjects::remove(maps_view_object_h hObj)
141 here_error_e error = __remove(hObj);
142 if (error == HERE_ERROR_NONE) __invalidate(hObj);
146 here_error_e HereViewObjects::__remove(maps_view_object_h hObj)
148 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
149 if (!__map) return HERE_ERROR_INVALID_OPERATION;
151 here_error_e error = HERE_ERROR_NOT_FOUND;
153 VisualObjects::iterator it;
154 pthread_mutex_lock(&__mutex);
155 while ((it = __currentObjects.find(hObj)) != __currentObjects.end())
157 __map->RemoveObject((GeoMapObject*)it->second);
158 it = __currentObjects.erase(it);
159 error = HERE_ERROR_NONE;
161 pthread_mutex_unlock(&__mutex);
166 here_error_e HereViewObjects::removeAll()
168 pthread_mutex_lock(&__mutex);
169 __currentObjects.clear();
170 __map->ClearMapObjects();
171 pthread_mutex_unlock(&__mutex);
174 return HERE_ERROR_NONE;
177 here_error_e HereViewObjects::move(maps_view_object_h hObj)
179 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
181 VisualObjects::iterator it;
182 while ((it = __currentObjects.find(hObj)) != __currentObjects.end())
184 MAPS_LOGD("TODO: implement moving");
187 return HERE_ERROR_NONE;
190 here_error_e HereViewObjects::update(maps_view_object_h hObj)
192 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
194 here_error_e error = HERE_ERROR_NOT_FOUND;
196 VisualObjects::iterator it = __currentObjects.find(hObj);
197 if (it != __currentObjects.end())
198 error = __update(hObj, (GeoMapObject*)(it->second));
200 if (error == HERE_ERROR_NONE) __invalidate(hObj);
204 here_error_e HereViewObjects::__update(maps_view_object_h hObj, GeoMapObject *hereObject)
206 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
208 here_error_e error = HERE_ERROR_UNKNOWN;
211 maps_view_object_type_e type;
212 maps_view_object_get_type(hObj, &type);
216 case MAPS_VIEW_OBJECT_MARKER:
217 error = __updateMarker(hObj, (GeoMapObjectMarker*)hereObject);
220 case MAPS_VIEW_OBJECT_POLYGON:
221 error = __updatePolygon(hObj, (GeoMapObjectPolygon*)hereObject);
224 case MAPS_VIEW_OBJECT_POLYLINE:
225 error = __updatePolyline(hObj, (GeoMapObjectPolyline*)hereObject);
228 #ifdef TIZEN_3_0_NEXT_MS
229 case MAPS_VIEW_OBJECT_ROUTE:
230 error = __updateRoute(hObj);
232 #endif /* TIZEN_3_0_NEXT_MS */
242 here_error_e HereViewObjects::__updateMarker(maps_view_object_h hMarker, GeoMapObjectMarker *hereMarker)
244 if (!hMarker || !hereMarker)
245 return HERE_ERROR_INVALID_PARAMETER;
247 if (!__evas || !__map)
248 return HERE_ERROR_INVALID_OPERATION;
251 int error = MAPS_ERROR_NONE;
252 maps_view_marker_type_e type;
256 maps_coordinates_h mapsCoord;
257 Evas_Object *img = NULL;
262 error = maps_view_object_marker_get_type(hMarker, &type);
263 if (error != MAPS_ERROR_NONE || type < MAPS_VIEW_MARKER_PIN || type > MAPS_VIEW_MARKER_STICKER) break;
265 error = maps_view_object_marker_get_image_file(hMarker, &szPath);
266 if (error != MAPS_ERROR_NONE || !szPath) break;
268 img = evas_object_image_add(__evas);
269 evas_object_image_file_set(img, szPath, NULL);
270 int err = evas_object_image_load_error_get(img);
272 if (err != EVAS_LOAD_ERROR_NONE)
274 MAPS_LOGE("Failed to load the image file for new marker. '%s'",
275 (szPath ? szPath : "null"));
281 evas_object_image_size_get(img, &w, &h);
284 unsigned char *src = (unsigned char*)evas_object_image_data_get(img, EINA_FALSE);
285 if (!src || nSize <= 0) {
286 MAPS_LOGE("Failed to get the image buffer of new marker");
287 error = MAPS_ERROR_OUT_OF_MEMORY;
291 unsigned char *dst = (unsigned char*)malloc(nSize);
293 error = MAPS_ERROR_OUT_OF_MEMORY;
296 memcpy(dst, src, nSize);
298 /* resize the marker image */
300 if (__resizeMarker(hMarker, w, h, &nw, &nh, &dst))
305 maps_view_object_marker_set_size(hMarker, w, h);
308 /* convert RGBA to BGRA for GL */
309 _Util::ConvertRGBA2BGRA(dst, (unsigned)w, (unsigned)h);
312 bmp.Construct((const unsigned char*)dst, nSize, Dimension(w, h));
313 hereMarker->SetBitmap(bmp);
318 maps_view_object_marker_get_coordinates(hMarker, &mapsCoord);
319 maps_coordinates_get_latitude(mapsCoord, &lat);
320 maps_coordinates_get_longitude(mapsCoord, &lng);
321 maps_coordinates_destroy(mapsCoord);
323 if (!HereUtils::IsValidCoord(lat, lng))
325 error = MAPS_ERROR_INVALID_PARAMETER;
329 hereMarker->SetPosition(GeoCoordinates(lat, lng));
332 Tizen::Maps::FloatPoint fpntOrigin(0.5, 0.5);
333 if (type == MAPS_VIEW_MARKER_PIN)
335 hereMarker->SetMarkerOrigin(fpntOrigin);
339 maps_view_object_marker_get_z_order(hMarker, &z_order);
340 hereMarker->SetZorder(z_order);
343 if (img) evas_object_del(img);
344 return (here_error_e)ConvertToHereError(error);
347 here_error_e HereViewObjects::__updatePolyline(maps_view_object_h hPolyline, GeoMapObjectPolyline *herePolyline)
349 if (!hPolyline || !herePolyline)
350 return HERE_ERROR_INVALID_PARAMETER;
352 int error = MAPS_ERROR_NONE;
353 GeoCoordinateList coordList;
354 unsigned char r, g, b, a;
358 error = maps_view_object_polyline_foreach_point(hPolyline, __foreachForCoordinates, &coordList);
359 if (error != MAPS_ERROR_NONE) break;
360 herePolyline->SetPath(coordList);
362 error = maps_view_object_polyline_get_color(hPolyline, &r, &g, &b, &a);
363 if (error != MAPS_ERROR_NONE) break;
364 herePolyline->SetStrokeColor(Color(r, g, b, a));
366 error = maps_view_object_polyline_get_width(hPolyline, &nThickness);
367 if (error != MAPS_ERROR_NONE) break;
368 herePolyline->SetStrokeThickness(nThickness);
371 return (here_error_e)ConvertToHereError(error);
374 here_error_e HereViewObjects::__updatePolygon(maps_view_object_h hPolygon, GeoMapObjectPolygon *herePolygon)
376 if (!hPolygon || !herePolygon)
377 return HERE_ERROR_INVALID_PARAMETER;
379 int error = MAPS_ERROR_NONE;
380 GeoCoordinateList coordList;
381 unsigned char r, g, b, a;
384 error = maps_view_object_polygon_foreach_point(hPolygon, __foreachForCoordinates, &coordList);
385 if (error != MAPS_ERROR_NONE) break;
386 herePolygon->SetPath(coordList);
388 error = maps_view_object_polygon_get_fill_color(hPolygon, &r, &g, &b, &a);
389 if (error != MAPS_ERROR_NONE) break;
390 herePolygon->SetFillColor(Color(r, g, b, a));
393 return (here_error_e)ConvertToHereError(error);
396 here_error_e HereViewObjects::__updateRoute(maps_view_object_h hRoute)
398 #ifdef TIZEN_3_0_NEXT_MS
399 if (!hRoute) return HERE_ERROR_INVALID_PARAMETER;
401 VisualObjects::iterator it;
403 if ((it = __currentObjects.find(hRoute)) != __currentObjects.end())
405 maps_route_h route = NULL;
406 int ret = maps_view_object_route_get_content(hRoute, &route);
407 if (ret != MAPS_ERROR_NONE || !route)
408 return HERE_ERROR_NONE;
410 GeoCoordinateList coordList;
411 GeoMapObjectPolyline *polyline_path = NULL, *polyline_seg = NULL;
413 if (it->second->GetType() == GeoMapObject::GMO_Polyline)
417 MAPS_LOGD("Route Path");
418 polyline_path = (GeoMapObjectPolyline*)it->second;
419 maps_route_foreach_path(route, __foreachForCoordinates, &coordList);
420 polyline_path->SetPath(coordList);
421 polyline_path->SetStrokeColor(Tizen::Maps::Color(255, 0, 0, 255));
422 polyline_path->SetStrokeThickness(3);
424 else if (!polyline_seg)
426 MAPS_LOGD("Route Segments");
427 polyline_seg = (GeoMapObjectPolyline*)it->second;
428 maps_route_foreach_path(route, __foreachForCoordinates, &coordList);
429 polyline_seg->SetPath(coordList);
430 polyline_seg->SetStrokeColor(Tizen::Maps::Color(0, 255, 0, 255));
431 polyline_seg->SetStrokeThickness(3);
434 else if (it->second->GetType() == GeoMapObject::GMO_Marker)
438 maps_route_destroy(route);
441 #endif /* TIZEN_3_0_NEXT_MS */
442 return HERE_ERROR_NONE;
445 here_error_e HereViewObjects::setVisible(maps_view_object_h hObj)
447 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
450 maps_view_object_get_visible(hObj, &visible);
451 return __setVisible(hObj, visible);
454 here_error_e HereViewObjects::__setVisible(maps_view_object_h hObj, bool bVisible)
456 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
458 here_error_e error = HERE_ERROR_NOT_FOUND;
460 VisualObjects::iterator it;
461 for (it = __currentObjects.begin(); it != __currentObjects.end(); it++)
463 if (it->first == hObj)
465 ((GeoMapObject*)it->second)->SetVisible(bVisible);
466 error = HERE_ERROR_NONE;
470 if (error == HERE_ERROR_NONE) __invalidate(hObj);
474 bool HereViewObjects::__foreachForCoordinates(int index, maps_coordinates_h point, void *user_data)
476 if (!point || !user_data)
479 if (!HereUtils::IsValid(*(maps_coordinates_s*)point))
485 double lat = 0.0, lng = 0.0;
488 error = maps_coordinates_get_latitude(point, &lat);
489 if (error != MAPS_ERROR_NONE) break;
491 error = maps_coordinates_get_longitude(point, &lng);
492 if (error != MAPS_ERROR_NONE) break;
495 MAPS_LOGD("[%d] %f,%f", index+1, lat, lng);
497 GeoCoordinateList *coordList = (GeoCoordinateList*)user_data;
498 coordList->push_back(GeoCoordinates(lat, lng));
502 bool HereViewObjects::__foreachForAddingGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
504 if (!user_data) return false;
506 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
507 here_error_e error = hereViewObjects->add(object);
508 return (error == HERE_ERROR_NONE);
511 bool HereViewObjects::__foreachForRemovingGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
513 if (!user_data) return false;
515 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
516 here_error_e error = hereViewObjects->remove(object);
517 return (error == HERE_ERROR_NONE);
520 bool HereViewObjects::__foreachForUpdatingGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
522 if (!user_data) return false;
524 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
525 here_error_e error = hereViewObjects->update(object);
526 return (error == HERE_ERROR_NONE);
529 bool HereViewObjects::__foreachForSettingVisibleGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
531 if (!user_data) return false;
533 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
534 here_error_e error = hereViewObjects->setVisible(object);
535 return (error == HERE_ERROR_NONE);
538 bool HereViewObjects::__resizeMarker(maps_view_object_h hMarker,
539 const int originWidth, const int originHeight,
540 int *newWidth, int *newHeight, unsigned char **bitmap)
542 if (!hMarker || !newWidth || !newHeight || !bitmap || !*bitmap)
545 int resizedWidth = 0, resizedHeight = 0;
546 maps_view_object_marker_get_size(hMarker, &resizedWidth, &resizedHeight);
548 if (__resizeBitmap(bitmap, originWidth, originHeight, resizedWidth, resizedHeight))
550 *newWidth = resizedWidth;
551 *newHeight = resizedHeight;
557 bool HereViewObjects::__resizeBitmap(unsigned char **curBmp, int curWidth, int curHeight, int newWidth, int newHeight)
559 if (!curBmp || curWidth <= 0 || curHeight <= 0 || newWidth <= 0 || newHeight <= 0) return false;
560 if (curWidth == newWidth && curHeight == newHeight) return false;
562 unsigned char* newBmp = new unsigned char[newWidth * newHeight * 4];
564 double scaleWidth = (double)newWidth / (double)curWidth;
565 double scaleHeight = (double)newHeight / (double)curHeight;
567 int newPixel, curPixel;
569 for(int y = 0; y < newHeight; y++)
571 for(int x = 0; x < newWidth; x++)
573 newPixel = (y * (newWidth *4)) + (x * 4);
574 curPixel = (((int)(y / scaleHeight) * (curWidth * 4)) + ((int)(x / scaleWidth) * 4));
576 newBmp[newPixel ] = (*curBmp)[curPixel ];
577 newBmp[newPixel + 1] = (*curBmp)[curPixel + 1];
578 newBmp[newPixel + 2] = (*curBmp)[curPixel + 2];
579 newBmp[newPixel + 3] = (*curBmp)[curPixel + 3];
588 void HereViewObjects::__invalidate(maps_view_object_h hObj)
590 maps_view_object_type_e type;
591 maps_view_object_get_type(hObj, &type);
593 if (!hObj || type != MAPS_VIEW_OBJECT_MARKER)
594 __map->InvalidateMapObjects();
596 __map->InvalidateMapMarkers();
599 HERE_PLUGIN_END_NAMESPACE