🙆🏻‍♀️ [React] Openlayers (2) 🙆🏻‍♀️


マッピングでのオブジェクトの描画+オブジェクトの修正


オブジェクトの描画


🙆🏻プロット🙆🏻‍♀️
前の投稿では、関数コンポーネントを使用して地図を表します.
次に、表示されるマップに必要なオブジェクトを描画します.(点、線、多角形、円)
オブジェクトのペイントと修正に必要なモジュール(Draw、Snap、Modify)、およびオブジェクトスタイルを指定するモジュール(Style、Circle、Fill、Stroke)をインポートします.
// MapTest.jsx
import React, { useEffect, useRef } from "react";

import { Map as OlMap, View } from "ol";
import { defaults as defaultControls } from "ol/control";
import { fromLonLat, get as getProjection } from "ol/proj";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { XYZ, Vector as VectorSource } from "ol/source";
// +++
import { Style, Circle as CircleStyle, Fill, Stroke } from "ol/style";
import { Draw, Snap, Modify } from "ol/interaction";
// +++
import "ol/ol.css";
選択オブジェクトタイプのselectが追加され、ペイントオブジェクトの関数などが追加されました.
// 객체가 그려질 레이어(점, 선, 도형)
// +++ 기존에 컴포넌트 안에 선언했던 initVectorLayer을 밖으로 꺼냄
const initVectorLayer = new VectorLayer({
  source: new VectorSource(),
  style: new Style({
    fill: new Fill({
      color: "rgba(0, 0, 0, 0.2)",
    }),
    stroke: new Stroke({
      color: "red",
      width: 2,
    }),
    image: new CircleStyle({
      radius: 7,
      fill: new Fill({
        color: "red",
      }),
    }),
  }),
});
// +++

export default function MapTest() {
  // +++
  const [gisMap, setGisMap] = useState({});
  const [featuresLayer, setFeaturesLayer] = useState(null);
  // interaction을 해제하기 위해
  const [drawSnapObj, setDrawSnapObj] = useState<any>({});
  // +++
  
  const mapContent = useRef(null);
  
  // +++
  const typeSelect = useRef(null);
  
  // select 값이 바뀌면 interaction 해제 뒤 addDrawSnap 호출.
  const onChangeHandler = () => {
    gisMap.removeInteraction(drawSnapObj.draw);
    gisMap.removeInteraction(drawSnapObj.snap);
    addDrawSnap();
  };
  
  // 객체 그리기 함수
  const addDrawSnap = () => {
    // select 값이 None일 때는 리턴
    if (typeSelect.current.value === "None") {
      return false;
    }
    
    const draw = new Draw({
      source: featuresLayer.getSource(),
      type: typeSelect.current.value,
    });
    gisMap.addInteraction(draw);
    
    const snap = new Snap({ source: featuresLayer.getSource() });
    gisMap.addInteraction(snap);
    
    // interaction을 해제하기 위해 담아 놓기.
    setDrawSnapObj({ draw, snap });
  }; 
  // +++

  useEffect(() => {
    if (!mapContent.current) {
      return;
    }

    const map = new OlMap({
      controls: defaultControls({ zoom: false, rotate: false }).extend([]),
      layers: [
        new TileLayer({
          source: new XYZ({ url: "http://xdworld.vworld.kr:8080/2d/Base/202002/{z}/{x}/{y}.png" }),
        }),
        initVectorLayer,
      ],
      view: new View({
        projection: getProjection("EPSG:3857"),
        center: fromLonLat([127.296364, 37.503429]),
        zoom: 15,
        minZoom: 7,
        maxZoom: 20,
      }),
      target: mapContent.current,
    });
    
    // +++ map과 initVectorLayer를 set한다. 추후 다른 함수에 이용. (추가, 수정 등)
    setGisMap(map);
    setFeaturesLayer(initVectorLayer);
    // +++

    return () => map.setTarget(undefined);
  }, []);
  
  // +++ gisMap이 있으면 addDrawSnap 호출.
  useEffect(() => {
    // gisMap에 map 존재 여부를 객체의 키의 길이로 판단.
    if (Object.keys(gisMap).length > 0) {
      addDrawSnap();
      
      // 그려진 객체 수정.
      const modify = new Modify({ source: initVectorLayer.getSource() });
      gisMap.addInteraction(modify);
    }

    return () => {};
  }, [addDrawSnap, gisMap, featuresLayer]);
  // +++


  return (
    <div className="gis-map-wrap">
      {/* +++ 객체 타입 선택 */}
      <select ref={typeSelect} defaultValue="None" onChange={() => onChangeHandler(e)}>
        <option value="None">선택</option>
        <option value="Point"></option>
        <option value="LineString"></option>
        <option value="Polygon">다각형</option>
        <option value="Circle">원형</option>
      </select>
      {/* +++ */}
      <div ref={mapContent}></div>
    </div>
  );
 }

ジグザグの種類を指定してオブジェクトを描画および修正できます.

次は..。🤔


描画したオブジェクトをGeoJSONに変換します.
OpenLayers公式サイト