서울시는 다양한 서비스와 데이터를 좀더 쉽게 이용하도록 하기 위해서 개인 개발자에게 다양한 API를 제공해주고 있습니다. 저도 이를 이용해서 [서울시공영주차장주차가능대수조회]와 [분실물 찾기]앱을 만들었습니다.

 

이에 관심 분을 위해서 사용방법을 적어 볼까 합니다.

이 정보는 물론 서울 열린 데이터 광장 홈페이지(http://data.seoul.go.kr/)에 다 있는 내용을 일단 제가 필요하다고 생각하는 부분을 정리해 보았습니다.

처음으로는 서울 열린 데이터 광장 홈페이지(http://data.seoul.go.kr/)에 접속하여 서울시 회원가입을 하고 로그인을 하는게 첫번째 순서입니다.

 

서울시가 아니고 전국적인 데이타는 공공데이터포털 (http://www.data.go.kr)도 있습니다.

공공API의 시스템 아키텍쳐는 아래와 같다고 합니다. 물론 개발하는데는 전혀 무관하지만 제가 워낙에 서버쪽 프로그램만 하다보니 이런 그림보면 일단 남 일 같지는 않아서요...(제가 10년넘게 이런 그림 참 많이 그렸기 때문에 ㅎㅎ)

 

공공API를 사용하는 절차는 아래와 같습니다.

 

서울시공공API사용방법

1. 참여소통 > 개발자공간 > 인증키신청 및 확인

2. 이용약관 동의 및 인증키 발급요청

3. 본인의 인증키 확인(로그인 필요)

4. OpenAPI 리스트에서 원하는 API 선택

5. 요청주소 및 요청인자 확인

6. 요청주소로 데이터 요청 후 사용

7. 획득한 데이터를 활용

 

토요일부터 농장 일을 하고자 했으나 회사 직원 결혼식 다녀와서는 힘도 들고 와이프도 힘드는지 침대에만 붙어있어서 그냥 보내고 나니 일요일 하루동안 7시간이나 일을 하느라 지금 내 허리는 끊어질 듯 아프기는 하지만 그래도 일단 올해 감자농사를 시작할 수 있다는 기쁨으로 이 글을 쓰게 된다.

올해부터는 주말에도 일찍 일어나기로 했기에 9시반쯤 일어나서 아침을 든든히 먹고 일단 모종상에 갔더니 이제 모종들이 얼굴을 내밀고 있다.

아싸 우리는 상추 모종(적상추,청상추,꽃상추 각 한판씩 3판)과 양파 모종,당근 씨앗 1통을 사고 퇴비도 5개 사서 일단 작은 밭으로 향한다.

오늘의 계획은 일단 작은 밭에 상추 모종을 심고 큰밭으로 넘어가서 양파모종과 당근파종을 하고 나는 감자둔덕을 만든다는 것이다.

지난주에 옮겨심었던 시금치는 그리 맘에 들 정도로 자리를 잡지는 못하고 약간은 비실비실해보여서 일단 물을 최대한 주고

 

 

상추 모종을 심을 구덩이를 좀 파고는 물을 그곳에만 넣어서는 상추 모종을 넣고 땅을 다져주는 방식으로 상추모종하나하나를 심어가다.이 작업을 하는데도 1시간넘게 걸린듯하다. 12시쯤되어서는 이제 큰밭으로 넘어간다.

 

 

이제는 나에게는 진정한 노가다.. 지난주의 밭은 장난이었다. 밭도 흙과 상태에 따라 가는게 너무 차이가 나는데 이곳은 아직도 일부는 삽이 안 들어갈 정도로 다져져 있는 흙이라서 지난주에 비하면 거의 2배의 시간이 들어간듯하다.아직도 많은 돌과 작년 다 걷어내지 못한 비닐조각들도 있어서...

 

일단 거름을 골고루 뿌려주고는 흙을 뒤집어 엎어서 거름이 안 쪽으로 들어가게도 하고 또 흙의 순환 차원에서 ..그리고는 고랑을 만들어서는 비닐을 씌운다.감자비닐은 저렇게 중간에 하얗게 되어있는 비닐이 더 쓰기에 좋다.

 

 

거의 점심먹은시간까지 포함해서 7시간 일을 했건만 겨우 6고랑을 만들었다. 예상보단 많이 못했지만 그래도 뭐 감자를 심을 정도는 해둔거같아서 주중에 어린이집애들이 이제는 감자를 파종할  수 있을 듯하다.

이제 쪽파는 좀만 더 키워면 먹을 수 있을 듯 하다.

 

시금치는 실컷 먹을 듯하게 또 시금치 1통을 심고

 

그 옆으로는 내가 가장 좋아하는 채소(?)인 양파 와 당근을 심어 두었다.

 

지난주 23일부터 주말농장 밭을 만들기 시작했다.

작년에 비하면 좀 늦은 시작인데 올해는 여행도 다녀오고 좀 날도 추워서 좀 늦게 시작한다.

겨울내내 밭을 놀려두었더니 역시나 밭이 심난하다.

 

 

작년에 쓰고 그대로 방치된 비닐이나 여러 쓰레기들 널려있다.

먼저 퇴비를 깔고 밭을 갈기 위해 모종상에 가서 퇴비 10포대를 일단 사고 시금치씨앗을 1봉지 사왔다. 아직 추운 날씨엔 시금치가 그래도 가장 잘 살 수 있는 작물이기에...

그런데 왠걸... 밭에는 겨우내 우리도 모르게 자라고 있던 쪽파가 한 가득 있다.허걱 왠 쪽파지? 했더니 작년 가을에 뿌려두고 제대로 안 나서 그냥 두었던 쪽파들이 한가득 이곳 저곳에서 나고 있었던 것이다. 자연은 우리에게 항상 감동을 준다.이런 맛에 텃밭을 하게 되는게 아닌가 싶다.

 

일단 23일 토요일은 큰밭(주인은 100평이라지만 보기엔 80평정도인 밭) 4고랑정도의 밭을 갈았다. 이 밭의 1/4정도는 갈아준듯하여 뿌듯하다. 이 곳에 시금치 1통을 심고 거의 2고랑은 안 심은 상태로 두었다.

 

24일 일요일은 작은 밭

이 곳은 우리 가족이 9년째 농사를 짓고 있는 곳이어서 일단 땅 힘이 좋아 작물이 잘 되는 곳이고 물도 맘껏 쓸 수 있어서 이곳은 잎채소를 주로 심는 곳이고 큰밭은 이제 3년차를 접어드는 곳이고 물이 없어서 그쪽은 주로 뿌리 작물을 심도록 일단 생각하고 올해는 그렇게 계획해 본다.

작은 밭에도 횡재가 있다.

겨울을 이겨낸 시금치... 재작년 가을엔 심어두었는데 작년엔 가을 수확이 안 좋아 경작을 거의 포기하면서 안 심었는데 왠 시금치지? 역시나 울 와이프의 밭을 놀리지 않겠다고 배추사이에 심어두었던 시금치 가을에 먹지도 못했는데 그게 겨울을 이겨내고 싹을 틔우고 있었다. 올해는 의도하지 않은 횡재가 많다 좋다~

 

여기저기 나있는 시금치를 한 곳으로 모아두고 퇴비 8개를 사고 넣고는 땅을 뒤집고는 갈아두었다. 그리고 와이프는 이곳에 아욱과 쑥갓 씨앗을 파종했다.

 

 지난 주말 온 가족이 거제/통영으로 봄여행을 떠났다.

광주가 고향이어서 한번도 경상남도 여행을 못해서 계획한 여행인데

서울에서 409키로가 그렇게 멀지는 몰랐다.

역시 무식하니 용감하다고 몰랐기에 1박2일로 떠날 수 있었던 여행이었다

혹시 나중에 가게 되면 3~4일 코스는 되여야 제대로 볼 수 있는 코스 인 듯하다.

토요일 새벽 3:30분에 일어나서 4시쯤 서울을 출발한 우리 가족은

겨우 8:30분 조금 넘어 지심도터미널에 도착했다.

 

첫 배가 8시반이었는데 그 배를 놓치고 일단 근처 식당에서

멍게비빔밥과 회덮밥을 먹었는데

첨에는 1만원이어서 "뭐 이렇게 비싸? 이거 관광지라고 바가지인가?" 싶었는데

정말 신선하고 멍게 향기도 넘 좋아서 만족적인 아침 식사가 되었다.

 

 

9시반에 출발하는 지심도배는 승객들이 다 타니 9시반이 다 되지도 않았는데 출발하는 듯 하다.

 바다길을 가르고 20분쯤 가서는 동백꽃의 섬 지심도에 우리 가족과 함께 승객을 내려주고는 다시 쏜살같이 다음 손님을 실으러 떠났다.

지심도는 동백꽃이 가득하며 1시간 반가량 봄기운을 만끽하며 트래킹하기에 좋은 곳이었다.

 

 

우리가족은 위 지도를 충분히 숙지하지 못해서 아쉽게도 활주로에서 아래로 내려와 버려서 위쪽은 보지못하고 활주로-포진지-탄약고-발전소-마끝으로 해서 선착장으로 돌아왔다.

지심도는 동백꽃의 섬답게 곳곳에 이렇게 동백꽃 하트가 가득했고

 

 

여러 봄꽃들이 벌써 만발하기도 했다.

유채꽃,진달래,개나리.. 지심도는 진정한 봄의 섬이었다.

 

운동장쯤에서 아저씨(?)할아버지가 동백꽃을 따고 계셔서 "뭐하세요?"하고 여쭤보니 이렇게 동백꽃에서 꿀물이 있다면서 몇개 따서 우리에게 한번씩 꿀물을 주시기도 했다. 나중에 안 사실이지만 나무에 있는 동백은 따면 벌금이 있다고 하니 자연보호와 공중도덕을 위해 우리 가족같은 일은 안 해야 할 듯...ㅋㅋㅋ

 

마끝은 절벽으로 되어있으면서도 참 아름다운 경치여서 많은 가족들이 그 곳에서 먹을 거를 펼치고 먹기도 하곤 했다.

 

이렇게 지심도를 다 돌아보고 나와서 터미널에 오니 이제는 꽤나 많은 사람들이 줄을 서서 기다리고있다.역시 아침 일찍 온 게 그래도 다행이다.아니면 최소 1시간은 그냥 날릴 듯 했다.

부두에는 해산물을 말리면서 팔고 계시는 분들도 꽤 나와있었다.

 

우리는 차를 타고 이제는 신선대와 바람의언덕으로 가다가 왠지 멋진 바다가 보이는 해수욕장이 있어 들러보니 그곳은 학동몽돌해수욕장이었다.

다른 해수욕장은 모레인데 이 곳 해수욕장들은 다 이렇게 몽돌이라는 돌로 되어있다니 참 이국적인 풍경이었다.

 

해수욕장 돌에 누워 일광욕하면서 각자 쥐포하나씩 뜯고는 다시 원래 목적지로 차를 몰았다.

바람의 언덕 또한 많이 알려진 곳인지 역시 많은 사람이 찾는 곳이며 참 경치가 좋은 곳이었다.

 

바람의 언덕을 보고 나오는 길에 아주머니와 아저씨가 낚시를 하고있는데 낚시대만 드리우면 학꽁치가 잡혀서 구경하고 있는데 우리 딸에게 낚시를 해보라고해서 학꽁치를 낚는 경험을 하기도 했다.

 

 

그리곤 그 바로옆 신선대를 갔는데 그 절경은 한 눈에 잡기 어려워서 파노라마샷으로 찍어보았다.

 

여차-홍포 해안도로가 좋다고해서 갔더니 "헉~!!! 이건 비포장도로..." 조금 당황스럽기는 했지만 거기서 멈춰서 본 이 경치는 그걸 다 잊을 만 했다.

이렇게 돌아다니니 거의 4시도 지나 이제는 점심겸 저녁을 먹으러 해물뚝배기를 먹으러갔는데 밥집은 거의다 우리가 첨에 도착했던 터미널 근처였다.

아마도 4~5번은 도로를 왕복한 듯 하다.다음 날 아침도 그쪽이었으니 뭐 담 부터는 그 근처에 숙소를 잡든지 해야 할 듯 하다.

해물뚝배기는 첨 싸고 푸짐함으로 우리 가족을 압도했지만 신선하지 않은 점이 약간 아쉬웠다.차라리 좀 비싸더라도 신선한 해산물로 든지 아님 좀 적게넣더라도 신선했음 좋았을 듯 하다.

 

하지만 양 하나는 압도할 만 했다.

아침일찍부터 움직여서인지 먹고 나니 넘 피곤이 몰려와서 6시도 되기전에 민박집에 들어가서 잠을 자고는 새벽엔 EPL도 봐주고 다시 일요일에는 7시에 일어나 부산을 갈까했으나 너무 늦어질 듯해서 그냥 일단 아침을 먹기로했는데 거제의 별미중 도다리쑥국이 있다고 해서 찾아서 가서 먹었는데 봄의 향도 느끼면서 담백한 맛이 일품이었다.

 

아침을 든든히 먹었으니 이제는 다시 여행을...

우리의 아픔이 간직된 거제포로수용소를 아이들과 돌면서 전쟁의 참혹함과 평화의 중요성에 대해 이야기도 나누고 이제는 통영으로 넘어가 이순신공원에서 이순신장군의 기를 받아 서울로 돌아왔다.

1시경에 충무김밥과 오미사꿀빵을 사가지고 출발할려했으나 오미사꿀빵은 일요일은 문을 닫는 바람에 꿀빵은 아쉬움만 남기고 충무김밥을 가지고 출발하여 휴게소에서 먹고 서울에 도착하니 6시이 걸려서 7시에 집에 들어왔다.

 

 

 


큰지도보기

지심도 / 섬

주소
경남 거제시 일운면 옥림리 57-1번지
전화
055-682-2233
설명
섬 전체가 동백나무로 덮여 있는 도서

 

나의 첫 서울시 공공앱을 이제 마켓으로 올릴 수 있을 정도로

완성된 듯 하다.

 

 

1. 사용에 관련된 주요기능

1) GPS가 켜있는 상태에서는 현재 위치 기준으로 가까운 주차장부터 찾아서 정렬

2) 서울시 공영주차장 19개의 주차장의 현재 잔여주차대수를 일괄으로 볼 수 있음

3) 주차장을 클릭하면 위치를 지도로 위치 확인 가능

