2012년 2월 26일 일요일

OGC SLD Converter for ArcGIS

자체 프로젝트로 진행된 ArcMap에서 설정한 레이어의 렌더러 + 심볼을 OGC SLD 포맷으로 변환하는 도구 구현 결과물
ArcObjects의 Symbol 인터페이스 및 SLD에 대해 다시한번 공부할 수 있어서 의미 있는 프로젝트였음

▣ 관련 내용
 - ArcGIS to SLD(Styled Layer Descriptor) 기능정의
 - SLD(Styled Layer Descriptor) Converter & Editor?
 - [GeoTools]Filter Encoding Quick Reference
 - GeoServer & SLD(Styled Layer Descriptor)
▣ OGC SLD Converter for ArcGIS
 - GeoServer : SLD 1.0.0 + Vendor Option
 - ArcGIS 10 + .NET C# + Custom ICommand 구현
 - 처음 기능정의에서 Drop shadow 등의 효과 추가

 - download sample sld : http://www.mediafire.com/?77av7f4fh00ezxv
▣ ArcGIS + GeoServer
아래 이미지에서 OpenLayers Control이 있는 이미지는 GeoServer에서 미리보기한 이미지임
▣ 다양한 심볼
stroke-dasharray를 이용한 철도심볼(++++)의 표현
<sld:Rule>
  <sld:Name>108</sld:Name>
  <sld:Title>108</sld:Title>
  <sld:MaxScaleDenominator>60000</sld:MaxScaleDenominator>
  <ogc:Filter>
    <ogc:PropertyIsEqualTo>
      <ogc:PropertyName>road_rank</ogc:PropertyName>
      <ogc:Literal>108</ogc:Literal>
    </ogc:PropertyIsEqualTo>
  </ogc:Filter>
  <sld:LineSymbolizer>
    <sld:Stroke>
      <sld:CssParameter name="stroke">#000000</sld:CssParameter>
      <sld:CssParameter name="stroke-width">0.8</sld:CssParameter>
      <sld:CssParameter name="stroke-linejoin">round</sld:CssParameter>
    </sld:Stroke>
  </sld:LineSymbolizer>
  <sld:LineSymbolizer>
    <sld:Stroke>
      <sld:CssParameter name="stroke">#000000</sld:CssParameter>
      <sld:CssParameter name="stroke-width">4</sld:CssParameter>
      <sld:CssParameter name="stroke-dasharray">0 7 1 7</sld:CssParameter>
      <sld:CssParameter name="stroke-dashoffset">0</sld:CssParameter>
    </sld:Stroke>
  </sld:LineSymbolizer>
</sld:Rule>
▣ Drop shadow + Label

건물에 대한 drop shadow 효과
<sld:Rule>
  <sld:Name>Drop shadow effect</sld:Name>
  <sld:Title>Drop shadow effect</sld:Title>
  <sld:MaxScaleDenominator>15000</sld:MaxScaleDenominator>
  <sld:PolygonSymbolizer>
    <sld:Geometry>
      <ogc:Function name="offset">
        <ogc:PropertyName>the_geom</ogc:PropertyName>
        <ogc:Literal>1</ogc:Literal>
        <ogc:Literal>-2.5</ogc:Literal>
      </ogc:Function>
    </sld:Geometry>
    <sld:Fill>
      <sld:CssParameter name="fill">#6E6E6E</sld:CssParameter>
    </sld:Fill>
  </sld:PolygonSymbolizer>
</sld:Rule>
<sld:Rule>
  <sld:MaxScaleDenominator>15000</sld:MaxScaleDenominator>
  <sld:PolygonSymbolizer>
    <sld:Fill>
      <sld:CssParameter name="fill">#E1E1E1</sld:CssParameter>
    </sld:Fill>
    <sld:Stroke>
      <sld:CssParameter name="stroke">#6E6E6E</sld:CssParameter>
      <sld:CssParameter name="stroke-width">0.4</sld:CssParameter>
    </sld:Stroke>
  </sld:PolygonSymbolizer>
