태양광 설비 관리를 위한 현장지원시스템 개발에 앞서서 …

태양광 설비를 관리하는 현장지원시스템을 모바일 GIS 엔진인 BlackPoint-Xr를 이용해 개발하게 되었습니다.

아래의 화면은 Mr.Tiler-Xr에서 드론으로 촬영한 영상 이미지를 배경도로 하고, 태양광과 관련된 설비인 태양광 어레이(Array)와 모듈(Module) 그리고 접속함, 인버터, 분전반, 배전반 등에 대한 설비를 표시한 것입니다.

Mr.Tiler-Xr은 수치지도를 이용해 배경지도를 디자인하고 타일맵으로 가공할 수 있는 툴이면서, 공간 데이터를 편집할 수 있는 기능도 제공합니다. 저는 개인적으로 GIS 시스템 개발을 위해 제공받은 SHP 파일이나 항공영상을 Mr.Tiler-Xr를 통해 살펴봅니다.

이 글은 현장지원 앱의 개발에 앞서 태양광 설비의 관리 업무에서 개발에 필요한 최소한의 지식을 얻기 위해 몇가지 설비를 간략하게 서술식으로 정리한 것입니다.

“태양광 모듈은 태양광 셀로 구성이 되는데요. 셀 1개가 생성하는 전압은 0.5V~0.6V이며, 전류는 4A~8A입니다. 또한 여러개의 모듈을 하나의 어레이로 단위로 구성합니다. 그리고 태양광발전소에 설치되는 분전반, 인버터, 분전반, 배전반은 생산된 전류를 모으고, 과전류가 발생하면 전류를 차단시키며 직류를 교류로, 또 교류를 직류르 변환하는 역활과 저압과 고압으로 변성하는 역활 등을 담당하는 장치들입니다.”

추후 태양광 설비 관리를 위한 현장지원시스템 개발이 완료되면 블로그를 통해 다시 소개해 드리도록 하겠습니다.

DuraMap-Xr을 이용한 좌표 변환 코드 샘플

DuraMap-Xr은 proj.4 기반의 문자열을 토대로 좌표계를 변환할 수 있는데요. 특히 좌표 변환시 10 파라메터에 해당하는 Molodensky-Badekas 모델을 지원합니다.

아래의 코드는 “대한민국 TM 중부원점(Bessel 타원체) – 10.405 보정”의 좌표계의 한 좌표인 (492385.95, 188096.47)를 “대한민국 TM 중부원점(GRS80 타원체)” 좌표계로 변환하는 코드 예입니다.

XrMapLib.Coord Pt;

Pt.X = 492385.95;
Pt.Y = 188096.47;

XrMapLib.Projection proj = new XrMapLib.Projection();

// 대한민국 TM 중부원점(Bessel 타원체) - 10.405 보정
proj.SourceProj4String = "+proj=tmerc +lat_0=38N +lon_0=127.0028902777778E +ellps=bessel +x_0=200000 +y_0=600000 +k=1 +units=m +no_defs";

// 대한민국 TM 중부원점(GRS80 타원체)
proj.TargetProj4String = "+proj=tmerc +lat_0=38N +lon_0=127E +ellps=GRS80 +x_0=200000 +y_0=600000 +k=1 +units=m +no_defs";

// 10 파라메터 적용(towgs84 파라메터)
proj.Set10Parameters(-145.907, 505.034, 685.756, -1.162, 2.347, 1.592, 6.342, -3159521.31, 4068151.32, 3748113.85);

proj.Transform(Pt);

코드를 보면 좌표계 지정을 위해서 사용한 proj.4 문자열에 towgs84에 해당하는 값을 14번째 코드처럼 별도의 매서드(Set10Parameters)로 지정한다는 것입니다. 3개 또는 7개의 파라메터 지정을 위해서는 각각 Set3Parameters, Set7Parameters 매서드를 사용합니다.

최종 좌표변환은 16번 코드의 Transform 매서드로 수행되는데요. 이 매서드는 변환할 입력 좌표 객체를 필요로 하고, 변환된 좌표는 다시 이 입력 좌표 객체에 저장되므로, 입력 좌표를 계속 유지하려면 복사본을 가지고 있어야 합니다.

