좌표계 변환을 위한 OpenAPI입니다. 변환하고자 하는 좌표에 대해 WKT 형태의 포인트, 폴리라인, 폴리곤 형식으로 지정할 수 있고 변환된 좌표 결과도 WKT로 받을 수 있음으로 매우 다양한 형태로 활용될 수 있습니다. 간단하게 하나의 WGS84 경위도 좌표계 (127, 37)을 카텍(Katech) 좌표계로 변환하기 위한 OpenAPI 호출 형태는 다음과 같습니다.![]()
간단한 URL 호출형태의 OpenAPI로써 사용된 인자값들은 다음과 같습니다.
변환될 좌표계를 지정하는 방식이 WKT라는 형식입니다. WKT에 대한 설명을 위해 폴리곤, 폴리라인, 포인트 들에 대한 간단한 예를 통해 설명하면 다음과 같습니다.
먼저 하나의 좌표를 지정할 수 있는 WKT 형태의 포인트의 예입니다. 하나의 좌표로 표현되는 포인트에 대한 WKT는 POINT 문자열로 시작합니다.
다음은 여러 개의 좌표들로 구성된 폴리라인에 대한 WKT 형태의 예입니다. 폴리라인에 대한 WKT는 선분(LINE)의 연속(STRING)이라는 의미로 LINESTRING 문자열 값으로 시작합니다.
그리고 여러 개의 좌표들로 구성된 폴리곤에 대한 WKT 형태의 예입니다. 폴리곤의 WKT는 POLYGON 문자열 값으로 시작합니다.
그리고 다음은 구멍(Hole)이 있는 폴리곤에 대한 WKT 형태의 예입니다. 위의 경우처럼 POLYGON 문자열로 시작합니다. 구멍(Hole)을 나타내는 폴리곤은 여러개가 올 수 있지만 구멍이 아닌 외곽을 나타내는 폴리곤은 하나만 올 수 있습니다.
이 좌표 변환 OpenAPI 서비스는 지오서비스 사에서 제공하고 있습니다. 학술/연구 그리고 상업적인 용도에 대해서 자유롭게 사용할 수 있습니다. 향후 더욱 다양한 좌표계를 지원할 예정입니다. 사용상의 개선점과 문제점에 대해서는 연락 또는 메일 주시면 검토 후 적극 반영토록 하겠습니다.
시간을 측정하는 ‘시계’, 나의 유일한 악세사리
나의 유일한 악세사리는 시계다. 핸드폰을 늘 손에 가지고 다니므로 실용성면에서 굳이 시계가 필요치 않지만.. 중요한 의미의 심벌(Symbol)로써 시계는 나에게 중요한 의미를 부여한다.

얼마전만 하더라도, 나는 하고자 하는 일에 대해서 정해진 기간안에 마무리하는 것에 대한 강박증이라는 매우 좋은 “습관”을 가지고 있었다. 그러다가 명확하지 않은 요구사항을 가진, 지지부진하게 진행되는 프로젝트를 진행하면서 이 습관에서 나는 서서히 멀어지고 있다.
이제는 다시, 하고자 하는 일에 대해서 정해진 기간안에 마무리하려는 내 의지를 다시 다져 잡고자 한다. 처음 이 시계를 손목에 차며 가졌던 초심의 마음을 다시 세긴다.
바로 이것만이 내가 원하는 바를 이룰 수 있는 가장 처음 채워야할, “첫단추”이다.
[GIS] 속성값으로 분류해 다수의 SHP로 저장하는 툴, ClassifySHP
지정된 조건과 일치하는 속성을 갖는 도형을 선택해 별도의 SHP 파일에 저장해주는 툴입니다. 조건을 여러 개를 지정할 수 있으므로 한번에 다수의 SHP 파일로 저장할 수 있습니다. 속성에 대한 조건은 정규 표현식을 사용합니다. 지정된 조건은 다시 파일로 저장해서 추후 다시 재사용할 수 있도록 하였습니다.

소스 코드와 실행파일을 따로 다운로드 받을 수 있도록 하였습니다. 아래의 링크를 통해 받으시기 바랍니다.
이 툴은 듀라맵(DuraMap-Xr)을 사용하므로 듀라맵을 먼저 PC에 등록해야 합니다. 듀라맵에 대한 자세한 설명과 다운로드는 다음 url을 참고하시기 바랍니다.
“휘파람 왈츠단” 이라는 만화의 그림체 중 한 컷…