</sld:Rule>
▣ PointSymbolizer - Marker Symbol
Picture Marker Symbol은 ExternalGraphic으로 저장
<sld:PointSymbolizer>
  <sld:Graphic>
    <sld:Mark>
      <sld:WellKnownName>circle</sld:WellKnownName>
      <sld:Fill>
        <sld:CssParameter name="fill">#9A7BB8</sld:CssParameter>
      </sld:Fill>
      <sld:Stroke>
        <sld:CssParameter name="stroke">#000000</sld:CssParameter>
        <sld:CssParameter name="stroke-width">1</sld:CssParameter>
      </sld:Stroke>
    </sld:Mark>
    <sld:Size>
      <ogc:Literal>13</ogc:Literal>
    </sld:Size>
  </sld:Graphic>
</sld:PointSymbolizer>
Simple Marker Symbol은 WellKnownName 설정
<sld:PointSymbolizer>
  <sld:Graphic>
    <sld:Mark>
      <sld:WellKnownName>circle</sld:WellKnownName>
      <sld:Fill>
        <sld:CssParameter name="fill">#9A7BB8</sld:CssParameter>
      </sld:Fill>
      <sld:Stroke>
        <sld:CssParameter name="stroke">#000000</sld:CssParameter>
        <sld:CssParameter name="stroke-width">1</sld:CssParameter>
      </sld:Stroke>
    </sld:Mark>
    <sld:Size>
      <ogc:Literal>13</ogc:Literal>
    </sld:Size>
  </sld:Graphic>
</sld:PointSymbolizer>
GeoServer는 현재 SLD 1.1 버전을 완전히 지원하지 않기 때문에 Character Marker Symbol은 WellKnownName에 ttf://폰트명#폰트인덱스 형식으로 사용
<sld:PointSymbolizer>
  <sld:Graphic>
    <sld:Mark>
      <sld:WellKnownName>ttf://ESRI Default Marker#0x0021</sld:WellKnownName>
      <sld:Fill>
        <sld:CssParameter name="fill">#FFFF00</sld:CssParameter>
      </sld:Fill>
    </sld:Mark>
    <sld:Size>
      <ogc:Literal>17</ogc:Literal>
    </sld:Size>
  </sld:Graphic>
</sld:PointSymbolizer>

Arrow Marker Symbol은 ExternalGraphic으로 저장하며 Picture Marker Symbol 참조
▣ LineSymbolizer - Line Symbol
Simple Line Symbol은 solid, dash, dash-dot, dash-dot-dot 등을 stroke-dasharray로 처리하며 위 [다양한 심볼] 예 참조
Cartographic Line Symbol은 stroke-dasharray로 처리하며 위 [다양한 심볼] 예 참조
Hash Line Symbol은 stroke-dasharray로 처리하며 위 [다양한 심볼] 예 참조
Multiple Layers는 sld에 각 라인심볼에 대한 Rule을 누적
▣ PolygonSymboizer - Polygon(Fill) Symbol
 - Fill 심볼은 Fill과 Stroke로 구성되며 위 Line/Marker 심볼 지원과 동일하므로 생략
 - Simple PolygonSymbolizer 예
<sld:FeatureTypeStyle>
  <sld:Name>Simple Renderer</sld:Name>
  <sld:Title>Simple Renderer</sld:Title>
  <sld:Rule>
    <sld:PolygonSymbolizer>
      <sld:Fill>
        <sld:CssParameter name="fill">#00A9E6</sld:CssParameter>
      </sld:Fill>
      <sld:Stroke>
        <sld:CssParameter name="stroke">#6E6E6E</sld:CssParameter>
        <sld:CssParameter name="stroke-width">0</sld:CssParameter>
        <sld:CssParameter name="stroke-opacity">0</sld:CssParameter>
      </sld:Stroke>
    </sld:PolygonSymbolizer>
  </sld:Rule>
