날뛰는 코드

JSON 파싱 두 마커사이 거리, 시간 파싱하기.(17/08/21) 본문

안드로이드/구글 맵

JSON 파싱 두 마커사이 거리, 시간 파싱하기.(17/08/21)

미 냉 2017. 8. 21. 18:21

*크게

= routes(경로) {  legs(구간) { steps(스텝) } } 으로 구성

 

* Legs의 distance, duration 의 text, value 를 뽑아내면 된다.

 

 "legs" : [
           
{
               
"arrival_time" : {
                 
"text" : "3:49pm",
                 
"time_zone" : "America/New_York",
                 
"value" : 1447188541
               
},
               
"departure_time" : {
                 
"text" : "3:00pm",
                 
"time_zone" : "America/New_York",
                 
"value" : 1447185623
               
},
               
"distance" : {
                 
"text" : "10.1 mi",
                 
"value" : 16273
               
},
               
"duration" : {
                 
"text" : "49 mins",
                 
"value" : 2918
               
},
               
"end_address" : "1 MetLife Stadium Dr, East Rutherford, NJ 07073, USA",
               
"end_location" : {
                 
"lat" : 40.814505,
                 
"lng" : -74.07272910000002
               
},
               
"start_address" : "75 Ninth Ave, New York, NY 10011, USA",
               
"start_location" : {
                 
"lat" : 40.7428444,
                 
"lng" : -74.00587019999999
               
},

 

 

*HashMap 사용

 

- 참고 사이트

http://arabiannight.tistory.com/entry/%EC%9E%90%EB%B0%94Java-%EC%9E%90%EB%B0%94-HashMap-%EC%9D%B4%EB%9E%80

 

HashMap또한 Map인터페이스를 구현한 녀석이기 때문에 Map의 속성을 모두 가지고 있고, 저장 방식 또한 동일 합니다. 그리고 해싱(hashing)이란 검색 방법을 사용하기 때문에 많은 양의 데이터를 검색하는데 있어서 뛰어난 성능을 보여줍니다.

출처: http://arabiannight.tistory.com/entry/자바Java-자바-HashMap-이란 [아라비안나이트]

 

 

 

** 후... 힘들었네이거

 

일단 Legs부분의 distance, duration 뽑아내는 거는 해놔서 괜찮았는데,

 

써보지 않은 HashMap 자료형 때문에 애먹었다.

그리고 기존의 polyline을 위해 만들어진 파싱, 리턴 구조라 아이에 새로 만드는게 나앗을 것 같다

 

근데 그냥 원래 있던 것을 수정하며 했다.

 

위에 두줄 썻다가 갑자기 생각이 떠올라서 

 

다르게 바꾸니까 그냥 된다.

 

내가멍청했었네

 

**

 


 

 

1. 파싱 부분 수정

 

* 원래 Google distance matrix를 이용해서 파싱해왔는데 

 

이 정보가 기존에 경로 polyline 그릴때 쓰던 Google direction에도 내용이 있었다.

 

Google direction 에는 앵간한 정보는 다있는듯

 


 

* 기존에 쓰던거

 

- Google distance matrix 구조

 

Response

{
   
"destination_addresses" : [ "San Francisco, CA, USA", "Victoria, BC, Canada" ],
   
"origin_addresses" : [ "Vancouver, BC, Canada", "Seattle, WA, USA" ],
   
"rows" : [
     
{
         
"elements" : [
           
{
               
"distance" : {
                 
"text" : "1,731 km",
                 
"value" : 1731438
               
},
               
"duration" : {
                 
"text" : "1 day 16 hours",
                 
"value" : 145285
               
},
               
"status" : "OK"
           
},
           
{
               
"distance" : {
                 
"text" : "267 km",
                 
"value" : 267181
               
},
               
"duration" : {
                 
"text" : "19 hours 43 mins",
                 
"value" : 71004
               
},
               
"status" : "OK"
           
}
         
]
     
},
     
{
         
"elements" : [
           
{
               
"distance" : {
                 
"text" : "1,480 km",
                 
"value" : 1479935
               
},
               
"duration" : {
                 
"text" : "1 day 0 hours",
                 
"value" : 87626
               
},
               
"status" : "OK"
           
},
           
{
               
"distance" : {
                 
"text" : "162 km",
                 
"value" : 161703
               
},
               
"duration" : {
                 
"text" : "14 hours 58 mins",
                 
"value" : 53884
               
},
               
"status" : "OK"
           
}
         
]
     
}
   
],
   
"status" : "OK"
}

 

-  파싱 코드

public List<List<String>> parse_DT(JSONObject jObject)
{
JSONArray jRows;
JSONArray jElements;

List<List<String>> data = new ArrayList<>();
List <String> iDistance = new ArrayList<>();
List <String> iDuration = new ArrayList<>();
//elements 는 여러개고
// distance,duration 조합이 여러개.
// e
// distance.get("text") for문 엘리먼츠 사이즈만큼.
Log.d("DisDur","1");
try {
Log.d("DisDur","2");
jRows = jObject.getJSONArray("rows");
for(int i=0;i<jRows.length();i++)
{

jElements = ((JSONObject)jRows.get(i)).getJSONArray("elements");
Log.d("DisDur",jElements.get(0).toString());
for(int j=0;j<jElements.length();j++)
{
Log.d("DisDur","4");
JSONObject jDis = ((JSONObject)jElements.get(i)).getJSONObject("distance");
JSONObject jDur = ((JSONObject)jElements.get(i)).getJSONObject("duration");

Log.d("DisDur",jDis.get("text").toString());
Log.d("DisDur",jDur.get("text").toString());

iDistance.add(jDis.get("text").toString());
iDuration.add(jDur.get("text").toString());
}
}
Log.d("DisDur","5");
data.add(iDistance);
data.add(iDuration);


} catch (JSONException e) {
Log.d("DisDur","catch당함");
e.printStackTrace();
}
for(int i=0;i<data.get(0).size();i++)
{
Log.d("DisDur",data.get(0).get(i)+"\n"+data.get(1).get(i)); //get0 : 거리 , get(1) : 시간
}
return data;
// System.out.println("??");
}

기존 Distance, Duration 가져오는 부분

 

그래도 이거 하면서 JSON 파싱 어떻게 하는지 공부했다.

몰랐었는데 

 

여기서 elements 부분의 정보가 

 

Google direction의 legs부분에 있었다.

 

기존 방식은 두개의 url이 달라서 따로 따로 보내서 각각 값을 받아오고, 구조도 이상해져 비효율 적이었다.

 

근데 그냥 이제 Google direction 에서 다 가져오려고한다.

 

 


 

 

 

 * 바꾼 부분

     => polyline 그릴 각 point, distance, duration 을 HashMap 리스트에 넣어 리턴한다.

 

public List<List<HashMap<String, String>>> parse(JSONObject jObject) {

List<List<HashMap<String, String>>> routes = new ArrayList<>();
JSONArray jRoutes;
JSONArray jLegs;
JSONArray jSteps;

try {
jRoutes = jObject.getJSONArray("routes");

/** Traversing all routes */
for (int i = 0; i < jRoutes.length(); i++) {
jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
List path = new ArrayList<>();
List l_DD = new ArrayList<>();
/** Traversing all legs */
for (int j = 0; j < jLegs.length(); j++) {
jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");
HashMap<String,String> h_DD = new HashMap<>();

JSONObject jDis = ((JSONObject)jLegs.get(i)).getJSONObject("distance");
JSONObject jDur = ((JSONObject)jLegs.get(i)).getJSONObject("duration");

h_DD.put("Distance",jDis.get("text").toString());
h_DD.put("Duration",jDur.get("text").toString()); // Distance Duraion 부분
Log.d("d_parsing","DP:"+ h_DD.get("Distance"));
path.add(h_DD);

/** Traversing all steps */
for (int k = 0; k < jSteps.length(); k++) {

String polyline = "";
polyline = (String) ((JSONObject) ((JSONObject) jSteps.get(k)).get("polyline")).get("points");
List<LatLng> list = decodePoly(polyline);

/** Traversing all points */
for (int l = 0; l < list.size(); l++) {
HashMap<String, String> hm = new HashMap<>();
hm.put("lat", Double.toString((list.get(l)).latitude));
hm.put("lng", Double.toString((list.get(l)).longitude)); // 각 포인트 위치
path.add(hm);
}
}
routes.add(path);
// routes.add(l_DD);
}
}
}//try
catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {

}
return routes;
}

 

 

각 legs 마다 거리, 소요시간 뺴서 path리스트에 담고, 경로 포인트도 같이 담아 보낸다.

 

이걸 메인엑티비티에서 키 값으로 구분해서 처리하게

 

            for (int i = 0; i < result.size(); i++) {
points = new ArrayList<>();
lineOptions = new PolylineOptions();

// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);


Log.d("d_parsing", "path size: " + Integer.toString(path.size()));
// Fetching all the points in i-th route

for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);

if(point.containsKey("Distance")||point.containsKey("Duration")) {
String Dis = point.get("Distance");
String Dur = point.get("Duration");
tv.append(Dis + " , " + Dur + "\n");
}
else{
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
// Log.d("d_parsing", "lat: " + Double.toString(lat) + " lng:" + Double.toString(lng));
points.add(position);
}

} // for
// Adding all the points in the route to LineOptions
// lineOptions.addAll(points);
lineOptions.addAll(points);
lineOptions.width(10);
lineOptions.color(Color.rgb(33, 142, 233));//8EC7fF

Log.d("onPostExecute","onPostExecute lineoptions decoded");

}
// Drawing polyline in the Google Map for the i-th route
if(lineOptions != null) {
map.addPolyline(lineOptions);
}
else {
Log.d("onPostExecute","without Polylines drawn");
}
}

대충 가져온거 처리하는 부분

 

파싱해서 리턴 받은 값을 키값(Distance, Duration, lat, lng)에 따라 구분해서 처리

 

이게 if문으로 키값구분해서 저렇게 안하면

 

point에 이상한값 들어가서 polyline이 그려지지 않았다 shit

 

 

 

 

 

* 결과

 

 

 

 

 

 

 

** 중간에 코드 막 바꾸다가 안되고 복구도 안되서 큰일 날뻔했는데 깃허브에 해놔서 다행히 복원했다.

 

깃허브 짱

 

생각보다 삽질해서 배고프네

 

전체코드:

 

https://github.com/littlecold2/googlemap_test

Comments