반응형

csv 파일의 경위도 좌표를 읽어 포인트를 생성하여 지도에 레이어를 추가하는 예제를 살펴보겠다.

 

www.data.go.kr 공공데이터포털에서 개방된 csv 데이터를 활용하여 테스트를 진행해보겠다.

 

사용한 라이브러리는 commons-csv, geotools를 사용했다.

 

 

<!--apache-csv-->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-csv</artifactId>
	<version>1.7</version>
</dependency>
<!--geotools-->
<dependency>
	<groupId>org.geotools</groupId>
	<artifactId>gt-main</artifactId>
	<version>${geotools.version}</version>
</dependency>
<dependency>
	<groupId>org.geotools</groupId>
	<artifactId>gt-geotiff</artifactId>
	<version>${geotools.version}</version>
</dependency>

 

공공데이털 포털에서 경위도 좌표가 포함된 csv 파일을 예제로 테스트해보겠다.

전기차 충전소 위치 및 현황 데이터를 사용했다.

 


String file ="파일경로+파일이름.csv";

File file = new File(file);

try {		
      CSVFormat format = CSVFormat.RFC4180.withHeader().withDelimiter(',');
      //보통 공공데이터포탈의 경우 인코딩은 euckr
      CSVParser parseCsv = CSVParser.parse(new File(dir+fileName), Charset.forName("EUC-KR"), format);
      List<CSVRecord> records = parseCsv.getRecords();
      List<SimpleFeature> features = new ArrayList<>();
	
      //포인트를 담을 geometryfacotry 생성
      GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
      SimpleFeatureTypeBuilder pointTb = new SimpleFeatureTypeBuilder();
	  
      //포인트 라벨을 충전소이름으로 설정
      pointTb.setName("csvPoints");
      pointTb.add("point",Point.class);
      pointTb.add("LABEL",String.class);

      Style pointStyle;
      //라벨 색상
      Color color = new Color(255,255,255);
      //포인트 색상
	  Color fillColor = new Color(255,0,0);
      Color fillColor = Color.decode(colorHex);
	  
      //배경지도는 브이월드 타일 레이어로 추가했다.
      String baseURL = "http://xdworld.vworld.kr:8080/2d/Base/201802/";
      MapContent mapContent = new MapContent();

      TileService service = new OSMService("vworld", baseURL);
      TileLayer tile_layer = new TileLayer(service);

      mapContent.addLayer(tile_layer);

      final DefaultFeatureCollection pointCollection = new DefaultFeatureCollection();
      SimpleFeatureBuilder pointFeatureBuilder = new SimpleFeatureBuilder(pointTb.buildFeatureType());

      Layer layerPoints;
      ArrayList<Coordinate> coords= new ArrayList<>();

      for(int i=1;i<records.size();i++) {
      
      	  String lonStr = records.get(i).get(columnX);//경도 컬럼
          String latStr = records.get(i).get(columnY);//위도 컬럼
          String label = records.get(i).get(1);//충전소명 라벨로 설정

          if(!lonStr.equals("") && !latStr.equals("") && label != null) {

              double lon = Double.parseDouble(lonStr);
              double lat = Double.parseDouble(latStr);

              Point point = geometryFactory.createPoint(new Coordinate(lon, lat));
              coords.add(new Coordinate(lon, lat));
              pointFeatureBuilder.add(point);
              pointFeatureBuilder.set("LABEL", label);

              SimpleFeature feature = pointFeatureBuilder.buildFeature(null);
              features.add(feature);
              pointCollection.add(feature);

          }

      }

      StyleBuilder styleBuilder = new StyleBuilder();
      //포인트 스타일 설정
      pointStyle = SLD.createPointStyle("Circle", Color.BLACK, fillColor , (float) 0.9, 8);
	  //라벨 폰트 스타일 설정
      Font font = styleBuilder.createFont("맑은 고딕", 10.0);
      TextSymbolizer textSymb = styleBuilder.createTextSymbolizer(Color.black, font, "LABEL");

      LabelPlacement labelPlace = styleBuilder.createPointPlacement(0.5, 1.5, 0.0); 
      textSymb.setLabelPlacement(labelPlace);

      Rule rule = styleBuilder.createRule(textSymb);
      pointStyle.featureTypeStyles().get(0).rules().add(rule);

      layerPoints = new FeatureLayer(pointCollection, pointStyle);
      mapContent.addLayer(layerPoints);
	  
      mapContent.getViewport().setMatchingAspectRatio(true);
      mapContent.getViewport().setBounds(bounds);
    
  } catch (Exception e) {
		e.printStackTrace();
  }
		

파일의 레코드 수만큼 스타일을 생성할 경우 그만큼 리소스를 사용하기 때문에 레코드 수 가 많은면 상당 시간 소요된다.

 

포인트 스타일을 줄 경우 pointcollection 객체 생성이 끝난 후 추가 해주는게 좋다.

 

반응형

+ Recent posts