</sld:FeatureTypeStyle>
▣ 지원대상 렌더러
- Simple Renderer, Unique Value Renderer, Classbreaks Renderer, Graduated Symbol Renderer 지원
- IProportionalSymbolRenderer, IBivariateRenderer, IDotDensityRenderer, IChartRenderer 미지원
위 예는 폴리곤 레이어의 인구 필드값을 이용하여 Graduated Symbol로 처리하며 각 급간은 Between Filter를 사용
Background 심볼 및 라벨 처리 지원하며 라벨은 Halo 지원
<sld:Rule>
  <sld:Name>Background Symbol</sld:Name>
  <sld:Title>Background Symbol</sld:Title>
  <sld:PolygonSymbolizer>
    <sld:Fill>
      <sld:CssParameter name="fill">#F5F5DC</sld:CssParameter>
    </sld:Fill>
    <sld:Stroke>
      <sld:CssParameter name="stroke">#4E4E4E</sld:CssParameter>
      <sld:CssParameter name="stroke-width">0.4</sld:CssParameter>
    </sld:Stroke>
  </sld:PolygonSymbolizer>
</sld:Rule>
<sld:Rule>
  <sld:Name>130362.000000 - 247320.000000</sld:Name>
  <sld:Title>130362.000000 - 247320.000000</sld:Title>
  <ogc:Filter>
    <ogc:PropertyIsBetween>
      <ogc:PropertyName>pop2008</ogc:PropertyName>
      <ogc:LowerBoundary>
        <ogc:Literal>130362</ogc:Literal>
      </ogc:LowerBoundary>
      <ogc:UpperBoundary>
        <ogc:Literal>247320</ogc:Literal>
      </ogc:UpperBoundary>
    </ogc:PropertyIsBetween>
  </ogc:Filter>
  <sld:PointSymbolizer>
    <sld:Graphic>
      <sld:Mark>
        <sld:WellKnownName>circle</sld:WellKnownName>
        <sld:Fill>
          <sld:CssParameter name="fill">#FF0000</sld:CssParameter>
        </sld:Fill>
        <sld:Stroke>
          <sld:CssParameter name="stroke">#FFFFFF</sld:CssParameter>
          <sld:CssParameter name="stroke-width">2</sld:CssParameter>
        </sld:Stroke>
      </sld:Mark>
      <sld:Size>
        <ogc:Literal>6.5</ogc:Literal>
      </sld:Size>
    </sld:Graphic>
  </sld:PointSymbolizer>
</sld:Rule> .............이후 생략
▣ TextSymbolizer - Label
Multiple Annotation class 및 Simple expression 지원
GeoServer VendorOption을 주석처리하여 사용자가 옵션을 변경해 볼 수 있도록 함
<sld:Rule>
  <sld:Name>Label - Default</sld:Name>
  <sld:Title>Label - Default</sld:Title>
  <sld:MaxScaleDenominator>30000</sld:MaxScaleDenominator>
  <sld:TextSymbolizer>
    <sld:Label><ogc:PropertyName>nam2</ogc:PropertyName></sld:Label>
    <sld:Font>
      <sld:CssParameter name="font-family">맑은 고딕</sld:CssParameter>
      <sld:CssParameter name="font-style">normal</sld:CssParameter>
      <sld:CssParameter name="font-weight">normal</sld:CssParameter>
      <sld:CssParameter name="font-size">11.7</sld:CssParameter>
    </sld:Font>
    <sld:LabelPlacement>
      <sld:PointPlacement>
        <sld:AnchorPoint>
          <sld:AnchorPointX>0.5</sld:AnchorPointX>
          <sld:AnchorPointY>0</sld:AnchorPointY>
        </sld:AnchorPoint>
        <sld:Displacement>
          <sld:DisplacementX>0</sld:DisplacementX>
          <sld:DisplacementY>10</sld:DisplacementY>
        </sld:Displacement>
      </sld:PointPlacement>
    </sld:LabelPlacement>
    <sld:Halo>
      <sld:Radius>1.3</sld:Radius>
      <sld:Fill>
        <sld:CssParameter name="fill">#FFFFFF</sld:CssParameter>
      </sld:Fill>
    </sld:Halo>
    <sld:Fill>
      <sld:CssParameter name="fill">#228B22</sld:CssParameter>
    </sld:Fill>
    <!--<VendorOption name="followLine">true</VendorOption>-->
    <!--<VendorOption name="maxAngleDelta">90</VendorOption>-->
    <!--<VendorOption name="maxDisplacement">400</VendorOption>-->
    <!--<VendorOption name="labelAllGroup">true</VendorOption>-->
    <!--<VendorOption name="repeat">150</VendorOption>-->
    <!--<VendorOption name="autoWrap">50</VendorOption>-->
    <!--<VendorOption name="forceLeftToRigth">false</VendorOption>-->
    <!--<VendorOption name="conflictResolution">false</VendorOption>-->
    <!--<VendorOption name="goodnessOfFit">0.3</VendorOption>-->
    <!--<VendorOption name="polygonAlign">mbr</VendorOption>-->
    <!--<VendorOption name="group">yes</VendorOption>-->
    <!--<VendorOption name="spaceAround">10</VendorOption>-->
  </sld:TextSymbolizer>
