주소를 좌표로, GeoCoder-Xr with Kakao, Naver, Google ㅡ 2016, v3.2

개 선 내 용

  • 최신 OpenAPI 반영 및 OpenAPI Key 값을 저장할 수 있도록 하였습니다 ㅡ 2016/01/03
  • 결과 SHP 파일을 상대경로로 지정할 경우에 대한 문제점을 개선하였습니다 ㅡ 2013/12/09
  • 지도 표시 창이 나타날때 다운되는 현상 제거하였습니다 ㅡ 2013/06/10

옛날 주소 또는 새주소를 X,Y나 경위도와 같은 좌표로 변환해 주는 기능을 지오코딩(Geocoding)이라고 합니다. 이 툴은 주소를 좌표로 변환해 주는 툴로써 기존의 GeoCoder의 기능을 개선한 버전(3.0)입니다. 많은 주소를 자동으로 손쉽게 변환할 수 있는데, 변환하고자 하는 주소의 목록은 엑셀을 통해 쉽게 만들 수 있습니다.

아래의 그림은 컴마(,)로 구분된 입력 데이터를 엑셀에서 불러온 것입니다. 엑셀에서 만들어진 주소를 포함하고 있는 데이터를 CVS 형식으로 저장하게 되면 바로 좌표로 변환할 수 있는 입력 데이터가 됩니다. 입력 데이터는 반드시 첫줄에 필드명으로 구성되어야 합니다.

사용자 삽입 이미지

결과 좌표 데이터를 SHP 뿐만 아니라 텍스트 파일로 저장할 수 있습니다.
변환된 결과 좌표는 지도 위에 표시됩니다. 변환에 실패한 주소(일반적으로 잘못된 주소임)를 별도의 파일로 저장해 놓을 수 있습니다. 이는 텍스트 파일로 저장하기 옵션이 활성화 되어 있을 경우에 가능합니다.

엑셀 등을 통해 얻은 주소 데이터를 아래의 그림에서처럼 불러와 좌표로 변환할 수 있습니다. 주의할 점은 주소값에 대한 필드를 반드시 지정해야 합니다.
아래의 그림은 OnSpatial에서 제공하는 우리나라 전국의 관공서에 대한 주소목록입니다.

사용자 삽입 이미지

좌표 변환이 완료되면 변환된 좌표가 실제 지도 상에 어디에 분포되는지 파악할 수 있도록 아래 그림처럼 지도 위에 맵핑되는 기능을 제공합니다. 이 기능은 좌표 변환이 완료되면 자동으로 나타납니다.

사용자 삽입 이미지

또한 지도가 표시되는 상태에서 상단에 직접 주소를 입력하고 찾기 버튼을 클릭하면 해당 위치로 지도가 이동됩니다.

사용자 삽입 이미지
이 프로그램에서 주소를 좌표로 변환하는 기능은 네이버, 다음, 구글의 OpenAPI를 활용하였습니다.  OpenAPI는 Key 방식의 라이센스를 통해 사용할 수 있습니다. 이 프로그램은 기본적인 라이센스 키를 가지고 작동되지만 혹… 작동상에 문제가 있을 경우 라이센스 키를 발급받아 사용하시기 바랍니다. OpenAPI에 대한 키(라이선스)를 받기 위한 방법은 아래 URL을 통해 살펴보시기 바랍니다.

또한 SHP 파일로 저장하기와 지도 표현 기능은 지오서비스의 듀라맵을 이용하였으므로 이 프로그램을 실행하기에 앞서 듀라맵의 최신버전(3.8 이상)을 먼저 설치하셔야 합니다. 듀라맵은 다음 URL을 통해 다운로드 받으실 수 있습니다.


끝으로 이 프로그램에 대한 실행 파일은 다음 URL을 통해 다운로드 받으실 수 있습니다. (압축이 풀리지 않을 경우 AlZip이나 7Zip과 같은 전용 압축 프로그램을 이용하시기 바랍니다.) 사용해 보시고.. 문제점이나 개선점 그리고 궁금하신 것은 언제든 메일을 통해 문의하시기 바랍니다.. ^^

C#으로 SQLite 다루기