“휘파람왈츠단”이라는 연재 만화를 오늘 처음 봤는데, 이 만화의 그림체가 어찌나 맘에 들던지.. 그 내용에는 상관없이 주문을 하려고 인터넷 서점에서 검색을 해보았으나.. 없다. =_= 아마도 인터넷 만화로만 연재되고 있는듯 하다. 그 중에서 한컷 잘라내 올려본다.
한껏 얻어 텨지고는 널부러져 누워있는데.. 비가 내리는 컷. 얻어 텨져 퉁~퉁~ 부어오른 얼굴을 시원한 비가 식혀주고 씻겨준다.
이 컷에 잠시 생각에 빠진 이유는.. 요즘 내 마음속에 조용히 외치고 있는.. “치열함”이다. 난 치열하게 살고 싶다. 온갖 어려움이 내 주위에 서성대다가 내게 덤벼드는 그 치열함속에서.. 그 어려움들에게 몰매를 맞고 넉다운이 되는 것을 원한다. 치열하게 싸우다 몸을 추스릴길이 없으면 바닦에 나둥그러져 잠시 눕는다. 비가 내리고.. 그 비를 맞고 부서진 내 몸을 다시 추스리고 일어선다..
“꿈”보다, “열정”보다.. 지금 나를 더 설레이게 하는 단어 “치열함”. 나는 그 속에서 살고 싶다. 나는 곧 그 속에서 살겠다.
다시 한번 더 조심스럽게.. 이 “치열함”이라는 단어 앞에서 “서성” 대다.. [2009/7/22]
이제.. 내 앞에 서성대는건 내가 아닌 너, “치열함”이다.. 부디 그러길…. [2010/6/16]
“치열함”이 이제 바로 내 앞에 섯음을 인식하다… [2011/7/1]
“치열함” 속에 살다.. 이 “치열함”을 부디 극복하길……. [2012/9/5]
“치열함”의 의미를 다시금 되돌아본다.. 배움이 있었다면 그 배움을 실천할 수 있길…. [2014/1/4]
전에 없던 “치열함” ! [2017/1/27]
플래시 빌더(Flash Builder)에서 협업을 위한 모듈화
플래시 빌더의 단점은 협업 개발이 어렵다는 것입니다. 사실.. 아직까지도 플래시에서 모듈을 통한 협업 개발이 충분한가라는 점에서.. 실제 프로젝트에 적용해보기 전까지는 확신할 수는 없지만 파악해본 바로는 충분히 가능하다.. 라고 판단됩니다.
메인 어플리케이션 프로젝트가 있고.. 이 메인 어플리케이션에서 사용하는 또 다른 별도의 모듈을 위한 프로젝트(모듈 프로젝트)가 있다고 하겠습니다. 모듈 프로젝트는 일반적인 플렉스 프로젝트(Flex Project)로 생성합니다.
이 모듈 프로젝트에 2개의 모듈을 추가하도록 하겠습니다. 첫번째는 단순히 함수만을 제공하는 모듈 클래스이고 두번째는 UI를 제공하는 모듈 클래스입니다. 먼저 함수만을 제공하는 모듈 클래스는 ActionScript Class로 해서 생성하며 클래스명은 Module1으로 지정하고 Super Class로는 반드시 ModuleBase로 지정합니다. 생성된 Module1.as 파일을 다음처럼 코딩합니다.
package
{
import mx.modules.ModuleBase;
public class Module1 extends ModuleBase
{
private var arg:Number = 1;
public function Module1(arg:Number)
{
super();
this.arg = arg;
}
public function sum(a:Number, b:Number):Number
{
return (a + b) * arg;
}
}
}
모듈 클래스의 생성자가 하나의 인자를 갖습니다. 그리고 sum이라는 함수를 제공합니다. 매우 단순한 모듈 클래스입니다. 이 모듈 클래스는 컴파일되어 Module1.swf 파일로 만들어져야 합니다만 확장자가 as는 자동으로 모듈로 만들어지지 않으므로 모듈 프로젝트의 속성창에서 Flex Modules에서 추가해야 합니다.

추가할때 Output Size 옵션을 Do not optimize로 선택해서 다양한 많은 어플리케이션에서 활용될 수 있도록 지정합니다.
이제 추가된 모듈 클래스인 Module1을 별개의 어플리케이션 프로젝트에서 사용해 보도록 하겠습니다. 버튼을 클릭했다고 할때 Module1 모듈 클래스를 활용하는 방식으로 하겠습니다. 버튼 클릭시 실행되는 코드는 다음과 같습니다.
private var iModuleInfo:IModuleInfo;
protected function onTest(event:MouseEvent):void
{
iModuleInfo = ModuleManager.getModule(
"../../eTAS_Modules/tstModule/bin-debug/Module1.swf");
iModuleInfo.addEventListener(ModuleEvent.READY, onModuleReady);
iModuleInfo.addEventListener(ModuleEvent.ERROR, onModuleError);
iModuleInfo.load();
}
5번째 줄에 모듈 프로젝트에서 생성된 Module1.swf를 지정하고 있습니다. 로컬에서 테스트할때는 이렇게 폴더 경로로 사용되지만 실제로 웹서버에 올려질때는 URL 경로가 사용됩니다. 모듈의 준비가 잘되었을때 실행되는 onModuleReady와 실패했을때 실행되는 onModuleError 함수는 다음과 같습니다.
private function onModuleReady(e:Event):void
{
e.target.removeEventListener(ModuleEvent.READY, onModuleReady);
e.target.removeEventListener(ModuleEvent.ERROR, onModuleError);
var mainClassName:String = iModuleInfo.factory.info().mainClassName;
var mainClass:Class =
iModuleInfo.factory["getDefinitionByName"](mainClassName) as Class;
var module:Object = new mainClass(100);
text.text = module.sum(100, 200);
}
private function onModuleError(e:Event):void
{
e.target.removeEventListener(ModuleEvent.READY, onModuleReady);
e.target.removeEventListener(ModuleEvent.ERROR, onModuleError);
// ERROR
}
6번에서 모듈의 클래스명을 가져오고 이 클래스 명으로부터 실제 클래스 타입을 8번 코드를 통해 얻습니다. 그리고 이 클래스 타입을 통해 실제 인스턴스를 10번 코드를 통해 생성합니다. 그리고 12번 코드처럼 사용합니다.
이제 다음으로 UI를 제공하는 모듈에 대한 생성과 사용에 대해서 정리해 보겠습니다. 모듈 프로젝트에서 MXML Module로 하여 새로운 파일을 생성합니다.

