Line aliasing in an optimized map service

The graphics pipeline used in ArcMap and the standard map service is based on Microsoft's Graphics Device Interface (GDI) technology. One of the limitations of this technology is that graphics can only be represented by integer coordinates. Real-world geometry does not typically occur only on whole numbers, so the coordinates would be rounded up or down when they are drawn using this graphics pipeline. This can be seen in vector export formats such as PDF—vector lines can contain some stair-stepping when they are closely inspected.

The graphics pipeline used by basemap layers and optimized map services can use the true noninteger coordinates of your geometry and can render with subpixel precision, resulting in greater accuracy in these vector formats. However, when these features are drawn to raster formats such as PNG or BMP, the geometries must be again rounded to render on a pixel at the requested resolution. At low resolutions, this can result in some aliasing with multilayer line symbols, such as cased road symbols.

Line aliasing in ArcMap and in the optimized map service
An example of aliasing due to more precise rendering (left: optimized map service, right: ArcMap)

The optimized map service is capable of applying anti-aliasing to alleviate the effects of the above issue, but there are some cases in which anti-aliasing is not the most optimal option. For example, utilizing anti-aliasing can reduce the performance of an optimized map service. Depending on the requirements of the service, this may be unacceptable. Also, for target formats that use an eight-bit palette (such as PNG 8 or GIF formats), anti-aliasing may not be as effective due to the dithering required to render continuous progressions of color. Note that anti-aliasing is not available for basemap layer drawing.

A comparison between aliased drawing and anti-aliased drawing
Anti-aliasing can greatly improve a line's appearance, but at the cost of performance. (Left: no Anti-Aliasing, Right, Best Anti-Aliasing)

To alleviate this issue without utilizing anti-aliasing, the Prepare window has an analyzer that will detect multilayer line symbols that could potentially exhibit this problem.

There are two solutions for this analyzer: the first is to flag this layer for automatic adjustment of line sizes upon conversion. When the map document is converted into a map service definition (MSD) file, the line widths of layers for which this option is enabled will be automatically changed to ensure that they will render consistently at 96 dpi or higher. The size of the symbol in the MXD will remain the same. For most users, this solution will be sufficient. Check the Preview window to ensure that the appearance of the corrected line meets your expectations. Note that this analyzer will not appear for basemap layers because automatic adjustment is always chosen for this case.

Line aliasing before and after fix
Left: Original line widths of the expressway symbol rendered in optimized map service; Right: After correction. Note that the casing lines no longer appear dashed in the corrected version.

An alternative solution would be to manually change the structure of the multilayer line symbol so that the line sizes are more appropriate. This also allows conversion for use with a target dpi other than 96 dpi (for instance, 72 dpi).

Designing lines for a specific resolution (dpi)

To determine the appropriate line sizes for a given resolution, input the sizes of each of the symbols in the multilayer line symbol into the following formulas. As discussed before, the value for TargetResolution should reflect the desired minimum resolution at which this symbol will be used.

WidthInPixels = (LineWidth in points * TargetResolution in dpi)/72

If the WidthInPixels is less than 1.5, the width should not be changed.

If the WidthInPixels is equal to or greater than 1.5, use the following formula to determine the edited width:

  1. NewWidthInPoints = (WidthInPixels + 0.5)
  2. Now round NewWidthInPoints to the nearest integer (whole number) value that is not greater than NewWidthInPoints.
  3. The final line width should be set to the (RoundedNewWidthInPoints * 72)/TargetResolution.

So, for example, if your desired resolution is 44 dpi, and your line symbol's width is 2.60, the math would be executed as follows:

  1. WidthInPixels = (2.60 * 44)/72.0.
  2. WidthInPixels is 1.5888888, which is greater than 1.5, so continue:
  3. NewWidthInPoints = (1.588888 + 0.5) = 2.10.
  4. Rounding down, NewWidthInPoints = 2.0.
  5. The final line width should be set to (2.0 * 72)/44 = 3.27 pts.

In another example, if your desired resolution is 120 dpi, and your new line symbol's width is 2.60, the math would be executed as follows:

  1. WidthInPixels = (2.60 * 120)/72.
  2. WidthInPixels is 4.33333, which is greater than 1.5, so continue:
  3. NewWidthInPoints = (4.33333 + 0.5) = 4.83.
  4. NewWidthInPoints is rounded down to the nearest integer, 4.0.
  5. The final line width should be set to (4.0 * 72)/120 = 2.4 pts.

Related Topics