본문 바로가기

SIA 인턴

Ovision Admin 페이지 개발 | SIA 인턴

Ovision

 

Ovision

SI Analytics solution accelerate utilizing in GEOINT to find creativeness in new forms of analytics and make experts' focus on insight ability.

ovision.ai

 

Ovision은 인공위성을 활용하여 사람이 일일이 분석하기 어려울 정도로 크고 방대한 위성 영상을 자동으로 분석하고 여러 유용한 정보로 제공해주는 소프트웨어이다.

 

 

Ovision의 주요 기능은 다음과 같다.

- AI 판독 결과 실시간 모니터링: 원하는 대상에 대한 분석 결과를 실시간으로 확인 가능

- 프로젝트 별 분석 관리: 목적에 맞는 지역과 타겟 별로 분석 결과를 관리할 수 있다.

- 보고서 자동 생성: 의사 결정자를 위한 핵심만 간추린 보고서를 자동으로 생성해서 제공

- 관심 지역 관리: 사용하던 지역 그대로 오비전에 간편하게 연결하여 사용하고, 손쉽게 관리

 

Ovision Admin 개발하면서의 생각

특정 지역의 판독 서비스를 사용자가 수행하려면 크레딧을 결제해야한다. 따라서 사용자는 크레딧을 결제하고 사용한다. 이런 과정에서 각각의 사용자에게 크레딧을 지급할 필요가 있다. 개발자라면 DB를 직접 수정할 수 있지만 비개발자라면 Admin 페이지를 활용해야한다.

 

Admin 페이지에서는 사용자 관리, 주문 현황, 사용현황을 파악할 수 있다. 페이지에서 사용하는 컴포넌트로는 ODS(Ovision Design System)을 사용하고 테이블은 Ant Design의 컴포넌트를 활용한다. 각각의 테이블에서의 정렬과 필터링등 어드민 사용자와의 인터랙션이 많다. 

 

 

Ant Design의 테이블 컴포넌트를 사용하면서 정말 컴포넌트의 설계가 야무지다는 생각을 했다. 정말 많은 케이스에 대한 처리가 있었고 테이블에서 필터링, 다중 체크, 페이지네이션등의 다양한 상호작용을 선언적으로 구현할 수 있었다. 

 

처음엔 기능 구현이 우선이라고 생각하고 컴포넌트를 작성했다. 테이블에 컬럼과 상호작용(필터링, 검색)이 많다보니 반복되는 작업이 많았고 좀 더 발전시킬 수 있겠다고 생각했다.(컴포넌트 분리, 추상화)

 

또한 더 개선하고 싶은점은 react-query를 사용하고 있지 않기 때문에 refetch 메커니즘을 refetch라는 상태변수와 그 상태변수가 변경될 때 useEffect에서 fetch 메서드를 실행하는 방식으로 구현된 부분이다. refetch를 위한 상태 변수 도입은 최선이었을까?

 

react-query에서 쿼리를 invalidate 시켰던 것처럼 구현할 수 있으면 좋지만 이렇게 하려면 react-query는 프로젝트에서 사용하고 있지 않았다. 이러한 상황에서 어쩌면 refetch 상태변수를 바꾸는게 최선일 수 있다고 생각하게된다.(Future Work: 고민 더 해보기) 리덕스에서 mutation이 완료되면 refetch 액션을 dispatch 할 수도 있지만 상태변수 도입을 통한 refetch는 괜찮은 판단이었던것 같다!

Data to CSV

JSON 데이터를 CSV 형태로 바꾸고 이를 다운로드 가능하게 해야했다. 우선 사용자 관리 테이블이나, 주문 현황, 사용현황테이블을 CSV 형태로 파싱했다.

 

 

function convertToCSV(objArray) {
  const header = Object.keys(objArray[0]).join(',');
  const rows = objArray.map(obj => Object.values(obj).join(','));
  return `${header}\n${rows.join('\n')}`;
}

 

헤더와 row를 구분해주고 데이터를 ,로 구분시켜서 붙인 문자열을 만들었다. 이후에 다음과 같이 호출해서 csv 문자열을 얻을 수 있었다.

 

const csv = converToCSV(data)

 

리액트 컴포넌트에서는 다음과 같이 다운로드 버튼을 만들고 이를 클릭하면 downloadCSV()라는 함수를 호출하여 다운로드를 구현할 수 있다.

 

import { useRef } from 'react';

function MyComponent() {
  const csvData = convertToCSV(data); // assuming this function is defined as shown in my previous answer
  const linkRef = useRef(null);

  function downloadCSV(filename = "data.csv") {
    const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    linkRef.current.href = url;
    linkRef.current.download = filename;
    linkRef.current.click();
    URL.revokeObjectURL(url);
  }

  return (
    <>
      <button onClick={downloadCSV}>Download CSV</button>
      <a href="#" ref={linkRef} style={{display: 'none'}}>Download</a>
    </>
  );
}

 

JavaScript에서는 URL.createObjectURL을 통해 Blob 객체(Blob.Binary Large Object 객체는 자바스크립트에서 이미지, 영상등의 멀티미디어 데이터를 다룰 때 사용한다. createObjectUrl에 입력 가능한 File, Blob, MediaSource 중 File은 Blob에 기반한 인터페이스이다.)를 나타낼 수 있다. 이 메서드를 호출하면 window의 document에서만 접근 가능한 url이 생성된다.(이 URL은 다른 window에서는 접근할 수 없다.) 이를 통해 image를 받았을 때 화면에 보여줄 수 있는 임시 url을 생성할 수 있다. URL.revokeObjectURL을 통해 createObjectURL을 통해 생성된 URL을 폐기 시킬 수 있다. 폐기하지 않으면 자바스크립트 엔진에서는 생성된 URL을 계속 사용하는 것으로 판단하여 GC가 동작하지 않게 된다.

 

CSV 포맷으로 변환한 후 다운로드 기능을 만드는 작업을 하면서 사용해보지 않은 브라우저 API를 사용해서 흥미로웠다.

 

Future Work

- Blob 객체

'SIA 인턴' 카테고리의 다른 글

Protocol Buffer  (0) 2023.03.02
OpenLayers 개념 및 용어 정리  (2) 2023.02.22