summaryrefslogtreecommitdiff
path: root/src/mapquest/mapquest_jsonparser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mapquest/mapquest_jsonparser.c')
-rw-r--r--src/mapquest/mapquest_jsonparser.c1124
1 files changed, 1124 insertions, 0 deletions
diff --git a/src/mapquest/mapquest_jsonparser.c b/src/mapquest/mapquest_jsonparser.c
new file mode 100644
index 0000000..e549a5c
--- /dev/null
+++ b/src/mapquest/mapquest_jsonparser.c
@@ -0,0 +1,1124 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <json-glib/json-glib.h>
+#include "mapquest_jsonparser.h"
+#include "mapquest_queue.h"
+#include "mapquest_debug.h"
+
+#define ROUTE_UNIT_CONVERSION_MILE_TO_M(x) (1609.34 * (x))
+#define ROUTE_UNIT_CONVERSION_MILE_TO_KM(x) (1.60934 * (x))
+#define ROUTE_UNIT_CONVERSION_MILE_TO_FT(x) (5280 * (x))
+#define ROUTE_UNIT_CONVERSION_MILE_TO_YD(x) (1760 * (x))
+
+static route_unit __route_unit = ROUTE_UNIT_M;
+static int __maneuver_index = 0;
+static coords_s __destination_point;
+
+static mapquest_error_e __convert_status(int status)
+{
+ mapquest_error_e error = MAPQUEST_ERROR_UNKNOWN;
+ switch (status) {
+ case 0:
+ {
+ /* Successful Geocode call */
+ error = MAPQUEST_ERROR_NONE;
+ break;
+ }
+ case 400:
+ {
+ /* Error with input - Illegal argument from request */
+ error = MAPQUEST_ERROR_INVALID_PARAMETER;
+ break;
+ }
+ case 403:
+ {
+ /* Key related error - Invalid key */
+ error = MAPQUEST_ERROR_KEY_NOT_AVAILABLE;
+ break;
+ }
+ case 500:
+ {
+ /* Unknown error */
+ error = MAPQUEST_ERROR_UNKNOWN;
+ break;
+ }
+ case -1:
+ {
+ /* Network error */
+ error = MAPQUEST_ERROR_NETWORK_UNREACHABLE;
+ break;
+ }
+ }
+
+ return error;
+}
+
+/************ GEOCODE ***************/
+
+static void __parse_lat_lng(JsonNode *node, GList **coordsList)
+{
+ if (!node || !coordsList) return;
+
+ gdouble latitude = 0.0;
+ gdouble longitude = 0.0;
+ JsonObject *resultObj = json_node_get_object(node);
+
+ if (resultObj) {
+ JsonNode *latNode = json_object_get_member(resultObj, "lat");
+
+ if (latNode) {
+ latitude = json_node_get_double(latNode);
+ MAP_DEBUG("Latitude :: >>> %f", latitude);
+ }
+
+ JsonNode *lngNode = json_object_get_member(resultObj, "lng");
+
+ if (lngNode) {
+ longitude = json_node_get_double(lngNode);
+ MAP_DEBUG("Longitude :: >>> %f", longitude);
+ }
+
+ coords_s *coords = (coords_s *)g_malloc0(sizeof(coords_s));
+ if (coords != NULL) {
+ MAP_DEBUG("Storing the latitude and longitude data..");
+ coords->latitude = latitude;
+ coords->longitude = longitude;
+ }
+
+ if (*coordsList == NULL)
+ *coordsList = g_list_append(*coordsList, coords);
+ else
+ *coordsList = g_list_insert_before(*coordsList, NULL, coords);
+ }
+}
+
+static void __parse_locations(JsonNode *node, GList **coordsList)
+{
+ if (!node || !coordsList) return;
+
+ JsonArray *resultArray = json_node_get_array(node);
+
+ int length = json_array_get_length(resultArray);
+
+ int index = 0;
+ for (index = 0; index < length; index++) {
+
+ JsonObject *obj = json_array_get_object_element(resultArray, index);
+
+ if (obj) {
+ JsonNode *latLngNode = json_object_get_member(obj, "latLng");
+
+ if (latLngNode)
+ __parse_lat_lng(latLngNode, coordsList);
+ }
+ }
+}
+
+static void __parse_geocode_response(char *response, int size, int *status, GList **coordsList)
+{
+ if (!response || !status || !coordsList) return;
+
+ *coordsList = NULL;
+
+ JsonParser *parser = NULL;
+ JsonNode *root = NULL;
+ JsonNode *node = NULL;
+ JsonObject *object = NULL;
+ GError *error = NULL;
+ char data[size + 1];
+
+ parser = json_parser_new();
+
+ strncpy(data, response, size);
+ data[size] = '\0';
+
+ if (!json_parser_load_from_data(parser, data, -1, &error)) {
+ MAP_DEBUG("Error in file parsing JSON..");
+ g_error_free(error);
+ g_object_unref(parser);
+ return;
+ }
+
+ root = json_parser_get_root(parser);
+
+ object = json_node_get_object(root);
+
+ node = json_object_get_member(object, "info");
+ JsonObject *infoObj = json_node_get_object(node);
+ if (infoObj) {
+ JsonNode *statusNode = json_object_get_member(infoObj, "statuscode");
+
+ if (statusNode) {
+ *status = json_node_get_int(statusNode);
+ MAP_DEBUG("status :: >>> %d", *status);
+ }
+ }
+
+ if (*status != 0) { /* SUCCESS */
+ *coordsList = NULL;
+ return;
+ }
+
+ node = json_object_get_member(object, "results");
+ JsonArray *resultArray = json_node_get_array(node);
+
+ int length = json_array_get_length(resultArray);
+
+ int index = 0;
+ for (index = 0; index < length; index++) {
+
+ JsonObject *obj = json_array_get_object_element(resultArray, index);
+
+ if (obj) {
+ JsonNode *locNode = json_object_get_member(obj, "locations");
+
+ if (locNode)
+ __parse_locations(locNode, coordsList);
+ }
+ }
+
+ g_object_unref(parser);
+}
+
+/****************** REVERSE GEOCODE *********************/
+
+static void __parse_revgeocode_address(JsonNode *node, mapquest_address_resp_s **respAddr)
+{
+ if (!node || !respAddr) return;
+
+ char *streetAddr = NULL;
+ char *neighbourhood = NULL;
+ char *city = NULL;
+ char *county = NULL;
+ char *state = NULL;
+ char *country = NULL;
+ char *postalCode = NULL;
+
+ JsonArray *resultArray = json_node_get_array(node);
+
+ int length = json_array_get_length(resultArray);
+
+ int index = 0;
+ for (index = 0; index < length; index++) {
+
+ JsonObject *obj = json_array_get_object_element(resultArray, index);
+
+ if (obj) {
+ JsonNode *tmp = NULL;
+
+ /* Street */
+ tmp = json_object_get_member(obj, "street");
+ if (tmp) {
+ streetAddr = (char *) json_node_get_string(tmp);
+ if (streetAddr && strlen(streetAddr) <= 0)
+ streetAddr = NULL;
+ } else {
+ streetAddr = NULL;
+ }
+
+ /* Neighborhood */
+ tmp = json_object_get_member(obj, "adminArea6");
+ if (tmp) {
+ neighbourhood = (char *) json_node_get_string(tmp);
+ if (neighbourhood && strlen(neighbourhood) <= 0)
+ neighbourhood = NULL;
+ } else {
+ neighbourhood = NULL;
+ }
+
+ /* City */
+ tmp = json_object_get_member(obj, "adminArea5");
+ if (tmp) {
+ city = (char *) json_node_get_string(tmp);
+ if (city && strlen(city) <= 0)
+ city = NULL;
+ } else {
+ city = NULL;
+ }
+
+ /* State */
+ tmp = json_object_get_member(obj, "adminArea3");
+ if (tmp) {
+ state = (char *) json_node_get_string(tmp);
+ if (state && strlen(state) <= 0)
+ state = NULL;
+ } else {
+ state = NULL;
+ }
+
+ /* County */
+ tmp = json_object_get_member(obj, "adminArea4");
+ if (tmp) {
+ county = (char *) json_node_get_string(tmp);
+ if (county && strlen(county) <= 0)
+ county = NULL;
+ } else {
+ county = NULL;
+ }
+
+ /* Country */
+ tmp = json_object_get_member(obj, "adminArea1");
+ if (tmp) {
+ country = (char *) json_node_get_string(tmp);
+ if (country && strlen(country) <= 0)
+ country = NULL;
+ } else {
+ country = NULL;
+ }
+
+ /* Postal Code */
+ tmp = json_object_get_member(obj, "postalCode");
+ if (tmp) {
+ postalCode = (char *) json_node_get_string(tmp);
+ if (postalCode && strlen(postalCode) <= 0)
+ postalCode = NULL;
+ } else {
+ postalCode = NULL;
+ }
+
+ if (!streetAddr && !neighbourhood && !city && !state && !county && !country && !postalCode)
+ continue;
+
+ *respAddr = (mapquest_address_resp_s *)g_malloc(sizeof(mapquest_address_resp_s));
+
+ if (*respAddr != NULL) {
+ /* Street Address */
+ if (streetAddr != NULL) {
+ (*respAddr)->street_add = (gchar *)g_malloc(strlen((char *)streetAddr) + 1);
+ strcpy((*respAddr)->street_add, (char *) streetAddr);
+ } else {
+ MAP_DEBUG("street is NULL");
+ (*respAddr)->street_add = NULL;
+ }
+
+ /* Neighbourhood */
+ if (neighbourhood != NULL) {
+ (*respAddr)->neighbourhood = (gchar *)g_malloc(strlen((char *)neighbourhood) + 1);
+ strcpy((*respAddr)->neighbourhood, (char *) neighbourhood);
+ } else {
+ MAP_DEBUG("neighbourhood is NULL");
+ (*respAddr)->neighbourhood = NULL;
+ }
+
+ /* City */
+ if (city != NULL) {
+ (*respAddr)->city = (gchar *)g_malloc(strlen((char *)city) + 1);
+ strcpy((*respAddr)->city, (char *) city);
+ } else {
+ MAP_DEBUG("city is NULL");
+ (*respAddr)->city = NULL;
+ }
+
+ /* County */
+ if (county != NULL) {
+ (*respAddr)->county = (gchar *)g_malloc(strlen((char *)county) + 1);
+ strcpy((*respAddr)->county, (char *) county);
+ } else {
+ MAP_DEBUG("county is NULL");
+ (*respAddr)->county = NULL;
+ }
+
+ /* State */
+ if (state != NULL) {
+ (*respAddr)->state = (gchar *)g_malloc(strlen((char *)state) + 1);
+ strcpy((*respAddr)->state, (char *) state);
+ } else {
+ MAP_DEBUG("state is NULL");
+ (*respAddr)->state = NULL;
+ }
+
+ /* Country */
+ if (country != NULL) {
+ (*respAddr)->country = (gchar *)g_malloc(strlen((char *)country) + 1);
+ strcpy((*respAddr)->country, (char *) country);
+ } else {
+ MAP_DEBUG("country is NULL");
+ (*respAddr)->country = NULL;
+ }
+
+ /* Country code */
+ MAP_DEBUG("country code is NULL");
+ (*respAddr)->country_code = NULL;
+
+ /* Postal Code */
+ if (postalCode != NULL) {
+ (*respAddr)->postal_code = (gchar *)g_malloc(strlen((char *)postalCode) + 1);
+ strcpy((*respAddr)->postal_code, (char *) postalCode);
+ } else {
+ MAP_DEBUG("postal_code is NULL");
+ (*respAddr)->postal_code = NULL;
+ }
+ }
+ }
+ }
+}
+
+static void __parse_revgeocode_response(char *response, int size, int *status, mapquest_address_resp_s **respAddr)
+{
+ if (!response || !status || !respAddr) return;
+
+ *respAddr = NULL;
+
+ JsonParser *parser;
+ JsonNode *root;
+ JsonNode *node;
+ JsonObject *object;
+ GError *error = NULL;
+ char data[size + 1];
+
+ parser = json_parser_new();
+
+ strncpy(data, response, size);
+ data[size] = '\0';
+
+ if (!json_parser_load_from_data(parser, data, -1, &error)) {
+ MAP_DEBUG("Error in file parsing JSON..");
+ g_error_free(error);
+ g_object_unref(parser);
+ return;
+ }
+
+ root = json_parser_get_root(parser);
+
+ object = json_node_get_object(root);
+
+ node = json_object_get_member(object, "info");
+ JsonObject *infoObj = json_node_get_object(node);
+ if (infoObj) {
+ JsonNode *statusNode = json_object_get_member(infoObj, "statuscode");
+
+ if (statusNode) {
+ *status = json_node_get_int(statusNode);
+ MAP_DEBUG("status :: >>> %d", *status);
+ }
+ }
+
+ if (*status != 0) { /* SUCCESS */
+ *respAddr = NULL;
+ return;
+ }
+
+ node = json_object_get_member(object, "results");
+ JsonArray *resultArray = json_node_get_array(node);
+
+ int length = json_array_get_length(resultArray);
+
+ int index = 0;
+ for (index = 0; index < length; index++) {
+
+ JsonObject *obj = json_array_get_object_element(resultArray, index);
+
+ if (obj) {
+ JsonNode *locNode = json_object_get_member(obj, "locations");
+
+ if (locNode)
+ __parse_revgeocode_address(locNode, respAddr);
+ }
+ }
+
+ g_object_unref(parser);
+}
+
+/**************** PLACE SEARCH ********************/
+
+static void __place_address_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
+{
+ if (!object || !member_name || !member_node || !user_data) return;
+
+ mapquest_address_resp_s **respAddr = (mapquest_address_resp_s **) user_data;
+
+ if (*respAddr) {
+ JsonNode *tmp = json_object_get_member(object, member_name);
+
+ if (!strcmp(member_name, "road"))
+ (*respAddr)->street_add = (char *) json_node_dup_string(tmp);
+ else if (!strcmp(member_name, "neighbourhood"))
+ (*respAddr)->neighbourhood = (char *) json_node_dup_string(tmp);
+ else if (!strcmp(member_name, "house_number"))
+ (*respAddr)->building_number = (char *) json_node_dup_string(tmp);
+ else if (!strcmp(member_name, "city"))
+ (*respAddr)->city = (char *) json_node_dup_string(tmp);
+ else if (!strcmp(member_name, "county"))
+ (*respAddr)->county = (char *) json_node_dup_string(tmp);
+ else if (!strcmp(member_name, "state"))
+ (*respAddr)->state = (char *) json_node_dup_string(tmp);
+ else if (!strcmp(member_name, "country"))
+ (*respAddr)->country = (char *) json_node_dup_string(tmp);
+ else if (!strcmp(member_name, "country_code"))
+ (*respAddr)->country_code = (char *) json_node_dup_string(tmp);
+ else if (!strcmp(member_name, "postcode"))
+ (*respAddr)->postal_code = (char *) json_node_dup_string(tmp);
+ } else {
+ *respAddr = NULL;
+ }
+}
+
+static void __place_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
+{
+ if (!object || !member_name || !member_node || !user_data) return;
+
+ mapquest_place_resp_s **respPlaces = (mapquest_place_resp_s **) user_data;
+
+ JsonNode *tmp = json_object_get_member(object, member_name);
+ char *str;
+
+ if (!strcmp(member_name, "place_id")) {
+ (*respPlaces)->place_id = (char *) json_node_get_string(tmp);
+ } else if (!strcmp(member_name, "lat")) {
+ str = (char *) json_node_get_string(tmp);
+ ((*respPlaces)->coordinates).latitude = (str ? atof(str) : 0);
+ } else if (!strcmp(member_name, "lon")) {
+ str = (char *) json_node_get_string(tmp);
+ ((*respPlaces)->coordinates).longitude = (str ? atof(str) : 0);
+ } else if (!strcmp(member_name, "class")) {
+ (*respPlaces)->category = (char *) json_node_dup_string(tmp);
+ } else if (!strcmp(member_name, "type")) {
+ (*respPlaces)->subcategory = (char *) json_node_dup_string(tmp);
+ } else if (!strcmp(member_name, "display_name")) {
+ (*respPlaces)->display_name = (char *) json_node_dup_string(tmp);
+ } else if (!strcmp(member_name, "address")) {
+ JsonObject *obj = json_node_get_object(member_node);
+
+ (*respPlaces)->address = (mapquest_address_resp_s *)g_malloc(sizeof(mapquest_address_resp_s));
+ if ((*respPlaces)->address) {
+ (*respPlaces)->address->street_add = NULL;
+ (*respPlaces)->address->neighbourhood = NULL;
+ (*respPlaces)->address->building_number = NULL;
+ (*respPlaces)->address->city = NULL;
+ (*respPlaces)->address->county = NULL;
+ (*respPlaces)->address->state = NULL;
+ (*respPlaces)->address->country = NULL;
+ (*respPlaces)->address->country_code = NULL;
+ (*respPlaces)->address->postal_code = NULL;
+ }
+
+ json_object_foreach_member(obj, __place_address_foreach, &((*respPlaces)->address));
+ } else if (!strcmp(member_name, "icon")) {
+ (*respPlaces)->icon_url = (char *) json_node_get_string(tmp);
+ }
+}
+
+static void __parse_place_response(char *response, int size, GList **placeList)
+{
+ if (!response || !placeList) return;
+
+ *placeList = NULL;
+
+ JsonParser *parser;
+ JsonNode *root;
+ GError *error = NULL;
+ char data[size + 1];
+
+ parser = json_parser_new();
+ if (!parser) return;
+
+ strncpy(data, response, size);
+ data[size] = '\0';
+
+ if (!json_parser_load_from_data(parser, data, -1, &error)) {
+ MAP_DEBUG("Error in file parsing JSON..");
+ g_error_free(error);
+ g_object_unref(parser);
+ return;
+ }
+
+ root = json_parser_get_root(parser);
+
+ JsonArray *placeArray = json_node_get_array(root);
+
+ int length = json_array_get_length(placeArray);
+ MAP_DEBUG("Places result count :: %d", length);
+
+ int index = 0;
+ for (index = 0; index < length; index++) {
+
+ JsonObject *obj = json_array_get_object_element(placeArray, index);
+
+ if (obj) {
+ mapquest_place_resp_s *respPlaces = (mapquest_place_resp_s *)g_malloc(sizeof(mapquest_place_resp_s));
+
+ if (respPlaces) {
+ respPlaces->place_id = NULL;
+ respPlaces->category = NULL;
+ respPlaces->subcategory = NULL;
+ respPlaces->display_name = NULL;
+ respPlaces->address = NULL;
+ respPlaces->icon_url = NULL;
+
+ json_object_foreach_member(obj, __place_foreach, &respPlaces);
+
+ if (*placeList == NULL)
+ *placeList = g_list_append(*placeList, respPlaces);
+ else
+ *placeList = g_list_insert_before(*placeList, NULL, respPlaces);
+ }
+ }
+ }
+
+ g_object_unref(parser);
+}
+
+/********************* ROUTE RESPONSE ***********************/
+
+static double __convert_distance_unit(double distance)
+{
+ double val = 0.0;
+ switch (__route_unit) {
+ case ROUTE_UNIT_M:
+ val = ROUTE_UNIT_CONVERSION_MILE_TO_M(distance);
+ break;
+ case ROUTE_UNIT_KM:
+ val = ROUTE_UNIT_CONVERSION_MILE_TO_KM(distance);
+ break;
+ case ROUTE_UNIT_FT:
+ val = ROUTE_UNIT_CONVERSION_MILE_TO_FT(distance);
+ break;
+ case ROUTE_UNIT_YD:
+ val = ROUTE_UNIT_CONVERSION_MILE_TO_YD(distance);
+ break;
+ }
+
+ return val;
+}
+
+static void __maneuver_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
+{
+ if (!object || !member_name || !member_node || !user_data) return;
+
+ mapquest_route_maneuver **maneuver = (mapquest_route_maneuver **) user_data;
+
+ JsonNode *tmp = json_object_get_member(object, member_name);
+
+ if (!strcmp(member_name, "startPoint")) {
+ JsonObject *coordsObj = json_node_get_object(tmp);
+
+ if (coordsObj) {
+ double latitude = 0.0;
+ double longitude = 0.0;
+ JsonNode *latNode = json_object_get_member(coordsObj, "lat");
+
+ if (latNode)
+ latitude = json_node_get_double(latNode);
+
+ JsonNode *lngNode = json_object_get_member(coordsObj, "lng");
+
+ if (lngNode)
+ longitude = json_node_get_double(lngNode);
+
+ coords_s start_point;
+ start_point.latitude = latitude;
+ start_point.longitude = longitude;
+
+ (*maneuver)->start_point = start_point;
+ }
+ } else if (!strcmp(member_name, "narrative")) {
+ (*maneuver)->instruction = (char *) json_node_dup_string(tmp);
+ } else if (!strcmp(member_name, "distance")) {
+ double dist = json_node_get_double(tmp);
+ (*maneuver)->distance = __convert_distance_unit(dist);
+ } else if (!strcmp(member_name, "time")) {
+ (*maneuver)->time = json_node_get_int(tmp);
+ } else if (!strcmp(member_name, "formattedTime")) {
+ (*maneuver)->formatted_time = (char *) json_node_dup_string(tmp);
+ } else if (!strcmp(member_name, "attributes")) {
+ (*maneuver)->attribute = json_node_get_int(tmp);
+ } else if (!strcmp(member_name, "turnType")) {
+ (*maneuver)->turn_type = json_node_get_int(tmp);
+ } else if (!strcmp(member_name, "direction")) {
+ (*maneuver)->direction = json_node_get_int(tmp);
+ } else if (!strcmp(member_name, "directionName")) {
+ (*maneuver)->direction_name = (char *) json_node_dup_string(tmp);
+ } else if (!strcmp(member_name, "index")) {
+ (*maneuver)->index = json_node_get_int(tmp);
+ } else if (!strcmp(member_name, "streets")) {
+ JsonArray *streetsArray = json_node_get_array(tmp);
+
+ int length = json_array_get_length(streetsArray);
+
+ char street_name[512];
+ strcpy(street_name, "");
+ int index = 0;
+ for (index = 0; index < length; index++) {
+ char *name = (char *) json_array_get_string_element(streetsArray, index);
+ if (name) {
+ if (index == 0) {
+ strncpy(street_name, name, sizeof(street_name)-1);
+ } else {
+ strcat(street_name, "/");
+ strncat(street_name, name, sizeof(street_name)-strlen(street_name)-1);
+ }
+ }
+ }
+
+ if (strlen(street_name) > 0) {
+ (*maneuver)->street_name = (gchar *)g_malloc0((strlen((char *)street_name)) + 1);
+ if ((*maneuver)->street_name)
+ strcpy((*maneuver)->street_name, (char *) street_name);
+ } else {
+ (*maneuver)->street_name = NULL;
+ }
+ }
+}
+
+static void __parse_maneuvers(JsonNode *node, mapquest_route_resp_s **routeResp)
+{
+ if (!node || !routeResp) return;
+
+ JsonArray *resultArray = json_node_get_array(node);
+
+ int length = json_array_get_length(resultArray);
+
+ int index = 0;
+ for (index = 0; index < length; index++) {
+
+ JsonObject *obj = json_array_get_object_element(resultArray, index);
+
+ if (obj) {
+ mapquest_route_maneuver *maneuver = (mapquest_route_maneuver *)g_malloc(sizeof(mapquest_route_maneuver));
+
+ if (maneuver) {
+ json_object_foreach_member(obj, __maneuver_foreach, &maneuver);
+
+ if (__maneuver_index != 0) {
+ if (maneuver->distance == 0.0 && maneuver->time == 0) {
+ maneuver->start_point = __destination_point;
+ maneuver->end_point = __destination_point;
+ } else {
+
+ }
+
+ GList *list = NULL;
+ list = g_list_last((*routeResp)->maneuvers);
+ if (list) {
+ mapquest_route_maneuver *tmp = (mapquest_route_maneuver *)list->data;
+ tmp->end_point = maneuver->start_point;
+ }
+ }
+
+ if ((*routeResp)->maneuvers == NULL)
+ (*routeResp)->maneuvers = g_list_append((*routeResp)->maneuvers, (gpointer)maneuver);
+ else
+ (*routeResp)->maneuvers = g_list_insert_before((*routeResp)->maneuvers, NULL, (gpointer)maneuver);
+ }
+ __maneuver_index++;
+ }
+ }
+}
+
+static void __shape_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
+{
+ if (!object || !member_name || !member_node || !user_data) return;
+
+ mapquest_route_resp_s **routeResp = (mapquest_route_resp_s **) user_data;
+
+ JsonNode *tmp = json_object_get_member(object, member_name);
+
+ if (!strcmp(member_name, "shapePoints")) {
+ JsonArray *shapePointsArray = json_node_get_array(tmp);
+
+ int length = json_array_get_length(shapePointsArray);
+
+ int index = 0;
+ double val = 0.0;
+ coords_s *coords = NULL;
+ for (index = 0; index < length; index++) {
+
+ val = (double) json_array_get_double_element(shapePointsArray, index);
+
+ if ((index % 2) == 0) {
+ /* Lat */
+ coords = (coords_s *)g_malloc0(sizeof(coords_s));
+ if (coords)
+ coords->latitude = val;
+ } else {
+ /* Lon */
+ if (coords) {
+ coords->longitude = val;
+ if ((*routeResp)->shapePoints == NULL)
+ (*routeResp)->shapePoints = g_list_append((*routeResp)->shapePoints, (gpointer)coords);
+ else
+ (*routeResp)->shapePoints = g_list_insert_before((*routeResp)->shapePoints, NULL, (gpointer)coords);
+ }
+ }
+ }
+ }
+
+}
+
+static void __bbox_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
+{
+ if (!object || !member_name || !member_node || !user_data) return;
+
+ mapquest_route_resp_s **routeResp = (mapquest_route_resp_s **) user_data;
+
+ JsonNode *tmp = json_object_get_member(object, member_name);
+
+ JsonObject *coordsObj = json_node_get_object(tmp);
+ double latitude = 0.0;
+ double longitude = 0.0;
+
+ if (coordsObj) {
+ JsonNode *latNode = json_object_get_member(coordsObj, "lat");
+
+ if (latNode)
+ latitude = json_node_get_double(latNode);
+
+ JsonNode *lngNode = json_object_get_member(coordsObj, "lng");
+
+ if (lngNode)
+ longitude = json_node_get_double(lngNode);
+ }
+
+ if (!strcmp(member_name, "ul")) {
+ ((*routeResp)->bounding_box).top_left.latitude = latitude;
+ ((*routeResp)->bounding_box).top_left.longitude = longitude;
+ } else if (!strcmp(member_name, "lr")) {
+ ((*routeResp)->bounding_box).bottom_right.latitude = latitude;
+ ((*routeResp)->bounding_box).bottom_right.longitude = longitude;
+ }
+}
+
+static void __parse_route_response(char *response, int size, int *status, mapquest_route_resp_s **routeResp)
+{
+ if (!response || !status || !routeResp) return;
+
+ *routeResp = NULL;
+
+ JsonParser *parser;
+ JsonNode *root;
+ JsonNode *node;
+ JsonObject *object;
+ GError *error = NULL;
+ char data[size + 1];
+
+ parser = json_parser_new();
+
+ strncpy(data, response, size);
+ data[size] = '\0';
+
+ if (!json_parser_load_from_data(parser, data, -1, &error)) {
+ MAP_DEBUG("Error in file parsing JSON..");
+ g_error_free(error);
+ g_object_unref(parser);
+ return;
+ }
+
+ root = json_parser_get_root(parser);
+
+ object = json_node_get_object(root);
+
+ node = json_object_get_member(object, "info");
+ JsonObject *infoObj = json_node_get_object(node);
+ if (infoObj) {
+ JsonNode *statusNode = json_object_get_member(infoObj, "statuscode");
+
+ if (statusNode) {
+ *status = json_node_get_int(statusNode);
+ MAP_DEBUG("status :: >>> %d", *status);
+ }
+ }
+
+ if (*status != 0) { /* SUCCESS */
+ *routeResp = NULL;
+ return;
+ }
+
+ *routeResp = (mapquest_route_resp_s *)g_malloc(sizeof(mapquest_route_resp_s));
+
+ if (!(*routeResp))
+ return;
+
+ (*routeResp)->maneuvers = NULL;
+ (*routeResp)->shapePoints = NULL;
+
+ node = json_object_get_member(object, "route");
+
+ if (!node)
+ return;
+
+ JsonObject *routeObject = json_node_get_object(node);
+
+ JsonNode *tmp = json_object_get_member(routeObject, "distance");
+
+ if (tmp) {
+ double dist = json_node_get_double(tmp);
+ (*routeResp)->distance = __convert_distance_unit(dist);
+ (*routeResp)->distance_unit = __route_unit;
+ }
+
+ tmp = json_object_get_member(routeObject, "boundingBox");
+
+ if (tmp) {
+ JsonObject *bbox = json_node_get_object(tmp);
+
+ json_object_foreach_member(bbox, __bbox_foreach, routeResp);
+ }
+
+ tmp = json_object_get_member(routeObject, "formattedTime");
+
+ if (tmp)
+ (*routeResp)->formatted_time = (char *) json_node_dup_string(tmp);
+
+ tmp = json_object_get_member(routeObject, "routeType");
+ if (tmp) {
+ (*routeResp)->type = ROUTE_TYPE_BICYCLE;
+
+ char *type = (char *) json_node_get_string(tmp);
+ if (type) {
+ if (!strcmp(type, "FASTEST"))
+ (*routeResp)->type = ROUTE_TYPE_FASTEST;
+ else if (!strcmp(type, "SHORTEST"))
+ (*routeResp)->type = ROUTE_TYPE_SHORTEST;
+ else if (!strcmp(type, "PEDESTRIAN"))
+ (*routeResp)->type = ROUTE_TYPE_PEDESTRIAN;
+ else if (!strcmp(type, "MULTIMODAL"))
+ (*routeResp)->type = ROUTE_TYPE_MULTIMODAL;
+ }
+ }
+
+ tmp = json_object_get_member(routeObject, "time");
+
+ if (tmp) {
+ int time = json_node_get_int(tmp);
+ (*routeResp)->time = time;
+ }
+
+ tmp = json_object_get_member(routeObject, "legs");
+
+ if (tmp) {
+ JsonArray *legsArray = json_node_get_array(tmp);
+
+ int length = json_array_get_length(legsArray);
+
+ int index = 0;
+ for (index = 0; index < length; index++) {
+
+ JsonObject *obj = json_array_get_object_element(legsArray, index);
+
+ if (obj) {
+ JsonNode *maneuversNode = json_object_get_member(obj, "maneuvers");
+
+ if (maneuversNode)
+ __parse_maneuvers(maneuversNode, routeResp);
+ }
+ }
+ }
+
+ tmp = json_object_get_member(routeObject, "shape");
+
+ if (tmp) {
+ JsonObject *shape = json_node_get_object(tmp);
+
+ json_object_foreach_member(shape, __shape_foreach, routeResp);
+ }
+
+ g_object_unref(parser);
+}
+
+void post_curl_response(char *response, int size, mapquest_resp_type type, void *user_data)
+{
+ if (!response) return;
+
+ if (!user_data) {
+ MAP_DEBUG("Response data is NULL");
+ return;
+ }
+
+ MAP_DEBUG("Response received from Curl. [Size=%d]", size);
+ switch (type) {
+ case RESP_TYPE_GEOCODE:
+ {
+ MAP_DEBUG("Inside Geocode JSON Parsing..");
+ int status = -1;
+ MapquestGeocodeQueryData *queryData = (MapquestGeocodeQueryData *)user_data;
+ MapquestGeocodeResponseData *responseData = (MapquestGeocodeResponseData *)g_malloc(sizeof(MapquestGeocodeResponseData));
+
+ if (responseData) {
+ responseData->requestId = queryData->requestId;
+ responseData->geocode_cb = queryData->geocode_cb;
+ responseData->user_data = queryData->user_data;
+
+ if (response && (size > 0)) {
+ GList *coordsList = NULL;
+ __parse_geocode_response(response, size, &status, &coordsList);
+
+ if (coordsList != NULL) {
+ /* Put the response in queue */
+ responseData->error = __convert_status(status);
+ responseData->coords = coordsList;
+ } else {
+ /* Response parsing failure */
+ responseData->error = __convert_status(status);
+ responseData->coords = NULL;
+ }
+ } else {
+ responseData->error = __convert_status(status);
+ responseData->coords = NULL;
+ }
+
+ mapquest_push_to_queue(type, (gpointer)responseData);
+ }
+
+ if (queryData) {
+ g_free(queryData);
+ queryData = NULL;
+ }
+ break;
+ }
+ case RESP_TYPE_REVGEOCODE:
+ {
+ MAP_DEBUG("Inside Rev Geocode JSON Parsing..");
+ int status = -1;
+ MapquestRevGeocodeQueryData *queryData = (MapquestRevGeocodeQueryData *)user_data;
+ MapquestRevGeocodeResponseData *responseData = (MapquestRevGeocodeResponseData *)g_malloc(sizeof(MapquestRevGeocodeResponseData));
+
+ if (responseData) {
+ responseData->requestId = queryData->requestId;
+ responseData->reverse_geocode_cb = queryData->reverse_geocode_cb;
+ responseData->user_data = queryData->user_data;
+
+ if (response && (size > 0)) {
+ /* Coords Result GList */
+ mapquest_address_resp_s *addrResponse = NULL;
+
+ MAP_DEBUG("Rev Geocode :- Parsing json Response");
+ __parse_revgeocode_response(response, size, &status, &addrResponse);
+
+ if (addrResponse != NULL) {
+ /* Put the response in queue */
+ responseData->error = __convert_status(status);
+ responseData->addressDetails = addrResponse;
+ } else {
+ /* REPSONSE PARSING FAILURE */
+ MAP_DEBUG("addr Response is NULL");
+ responseData->error = __convert_status(status);
+ responseData->addressDetails = NULL;
+ }
+ } else {
+ MAP_DEBUG("JSON Response is NULL..");
+ responseData->error = __convert_status(status);
+ responseData->addressDetails = NULL;
+ }
+
+ mapquest_push_to_queue(type, (gpointer)responseData);
+ }
+
+ if (queryData) {
+ g_free(queryData);
+ queryData = NULL;
+ }
+ break;
+ }
+ case RESP_TYPE_PLACES:
+ {
+ MAP_DEBUG("Inside Places JSON Parsing..");
+ MapquestPlaceQueryData *queryData = (MapquestPlaceQueryData *)user_data;
+ MapquestPlaceResponseData *responseData = (MapquestPlaceResponseData *)g_malloc(sizeof(MapquestPlaceResponseData));
+
+ if (responseData) {
+ responseData->requestId = queryData->requestId;
+ responseData->place_search_cb = queryData->place_search_cb;
+ responseData->user_data = queryData->user_data;
+
+ if (response && (size > 0)) {
+ /* Coords Result GList */
+ GList *placeList = NULL;
+
+ MAP_DEBUG("Search Places :- Parsing Json Response");
+ __parse_place_response(response, size, &placeList);
+
+ if (placeList != NULL) {
+ /* Put the response in queue */
+ responseData->error = MAPQUEST_ERROR_NONE;
+ responseData->places = placeList;
+ } else {
+ /* REPSONSE PARSING FAILURE */
+ MAP_DEBUG("addr Response is NULL");
+ responseData->error = MAPQUEST_ERROR_UNKNOWN;
+ responseData->places = NULL;
+ }
+ } else {
+ responseData->error = MAPQUEST_ERROR_UNKNOWN;
+ responseData->places = NULL;
+ }
+
+ mapquest_push_to_queue(type, (gpointer)responseData);
+ }
+
+ if (queryData) {
+ g_free(queryData);
+ queryData = NULL;
+ }
+
+ break;
+ }
+ case RESP_TYPE_ROUTE:
+ {
+ MAP_DEBUG("Inside Route JSON Parsing..");
+ int status = -1;
+ MapquestRouteQueryData *queryData = (MapquestRouteQueryData *)user_data;
+ __route_unit = queryData->unit;
+ __maneuver_index = 0;
+ __destination_point = queryData->destination;
+
+ MapquestRouteResponseData *responseData = (MapquestRouteResponseData *)g_malloc(sizeof(MapquestRouteResponseData));
+
+ if (responseData) {
+ responseData->requestId = queryData->requestId;
+ responseData->route_cb = queryData->route_cb;
+ responseData->user_data = queryData->user_data;
+
+ if (response && (size > 0)) {
+ /* Coords Result GList */
+ mapquest_route_resp_s *routeResponse = NULL;
+
+ MAP_DEBUG("Route :- Parsing Response");
+ __parse_route_response(response, size, &status, &routeResponse);
+
+ if (routeResponse != NULL) {
+ /* Put the response in queue */
+ responseData->error = __convert_status(status);
+ responseData->routeResponse = routeResponse;
+ } else {
+ /* REPSONSE PARSING FAILURE */
+ MAP_DEBUG("route Response is NULL");
+ responseData->error = __convert_status(status);
+ responseData->routeResponse = NULL;
+ }
+ } else {
+ responseData->error = __convert_status(status);
+ responseData->routeResponse = NULL;
+ }
+
+ mapquest_push_to_queue(type, (gpointer)responseData);
+ }
+
+ if (queryData) {
+ g_free(queryData);
+ queryData = NULL;
+ }
+
+ break;
+ }
+ default:
+ {
+ MAP_DEBUG("Inside default JSON Parsing..");
+ break;
+ }
+ }
+}