4) 자세한 내용은 전화번호로 전화하여 문의 가능

2. 아쉬운 점

1) 좀더 많은 데이타(주차요금 등..)이 없음이 좀 아쉽다.

2) 보다 많은 주차장의 정보를 볼 수 있으면 좋으련만 19개의 주차장만 데이타를 제공한다.

3. 사용된 기술적 요소

1) html  request

- 서울시 공공API사용시 와 다음 로컬 API사용시 사용

- 아래는 서울시 공공API사용시 예제

 			  try{
				  URL url = new URL(urls[0]);
				  HttpURLConnection conn = (HttpURLConnection)url.openConnection();
				  if(conn != null){
					  conn.setConnectTimeout(10000);
					  conn.setUseCaches(false);
			        
					  if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
						  BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));      
						  for(;;){
							  String line = br.readLine();
							  if(line == null) break;
							  html.append(line+"\n");     
						  }     
						  br.close();
					  }
					  else{
			     
					  }
					  conn.disconnect();
				  }   
			  }
			  catch(Exception ex)
			  {
				  Log.e(TAG,"DownloadHtml ex=["+ex+"]"); 
				  return null;
			  } 

2) AsynTask기능

- 안드로이드 3.0(허니콤)부터는 network을 사용시에는 asyntask를 사용하여 처리가 늦어질 때를 대비하여 화면반응속도를 따로 처리하게 하여 사용자에게 앱이 죽은 듯 보여짐을 방지하고자 한다.