최단 경로 탐색 – Dijkstra 알고리즘

다익스트라 알고리즘은 시작 노드만을 지정하면, 이 시작 노드에서 다른 모든 노드에 대한 최단 경로들을 분석해 줍니다. 참고로 최단 경로 탐색 알고리즘의 다른 형태로  A*(에이스타) 알고리즘이 있는데요. A* 알고리즘은 시작 노드에서 목적지 노드를 지정해주면 이 2개의 노드 간의 최단 경로 하나만을 분석해 줍니다.

이 글은 다익스트라 알고리즘에 대한 이런 저런 장황한 설명을 배제하고 실제 예를 들어, 그 예에 대한 최단 경로 탐색을 위한 다익스트라 알고리즘에 대해 설명합니다.

먼저 다음과 같은 예를 들어 보겠습니다.

위의 그림을 간단히 설명하면, 0부터 6번까지의 노드(Node)가 존재하고 각 노드를 연결하는 선인 링크(Link)가 있습니다.  각 링크에는 숫자가 표시되어 있는데요. 이 숫자는 해당 링크를 지나갈때에 소요되는 비용(Cost, 경비)로 생각할 수 있습니다. 예를 들어, 2번 노드와 6번 노드 사이에 비용 8인 링크가 있는데요. 이는 2번 노드에서 6번 노드를 지나간다고 할때 8의 비용이 필요하다는 의미입니다. 비용이 적을 수록 상대적으로 더 좋은 경로이겠지요.

이제 위의 예, 즉 0번 노드를 시작점으로 해서 나머지  1, 2, 3, 4, 5, 6 번 노드를 목적지로 하는 최단 경로 6개를 구할 수 있는 방법이 바로 다익스트라 알고리즘입니다.

이상의 문제 해결을 위해 가장 먼저 시작되는 연산은 다음 그림과 같습니다.

위의 그림에서 S 은 이미 처리가 완결된 노드의 집합인데요. 가장 먼저 시작 노드인 0번을 집어 놓음으로써 0번 노드에 대한 처리를 시작합니다. D 저장소는 0번~6번까지의 노드에 대해, 시작노드로부터 소요되는 비용을 저장하고 있습니다. D 저장소의 상단 행은 노드의 번호이고 하단 행은 시작노드로부터 소요되는 비용입니다. 위 그림에서 D 저장소를 보면 0번 노드는 시작노드이므로 소요되는 비용이 0이고, 0번 노드와 링크로 연결된 1번과 3번 노드는 각각 5와 1의 비용이 소요되는 것으로 기록되어 있습니다. T 저장소는 해당 노드로 가는데 연결된 노드의 번호를 담고 있는데요. T 저장소이 상단 행은 노드의 번호이고 하단 노드는 연결된 노드 번호입니다. 위의 그림을 보면 1번 노드와 3번 노드는 0번 노드와 연결되어 있으므로 0으로 기록되어져 있습니다. 이게 주어진 문제에 대한 다익스트라 알고리즘의 첫번째 처리입니다.

이제 다음 처리에 대한 그림을 살펴 보겠습니다.

S집합에 3번 노드를 추가했습니다. 이유는 D 저장소에 3번 노드에 대한 비용값이 가장 최소이기 때문입니다. S집합에 3번 노드를 추가함으로써 3번 노드와 링크로 연결된 2번과 5번 노드에 대한 비용값을 계산해 D 저장소에 기록해야 하는데요. 시작 노드인 0번 노드에서 2번 노드까지 가기 위해서 소요되는 비용은 총 3입니다. 이유는 0번-3번-2번 노드로 가야하므로 비용값은 0번-3번 노드로 가는 비용 1과 3번과 2번 노드로 가는 비용 2를 합한 값입니다. 이러한 계산은 D 저장소를 활용하면 쉽게 계산할 수 있는데요. 이미 시작노드에서 각 노드로 가는 비용이 계산되어 있기 때문에 마지막 노드로 가는 비용만을 더해주면 되기 때문입니다. 5번 노드에 대한 비용은 동일한 방식으로 1+1인 2가 됩니다. 그리고 T 저장소도 각 노드에 대해 이전에 연결된 노드값을 기록해 둡니다. T 저장소의 2번과 5번 노드는 3번 노드를 통해 연결되어 있으므로 3을 기록합니다. 다음 처리에 대한 그림을 살펴봅시다.