</sld:Rule>
▣ RasterSymbolizer
▣ PostGIS Query Layer
ArcGIS 10 버전 이후부터 Query Layer를 지원하나 여러 레이어를 한번에 불러 볼 수 있도록 PostGIS 전용 레이어 불러오기 기능 추가

2012년 2월 22일 수요일

ArcGIS to SLD(Styled Layer Descriptor) 기능정의

ArcMap의 레이어를 SLD(Styled Layer Descriptor) 파일로 내보내기 위한 도구 개발

SLD 변환도구 이전글: SLD(Styled Layer Descriptor) Converter & Editor? 참조

▣ SLD 지원 대상
 - GeoServer : SLD 1.0.0 + Vendor Option
 - ArcGIS 10 + .NET C# + Custom ICommand 구현

▣ GeoServer에서의 SLD 지원 현황
 - 현재 GeoSErver에서 SLD 인코딩은 ISO-8859-1을 사용하며 utf-8로 저장 후 GeoServer Administrator 페이지에서 Style을 수정하는 경우 헤더 부분 및 한글이 깨지는 현상 발생
 - 그러나 저장 후 GeoServer Data Directory의 styles 폴더에서 sld를 열고 한글 입력 후 재실행하면 작동은 함
   - <?xml version="1.0" encoding="ISO-8859-1"?>
   - <?xml version="1.0" encoding="utf-8"?>
 - GeoServer의 Styling(http://docs.geoserver.org/stable/en/user/styling/index.html) user guide를 분석하여 Vendor Option 등을 확인

 - Arc2Earth 도구를 이용하여 각각의 렌더러 및 심볼 지원 벤치마킹
   - 테스트 결과 부분적으로 GeoServer에서 오류 발생

▣ 기능 정의
 - 저장할 파일의 인코딩 선택
 - Point Symbol일 경우 아이콘(ExternalGraphic, png)로 저장할 수 있는 옵션 선택
 - 아이콘으로 저장할 경우 아이콘 크기 설정: 16 * 16, 32 * 32, 또는 SLD에 설정된 Graphic 크기
 - 라벨이나 Filter 사용시 필드 이름 선택: Normal, UpperCase, LowerCase
 - 저장할 레이어 이름에 prefix 설정 가능
 - 저장파일의 확장자 설정 : .sld 또는 .xml
 - SLD 버전 선택 : 현재 1.0.0이지만 향후 확장 고려
 - 내보내기할 레이어는 사용자가 선택하고 배치로 내보낼 수 있어야 함
 - 지원하지 않는 렌더러(Feature Rendere 또는 Raster Renderer)는 로그 작성
 - 지원하지 않는 심볼이나 대체되는 심볼 역시 로그 작성

▣ User Interface

[GeoTools]Filter Encoding Quick Reference

SLD Converter 구현 중에 Filter Encoding이 포함되어 있어 간략하게나마 Filter Encoding을 도식화해 보았다.

SLD 변환도구는 이전글: SLD(Styled Layer Descriptor) Converter & Editor? 참조

현재  OGC Filter Encoding 표준은 2.0 버전이 최신이지만 GeoTools에서는 Filter 1.0, Filter 1.1을 지원하고 있다.
▣ Filter
▣ BinaryLogicOperator
▣ BinaryComparisonOperator
▣ SpatialOperator
▣ 참고
 - http://docs.geotools.org/latest/userguide/library/opengis/filter.html

GeoServer & SLD(Styled Layer Descriptor)

현재 GeoToolsGeoServer는 공식적으로는 SLD version 1.0.0을 지원하고 있다고 하지만 SLD 1.0, 1.1, GeoServer옵션(Vendor 옵션)을 함께 사용하고 있다.

SLD Converter 구현을 위해서 간략하게 SLD를 정리해 보았다.
SLD 변환도구는 이전글: SLD(Styled Layer Descriptor) Converter & Editor? 참조

▣ SLD의 기본 구조
예)
<?xml version="1.0" encoding="utf-8"?>
<sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" version="1.0.0">
  <sld:NamedLayer>
    <sld:Name>firestation</sld:Name>
    <sld:UserStyle>
      <sld:Name>firestation</sld:Name>
      <sld:FeatureTypeStyle>
        <sld:Name>Simple Renderer</sld:Name>
        <sld:Title>Simple Renderer</sld:Title>
        <sld:Rule>
          <sld:PointSymbolizer>
            <sld:Graphic>
              <sld:Mark>
                <sld:WellKnownName>square</sld:WellKnownName>
                <sld:Fill>
                  <sld:CssParameter name="fill">#FF0000</sld:CssParameter>
                </sld:Fill>
              </sld:Mark>
              <sld:Size>
                <ogc:Literal>8</ogc:Literal>
              </sld:Size>
            </sld:Graphic>
          </sld:PointSymbolizer>
        </sld:Rule>
      </sld:FeatureTypeStyle>
    </sld:UserStyle>
  </sld:NamedLayer>