메모리 기반에서 자료를 다루기 위해 Array나 Linked List 그리고 Hashmap 등을 사용하지만, 대용량 또는 SQL 문을 통한 다양한 조건검색을 위해 DBMS을 사용해야할 때가 있습니다. 설치도 필요없고 가볍고 빠르게 사용할 수 있는 Local DBMS로 SQLite는 안드로이드나 SVN 등과 같이 매우 광범위하게 사용되는데.. C#으로 이 SQLite를 다루는 내용에 대해 정리를 해 봅니다.

C#에서 SQLite를 사용하기 위해서는 먼저 .NET용 SQLite 어셈블리 모듈을 설치해야 합니다. SQLite 공식 사이트에서 관련 파일을 설치할 수 있는 setup 파일을 받아 설치하기 바랍니다.

개발을 위해 필요한 파일이 설치되면 Visual Studio에서 C# 프로젝트를 생성하고 아래의 화면처럼 어셈블리 참조를 추가해 줍니다.

위의 화면에서 추가한 System.Data.SQLite 참조는 SQLite를 위한 ADO.NET 데이터 제공자(Data Provider)입니다. 이 참조는 앞서 설치된 폴더에 System.Data.SQLite.dll 파일을 통해 추가할 수 있습니다.

참조를 추가했으므로 코드에서 참조와 관련된 클래스를 빠르게 접근하기 위한 아래의 using 문을 추가합니다.

using System.Data.SQLite;

이제 다음과 같은 폼을 디자인함으로써 SQLite에 대한 주요 내용에 대한 코드를 살펴 보겠습니다.

폼 상에 버튼의 제목을 통해 우리가 파악할 SQLite에 대한 코드가 무엇인지 짐작할 수 있습니다. 즉, 아래와 같습니다.

  1. Create DB File – SQLite DB 파일을 생성합니다.
  2. Open DB – 생성한 DB 파일을 사용하기 위해 연결합니다.
  3. Create Table – DB 파일에 테이블을 생성합니다.
  4. Insert Row – 생성한 테이블에 Row를 추가합니다.
  5. Query Data – 테이블에 저장된 데이터를 조회합니다.
  6. Close Connection – DB 파일에 대한 연결을 닫습니다.

먼저 SQLite DB 파일을 생성하는 버튼에 대한 코드는 다음과 같습니다.

SQLiteConnection.CreateFile("c:/a.sqlite");

위의 코드가 성공한다면 C:\ 경로에 a.sqlite라는 파일이 생성될 것입니다. 다음은 생성한 DB 파일을 사용하기 위해 연결하는 코드입니다.

conn = new SQLiteConnection("Data Source=c:/a.sqlite;Version=3;");
conn.Open();

위의 코드에서 conn 변수는 다음과 같이 정의되어 있습니다.

private SQLiteConnection conn = null;

이제 다음은 DB 파일에 테이블을 생성하는 코드입니다.

string sql = "create table members (name varchar(20), age int)";

SQLiteCommand command = new SQLiteCommand(sql, conn);
int result = command.ExecuteNonQuery();

sql = "create index idx01 on members(name)";
command = new SQLiteCommand(sql, conn);
result = command.ExecuteNonQuery();

우리가 흔히 알고 있는 CREATE SQL 문을 통해 테이블을 생성하고 있습니다. 추가적으로 인덱스(INDEX)까지도 생성하고 있습니다. 이제 다음은 생성한 테이블에 Row를 추가하는 코드입니다.

String sql = "insert into members (name, age) values ('김도현', 6)";

SQLiteCommand command = new SQLiteCommand(sql, conn);
int result = command.ExecuteNonQuery();

아.. 우리 와이프 코고는 소리가 들리네요.. -_-; 여튼.. 위의 코드를 보면 Row를 추가하기 위해 흔히 알고 있는 INSERT SQL문을 사용하고 있습니다. 다음은 테이블에 저장된 데이터에 대한 조회 코드입니다.

String sql = "select * from members";

SQLiteCommand cmd = new SQLiteCommand(sql, conn);
SQLiteDataReader rdr = cmd.ExecuteReader();
while (rdr.Read()) {
    MessageBox.Show(rdr["name"] + " " + rdr["age"]);
}

rdr.Close();