파일명은 Module2로 하고 Output Size 옵션을 Do not optimize로 하여 다른 많은 프로젝트에서 재활용할 수 있도록 합니다. 생성된 Module2.mxml을 다음처럼 코딩합니다.
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
import geoservice.XrMap;
private var map:XrMap = null;
public function setup(map:XrMap):void
{
this.map = map;
}
protected function onClick(event:MouseEvent):void
{
map.coordMapper.setMapScale(500);
map.update();
}
]]>
하나의 버튼 컴포넌트를 배치했고 이 버튼에 대한 클릭 이벤트를 지정했습니다. 그리고 setup이라는 함수를 하나 추가해서 이 UI 모듈의 코드들이 실행하기 위해 필요한 설정값들을 지정할 수 있도록 하였습니다.
이 Module2에 대한 모듈 UI를 별도의 어플리케이션 프로젝트에 사용해 보도록 하겠습니다. 어클리케이션 프로젝트의 메인 mxml에 다음과 같은 UI 컴포넌트를 추가합니다.
네! 바로 앞서 만들어 놓은 Module2 모듈 UI가 들어갈 자리입니다. id는 modLoader로 했음을 기억합시다! 버튼을 클릭하면 이 modLoader에 앞서 만들어 놓은 UI 모듈을 올려 보도록 하겠습니다.
protected function onTest(event:MouseEvent):void
{
modLoader.addEventListener(ModuleEvent.READY, onUIModuleReady);
modLoader.addEventListener(ModuleEvent.ERROR, onUIModuleError);
modLoader.url = "../../eTAS_Modules/tstModule/bin-debug/Module2.swf"
}
모듈 로딩이 성공했을때와 실패했을때에 대한 이벤트 리스너를 지정했고 modLoader의 url 속성에 적재할 UI 모듈에 대한 경로와 파일명을 지정했습니다. 로컬에서는 이처럼 디렉토리 경로지만 실제 웹서버에 올라가면 URL 경로로 변경해줘야 합니다. 모듈 로딩이 성공했을때와 실패했을때에 대한 이벤트 리스너의 코드는 다음과 같습니다.
private function onUIModuleReady(e:Event):void
{
modLoader.removeEventListener(ModuleEvent.READY, onModuleReady);
modLoader.removeEventListener(ModuleEvent.ERROR, onModuleError);
modLoader.child.addEventListener(FlexEvent.CREATION_COMPLETE,
onUIModuleCreateCompleted);
}
private function onUIModuleError(e:Event):void
{
modLoader.removeEventListener(ModuleEvent.READY, onUIModuleReady);
modLoader.removeEventListener(ModuleEvent.ERROR, onUIModuleError);
// ERROR!
}
모듈이 성공적으로 로딩이 되면 6번 코드처럼 UI 모듈을 구성하는 UI가 생성되는 이벤트 리스너를 지정해야 합니다. UI가 생성되는 이벤트 리스너 함수인 onUIModuleCreateCompleted의 코드는 다음과 같습니다.
private function onUIModuleCreateCompleted(e:Event):void
{
modLoader.child.removeEventListener(FlexEvent.CREATION_COMPLETE,
onUIModuleCreateCompleted);
var ui:Object = modLoader.child;
ui.setup(map);
}
7번 코드가 바로 앞서 UI 모듈에서 추가했던 함수입니다. UI 모듈의 버튼을 클릭하면 지정된 코드가 실행되게 됩니다.
비록…. 모듈에 대한 설명예를 단순하게 들었지만 필요한 것들에 대해서 최소한으로.. 그리고 필요한 모든 것을 설명한듯합니다. 물론 실전에서 적용해보고 부족한 부분에 대해서 덧붙이도록 하겠습니다.
