mxd to SLD – ArcMap2SLD


ArcMap2SLD screenshot
Fig 1 – ArcMap2SLD tool running with ArcMap 9.3

I had some more time to work out the ArcMap2SLD script tool.

Using an mxd in ArcMap 9.3, I first made sure all of my shape layers were connected. Then I ran the ArcMap2SLD tool which requires a session of ArcMap to be running.

This is a simple ArcMap project with a set of shp layers. It takes about 5-10 minutes to run through all the layers. The analysis seems to read through each symbol in a layer and then to loop through every record. After a few minutes it asks again for a file to store the sld and now the test.sld is ready.

The resulting SLD is a single file with all of the Feature types and rules listed together:

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<sld:StyledLayerDescriptor version="1.0.0"
xmlns:sld="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xlink="http://www.w3.org/1999/xlink">
  <sld:NamedLayer>
    <sld:Name>ovroads</sld:Name>
    <sld:UserStyle>
      <sld:Name>Style1</sld:Name>
      <sld:FeatureTypeStyle>
        <sld:FeatureTypeName>ovroads</sld:FeatureTypeName>
        <sld:Rule>
          <sld:Name>Interstates</sld:Name>
          <sld:Title>Interstates</sld:Title>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>RDCLS</ogc:PropertyName>
              <ogc:Literal>010</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-opacity">1</sld:CssParameter>
            </sld:Stroke>
          </sld:LineSymbolizer>
          <sld:LineSymbolizer>
            <sld:Stroke>
              <sld:CssParameter name="stroke">#FFFB86</sld:CssParameter>
              <sld:CssParameter name="stroke-width">2.6</sld:CssParameter>
              <sld:CssParameter name="stroke-opacity">1</sld:CssParameter>
            </sld:Stroke>
          </sld:LineSymbolizer>
          <sld:LineSymbolizer>
            <sld:Stroke>
              <sld:CssParameter name="stroke">#000000</sld:CssParameter>
              <sld:CssParameter name="stroke-width">3.4</sld:CssParameter>
              <sld:CssParameter name="stroke-opacity">1</sld:CssParameter>
            </sld:Stroke>
          </sld:LineSymbolizer>
        </sld:Rule>
            .
            .

Copying a subset for the roads layer into GeoServer style did not produce any features the first time around.

First the Filter PropertyName is case sensitive. The loading batch I used produces lower case field names in the PostGIS tables. As a result the RDCLS property name had to be changed to rdcls through out the SLD.

If you notice in the above SLD output, the Geometry reference is missing:
    <Geometry><ogc:PropertyName>the_geom</ogc:PropertyName></Geometry>

Also missing are scale elements:
    <MinScaleDenominator>32000</MinScaleDenominator>
    <MaxScaleDenominator>20000000</MaxScaleDenominator>

After the necessary modification the SLD rules look like this:

        <Rule>
          <Name>U S Highways</Name>
          <Title>U S Highways</Title>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>rdcls</ogc:PropertyName>
              <ogc:Literal>014</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <MinScaleDenominator>32000</MinScaleDenominator>
          <MaxScaleDenominator>20000000</MaxScaleDenominator>
          <LineSymbolizer>
            <Geometry>
              <ogc:PropertyName>the_geom</ogc:PropertyName>
            </Geometry>
            <Stroke>
              <CssParameter name="stroke">#FA3411</CssParameter>
              <CssParameter name="stroke-width">3.4</CssParameter>
              <CssParameter name="stroke-opacity">1</CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>

This still requires some manual intervention, but it does handle setting Filters, stroke color, stroke-width, and stroke-opacity parameters with a text editor along with cut & paste. It handled the PolygonSymbolizer in the mxd as well.

This is a time saver, however, the appearance didn’t seem to match in the resulting SLD tilesources. It appears as though some of the SLD stroke widths end up masking underlying strokes so that for example the purple highway symbolization does not appear in the SLD tilesource version.

ArcMap2SLD screenshot
Fig 2 – Silverlight tile source with new SLD

After some examination I realized that multiple LineSymbolizations were in reverse order. The thickest line width needs to be first with thinner stroke widths later in the SLD file, because rendering is in file order. Here is an example of the final resulting SLD LineSymbolization with corrected ordering:

        <Rule>
          <Name>Boulder Turnpike</Name>
          <Title>Boulder Turnpike</Title>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>rdcls</ogc:PropertyName>
              <ogc:Literal>016</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <MinScaleDenominator>32000</MinScaleDenominator>
          <MaxScaleDenominator>20000000</MaxScaleDenominator>
          <LineSymbolizer>
            <Geometry><ogc:PropertyName>the_geom</ogc:PropertyName></Geometry>
            <Stroke>
              <CssParameter name="stroke">#000000</CssParameter>
              <CssParameter name="stroke-width">3.4</CssParameter>
              <CssParameter name="stroke-opacity">1</CssParameter>
            </Stroke>
          </LineSymbolizer>

          <LineSymbolizer>
            <Geometry><ogc:PropertyName>the_geom</ogc:PropertyName></Geometry>
            <Stroke>
              <CssParameter name="stroke">#FFFB86</CssParameter>
              <CssParameter name="stroke-width">2.6</CssParameter>
              <CssParameter name="stroke-opacity">1</CssParameter>
            </Stroke>
          </LineSymbolizer>

          <LineSymbolizer>
            <Geometry><ogc:PropertyName>the_geom</ogc:PropertyName></Geometry>
            <Stroke>
              <CssParameter name="stroke">#000000</CssParameter>
              <CssParameter name="stroke-width">0.8</CssParameter>
              <CssParameter name="stroke-opacity">1</CssParameter>
            </Stroke>
          </LineSymbolizer>
        </Rule>

ArcMap2SLD screenshot
Fig 3 – Silverlight tile source with new SLD with corrected order

Summary

This tool appears to be a helpful start for translating mxd style to sld. The result gives colors and basic widths etc but requires several modifications:

  1. match case to the PostGIS table
  2. add Geometry elements
  3. add min and max scale denominators
  4. reverse order of multiple LineSymbolizations

It’s still a good start.

Comments are closed.