Geoserver

이정수·2025년 1월 3일
0

기타 기술 정리

목록 보기
3/5

GeoServer (Geo-spatial Gateway) geoserver.org : OSGeo
。Web상에서 GIS처럼 공간데이터를 공유 및 편집할 수 있는 Java로 개발된 오픈소스 GIS Software Server
▶ Spring 처럼 Java 기반 Server이므로, 사전에 Java의 설치가 필요하다.

Map Server : 사용자 브라우저에서 지도를 조작 시 일일이 Vector로 point, line, polygon을 Server-side에서 렌더링하여 사용자에게 이미지 형태로 가공하여 WMS, WTMS로서 지도데이터를 제공.

GeoserverPostGIS를 등록 시 GeoServerPostGIS 데이터를 "실시간으로" 조회하여 제공하므로, PostGIS 테이블이 변경되면 GeoServer에서도 즉시 반영

。다양한 source (DB, shape file, raster data)등의 geospatial data를 다양한 SRS의 layer로 게시(publish) 및 웹 서비스를 통해 Web에서 접근하도록 하는 기능을 수행.
▶ raw geospatial data와 지도시각화 또는 공간분석이 필요한 application 간 다리 역할을 수행.

。사용자 브라우저에서 지도를 조작 시 일일이 Vector로 point, line, polygon을 즉석에서 그리는 것을 Server-side에서 렌더링하여 사용자에게 이미지 형태로 제공.

PostGIS DB의 Layer를 GeoServer로 발행하여 등록 후 data type( Vector, Raster )에 따라서 WMS , WFS , WCS등으로 서비스 할 수 있음.