SELECT SQL문을 통해 조회할 수 있으며, SQLiteDataReader 클래스를 통해 실제 조회된 데이터를 필드별로 읽어 낼 수 있는 것을 볼 수 있습니다. 이제 끝으로 DB에 연결된 Connection 객체를 닫는 코드는 아래와 같습니다.

conn.Close();

자, 이상으로 요긴하게 바로 사용할 수 있는 Local DBMS인 SQLite를 C#에서 사용할 수 있는 최소한의 내용을 정리해 보았습니다.

DuraMap-Xr의 SpatialOperator를 이용한 공간연산 응용예

DuraMap-Xr은 Windows 기반의 Desktop GIS Application 개발을 위한 맵 엔진입니다. DuraMap-Xr의 기능 중 SpatialOperator 기능은 벡터 데이터 간의 Intersects나 Intersection과 같은 API와 단일 벡테 데이터의 Buffer 연산자와 같은 API를 제공합니다. 이러한 연산자를 이용하여 다음과 같은 기능에 DuraMap-Xr이 활용되었는데요. 간단히 소개해 봅니다.

위의 그림은 건물 레이어와 홍수범람에 대한 하천 레이어 그리고 행정구역도 레이어로 구성된 간단한 지도입니다. 건물 레이어의 건물 도형 데이터에는 인구수에 대한 속성 데이터가 조인되어 있습니다. 건물 중 홍수범람에 대한 하천 레이어의 도형과 교차(Intersects)되는 건물을 추출하고 추출된 건물에 거주하는 인구수의 총합을 계산해야 합니다. 바로 이 인구수가 홍수에 의한 피해 인구수라고 생각할 수 있습니다.

위의 UI는 위에서 설명한 기능에 대해 실제 구현한 UI입니다. 홍수피해의 결과로 4006명이 산출되었고, 피해를 받은 건물은 result.shp 파일로 저장되도록 하였습니다.

위의 이미지에서 빨간색 도형이 기능에 대한 결과로 생성된 홍수 피해를 받은 건물에 대한 레이어어 입니다. 이미지를 살펴보면, 건물이 하천 경계 도형으로 클리핑(Intersection) 처리 되어 저장된 것을 볼 수 있습니다.

DuraMap-Xr은 우리가 흔히 알고 있는 지도 위에 도형 매쉬업이라는 단순한 기능에서 한발 더 나아가 각 도형들간의 관계와 연산을 통해 더욱 의미 있는 결과를 생성해 내는 GIS 엔진입니다.

Node.js 정리

자바스크립트로 서버 어플리케이션을 개발할 수 있는 Node.js는 다음과 같은 특징을 갖습니다.

  • 단일 스레드 기반으로 동작함으로써 직관적이고 단순해 안정적이라고 할 수 있음. 특히 스레드간 데이터 동기화등에 대한 골치 아픈 문제가 근본적으로 없다는 점이 큰 장점이지만, 스레드에 숙련된 개발자에게는 한계가 될 수 있음
  • 단일 스레드 기반이므로 클라이언트 측의 요청에 대한 빠른 응답에 대한 처리는 비동기 IO 방식을 활용함
  • 위의 2가지의 특징과 자바스크립트라는 한계로 인해 서비스 내용을 생성하는데 아주 짧은 시간을 필요로 하는 경우에 대한 서버 개발에 알맞음. 즉, CPU에 너무 많은 부하를 주는 연산이 아닌 간단하고 명료한 서비스에 적합함. 간단하고 명료하다는 기준은 서버의 사양 등에 따라 매우 상대적임.
  • 흔히 Node Application이라고 하는 것은 Node.js로 개발한 서버 프로그램을 언급하는 것임
  • npm이라는 기능을 통해 Node.js의 확장기능을 추가로 설치할 수 있는데, 확장 기능의 개발과 npm과 같은 손쉬운 추가 방식은 Node.js의 장점 중 특장점이라고 할 수 있음