</sld:StyledLayerDescriptor>
▣ Symbolizer의 종류
Symbolizer는 PointSymbolizer, LineSymbolizer, PolygonSymbolizer, TextSymbolizer, RasterSymbolizer로 구성
▣ Graphic, Stroke, Fill Symbol
 - 모든 심볼은 Opacity 속성을 이용해서 투명도를 조절할수 있음(0~1값이며 0은 투명)
 - Graphic은 Point, Stroke는 Line, Fill은 Polygon을 표현하며
 - Graphic은 여러개의 GraphicalSymbol을 가질 수 있으며 Mark와 ExternalGraphic으로 분류
 - GeoServer에서 WellKnownName("square", "circle", "triangle", "star", "cross", "x") 외에  shape, ttf 확장이 가능하다.
 - http://2010.foss4g.org/presentations/3588.pdf 참조
▣ RasterSymbolizer 구성요소
 - ColorMap은 여러개의 ColorMapEntry를 가질 수 있음
 - 현재 GeoServer에서는 ChannelSelection, ContrastEnhancement, ColorMap만 지원하며, ImageOutline, OverlapBehavior, ShadedRelief은 미지원
▣ TextSymbolzier 구성요소
- TextSymbolizer는 Label(하나 또는 여러 필드의 조합), Font, Halo, Label의 위치 등을 설정할 수 있음
 - LabelPlacement는 PointPlacement와 LinePlacement로 구성됨
 - PointPlacement는 일반적으로 포인트와 폴리곤의 라벨을 처리하며 Rotation을 설정해서 회전이 가능
 - LinePlacement는 라인 피쳐의 라벨리에 사용되며 GeoServer에서는 이 외 다양한 Vendor 옵션이 있음
▣ 참고
 - http://www.opengeospatial.org/standards/sld
 - http://docs.geotools.org/latest/userguide/library/opengis/se.html
 - http://docs.geoserver.org/stable/en/user/styling/index.html