S 집합에 5를 추가했습니다. 이는 이미 처리가 완료된 노드 이외의 노드 중 5번 노드의 비용이 2로 가장 최소이기 때문입니다.  이미 처리가 완료된 노드인지 S 집합에 존재하는지를 보면 알 수 있습니다. 5번 노드에 대해 연결된 노드는 2, 3, 6번 노드인데요. 이미 3번은 처리가 완료되었으므로 2번 노드와 3번 노드에 대해 D 저장소의 값을 갱신해야 합니다. 5번 노드를 거쳐 2번 노드를 갈 경우 소요되는 비용은 2+2로 4입니다. 이 값은 이미 전 단계에서 계산된 비용값(3)보다 크므로 무시합니다. 6번 노드에 대한 비용값은 5번 노드까지 오는데 소요된 비용값(2)와 5번에서 6번 노드로 가는데 추가적으로 필요한 비용 3을 합한 값 5이므로, 이 값을 D 저장소에 기록하고 T 저장소의 6번 노드 값에 5번 노드를 기록합니다. 다음 단계로 넘어 갑니다. 

처리가 완결되지 않은 노드 중 비용이 최소인 노드는 2번인데요. 2번 노드와 연결된 노드는 1, 3, 5, 6번 노드입니다. 처리가 완결된 노드를 저장하고 있는 S 집합을 통해 3번 노드와 5번 노드는 더 이상 고려할 필요가 없다는 것을 알 수 있으니, 1, 6번만 고려하면 됩니다. 먼저 1번의 경우 소요되는 비용은 3+1로 4인데요. 이 값은 이전 단계에서 계산된 비용값(5)보다 작으로 D 저장소의 값을 변경 합니다. D 저장소가 변경되면  T 저장소의 값도 2번 노드로 변경합니다. 중요한 부분이므로 위의 그림에서 빨간색으로 표시했습니다. 이제 남은 6번 노드에 대한 비용값을 계산해 보면 3+8로 11인데요. 이 값은 이전 단계에서 계산된 비용인 5보다 크므로 무시합니다. 다음 단계로 진행합니다.

처리가 완료된 노드가 아닌 것 중 1번 노드의 비용이 현재 가장 최소이므로 집합 S에 1번 노드를 추가하고 1번 노드와 연결된 0, 2, 4번 노드 중 완결되지 않은 4번 노드에 대한 비용값을 계산합니다. 4번 노드의 비용값은 4+3으로 7이므로 이 값을 D 저장소에 기록하고 T 저장소에 1번 노드를 기록합니다.

이미 처리가 완료된 노드가 아닌 것 중 최소인 노드는 6번 노드인데요. 이 6번 노드를 집합 S에 추가하고 6번 노드와 링크로 연결된  1, 2, 4, 5 중 처리가 완결되지 않은 노드는 4번인데요. 6번 노드를 경유해 4번 노드로 가기 위한 비용은 5 + 1인 6으로 계산되며, 이 값은 이전 단계에서 계산된 값(7)보다 작으므로 D 저장소가 변경되고, 이와 함께 T 저장소에 대해서도 4번 노드에 대해 6번 노드로 변경합니다.  다음 단계로 진행합니다.

처리되지 않은 노드 중, 이제 유일하게 4번 노드만 남았는데요. 4번 노드와 연결된 1, 6번 노드에 대해 처리를 해야 하는데 이미 1, 6번 노드는 처리가 완결되었으므로 더 이상 진행하지 않고 종료됩니다.