Postgres만 사용하지 않고, GeoServer를 함께 사용하는 이유는 Postgres DBVector data만 전달이 가능하므로, 해당 data의 용량이 큰 경우 일일이 DB를 통해 Map을 표현하면 렉이 걸리므로, GeoServer에서 벡터데이터를 WMS로 이미지데이터로 렌더링하여 Server-Side-Rendering을 이용.

  • GeoServer 주요기능
    • Data Publish : GIS 서비스 표준 종류
      。GeoServer는 geospatial data를 WMS , WFS , WCS, WPS 표준에 따라 Web 상에서 data publish service 및 geospatial data를 관리하는 Web Interface 제공.
      JPEG , PNG , GeoTiff , JPEG2000 , Erdas Imagine등의 raster data format과 Shapefile , GeoPackage , PostGIS , GML 등의 Vector data format을 지원.

    • 상호운용성 : OGC(Open Geospatial Consortium) 표준을 준수하여 다양한 GIS application과 호환성을 보장.

    • Custom Styling :
      SLD , CSS를 사용하여 geospatial data의 styling을 지원.
      SLD(Standard Layer Descriptor) : geospatial data의 style을 XML 형식으로 표현.

    • 확장성 : GeoServer는 큰 용량의 dataset을 처리 할 수 있으며, PostGIS , Oracle Spatial등과 같은 Geospatial DB와 통합이 가능.


  • 데이터 : Data
    • 레이어 미리보기(Layer Preview) :
      。사용자가 GeoServer에 추가한 layer에 접근 및 OpenLayers , KML , GML 외 다양한 format으로 layer을 배포가 가능.


      。Geoserver의 Layer를 다음 다양한 Format들로 배포가 가능하다.

    • 작업공간(Workspace)
      。작업공간 정의 시, 새로운 Project를 시작 시 해당 Project에 관련된 레이어(layers), 저장소(stores), 스타일(styles)에 대한 정보를 담는 folder 역할을 수행.




    • 저장소(stores)
      。GeoServer에 데이터를 제공하는 별개의 source를 가지는 저장소를 관리하는 역할을 수행.
      。기존 저장소를 삭제하거나 새로운 저장소를 추가할 수 있으며 사전에 작업공간이 필요
      • Shape file 저장소 생성


        Directory of spatial files (shapefiles) 선택 시 shapefile 등을 포함하는 directory 위치로 설정.


      • PostGIS 저장소 생성
        PostGIS DB의 Layer를 GeoServer로 발행하여 등록 후 data type( Vector, Raster )에 따라서 WMS , WFS , WCS등으로 서비스 할 수 있음.
        저장소에서 PostGIS를 선택 후 pgadmin4 에서 정의된 DB 정보를 기입 후 DB 생성.

        。이후 DB내 정의 된 Layer들을 GeoServer의 Layer로서 발행하여 등록.
        pgadmin4 DB에 저장된 Layer를 GeoServer Layer로 발행하여 레이어 미리보기로 시각화 할 수 있다.


    • 레이어(Layers)
      。GeoServer에서 발행한 layer를 관리.
      。해당 Layer들은 GeoServer에서 정의된 stores에서 가져온다.
      。배포된 Layer는 다른 이름의 Layer로 설정하여 다시 배포할 수 있다.


      。 Layer를 생성 시 사전에 해당 Layer를 저장할 저장소가 필요로한다.
      Workspace이름:stores이름으로 표기됨.
      ▶ 이후 발행하기를 눌러서 새로운 layer를 추가.

      데이터탭에서 레이어 기본정보이름 설정 후 공간 좌표 체계에서 데이터로부터 계산하기원본 영역으로부터 계산하기를 누른 후 저장.
      ▶ 기존 DB에서 정의된 Layer의 SRS(Spatial Reference System)EPSG:4326이더라도 Layer를 GeoServer로 import 시 정의한 좌표체계에서 해당 SRS를 변경할 수 있다.

      좌표체계 처리 방식 : 원본을 정의한 좌표체계로 투영을 선택 시 레이어 생성 후 레이어 미리보기를 통해 데이터를 배포할 경우 정의한 좌표체계의 좌표계로 배포.
      정의한 좌표체계 사용을 선택 할 경우 데이터 배포 시 원본데이터의 좌표계로 배포됨.

      원본 데이터 최소경계 영역(Native Bounding Box) : 원본 데이터 좌표체계원본 SRS 기준으로 최소경계를 계산.
      위/경도영역(Lat/Log Bounding Box) : SRS EPSG:4326에서 원본데이터의 위,경도 기준 경계영역을 계산.

      。해당 과정에서 Layer의 Table 정보도 확인 가능.

      발행탭의 WMS 설정에서 Layer의 Styling을 지정할 수 있다.

      유형 : 상단 5개 기준 Polygon , point , Polygon , LineString , Image
      이름 : Workspace이름:Layer이름으로 표기.
      。 이후 레이어 미리보기 에서 해당 layer를 조회할 수 있다.

    • 레이어 그룹(Layer Groups)
      。복수 이상의 Layer를 결합하여 하나의 layer로서 다루는 역할을 수행.


      레이어 그룹 생성 시 이름개요를 기재 및 공간 좌표 체계를 설정.

      레이어 목록에서 레이어 추가하기...를 통해 레이어를 추가.
      그리기 순서에 따라 Map에 표현되므로, BaseMap Layer를 먼저 그리는게 좋다.
      ▶ 순서는 화살표를 통해 변경이 가능.

      。이후 영역에서 데이터 최소경계 영역 계산하기를 누른 후 저장.

      。생성된 레이어 그룹레이어 미리보기에서 조회가 가능.

    • 스타일(Styles)
      。Geoserver에서 발행하여 layer와 feature를 styling하기 위한 모든 styling 정보를 포함한 파일
      ▶ custom style을 생성하여 layer에 할당한 후 layer preview에 적용 가능.
      SLD(Styled Layer Descriptor)를 사용하여 data에 색상 및 label 등의 style을 지정 가능.
      ▶ 스타일 목록에서 Style의 SLD를 확인 및 수정이 가능.

      GeoServer/SLD Cookbook
      point , line , polygon , raster에 대한 SLD 예제가 존재.

      Zoom-based-styling : Zoom-based-point, Zoom-based-line, Zoom-based-Polygon:
      。 해당 SLD 코드를 이용하여 특정 Zoom Level 조건에서의 point,line,polygon 객체의 style을 표현가능.
      ▶ layer를 zoom-in 시 특정 객체들을 보이게하면서 label도 같이 표현하는 작용을 수행할 수 있다.
      • 특정 레이어에 적용할 STYLE 변경
        레이어 탭에서 style을 수정할 레이어 선택.

        발행 탭 중간에 WMS 설정에서 style을 지정.


      • SLD를 설정하여 Style 생성하기.

        스타일에서 스타일 생성 시 스타일 내용에서 Styling할 객체 ( point, Line, polygon, raster )를 선택 후 생성하기...를 눌러서 SLD코드를 생성.
        기존 스타일로부터 복사합니다 는 기존에 GeoServer에 존재하는 Style의 SLD코드를 가져와서 복사하는 역할을 수행.
        。생성된 SLD코드는 XML format을 가지며 <Name>는 생성할 스타일 데이터의 이름을 설정.

        GeoServer/SLD Cookbook 해당 사이트에서 사용할 style의 SLD 코드를 가져온 후 위 생성된 SLD코드에서 <FeatureTypeStyle> 부분만 대체해서 붙여넣기하기.

        。이후 범례범례 미리보기를 통해 SLD에 의해 적용된 style을 확인 가능.

        。저장할 경우 다음처럼 생성된 style을 확인할 수 있다.

        。이후 레이어에서 styling할 Layer를 클릭 후 발행 탭의 WMS 설정에서 해당 생성된 style을 적용.
        기본 스타일 하단에 범례를 미리보기할 수 있다.

        。styling 설정 후 레이어 미리보기를 통해 layer 확인 시 다음처럼 설정됨을 확인 가능.

        ▶ Style 적용이 안되는 경우, Layer의 좌표계를 다시 설정하여 공간 좌표 체계에서 데이터로부터 계산하기원본 영역으로부터 계산하기를 재설정하기.

        SLD 코드 해석

              <FeatureTypeStyle>
                <Rule>
                  <Title>&lt; 2M</Title>
                  <ogc:Filter>
                    <ogc:PropertyIsLessThan>
                     <ogc:PropertyName>PERSONS</ogc:PropertyName>
                     <ogc:Literal>2000000</ogc:Literal>
                    </ogc:PropertyIsLessThan>
                  </ogc:Filter>
                  <PolygonSymbolizer>
                     <Fill>
                        <!-- CssParameters allowed are fill (the color) and fill-opacity -->
                        <CssParameter name="fill">#4DFF4D</CssParameter>
                        <CssParameter name="fill-opacity">0.7</CssParameter>
                     </Fill>     
                  </PolygonSymbolizer>
                </Rule>
                <Rule>
                  <Title>2M - 4M</Title>
                  <ogc:Filter>
                    <ogc:PropertyIsBetween>
                      <ogc:PropertyName>PERSONS</ogc:PropertyName>
                      <ogc:LowerBoundary>
                        <ogc:Literal>2000000</ogc:Literal>
                      </ogc:LowerBoundary>
                      <ogc:UpperBoundary>
                        <ogc:Literal>4000000</ogc:Literal>
                      </ogc:UpperBoundary>
                    </ogc:PropertyIsBetween>
                  </ogc:Filter>
                  <PolygonSymbolizer>
                     <Fill>
                        <!-- CssParameters allowed are fill (the color) and fill-opacity -->
                        <CssParameter name="fill">#FF4D4D</CssParameter>
                        <CssParameter name="fill-opacity">0.7</CssParameter>
                     </Fill>     
                  </PolygonSymbolizer>
                </Rule>
                <Rule>
                  <Title>&gt; 4M</Title>
                  <!-- like a linesymbolizer but with a fill too -->
                  <ogc:Filter>
                    <ogc:PropertyIsGreaterThan>
                     <ogc:PropertyName>PERSONS</ogc:PropertyName>
                     <ogc:Literal>4000000</ogc:Literal>
                    </ogc:PropertyIsGreaterThan>
                  </ogc:Filter>
                  <PolygonSymbolizer>
                     <Fill>
                        <!-- CssParameters allowed are fill (the color) and fill-opacity -->
                        <CssParameter name="fill">#4D4DFF</CssParameter>
                        <CssParameter name="fill-opacity">0.7</CssParameter>
                     </Fill>     
                  </PolygonSymbolizer>
                </Rule>
                <Rule>
                  <Title>Boundary</Title>
                  <LineSymbolizer>
                    <Stroke>
                      <CssParameter name="stroke-width">0.2</CssParameter>
                    </Stroke>
                  </LineSymbolizer>
                  <TextSymbolizer>
                    <Label>
                      <ogc:PropertyName>STATE_ABBR</ogc:PropertyName>
                    </Label>
                    <Font>
                      <CssParameter name="font-family">Times New Roman</CssParameter>
                      <CssParameter name="font-style">Normal</CssParameter>
                      <CssParameter name="font-size">14</CssParameter>
                    </Font>
                    <LabelPlacement>
                      <PointPlacement>
                        <AnchorPoint>
                          <AnchorPointX>0.5</AnchorPointX>
                          <AnchorPointY>0.5</AnchorPointY>
                        </AnchorPoint>
                      </PointPlacement>
                    </LabelPlacement>
                  </TextSymbolizer>
                </Rule>
             </FeatureTypeStyle>
        • <FeatureTypeStyle> :
          。Style은 여러개의 <Rule>를 포함할 수 있다.

          <Rule>를 여러개 정의 시 다음처럼 범례를 여러개 설정이 가능.

        • <Rule> :
          。특정 type에 대한 style.
          <Title> : 범례에 표현될 문자열 또는 값을 표시.
          。각 type에 따라서 <PointSymbolizer> , <PolygonSymbolizer> 등으로 구분됨.
          <PolygonSymbolizer>
                      <Fill>
                        <CssParameter name="fill">#ffff00
                        </CssParameter>
                      </Fill>
                      <Stroke>
                        <CssParameter name="stroke">#000000</CssParameter>
                        <CssParameter name="stroke-width">0.5</CssParameter>
                      </Stroke>
          </PolygonSymbolizer>

          <Fill> : Polygon의 색상을 지정.
          <Stroke> : Line의 색상 및 너비를 지정.
          <CssParameter>를 이용하여 hexcode(ex.#0099cc)를 통해 Polygon의 색상을 지정.

          • <ogc:Filter> :
            。특정 조건에 따라서 Style을 부여하는 역할을 수행.
            <ogc:PropertyName> : 값 범위를 설정할 특정 Field를 지정.

            <ogc:PropertyIsLessThan> : Field값이 특정 값 미만일때 해당 <Rule>의 style을 지정.
          <ogc:PropertyIsLessThan>
                       <ogc:PropertyName>PERSONS</ogc:PropertyName>
                       <ogc:Literal>2000000</ogc:Literal>
          </ogc:PropertyIsLessThan>

          <ogc:PropertyIsBetween> : Field값이 복수의 특정 값 사이일때 해당 <Rule>의 style을 지정.

          <ogc:PropertyIsBetween>
                        <ogc:PropertyName>PERSONS</ogc:PropertyName>
                        <ogc:LowerBoundary>
                          <ogc:Literal>2000000</ogc:Literal>
                        </ogc:LowerBoundary>
                        <ogc:UpperBoundary>
                          <ogc:Literal>4000000</ogc:Literal>
                        </ogc:UpperBoundary>
          </ogc:PropertyIsBetween>

          <ogc:PropertyIsGreaterThan> : Field값이 특정 값 이상일때 해당 <Rule>의 style을 지정.

          <ogc:PropertyIsGreaterThan>
                       <ogc:PropertyName>PERSONS</ogc:PropertyName>
                       <ogc:Literal>4000000</ogc:Literal>
          </ogc:PropertyIsGreaterThan>

          <ogc:PropertyIsGreaterThanOrEqualTo> : Field값이 특정 값과 같거나 이상일때 해당 <Rule>의 style을 지정.

geoserver 설치 및 서버구동
Geoserver.org에서 Platform Independent Binary파일을 다운로드 및 C:/Program files/ 에 압축풀기 수행.
geoserver2.26.1 기준 JAVA JDK 11 설치가 사전에 필요.
。환경변수에서 다음의 환경변수를 정의.
JAVA_HOME : C:\Program Files\Java\jdk-11 : 사용할 JAVA의 위치 정의.
GEOSERVER_HOME : C:\Program Files\GeoServer\geoserver-2.26.1-bin : GeoServer가 설치된 Jetty 또는 Tomcat 폴더
GEOSERVER_DATA_DIR : C:\Program Files\GeoServer\geoserver-2.26.1-bin\data_dir : GeoServer Data Directory 위치.
이후 geoserver의 bin 폴더에서 startup.bat 파일을 관리자권한으로 실행 시 서버가 구동됨.

。다음처럼 GeoServer가 자동으로 구동이 되는 경우 다음 url로 접속
http://localhost:8080/geoserver

。다음처럼 서버에 접속이 가능함을 확인 가능.
。기본계정은 ID : admin / PW : geoserver
기본계정은 GeoServer의 모든 기능을 사용할 수 있다.

  • 서버 종료하는 방법
    localhost:8080의 url을 사용하므로, 다른 서버 (ex. spring)을 구동 시 해당 서버를 종료해야한다.
    。cmd를 켠 후 다음 구문을 입력
    netstat -ano | find "8080"
    。이후 현재 이용 중인 server port들이 도출 시 맨 오른쪽의 PID 번호를 이용하여 해당 port의 process를 종료.
    taskkill -pid PID번호 /f

    。프로토콜종류 / Local Address (출발지주소 및 포트) / Foreign Address (목적지주소 및 포트) / State 포트 상태 표기 / PID
    LISTENING : 연결 요구를 기다리는 상태로서 Port가 열린것을 의미.
    • netstat (network statistics)
      。네트워크 접속, 라우팅 테이블, 네트워크 인터페이스의 통계 정보를 지시하는 도구.

GeoServer 실습 - 보안

  • 실습파일 준비하기

    Postgres DB에서 실습에 활용할 DB를 생성 및 Extension...에서 PostGIS를 설치.

    QGIS에서 pgadmin4의 DB와 연결 및 실습 shp파일을 import.


    GeoServer에서 각각 2개의 작업공간 정의 후 저장소를 동일하게 PostGIS로 설정하여 생성




    。이후 각각의 작업공간에 대해 저장소에서 Layer를 발행.

  • GeoServer 상에서 User Role 설정하기.
    public user : public data에 대해서만 조회, 작성 및 다운로드가 가능.
    private user : private data에 대해서 조회가 가능하지만, 다운로드는 불가능.
    private edit : private datapublic data 모두 조회, 작성 및 다운로드도 가능.
    • 보안사용자, 그룹, 역할(Users, Groups and Roles)에서 Role 생성
      역할 서비스default를 클릭 후 역할 탭에서 새로운 역할 추가 선택하여 다음 3개의 ROLE을 추가
      ROLE_COMPANY_EDITpublic user
      ROLE_TRANSPORTATION_VIEWprivate user
      ROLE_TRANSPORTATION_EDITprivate edit



    • 보안사용자, 그룹, 역할(Users, Groups and Roles)에서 Role을 부여한 계정 생성
      。이후 사용자 그룹 서비스default를 클릭 후 사용자 탭에서 새로운 사용자 추가를 통해 사전에 정의한 Role을 부여한 계정을 각각 추가.
      ▶ 해당 탭에서는 ID와 PW를 정의하여 로그인이 가능한 계정 생성이 가능.



    • 보안데이터에서 Role에 대해 데이터에 대한 권한 부여하기
      。해당 기능에서 새로운 룰 추가하기를 통해 각 작업공간의 Layer에 대해 접근할 수 있는 Role을 설정 가능.
      액세스 모드(Access mode) :
      읽기(Read) : 레이어 미리보기 만 사용 가능
      관리자(Admin) : 데이터의 모든 기능 사용 가능 ( 레이어 미리보기, 작업공간, 레이어 .. etc )




      transport_view_user , transport_edit_user는 모든 작업공간에 대해 조회가 가능하므로, *으로 설정.
      company_userpublic 작업공간에 대해 조회가 가능하므로, company으로 설정.

    • 보안서비스에서 데이터에 대한 다운로드 권한 부여하기
      새로운 룰 추가에서 다음처럼 설정.
      ▶ 해당 선택된 Role의 계정으로 Log-in 시WFS Service를 Access 할 수 있다.
      ROLE_TRANSPORTATION_VIEW의 경우 해당 WFS Service를 사용할 수 없음.
      ▶ 추가적으로 method에 관련해서도 제약을 할 수 있다.

      • ID : company_user로 로그인 할 경우 :
        。Access mode : 관리자

        보안데이터에 의해 작업공간 company의 layer에 대해 데이터의 모든 기능을 사용 가능하며 서비스에 의해 다운로드가 가능하지만 , 작업공간 transport의 layer은 access 할 수 없다.

      • ID : transport_view_user로 로그인 할 경우
        。Access mode : 읽기

        보안데이터에 의해 작업공간 companytransport의 layer 모두 레이어 미리보기를 통해 조회만 가능하지만, 서비스에 의해 다운로드가 불가능.

        GeoJSON형식으로 다운로드 시도 시 다음처럼 Ban.

      • ID : transport_edit_user로 로그인 할 경우
        。Access mode : 읽기, 쓰기


        transport_view_user와 동일하게 보안데이터에 의해 작업공간 companytransport의 layer 모두 레이어 미리보기를 통해 조회만 가능하지만 서비스에 의해 WFS 서비스 설정을 통해 다운로드가 가능.

OpenLayersWMS Server에서 생성한 WMS 활용

  • GeoServer를 통해 제공된 WMS Map Layer를 OpenLayers를 통해 표현하기
    • GeoServer레이어 미리보기에서 레이어를 OpenLayers 포맷으로 추출 후 URL을 추출.
              http://localhost:8080/geoserver/company/wms?
              service=WMS&version=1.1.0&request=GetMap&layers=company%3AIndian_States&
              bbox=68.18624899229724%2C6.755952899606655%2C97.41529266802229%2C37.078268059623326&
              width=740&height=768&srs=EPSG%3A4326&styles=&format=application/openlayers

    。 다음처럼 URL에서 해당 WMS의 정보를 확인할 수 있다.
    %3A : :를 의미 . ▶ company:Indian_States
    %2F : /를 의미.

    • WMS Layer를 TileWMS source로 받아서 Tile layer 생성 (TileWMS)
      。WMS Layer를 TileWMS source로 생성.
    var tileSource = new ol.source.TileWMS({
      url:'http://localhost:8080/geoserver/company/wms',
      params:{
        'FORMAT': 'image/png',   
        'LAYERS':'company:Indian_States',
        'VERSION': '1.1.0'
      },
      serverType:'geoserver',
    })

    。이후 Tile Layer를 생성하여 map에 표현

    var tileLayer = new ol.layer.Tile({
      source:tileSource,
      zIndex:2,
    })
    map1.addLayer(tileLayer)


    WMS 사용 시 브라우저의 Map 상에서 이동 및 scale 조정 시 그에 맞게 일일이 WMS Server에서 Tile을 생성하여 return.
    WFS를 이용하여 추가도 가능하지만, data의 큰 용량 때문에 좋지 않은 방법임.
    ▶ 큰 용량의 Tile Map은 WMS를 사용하는게 좋다.

    • WMS Layer를 ImageWMS source로 받아서 Image layer 생성 (ImageWMS)
    var imageSource = new ol.source.ImageWMS({
      url : 'http://localhost:8080/geoserver/company/wms',
      params : { 'LAYERS':'company:Indian_States' },
      serverType : 'geoserver'
    })
    var imageLayer = new ol.layer.Image({
      source : imageSource,
      zIndex : 2,
    })
    map1.addLayer(imageLayer)


    TileWMS에 비해 Image를 하나의 파일로 제공하므로 부하가 크기에 오래 걸린다.

    • CORS 관련 오류 해결
      。특정 작업공간의 Layer를 OpenLayers로 접근 시 ChromeCORB Block 오류 또는 서버 콘솔에서 geoserver warn [servlet.pagenotfound] - no mapping for get /geoserver/company/wms 오류 발생 시 작업공간에서 접근할 WMS Layer의 작업공간( ex : compnay )을 선택 후 Security 탭에서 ROLE_ANONYMOUS읽기에 대해서 액세스 권한을 부여.


  • WMS Map Layer의 속성정보 표현하기.

    。다음처럼 GeoServer의 Layer는 속성정보를 포함하며 특정 지점을 클릭 시 해당 좌표지점의 속성정보를 도출.
    OpenLayers에서 event를 생성하여 Client가 Map상에서 특정 지점을 클릭 시 GeoServer를 통해 해당 지점의 속성정보를 도출하는 기능 구현하기.
    • getFeatureInfoUrl(coordinate, resolution, projection, params) : ol/source/ImageWMS
      TileWMS , ImageWMS의 메소드
      ImageWMS객체.getFeatureInfoUrl(coordinate, resolution, projection, params)

      。WMS Request를 통해 특정 지점의 속성정보를 가져오는 함수.
      ▶ 해당 함수는 사용자가 브라우저의 Map에서 특정 지점을 클릭 시 해당 지점의 좌표, Map의 View의 zoom level 등을 기반으로 GetFeatureInfo Request URL을 생성한다.
      ▶ 생성한 URL은 서버에 전송하여 WMS Server는 특정좌표의 속성정보를 JSON, XML등의 format으로 return.

      WMS Server가 Client에 제공한 WMS Map LayerImage Layer로서 속성정보를 포함하고 있지 않지만, 해당 Image Layer의 특정 좌표를 WMS Server에 전송하면서 해당 좌표의 속성정보를 받아오는 방식임.
      • coordinate : 사용자가 click한 지점의 좌표

      • resolution : Map의 해상도.
        ▶ 보통 map객체.getView().getResolution()을 통해 현재 map 해상도를 가져옴.

      • projection : SRS를 정의.
        ▶ 보통 WMS Layer와 동일한 EPSG 코드를 지정.

      • params : WMS Request에 관련된 Parameter.
        • INFO_FORMAT : 서버에서 지원하는 Response format으로 주로 JSON, XML을 정의.
          'application/json' , 'text/xml'

        • QUERY_LAYERS :
          。WMS Map Layer의 이름을 지정.


    • map객체.on('fire옵션',트리거 함수)를 이용하여 GetFeatureInfo Request URL을 생성하는 Map interaction 생성하기.
    map1.on('click',function(evt){
      var ViewResolution = View.getResolution();
      // map1의 View 객체의 해상도를 return.
      var ClickedCoordinates = evt.coordinate;
      // Map 상의 click한 지점의 좌표를 return.
      var projection = 'EPSG:4326';
      var params = {'INFO_FORMAT':'application/json','QUERY_LAYERS':'company:Indian_States'}
      var url = imageSource.getFeatureInfoUrl(ClickedCoordinates,ViewResolution,projection,params);
      console.log(url);
    })

    imageSource : WMS Layer(company:Indian_States)를 imageWMS로 생성한 Layer 객체.

    Map 상에 특정 지점을 click 시 해당 지점의 GetFeatureInfo Request URL를 생성하여 출력.

    。해당 URL을 클릭 할 경우 다음처럼 GeoJSON 형식으로 지점에 관한 metadata가 기입된 상태로 return.

    • 생성한 GetFeatureInfo Request URL을 통해 GeoJSON을 얻은 후 Vector Layer 생성하기.
      ol.source.Vector({format:ol.format.GeoJSON(), url:url})을 통해 URL을 통해 얻은 GeoJSON으로 Vector source를 생성한다.
    map1.on('click',function(evt){
      var ViewResolution = View.getResolution();
      // map1의 View 객체의 해상도를 return.
      var ClickedCoordinates = evt.coordinate;
      // Map 상의 click한 지점의 좌표를 return.
      var projection = 'EPSG:4326';
      var params = {'INFO_FORMAT':'application/json','QUERY_LAYERS':'company:Indian_States'}
      var url = imageSource.getFeatureInfoUrl(ClickedCoordinates,ViewResolution,projection,params);
      var vectorSource = new ol.source.Vector({
        format: new ol.format.GeoJSON(),
        url:url,
      })
      var vectorLayer = new ol.layer.Vector({
        source:vectorSource,
        style: new ol.style.Style({
          fill:new ol.style.Fill({
            color:'##ff0000'
          })
        }),
        zIndex:3
      })
      map1.addLayer(vectorLayer)
    })



    • Jquery를 이용해 GetFeatureInfo Request URL의 속성정보(Properties) 표현하기
      jquery cdn : html header에 다음 코드를 기입.
    <script
      src="https://code.jquery.com/jquery-3.7.1.js"
      integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4="
      crossorigin="anonymous"></script>`

    。이후 Jquery$.getJSON()메소드를 이용하여 다음 코드를 작성.

    $.getJSON(url,function(data){
        var arrofFeatures = data.features;
        // data : JSON 객체
        // arrofFeatures : data에서 Features 객체를 배열로 추출
        if (arrofFeatures.length > 0){
          var propertiesObj = arrofFeatures[0].properties;
        // propertiesObj :  Feature객체에서 properties 객체를 배열로 추출.
        console.log('state_name : ' + propertiesObj['st_nm'])
        // properties 객체는 dictionary 형식이므로, key를 통해 value를 참조.
        } else {
          console.log('click on map')
        }
      })


    Map의 특정 지역을 click 시 GetFeatureInfo Request URL을 통해 반환된 해당 지역의 GeoJSON에서 다음처럼 properties 정보를 추출하여 콘솔에 표기.

    $.getJSON( url , callback함수 ) jQuery.getJSON
    url을 통해 비동기 HTTP GET Request를 수행하여 서버에서 JSON을 받는 역할을 수행

    • url : resource의 url ( GeoJSON을 return )
    • callback함수 : Request가 성공 시 실행되는 callback함수

      getJSONcallback함수의 매개변수

      • data : Server에서 반환된 JSON 데이터
      • textStatus : 요청 상태를 설명하는 문자열

OpenLayers에 WMS Server에서 WFS로 생성한 Vector Data 활용
GeoServer에서 레이어 미리보기를 통해 Layer를 GeoJSON format으로 배포 후 URL을 복사할 경우,
다음처럼 URL이 WFS 형식으로 지정됨.

http://localhost:8080/geoserver/company/ows?
service=WFS&version=1.0.0&request=GetFeature&typeName=company%3AIndian_States
&maxFeatures=50&outputFormat=application%2Fjson

。 이때, GeoServer에서 Layer를 WFS로 배포하는 경우 feature의 수가 많아 application의 원활한 작동을 위해 maxFeatures=50으로 feature의 수를 제한.
Feature의 수를 제한할 필요가 없는 경우 해당 구문을 url에서 삭제한다.

。해당 WFS 표준의 url을 OpenLayers로 활용 시 ol.source.Vector() , ol.layer.Vector()을 활용.

var WFSSource = new ol.source.Vector({
  format: new ol.format.GeoJSON(),
  url: 'http://localhost:8080/geoserver/company/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=company%3Adistrict&outputFormat=application%2Fjson'
})
var WFSLayer = new ol.layer.Vector({
  source:WFSSource,
  zIndex:3,
})
map1.addLayer(WFSLayer)


▶ 해당 WFS layer의 feature수가 상당히 많아 Map에서 zoom-in 등의 작용을 할 때 버벅임이 발생한다.

WFS를 활용 시 버벅임을 줄이는 방법

  • ol.loadingstrategy ol/loadingstrategy
    GeoServerWFS를 통해 layer를 GET 또는 FETCH할 경우, 항상 layer의 전체 범위의 Feature를 포함한 GeoJSON을 전달.
    zoomlevel을 높여서 MapViewport 내부에서 표현되는 범위에서의 Feature만을 포함한 GeoJSON을 GET 또는 FETCH하면서 loading 속도를 높인다.
url: function(extent){
    console.log(extent);
    return 'http://localhost:8080/geoserver/company/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=company%3Adistrict&srsname=EPSG:4326
    &bbox=' + extent.join(",") + ',EPSG:4326&outputFormat=application%2Fjson';
}

。다음처럼 url 부분에 function(extent)를 정의한 후 WFS layer의 url에 다음 구문을 추가
&srsname=EPSG:4326&bbox=' + extent.join(",") + ',EPSG:4326
extent는 해당 html element (viewport)의 [minX, minY, maxX, maxY]를 반환.
▶ 좌표계 기준 EPSG:4326bbox로 정의된 해당 영역에 대해서만 WFS url을 통해 GeoJSON을 전달받음.

var WFSSource = new ol.source.Vector({
  format: new ol.format.GeoJSON(),
  url: function(extent){
    console.log(extent);
    return 'http://localhost:8080/geoserver/company/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=company%3Adistrict&srsname=EPSG:4326&bbox=' + extent.join(",") + ',EPSG:4326&outputFormat=application%2Fjson';
   },
   strategy : ol.loadingstrategy.bbox
})

。해당 함수를 이용해 정의할 경우 ol.source.Vector()의 생성자에 strategy:ol.loading.strategy.bbox를 추가 정의.
strategyol.loadingstrategy.all을 통해 전체범위의 GeoJSON를 FETCH하는 방식이 default이지만, 최적화를 위해 bbox를 정의하여 strategyol.loadingstrategy.bbox로 정의하여 해당 viewport 범위에 대해서만 GeoJSON을 FETCH.

。높은 zoomlevel에서의 viewport 내부범위만 정의한 URL을 GeoServer에 전달하여 받은 GeoJSON의 상대적으로 적은 수의 Feature에 대해서만 Vector Source를 통해 Vector Layer가 생성되어 표현되므로 버벅임이 상대적으로 많이 사라졌다.
▶ 반면 낮은 zoomlevel에서 viewport내 표현되는 Feature 수가 많아지므로 버벅임이 증가한다.

  • CORS오류가 발생하는 경우
    。크롬브라우저에 CORS Unblock을 설치.
profile
공부기록 블로그

0개의 댓글