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 전용 레이어 불러오기 기능 추가