이상의 결과에서 T 저장소를 통해 출발 노드인 0번 노드에서 각 노드에 대한 최단 경로를 파악할 수 있습니다. 0번 노드에서 1번 노드에 대한 최단 경로는 (1번 노드)←(2번 노드)←(3번 노드)←(0번 노드)가 됩니다. 이는 T 저장소를 보면, 먼저 1번 노드에 연결되는 노드는 2번 노드라는 것을 알 수 있고, 다시 2번 노드는 3번 노드와 연결되며 3번 노드는 시작 노드인 0번 노드라고 기록되어 있기 때문입니다. 시작 노드 0번에서 각 노드에 대한 최단 경로를 정리하면 다음과 같습니다.

  • 0번 노드에서 1번 노드 : (1번 노드)←(2번 노드)←(3번 노드)←(0번 노드)
  • 0번 노드에서 2번 노드 : (2번 노드)←(3번 노드)←(0번 노드)
  • 0번 노드에서 3번 노드 : (3번 노드)←(0번 노드)
  • 0번 노드에서 4번 노드 : (4번 노드)←(6번 노드)←(5번 노드)←(3번 노드)←(0번 노드)
  • 0번 노드에서 5번 노드 : (5번 노드)←(3번 노드)←(0번 노드)
  • 0번 노드에서 6번 노드 : (6번 노드)←(5번 노드)←(3번 노드)←(0번 노드)

[PostgreSQL] CREATE TABLE 예제

PostgreSQL에서 geometry 타입을 갖는 Table을 생성하고자 할때, 사용한 SQL 문에 대해 정리해 봅니다. 아래와 같은 형태의 테이블 2개에 대한 생성인데요.

위 형태의 테이블 2개에 대한 CREATE 문은 아래와 같습니다. 실제 용도는 네트워크 DB에 대한 Node, Link 관련 데이터를 저장하는 Table 생성에 대한 SQL입니다.

CREATE TABLE public.ecl_network_link
(
  networkid uuid PRIMARY KEY,  
  facility_layer character varying(30),
  snode_id uuid,
  snode_layer character varying(30),
  enode_id uuid,
  enode_layer character varying(30),
  the_geom geometry(MultiLineString)
);

ALTER TABLE public.ecl_network_link
  OWNER TO postgres;

CREATE INDEX ecl_network_link_geom_idx
  ON public.ecl_network_link
  USING gist
  (the_geom);
CREATE TABLE public.ecl_network_node
(
  networkid uuid PRIMARY KEY,  
  facility_layer character varying(30),
  the_geom geometry(Point)
);

ALTER TABLE public.ecl_network_node
  OWNER TO postgres;

CREATE INDEX ecl_network_node_geom_idx
  ON public.ecl_network_node
  USING gist
  (the_geom);

[미국 SGIP 2016 전시회] MicroGrid Platform 중 GIS Studio

금번 미국에서 SGIP 2016 전시회에 한국전력연구원에서 개발 중인 MicroGird Platform이 세계적으로 소개 되고 있습니다. MicroGrid Platform은 전력설비 감시를 위한 SCADA Platform, 전력 분석을 위한 SCL Studio, 전력 사업자 및 개발자들을 하나로 모아 참여할 수 있는 Smart Portal & API, 위치기반의 전력설비 관리를 위한 GIS Studio, 전력 사업자가 자신이 생산한 전력을 판매하기 위한 입찰 시장인 New Market Service 등으로 구성되는데요. 이중 회사에서는 GIS Studio를 개발하고 있습니다. 전시회를 위해 만든 팜플렛이 있기에 GIS Studio를 올려 봅니다.

웹 기반의 Map Viewer 및 Editor는 FingerEyes-Xr for HTML5를 사용했고, 공간서버(Spatial Server)는 GeoService-Xr이 이용되었으며, DBMS는 PostgreSQL + postGIS가 사용 되었습니다.

현재 전력 설비 표출과 신규 및 변경된 전력 설비를 웹에서 바로 편집할 수 있는 기능을 마무리하는 단계이고, 이제 역률, 부하, 전압, 주파수 등에 대한 전력 계측값 및 분석값을 지도 상에 어떻게 효과적으로 표현함으로써 해당 분야의 전문가에게 새로운 영감을 줄 수 있을지 상당한 고민이 반영되어야 할 단계입니다.