3) xml parser

- 서울공공API와 다음로컬 API시 xml로 받아서 분석하는 로직

		//API 요청 및 반환
		URLConnection conn = url.openConnection();
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.parse(conn.getInputStream());
		
		//channel노드를 객체화 하기
		Node node = doc.getElementsByTagName("channel").item(0);
		for (int i=0 ;i< node.getChildNodes().getLength();i++) {
			Node channelNode = node.getChildNodes().item(i);
			String nodeName = channelNode.getNodeName();
			
			//item 노드들일 경우
			if ("item".equals(nodeName)) 
			{
				//item노드의 자식노드를 검색
				for (int j=0 ;j< channelNode.getChildNodes().getLength();j++) 
				{
					Node itemNode = channelNode.getChildNodes().item(j);
					//title노드 일 경우 출력
					if("lng".equals(itemNode.getNodeName())){
						xy[0]= itemNode.getTextContent();
						
					}else if("lat".equals(itemNode.getNodeName())){
						xy[1]= itemNode.getTextContent();
						
					}	
				}
			}

4) SQLite

- 각 주차장의 데이타를 DB에 저장하는 데 사용함

5) tableview

- scrolling하는 기능의 추가와 헤더와 contents부분의 column사이즈를 맞추는 문제와 click event부여하는 문제 어느 것 하나 쉽지만은 않았음

