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()
34 pthread_mutex_init(&__mutex, NULL);
37 HereViewObjects::~HereViewObjects()
39 pthread_mutex_destroy(&__mutex);
42 void HereViewObjects::set(GeoTiledMap *map, Evas *evas)
44 if (!map && !evas) removeAll();
49 here_error_e HereViewObjects::add(maps_view_object_h hObj)
51 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
53 here_error_e error = HERE_ERROR_INVALID_PARAMETER;
54 if (__currentObjects.find(hObj) == __currentObjects.end())
57 if (error == HERE_ERROR_NONE) __invalidate(hObj);
61 here_error_e HereViewObjects::__add(maps_view_object_h hObj)
63 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
64 if (!__map) return HERE_ERROR_INVALID_OPERATION;
66 here_error_e error = HERE_ERROR_NONE;
67 GeoMapObject *hereObject = NULL;
68 maps_view_object_type_e type;
69 maps_view_object_get_type(hObj, &type);
72 case MAPS_VIEW_OBJECT_MARKER:
73 hereObject = new (std::nothrow) GeoMapObjectMarker;
74 error = __updateMarker(hObj, (GeoMapObjectMarker*)hereObject);
77 case MAPS_VIEW_OBJECT_POLYGON:
78 hereObject = new (std::nothrow) GeoMapObjectPolygon;
79 error = __updatePolygon(hObj, (GeoMapObjectPolygon*)hereObject);
82 case MAPS_VIEW_OBJECT_POLYLINE:
83 hereObject = new (std::nothrow) GeoMapObjectPolyline;
84 error = __updatePolyline(hObj, (GeoMapObjectPolyline*)hereObject);
86 #ifdef TIZEN_3_0_NEXT_MS
87 case MAPS_VIEW_OBJECT_ROUTE:
88 for (int i=0; i < 2; i++) {
89 hereObject = new (std::nothrow) GeoMapObjectPolyline;
91 __map->AddObject(hereObject);
92 error = __updateRoute(hObj);
93 if (error != HERE_ERROR_NONE) break;
94 pthread_mutex_lock(&__mutex);
95 __currentObjects.insert(std::make_pair(hObj, (GeoMapObjectPolyline*)hereObject));
96 pthread_mutex_unlock(&__mutex);
99 hereObject = new (std::nothrow) GeoMapObjectMarker;
101 __map->AddObject(hereObject);
102 error = __updateRoute(hObj);
103 if (error != HERE_ERROR_NONE) break;
104 pthread_mutex_lock(&__mutex);
105 __currentObjects.insert(std::make_pair(hObj, (GeoMapObjectMarker*)hereObject));
106 pthread_mutex_unlock(&__mutex);
110 #endif /* TIZEN_3_0_NEXT_MS */
112 error = HERE_ERROR_INVALID_PARAMETER;
116 if (error != HERE_ERROR_NONE) {
117 if (hereObject) delete hereObject;
122 #ifdef TIZEN_3_0_NEXT_MS
123 && type != MAPS_VIEW_OBJECT_ROUTE
124 #endif /* TIZEN_3_0_NEXT_MS */
126 __map->AddObject(hereObject);
127 pthread_mutex_lock(&__mutex);
128 __currentObjects.insert(std::make_pair(hObj, hereObject));
129 pthread_mutex_unlock(&__mutex);
135 here_error_e HereViewObjects::remove(maps_view_object_h hObj)
137 here_error_e error = __remove(hObj);
138 if (error == HERE_ERROR_NONE) __invalidate(hObj);
142 here_error_e HereViewObjects::__remove(maps_view_object_h hObj)
144 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
145 if (!__map) return HERE_ERROR_INVALID_OPERATION;
147 here_error_e error = HERE_ERROR_NOT_FOUND;
149 VisualObjects::iterator it;
150 pthread_mutex_lock(&__mutex);
151 while ((it = __currentObjects.find(hObj)) != __currentObjects.end()) {
152 __map->RemoveObject((GeoMapObject*)it->second);
153 it = __currentObjects.erase(it);
154 error = HERE_ERROR_NONE;
156 pthread_mutex_unlock(&__mutex);
161 here_error_e HereViewObjects::removeAll()
163 pthread_mutex_lock(&__mutex);
164 __currentObjects.clear();
165 __map->ClearMapObjects();
166 pthread_mutex_unlock(&__mutex);
169 return HERE_ERROR_NONE;
172 here_error_e HereViewObjects::move(maps_view_object_h hObj)
174 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
176 VisualObjects::iterator it;
177 while ((it = __currentObjects.find(hObj)) != __currentObjects.end())
178 MAPS_LOGD("TODO: implement moving");
180 return HERE_ERROR_NONE;
183 here_error_e HereViewObjects::update(maps_view_object_h hObj)
185 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
187 here_error_e error = HERE_ERROR_NOT_FOUND;
189 VisualObjects::iterator it = __currentObjects.find(hObj);
190 if (it != __currentObjects.end())
191 error = __update(hObj, (GeoMapObject*)(it->second));
193 if (error == HERE_ERROR_NONE) __invalidate(hObj);
197 here_error_e HereViewObjects::__update(maps_view_object_h hObj, GeoMapObject *hereObject)
199 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
201 here_error_e error = HERE_ERROR_UNKNOWN;
204 maps_view_object_type_e type;
205 maps_view_object_get_type(hObj, &type);
208 case MAPS_VIEW_OBJECT_MARKER:
209 error = __updateMarker(hObj, (GeoMapObjectMarker*)hereObject);
212 case MAPS_VIEW_OBJECT_POLYGON:
213 error = __updatePolygon(hObj, (GeoMapObjectPolygon*)hereObject);
216 case MAPS_VIEW_OBJECT_POLYLINE:
217 error = __updatePolyline(hObj, (GeoMapObjectPolyline*)hereObject);
220 #ifdef TIZEN_3_0_NEXT_MS
221 case MAPS_VIEW_OBJECT_ROUTE:
222 error = __updateRoute(hObj);
224 #endif /* TIZEN_3_0_NEXT_MS */
234 here_error_e HereViewObjects::__updateMarker(maps_view_object_h hMarker, GeoMapObjectMarker *hereMarker)
236 if (!hMarker || !hereMarker)
237 return HERE_ERROR_INVALID_PARAMETER;
239 if (!__evas || !__map)
240 return HERE_ERROR_INVALID_OPERATION;
243 int error = MAPS_ERROR_NONE;
244 maps_view_marker_type_e type;
248 maps_coordinates_h mapsCoord;
249 Evas_Object *img = NULL;
254 error = maps_view_object_marker_get_type(hMarker, &type);
255 if (error != MAPS_ERROR_NONE || type < MAPS_VIEW_MARKER_PIN || type > MAPS_VIEW_MARKER_STICKER) break;
257 error = maps_view_object_marker_get_image_file(hMarker, &szPath);
258 if (error != MAPS_ERROR_NONE || !szPath) break;
260 img = evas_object_image_add(__evas);
261 evas_object_image_file_set(img, szPath, NULL);
262 int err = evas_object_image_load_error_get(img);
264 if (err != EVAS_LOAD_ERROR_NONE) {
265 MAPS_LOGE("Failed to load the image file for new marker. '%s'",
266 (szPath ? szPath : "null"));
272 evas_object_image_size_get(img, &w, &h);
275 unsigned char *src = (unsigned char*)evas_object_image_data_get(img, EINA_FALSE);
276 if (!src || nSize <= 0) {
277 MAPS_LOGE("Failed to get the image buffer of new marker");
278 error = MAPS_ERROR_OUT_OF_MEMORY;
282 unsigned char *dst = (unsigned char*)malloc(nSize);
284 error = MAPS_ERROR_OUT_OF_MEMORY;
287 memcpy(dst, src, nSize);
289 /* resize the marker image */
291 if (__resizeMarker(hMarker, w, h, &nw, &nh, &dst)) {
296 maps_view_object_marker_set_size(hMarker, w, h);
298 /* convert RGBA to BGRA for GL */
299 _Util::ConvertRGBA2BGRA(dst, (unsigned)w, (unsigned)h);
302 if (bmp.Construct((const unsigned char*)dst, nSize, Dimension(w, h)) != 0) {
303 MAPS_LOGE("Failed to construct a bitmap object");
304 error = MAPS_ERROR_INVALID_OPERATION;
308 hereMarker->SetBitmap(bmp);
313 maps_view_object_marker_get_coordinates(hMarker, &mapsCoord);
314 maps_coordinates_get_latitude(mapsCoord, &lat);
315 maps_coordinates_get_longitude(mapsCoord, &lng);
316 maps_coordinates_destroy(mapsCoord);
318 if (!HereUtils::IsValidCoord(lat, lng)) {
319 error = MAPS_ERROR_INVALID_PARAMETER;
323 hereMarker->SetPosition(GeoCoordinates(lat, lng));
326 Tizen::Maps::FloatPoint fpntOrigin(0.5, 0.5);
327 if (type == MAPS_VIEW_MARKER_PIN)
329 hereMarker->SetMarkerOrigin(fpntOrigin);
333 maps_view_object_marker_get_z_order(hMarker, &z_order);
334 hereMarker->SetZOrder(z_order);
337 if (img) evas_object_del(img);
338 return (here_error_e)ConvertToHereError(error);
341 here_error_e HereViewObjects::__updatePolyline(maps_view_object_h hPolyline, GeoMapObjectPolyline *herePolyline)
343 if (!hPolyline || !herePolyline)
344 return HERE_ERROR_INVALID_PARAMETER;
346 int error = MAPS_ERROR_NONE;
347 GeoCoordinateList coordList;
348 unsigned char r, g, b, a;
352 error = maps_view_object_polyline_foreach_point(hPolyline, __foreachForCoordinates, &coordList);
353 if (error != MAPS_ERROR_NONE) break;
354 herePolyline->SetPath(coordList);
356 error = maps_view_object_polyline_get_color(hPolyline, &r, &g, &b, &a);
357 if (error != MAPS_ERROR_NONE) break;
358 herePolyline->SetStrokeColor(Color(r, g, b, a));
360 error = maps_view_object_polyline_get_width(hPolyline, &nThickness);
361 if (error != MAPS_ERROR_NONE) break;
362 herePolyline->SetStrokeThickness(nThickness);
365 return (here_error_e)ConvertToHereError(error);
368 here_error_e HereViewObjects::__updatePolygon(maps_view_object_h hPolygon, GeoMapObjectPolygon *herePolygon)
370 if (!hPolygon || !herePolygon)
371 return HERE_ERROR_INVALID_PARAMETER;
373 int error = MAPS_ERROR_NONE;
374 GeoCoordinateList coordList;
375 unsigned char r, g, b, a;
378 error = maps_view_object_polygon_foreach_point(hPolygon, __foreachForCoordinates, &coordList);
379 if (error != MAPS_ERROR_NONE) break;
380 herePolygon->SetPath(coordList);
382 error = maps_view_object_polygon_get_fill_color(hPolygon, &r, &g, &b, &a);
383 if (error != MAPS_ERROR_NONE) break;
384 herePolygon->SetFillColor(Color(r, g, b, a));
387 return (here_error_e)ConvertToHereError(error);
390 here_error_e HereViewObjects::__updateRoute(maps_view_object_h hRoute)
392 #ifdef TIZEN_3_0_NEXT_MS
393 if (!hRoute) return HERE_ERROR_INVALID_PARAMETER;
395 VisualObjects::iterator it;
397 if ((it = __currentObjects.find(hRoute)) != __currentObjects.end()) {
398 maps_route_h route = NULL;
399 int ret = maps_view_object_route_get_content(hRoute, &route);
400 if (ret != MAPS_ERROR_NONE || !route)
401 return HERE_ERROR_NONE;
403 GeoCoordinateList coordList;
404 GeoMapObjectPolyline *polyline_path = NULL, *polyline_seg = NULL;
406 if (it->second->GetType() == GeoMapObject::GMO_Polyline) {
407 if (!polyline_path) {
408 MAPS_LOGD("Route Path");
409 polyline_path = (GeoMapObjectPolyline*)it->second;
410 maps_route_foreach_path(route, __foreachForCoordinates, &coordList);
411 polyline_path->SetPath(coordList);
412 polyline_path->SetStrokeColor(Tizen::Maps::Color(255, 0, 0, 255));
413 polyline_path->SetStrokeThickness(3);
414 } else if (!polyline_seg) {
415 MAPS_LOGD("Route Segments");
416 polyline_seg = (GeoMapObjectPolyline*)it->second;
417 maps_route_foreach_path(route, __foreachForCoordinates, &coordList);
418 polyline_seg->SetPath(coordList);
419 polyline_seg->SetStrokeColor(Tizen::Maps::Color(0, 255, 0, 255));
420 polyline_seg->SetStrokeThickness(3);
422 } else if (it->second->GetType() == GeoMapObject::GMO_Marker) {
425 maps_route_destroy(route);
428 #endif /* TIZEN_3_0_NEXT_MS */
429 return HERE_ERROR_NONE;
432 here_error_e HereViewObjects::setVisible(maps_view_object_h hObj)
434 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
437 maps_view_object_get_visible(hObj, &visible);
438 return __setVisible(hObj, visible);
441 here_error_e HereViewObjects::__setVisible(maps_view_object_h hObj, bool bVisible)
443 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
445 here_error_e error = HERE_ERROR_NOT_FOUND;
447 VisualObjects::iterator it;
448 for (it = __currentObjects.begin(); it != __currentObjects.end(); it++) {
449 if (it->first == hObj) {
450 ((GeoMapObject*)it->second)->SetVisible(bVisible);
451 error = HERE_ERROR_NONE;
455 if (error == HERE_ERROR_NONE) __invalidate(hObj);
459 bool HereViewObjects::__foreachForCoordinates(int index, maps_coordinates_h point, void *user_data)
461 if (!point || !user_data)
464 if (!HereUtils::IsValid(*(maps_coordinates_s*)point))
468 double lat = 0.0, lng = 0.0;
471 error = maps_coordinates_get_latitude(point, &lat);
472 if (error != MAPS_ERROR_NONE) break;
474 error = maps_coordinates_get_longitude(point, &lng);
475 if (error != MAPS_ERROR_NONE) break;
478 MAPS_LOGD("[%d] %f,%f", index+1, lat, lng);
480 GeoCoordinateList *coordList = (GeoCoordinateList*)user_data;
481 coordList->push_back(GeoCoordinates(lat, lng));
485 bool HereViewObjects::__foreachForAddingGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
487 if (!user_data) return false;
489 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
490 here_error_e error = hereViewObjects->add(object);
491 return (error == HERE_ERROR_NONE);
494 bool HereViewObjects::__foreachForRemovingGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
496 if (!user_data) return false;
498 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
499 here_error_e error = hereViewObjects->remove(object);
500 return (error == HERE_ERROR_NONE);
503 bool HereViewObjects::__foreachForUpdatingGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
505 if (!user_data) return false;
507 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
508 here_error_e error = hereViewObjects->update(object);
509 return (error == HERE_ERROR_NONE);
512 bool HereViewObjects::__foreachForSettingVisibleGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
514 if (!user_data) return false;
516 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
517 here_error_e error = hereViewObjects->setVisible(object);
518 return (error == HERE_ERROR_NONE);
521 bool HereViewObjects::__resizeMarker(maps_view_object_h hMarker,
522 const int originWidth, const int originHeight,
523 int *newWidth, int *newHeight, unsigned char **bitmap)
525 if (!hMarker || !newWidth || !newHeight || !bitmap || !*bitmap)
528 int resizedWidth = 0, resizedHeight = 0;
529 maps_view_object_marker_get_size(hMarker, &resizedWidth, &resizedHeight);
531 /* Set the size proportionally if one of new sizes is zero. */
532 if (resizedWidth == 0 && resizedHeight > 0)
533 resizedWidth = resizedHeight * (originWidth / originHeight);
534 else if (resizedHeight == 0 && resizedWidth > 0)
535 resizedHeight = resizedWidth * (originHeight / originWidth);
537 if (__resizeBitmap(bitmap, originWidth, originHeight, resizedWidth, resizedHeight)) {
538 *newWidth = resizedWidth;
539 *newHeight = resizedHeight;
545 bool HereViewObjects::__resizeBitmap(unsigned char **curBmp, int curWidth, int curHeight, int newWidth, int newHeight)
547 if (!curBmp || curWidth <= 0 || curHeight <= 0 || newWidth <= 0 || newHeight <= 0) return false;
548 if (curWidth == newWidth && curHeight == newHeight) return false;
550 unsigned char *newBmp = (unsigned char*)malloc(newWidth * newHeight * 4);
552 MAPS_LOGD("malloc failed for newBmp");
556 double scaleWidth = (double)newWidth / (double)curWidth;
557 double scaleHeight = (double)newHeight / (double)curHeight;
559 int newPixel, curPixel;
561 for (int y = 0; y < newHeight; y++) {
562 for (int x = 0; x < newWidth; x++) {
563 newPixel = (y * (newWidth *4)) + (x * 4);
564 curPixel = (((int)(y / scaleHeight) * (curWidth * 4)) + ((int)(x / scaleWidth) * 4));
566 newBmp[newPixel ] = (*curBmp)[curPixel ];
567 newBmp[newPixel + 1] = (*curBmp)[curPixel + 1];
568 newBmp[newPixel + 2] = (*curBmp)[curPixel + 2];
569 newBmp[newPixel + 3] = (*curBmp)[curPixel + 3];
578 void HereViewObjects::__invalidate(maps_view_object_h hObj)
580 maps_view_object_type_e type;
581 maps_view_object_get_type(hObj, &type);
583 if (!hObj || type != MAPS_VIEW_OBJECT_MARKER)
584 __map->InvalidateMapObjects();
586 __map->InvalidateMapMarkers();
589 HERE_PLUGIN_END_NAMESPACE