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);
70 case MAPS_VIEW_OBJECT_MARKER:
71 hereObject = new (std::nothrow) GeoMapObjectMarker;
72 error = __updateMarker(hObj, (GeoMapObjectMarker*)hereObject);
75 case MAPS_VIEW_OBJECT_POLYGON:
76 hereObject = new (std::nothrow) GeoMapObjectPolygon;
77 error = __updatePolygon(hObj, (GeoMapObjectPolygon*)hereObject);
80 case MAPS_VIEW_OBJECT_POLYLINE:
81 hereObject = new (std::nothrow) GeoMapObjectPolyline;
82 error = __updatePolyline(hObj, (GeoMapObjectPolyline*)hereObject);
84 #ifdef TIZEN_3_0_NEXT_MS
85 case MAPS_VIEW_OBJECT_ROUTE:
86 for (int i=0; i < 2; i++) {
87 hereObject = new (std::nothrow) GeoMapObjectPolyline;
89 __map->AddObject(hereObject);
90 error = __updateRoute(hObj);
91 if (error != HERE_ERROR_NONE) break;
92 pthread_mutex_lock(&__mutex);
93 __currentObjects.insert(std::make_pair(hObj, (GeoMapObjectPolyline*)hereObject));
94 pthread_mutex_unlock(&__mutex);
97 hereObject = new (std::nothrow) GeoMapObjectMarker;
99 __map->AddObject(hereObject);
100 error = __updateRoute(hObj);
101 if (error != HERE_ERROR_NONE) break;
102 pthread_mutex_lock(&__mutex);
103 __currentObjects.insert(std::make_pair(hObj, (GeoMapObjectMarker*)hereObject));
104 pthread_mutex_unlock(&__mutex);
108 #endif /* TIZEN_3_0_NEXT_MS */
110 error = HERE_ERROR_INVALID_PARAMETER;
114 if (error != HERE_ERROR_NONE) {
115 if (hereObject) delete hereObject;
120 #ifdef TIZEN_3_0_NEXT_MS
121 && type != MAPS_VIEW_OBJECT_ROUTE
122 #endif /* TIZEN_3_0_NEXT_MS */
124 __map->AddObject(hereObject);
125 pthread_mutex_lock(&__mutex);
126 __currentObjects.insert(std::make_pair(hObj, hereObject));
127 pthread_mutex_unlock(&__mutex);
133 here_error_e HereViewObjects::remove(maps_view_object_h hObj)
135 here_error_e error = __remove(hObj);
136 if (error == HERE_ERROR_NONE) __invalidate(hObj);
140 here_error_e HereViewObjects::__remove(maps_view_object_h hObj)
142 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
143 if (!__map) return HERE_ERROR_INVALID_OPERATION;
145 here_error_e error = HERE_ERROR_NOT_FOUND;
147 VisualObjects::iterator it;
148 pthread_mutex_lock(&__mutex);
149 while ((it = __currentObjects.find(hObj)) != __currentObjects.end()) {
150 __map->RemoveObject((GeoMapObject*)it->second);
151 it = __currentObjects.erase(it);
152 error = HERE_ERROR_NONE;
154 pthread_mutex_unlock(&__mutex);
159 here_error_e HereViewObjects::removeAll()
161 pthread_mutex_lock(&__mutex);
162 __currentObjects.clear();
163 __map->ClearMapObjects();
164 pthread_mutex_unlock(&__mutex);
167 return HERE_ERROR_NONE;
170 here_error_e HereViewObjects::move(maps_view_object_h hObj)
172 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
174 VisualObjects::iterator it;
175 while ((it = __currentObjects.find(hObj)) != __currentObjects.end())
176 MAPS_LOGD("TODO: implement moving");
178 return HERE_ERROR_NONE;
181 here_error_e HereViewObjects::update(maps_view_object_h hObj)
183 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
185 here_error_e error = HERE_ERROR_NOT_FOUND;
187 VisualObjects::iterator it = __currentObjects.find(hObj);
188 if (it != __currentObjects.end())
189 error = __update(hObj, (GeoMapObject*)(it->second));
191 if (error == HERE_ERROR_NONE) __invalidate(hObj);
195 here_error_e HereViewObjects::__update(maps_view_object_h hObj, GeoMapObject *hereObject)
197 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
199 here_error_e error = HERE_ERROR_UNKNOWN;
202 maps_view_object_type_e type;
203 maps_view_object_get_type(hObj, &type);
206 case MAPS_VIEW_OBJECT_MARKER:
207 error = __updateMarker(hObj, (GeoMapObjectMarker*)hereObject);
210 case MAPS_VIEW_OBJECT_POLYGON:
211 error = __updatePolygon(hObj, (GeoMapObjectPolygon*)hereObject);
214 case MAPS_VIEW_OBJECT_POLYLINE:
215 error = __updatePolyline(hObj, (GeoMapObjectPolyline*)hereObject);
218 #ifdef TIZEN_3_0_NEXT_MS
219 case MAPS_VIEW_OBJECT_ROUTE:
220 error = __updateRoute(hObj);
222 #endif /* TIZEN_3_0_NEXT_MS */
232 here_error_e HereViewObjects::__updateMarker(maps_view_object_h hMarker, GeoMapObjectMarker *hereMarker)
234 if (!hMarker || !hereMarker)
235 return HERE_ERROR_INVALID_PARAMETER;
237 if (!__evas || !__map)
238 return HERE_ERROR_INVALID_OPERATION;
241 int error = MAPS_ERROR_NONE;
242 maps_view_marker_type_e type;
246 maps_coordinates_h mapsCoord;
247 Evas_Object *img = NULL;
252 error = maps_view_object_marker_get_type(hMarker, &type);
253 if (error != MAPS_ERROR_NONE || type < MAPS_VIEW_MARKER_PIN || type > MAPS_VIEW_MARKER_STICKER) break;
255 error = maps_view_object_marker_get_image_file(hMarker, &szPath);
256 if (error != MAPS_ERROR_NONE || !szPath) break;
258 img = evas_object_image_add(__evas);
259 evas_object_image_file_set(img, szPath, NULL);
260 int err = evas_object_image_load_error_get(img);
262 if (err != EVAS_LOAD_ERROR_NONE) {
263 MAPS_LOGE("Failed to load the image file for new marker. '%s'",
264 (szPath ? szPath : "null"));
270 evas_object_image_size_get(img, &w, &h);
273 unsigned char *src = (unsigned char*)evas_object_image_data_get(img, EINA_FALSE);
274 if (!src || nSize <= 0) {
275 MAPS_LOGE("Failed to get the image buffer of new marker");
276 error = MAPS_ERROR_OUT_OF_MEMORY;
280 unsigned char *dst = (unsigned char*)malloc(nSize);
282 error = MAPS_ERROR_OUT_OF_MEMORY;
285 memcpy(dst, src, nSize);
287 /* resize the marker image */
289 if (__resizeMarker(hMarker, w, h, &nw, &nh, &dst)) {
293 maps_view_object_marker_set_size(hMarker, w, h);
296 /* convert RGBA to BGRA for GL */
297 _Util::ConvertRGBA2BGRA(dst, (unsigned)w, (unsigned)h);
300 bmp.Construct((const unsigned char*)dst, nSize, Dimension(w, h));
301 hereMarker->SetBitmap(bmp);
306 maps_view_object_marker_get_coordinates(hMarker, &mapsCoord);
307 maps_coordinates_get_latitude(mapsCoord, &lat);
308 maps_coordinates_get_longitude(mapsCoord, &lng);
309 maps_coordinates_destroy(mapsCoord);
311 if (!HereUtils::IsValidCoord(lat, lng)) {
312 error = MAPS_ERROR_INVALID_PARAMETER;
316 hereMarker->SetPosition(GeoCoordinates(lat, lng));
319 Tizen::Maps::FloatPoint fpntOrigin(0.5, 0.5);
320 if (type == MAPS_VIEW_MARKER_PIN)
322 hereMarker->SetMarkerOrigin(fpntOrigin);
326 maps_view_object_marker_get_z_order(hMarker, &z_order);
327 hereMarker->SetZorder(z_order);
330 if (img) evas_object_del(img);
331 return (here_error_e)ConvertToHereError(error);
334 here_error_e HereViewObjects::__updatePolyline(maps_view_object_h hPolyline, GeoMapObjectPolyline *herePolyline)
336 if (!hPolyline || !herePolyline)
337 return HERE_ERROR_INVALID_PARAMETER;
339 int error = MAPS_ERROR_NONE;
340 GeoCoordinateList coordList;
341 unsigned char r, g, b, a;
345 error = maps_view_object_polyline_foreach_point(hPolyline, __foreachForCoordinates, &coordList);
346 if (error != MAPS_ERROR_NONE) break;
347 herePolyline->SetPath(coordList);
349 error = maps_view_object_polyline_get_color(hPolyline, &r, &g, &b, &a);
350 if (error != MAPS_ERROR_NONE) break;
351 herePolyline->SetStrokeColor(Color(r, g, b, a));
353 error = maps_view_object_polyline_get_width(hPolyline, &nThickness);
354 if (error != MAPS_ERROR_NONE) break;
355 herePolyline->SetStrokeThickness(nThickness);
358 return (here_error_e)ConvertToHereError(error);
361 here_error_e HereViewObjects::__updatePolygon(maps_view_object_h hPolygon, GeoMapObjectPolygon *herePolygon)
363 if (!hPolygon || !herePolygon)
364 return HERE_ERROR_INVALID_PARAMETER;
366 int error = MAPS_ERROR_NONE;
367 GeoCoordinateList coordList;
368 unsigned char r, g, b, a;
371 error = maps_view_object_polygon_foreach_point(hPolygon, __foreachForCoordinates, &coordList);
372 if (error != MAPS_ERROR_NONE) break;
373 herePolygon->SetPath(coordList);
375 error = maps_view_object_polygon_get_fill_color(hPolygon, &r, &g, &b, &a);
376 if (error != MAPS_ERROR_NONE) break;
377 herePolygon->SetFillColor(Color(r, g, b, a));
380 return (here_error_e)ConvertToHereError(error);
383 here_error_e HereViewObjects::__updateRoute(maps_view_object_h hRoute)
385 #ifdef TIZEN_3_0_NEXT_MS
386 if (!hRoute) return HERE_ERROR_INVALID_PARAMETER;
388 VisualObjects::iterator it;
390 if ((it = __currentObjects.find(hRoute)) != __currentObjects.end()) {
391 maps_route_h route = NULL;
392 int ret = maps_view_object_route_get_content(hRoute, &route);
393 if (ret != MAPS_ERROR_NONE || !route)
394 return HERE_ERROR_NONE;
396 GeoCoordinateList coordList;
397 GeoMapObjectPolyline *polyline_path = NULL, *polyline_seg = NULL;
399 if (it->second->GetType() == GeoMapObject::GMO_Polyline) {
400 if (!polyline_path) {
401 MAPS_LOGD("Route Path");
402 polyline_path = (GeoMapObjectPolyline*)it->second;
403 maps_route_foreach_path(route, __foreachForCoordinates, &coordList);
404 polyline_path->SetPath(coordList);
405 polyline_path->SetStrokeColor(Tizen::Maps::Color(255, 0, 0, 255));
406 polyline_path->SetStrokeThickness(3);
407 } else if (!polyline_seg) {
408 MAPS_LOGD("Route Segments");
409 polyline_seg = (GeoMapObjectPolyline*)it->second;
410 maps_route_foreach_path(route, __foreachForCoordinates, &coordList);
411 polyline_seg->SetPath(coordList);
412 polyline_seg->SetStrokeColor(Tizen::Maps::Color(0, 255, 0, 255));
413 polyline_seg->SetStrokeThickness(3);
415 } else if (it->second->GetType() == GeoMapObject::GMO_Marker) {
418 maps_route_destroy(route);
421 #endif /* TIZEN_3_0_NEXT_MS */
422 return HERE_ERROR_NONE;
425 here_error_e HereViewObjects::setVisible(maps_view_object_h hObj)
427 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
430 maps_view_object_get_visible(hObj, &visible);
431 return __setVisible(hObj, visible);
434 here_error_e HereViewObjects::__setVisible(maps_view_object_h hObj, bool bVisible)
436 if (!hObj) return HERE_ERROR_INVALID_PARAMETER;
438 here_error_e error = HERE_ERROR_NOT_FOUND;
440 VisualObjects::iterator it;
441 for (it = __currentObjects.begin(); it != __currentObjects.end(); it++) {
442 if (it->first == hObj) {
443 ((GeoMapObject*)it->second)->SetVisible(bVisible);
444 error = HERE_ERROR_NONE;
448 if (error == HERE_ERROR_NONE) __invalidate(hObj);
452 bool HereViewObjects::__foreachForCoordinates(int index, maps_coordinates_h point, void *user_data)
454 if (!point || !user_data)
457 if (!HereUtils::IsValid(*(maps_coordinates_s*)point))
461 double lat = 0.0, lng = 0.0;
464 error = maps_coordinates_get_latitude(point, &lat);
465 if (error != MAPS_ERROR_NONE) break;
467 error = maps_coordinates_get_longitude(point, &lng);
468 if (error != MAPS_ERROR_NONE) break;
471 MAPS_LOGD("[%d] %f,%f", index+1, lat, lng);
473 GeoCoordinateList *coordList = (GeoCoordinateList*)user_data;
474 coordList->push_back(GeoCoordinates(lat, lng));
478 bool HereViewObjects::__foreachForAddingGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
480 if (!user_data) return false;
482 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
483 here_error_e error = hereViewObjects->add(object);
484 return (error == HERE_ERROR_NONE);
487 bool HereViewObjects::__foreachForRemovingGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
489 if (!user_data) return false;
491 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
492 here_error_e error = hereViewObjects->remove(object);
493 return (error == HERE_ERROR_NONE);
496 bool HereViewObjects::__foreachForUpdatingGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
498 if (!user_data) return false;
500 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
501 here_error_e error = hereViewObjects->update(object);
502 return (error == HERE_ERROR_NONE);
505 bool HereViewObjects::__foreachForSettingVisibleGroupObjects(int index, int total, maps_view_object_h object, void *user_data)
507 if (!user_data) return false;
509 HereViewObjects *hereViewObjects = (HereViewObjects*)user_data;
510 here_error_e error = hereViewObjects->setVisible(object);
511 return (error == HERE_ERROR_NONE);
514 bool HereViewObjects::__resizeMarker(maps_view_object_h hMarker,
515 const int originWidth, const int originHeight,
516 int *newWidth, int *newHeight, unsigned char **bitmap)
518 if (!hMarker || !newWidth || !newHeight || !bitmap || !*bitmap)
521 int resizedWidth = 0, resizedHeight = 0;
522 maps_view_object_marker_get_size(hMarker, &resizedWidth, &resizedHeight);
524 if (__resizeBitmap(bitmap, originWidth, originHeight, resizedWidth, resizedHeight)) {
525 *newWidth = resizedWidth;
526 *newHeight = resizedHeight;
532 bool HereViewObjects::__resizeBitmap(unsigned char **curBmp, int curWidth, int curHeight, int newWidth, int newHeight)
534 if (!curBmp || curWidth <= 0 || curHeight <= 0 || newWidth <= 0 || newHeight <= 0) return false;
535 if (curWidth == newWidth && curHeight == newHeight) return false;
537 unsigned char* newBmp = new unsigned char[newWidth * newHeight * 4];
539 double scaleWidth = (double)newWidth / (double)curWidth;
540 double scaleHeight = (double)newHeight / (double)curHeight;
542 int newPixel, curPixel;
544 for (int y = 0; y < newHeight; y++) {
545 for (int x = 0; x < newWidth; x++) {
546 newPixel = (y * (newWidth *4)) + (x * 4);
547 curPixel = (((int)(y / scaleHeight) * (curWidth * 4)) + ((int)(x / scaleWidth) * 4));
549 newBmp[newPixel ] = (*curBmp)[curPixel ];
550 newBmp[newPixel + 1] = (*curBmp)[curPixel + 1];
551 newBmp[newPixel + 2] = (*curBmp)[curPixel + 2];
552 newBmp[newPixel + 3] = (*curBmp)[curPixel + 3];
561 void HereViewObjects::__invalidate(maps_view_object_h hObj)
563 maps_view_object_type_e type;
564 maps_view_object_get_type(hObj, &type);
566 if (!hObj || type != MAPS_VIEW_OBJECT_MARKER)
567 __map->InvalidateMapObjects();
569 __map->InvalidateMapMarkers();
572 HERE_PLUGIN_END_NAMESPACE