6) 서울시 공공API 사용

- 서울시는 여러 공공의 데이타(http://data.seoul.go.kr/)를 시민들이 사용하기 편리하도록 공개하고 있음 이 앱은 이 데이타를 기반으로 만들어진 앱임

 7) 다음 API사용

- 다음의 로컬 API와 지도 API사용

		mapView = new MapView(this);
		
		mapView.setDaumMapApiKey("bcc6844e5b1aea2eda0dd7b52860dc30e3b97950");
		mapView.setOpenAPIKeyAuthenticationResultListener(this);
		mapView.setMapViewEventListener(this);
		mapView.setCurrentLocationEventListener(this);
		mapView.setPOIItemEventListener(this);

		mapView.setMapType(MapView.MapType.Standard);
		Log.d(TAG,"[1]dlng:["+ dlng + "],["+dlat +"]");
		// Move and Zoom to
		
		mapView.setMapCenterPointAndZoomLevel(MapPoint.mapPointWithGeoCoord(dlat, dlng),1, true);
		
		MapPOIItem poiItem1 = new MapPOIItem();
		poiItem1.setItemName(sname);
		
		poiItem1.setMapPoint(MapPoint.mapPointWithGeoCoord(dlat, dlng));
		poiItem1.setMarkerType(MapPOIItem.MarkerType.BluePin);
		poiItem1.setShowAnimationType(MapPOIItem.ShowAnimationType.NoAnimation);
		poiItem1.setShowCalloutBalloonOnTouch(true);
		poiItem1.setTag(153);	
		mapView.addPOIItem(poiItem1);
		mapView.fitMapViewAreaToShowAllPOIItems();
		linearLayout.addView(mapView);	

