MariaDB의 JDBC 연결

MySQL에서 파생된 MariaDB를 프로젝트에 사용하고 있는데요. 이 MariaDB를 Java에서 연결해 필요한 데이터를 조회하기 위해 JDBC를 사용하는 코드를 정리해 둡니다.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class MainEntry {
    public static void main(String[] args) {
        Connection con = null;
        PreparedStatement pstmt = null;   
        ResultSet rs = null;

        try {
            Class.forName("org.mariadb.jdbc.Driver");
			
            con = DriverManager.getConnection(
                "jdbc:mariadb://100.100.100.7:3306/dbname",
                "userId",
                "password");
						
            pstmt = con.prepareStatement("select * from his_bus_voltage");
			
            rs = pstmt.executeQuery();
			
            while(rs.next()) {
                //.
            }
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(rs != null) {
                    rs.close(); // 선택 사항
                }
				
                if(pstmt != null) {
                    pstmt.close(); // 선택사항이지만 호출 추천
                }
			
                if(con != null) {
                    con.close(); // 필수 사항
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

MariaDB의 JDBC 라이브러리는 공식 사이트인 https://downloads.mariadb.org/connector-java/에서 다운로드받았으며, 이 글을 작성할 때는 mariadb-java-client-2.0.3.jar를 사용하였습니다.

CentOS 7에서 Postgresql 9.6.2, Postgis 2.3.2-1 설치(인터넷 환경)

인터넷이 되는 환경에서 PostgreSQL(9.6.2)와 PostGIS(2.3.2)를 설치하는 절차입니다.

PostgreSQL 9.6.2 설치

1. PostgreSQL과 PostGIS 설치를 위한 yum 저장소 업데이트

rpm -Uvh https://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm

2. PostgreSQL 설치

yum install postgresql96-server postgresql96

3. 데이터베이스 저장소 생성

./postgresql96-setup initdb

4. PostgreSQL 서비스 실행

systemctl enable postgresql-9.6
systemctl enable postgresql-9.6.service
systemctl start postgresql-9.6.service

5. 방화벽에서 port 5432번 개방

firewall-cmd --zone=public --add-port=5432/tcp

6. 외부에서 DBMS 접근 허용 설정

vi postgresql.conf

아래처럼 편집

listen_addresses = "*"

7. postgres 사용자 암호 설정

su - postgres
psql
\password postgres
\q

8. 이전 사용자로 복귀
su - root

9. 외부 접속을 위한 보안설정 변경

vi pg_hba.conf

아래처럼 편집

local all all peer 문자열을 local all all md5 로 변경
host all all 127.0.0.1/32 ident 문자열을 host all all 0.0.0.0/0 md5 로 변경
host all all ::1/128 ident 문자열을 host all all ::1/128 md5 로 변경

10. PostgreSQL 서비스 재기동

systemctl stop postgresql-9.6.service
systemctl start postgresql-9.6.service

11. [2017-07-08 추가] UUID 확장 기능 설치를 위해 다음 명령이 필요함

systemctl stop postgresql-9.6.service
yum install postgresql96-contrib.x86_64
systemctl start postgresql-9.6.service

PostGIS 설치

yum install epel-release
yum install postgis2_96.x86_64
systemctl restart postgresql-9.6.service

DuraMap-Xr에서 Image Symbol 크기 조정

듀라맵에서 ShapeMapLayer에 대한 이미지 심벌을 지정할 경우에, 그 크기는 원본 이미지 크기 그대로 표시됩니다. 이에 대해 개발자가 직접 이미지의 크기를 지정할 수 있는 방식도 제공되는데요. 아래의 코드는 이미지의 크기를 가로 84px로 지정하는 경우입니다. 세로의 크기는 가로와 세로에 대한 비율을 유지하도록 자동으로 계산됩니다.

axXr1.Layers.AddShapeMapLayer("lyr", "D:/__Data__/points.shp");
axXr1.WaitForAllConnections();

if (axXr1.Resources.AddImageResource("img", "d:/__data__/temperature.png"))
{
    var sym = axXr1.Layers.GetLayerAsShapeMap("lyr").PointSymbol;

    sym.SetImage("img", axXr1.Resources);
    sym.Size = 84; // 이미지 심벌을 가로로 84px로 지정 !!
}

axXr1.Update();

위의 코드와 함께 듀라맵에 소소한 개선으로 두가지가 이루어졌는데요. 첫째는 휠마우스에 대한 Delta 값을 보다 정확히 음수와 양수로 얻을 수 있다는 것과 두번째는 GetFIDFromMousePoint 매서드를 통해 도형을 선택할 때, 포인트 심벌의 크기에 맞춰 선택할 수 있도록 개선되었는데요. 기존에는 포인트 심벌의 크기를 고려하지 않아 포인트의 심벌 중앙을 클릭해야 선택되는 사용상의 불편함이 해소되었습니다.

환경계측데이터에 대한 보간 및 TMS 가공

환경과 관련된 계측 데이터에는 풍속, 풍향, 온도, 미세먼지, 오존농도 등이 있습니다. 이러한 계측 데이터는 일정한 시간 주기로 측정되고 측정된 값은 관련된 시스템의 서버에 저장되어, 이를 필요로 하는 곳에서 활용할 수 있도록 다양한 방식으로 제공되는데요. 제공되는 방식은 파일 기반으로 다운로드 받을 수 있거나 OpenAPI 형태로 효과적으로 서비스 받을 수 있습니다.

계측 데이터는 공간 상에 특정한 위치에 계측기를 설치하여 측정되는데요. 측정되지 못하는 지점에 대한 계측값은 이미 계측된 다른 가까운 지점들을 이용하여 보간(Interpolation)됩니다. 공간에 대한 보간 알고리즘은 Spline, Kernel Density, IDW, Kriging 등이 있고 각 보간 알고리즘마다 하나의 좋은 주제로써 추후 시간을 내어 연구해 볼만합니다.

이 글은 이러한 환경과 관련된 계측 데이터를 보간하고, 보간된 결과를 웹에서 누구나 쉽게 조회할 수 있도록 지도로 서비스할 수 있는 TMS 형태로 가공하여 OpenLayer나 Leaflet와 같은 가장 많이 사용하는 오픈소스 기반의 클라이언트 지도 엔진에서 활용하는 것에 대한 내용을 정리해 보았는데요. 각 처리 과정에서 활용한 툴은 자체적으로 개발된 엔진을 이용하여 보다 빠르게 처리할 수 있었습니다.

최종적으로 웹 기반의 지도로 서비스될 계측 데이터는 ‘온도’로 하였습니다. 전세계의 온도 데이터는 다양한 경로를 통해 다운로드받을 수 있습니다. 아래의 그림은 전세계의 위경도에 대해 1도마다 측정된 온도 데이터를 보다 쉽게 보간할 수 있도록 SHP 파일 형태로 변환하는 내용입니다.

온도에 대한 계측 지점에 대한 온도값 속성으로 단위가 켈빈인 K 값을 담고 있습니다.

이제 이 계측값에 대한 SHP 파일을 보간을 통해 모든 지점에 대한 계측값을 계산할 수 있는데요. 아래의 그림은 보간 방법 중 IDW 알고리즘을 사용한 것으로, 그 결과에 대해 의미있는 색상을 적용해 표현한 것입니다.

보간된 데이터는 그리드(Grid) 형태입니다. 이를 TMS 형태의 격자로 가공하기 위해 아래의 화면과 같이 Mr.Tiler-Xr이라는 타일맵 가공툴을 이용해 가공합니다.

이렇게 가공된 TMS 형식의 타일맵에 약간의 투명도를 주어 OpenLayers를 이용해 OpenStreetMap을 배경지도 상에 정확히 중첩되는지 확인한 화면은 아래와 같습니다.

추후 이러한 일련된 과정을 자동화하여 주기적으로 들어오는 계측값을 자동으로 TMS 형식의 타일맵으로 가공해 서버측에 저장해 두는 기능을 고려하고 있습니다.

[golang] 배열을 포인터로 전달하는 함수

Go는 배열을 함수로 전달할때 배열의 전체를 복사한 값 형식으로 함수에 전달합니다. 결국 함수 안에서 해당 배열의 요소를 변경하여도 파라메터로 전달되어진 그 원래의 배열에 변경이 생기지 않습니다. 그러나 이 배열을 포인터로 전달하면 함수 내부에서 변경되는 대상이 원본이므로 변경 내용을 유지됩니다. 아래는 배열을 포인터 타입으로 함수에 전달하는 예제입니다.

package main

import "fmt"

func f(a *[3]int) {
	a[1] = 100
}

func main() {
	a := [3]int{1, 2, 3}

	f(&a)

	fmt.Println(a[1])
}