뭐 일단, 이제는 내 스스로에게 상당히 친숙하고 호감도가 높아진 자바스크립트라는 언어를 통해 서버를 개발할 수 있다는 점에서 Node.js는 충분히 매력적이라고 할 수 있는데요. 특히 스크립트이기 때문에 소스코드를 변경하면 바로 해당 변경 내용을 쉽게 배포할 수 있다는 점이 가장 매력적이라고 할 수 있습니다. 게다가 퍼포먼스 적인 측면에서 V8이라는 자바스크립트 엔진을 사용함으로써 생각 이상으로 상당히 뛰어나다라는 평가 역시 매우 큰 장점입니다. 몇가지 Node.js에 대한 간단한 샘플 코드를 통해 웹상에서 수집한 Node.js에 대한 내용을 정리해 보겠습니다.

먼저 가장 간단한 Node.js의 샘플 코드입니다.

var http = require('http');

http.createServer(
  function(request, response) {
    response.writeHead(200, { 'Content-Type' : 'text/plain' });
    response.write("Hello, I am a Korea! GIS Developer.");
    response.end();
  }
).listen(8888);

위의 코드는 8888 포트를 통해 HTTP 서버(웹서버) 기능을 가진 프로그램 코드로 클라이언트에게 고정된 문서를 서비스하는 코드입니다.

다음은 URL을 통한 QueryString을 받아 해석하는 코드입니다.

var http = require('http');
var url = require('url');

var server = http.createServer();

server.addListener('request', function(request, response) {
  console.log('requested ...');

  response.writeHead(200, {'Content-Type' : 'text/plain'} );
  var parseUrl = url.parse(request.url, true);
  //var pathname = parseUrl.pathname;
  var query = parseUrl.query;
 
  response.write("a for QueryString : " + query.a);
  response.end();
});

server.listen(8888);

QueryString으로 a=123으로 주었을 경우, a for QueryString : 123 과 같은 문서를 서비스할 것입니다. 주석으로 처리된 pathname은, 예를 들어 http://www.gisdeveloper.co.kr:8888/Hello?a=133과 같은 URL 호출일 경우 Hello가 됩니다.

다음은 POST 방식을 통한 호출에 대한 코드 예입니다.

http = require('http') ,qs = require('querystring');

http.createServer(function (req, res) {
  if( req.url == '/' && req.method == 'POST'){
    var postBody = '';

    req.on('data', function (data) {
      postBody += data;
    });

    req.on('end', function () {
      var post = qs.parse(postBody);
      //post데이터확인
      console.log(post['postname']);
    });

    res.end('true');
  } else {
    res.writeHead(404, {'Content-Type': 'text/plain'});
    res.end('404 ERROR');
}
}).listen(8888);

끝으로 Node.js와 DBMS 연동에 대한 코드인데요. DBMS는 MongoDB로써 Node.js는 MongoDB와의 연동을 위해 Mongoose 모듈을 사용합니다. 이 Mongoose는 npm을 통해 설치할 수 있습니다. 참고로 버전 2.7대의 파이션이 필요합니다.

var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/myDB');

var db = mongoose.connection;

db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback() {
  console.log('open');
});

var userSchema = mongoose.Schema({
  username: 'string',
  age: 'number'
});

var User = mongoose.model('User', userSchema);

var user1 = new User({ username: 'gchoi', age: 30 });
var user2 = new User({ username: 'jmpark', 'age': 29 });

user1.save(function (err, user1) {
  if(err) 
    console.log('error');
});

user2.save(function (err, user2) {
  if(err)
    console.log('error');
});

이상으로 예제 코드를 중심으로한 Node.js에 대한 내용을 정리해 보았습니다.

제대로 ‘잘’ 만들기

사용자 삽입 이미지

기본적으로는 매우 당연한 사실인데.. 오랜 기다림과 과정 속에서 이러한 기본적인 것이 왜곡되어 잊어지는 경우가 있는 것 같다. 다른 새로운 도전과 기회의 탐닉도 필요할테지만(과연, 그럴까?).. 최소한 이러한 기본적인 생각을 기반으로 무엇이든 해야 하지 않겠는가. 다 필요없다. 오직 ‘제대로’ 만들어 보자. 사실 ‘제대로’ 만들기 보다 더 어려운 것이 있을까? ‘제대로’ 만들지 못하다보니.. 이런 저런 잡념과 샛길이 생기지 않나 싶다. 그래, 제대로 ‘잘’ 만들어 보자 ㅡ !