8) Action Bar에  refresh 메뉴 추가

9) intent

- 상세조회시 페이지를 다른 class로 하여 intent를 사용하여 call했으며 전화를 calling시에도 사용

10) 현위치 도출

- GPS를 이용하여 최근저장 위치를 처음에는 불러주고

나중에 이동시마다 10분간격으로 현위치를 저장하고 이에 따른 거리를 계산하도록 함

 

SeoulParking_20130320 (2).zip

 

 

해외축구 앱을 만들 때도 그렇고

1TO50게임 앱을 만들 때도 Gridview를 사용하면서

계속 onItemClick이벤트을 구현하고자 노력했으나

사실 몇일째 그 문제가 해결되지 않았다.

그래서 해외축구앱에서는

button에 click이벤트로 이것을 해결했으나

이번에는 이 문제를 해결해보고자

붙잡고 늘어져봤다.

한주내내 이렇게 저렇게 해본 결과 알게 되었다.

gridview에 각 sel에는 click이벤트가 있는 위젯을 사용하면 안되는 거였다.

ImageButton위젯이 아니라

ImageView위젯을 사용해야하는 거였다.

이전소스

ImageButton btn1 = (ImageButton) view.findViewById(R.id.imgbtn1);
    btn1.setBackgroundColor(Color.WHITE);
    btn1.setLayoutParams(new GridView.LayoutParams(ImageOneActivity.mwidth, ImageOneActivity.mwidth));
    btn1.setImageResource((R.drawable.btn01 +position));
    if(btn1 != null){
    System.out.println("position:["+ position+ "],btn1:["+btn1 +"]");
    btn1.setOnClickListener(clickListener);
}

제대로 구동되는 소스

 ImageView btn1 = (ImageView) view.findViewById(R.id.imgbtn1);
    btn1.setBackgroundColor(Color.WHITE);
    btn1.setLayoutParams(new GridView.LayoutParams(ImageOneActivity.mwidth, ImageOneActivity.mwidth));
    btn1.setImageResource((R.drawable.btn01 +position));
 
 
   gridview.setOnItemClickListener(new OnItemClickListener() {
     public void onItemClick(AdapterView<?> parent, View v,
       int position, long id) {
      
      Toast.makeText(getApplicationContext(),""+position, Toast.LENGTH_SHORT).show();
  }
 }); 

이런 문제는 나만 몰랐던 걸까?
왠만한 검색으로 나오지 않아 한참 고생했다.
역시 좌충우돌이다.
전체 소스

 

Image_1_50(20130308).zip

+ Recent posts