MapDotNet UX Help

Overview of the Map Model

MapDotNet UX uses a map model that leverages XAML.  The map model uses classes in ISC.MapDotNetServer.Common and ISC.MapDotNetServer.Common.Maps.  Note that the contents of these namespaces are slightly different under Silverlight.  These differences will be discussed where applicable.

Maps are generally created using MapDotNet Studio.  Maps are represented in code by the map model, which may be manipulated for runtime changes to map displays.

The Map Request

The most common use for the map model is to request a map.  This is done through the MapRequest class.  If you are working directly with a map service (MapService.svc) through a client proxy, you will serialize a MapRequest and pass it to one of the GetMap methods.  In this case you will need to deserialize and handle the MapResponse yourself.  If you are using the RIM controls, the Descriptor for a TileLayer that uses an MDNSMapTileRequestor will be a MapRequest.  Note: if the RIM map is set up declaratively, the Descriptor in the markup is a string.  It is not available as a MapRequest until the RIM Map's TileLayerSetupComplete event occurs.

Properties of the MapRequest class include:

  • Map - this is the map object itself. 
  • RequestEnvelope - this is the area to be rendered, in map units. If a TileLayer is used, the TileLayer sets this property. If the MapService is used directly, be sure to check the MapResponse.ResponseEnvelope property, as the area that is actually rendered will be expanded if the request envelope does not have the same aspect ratio as the requested image.
  • ImageType - the type of image to return, options are GIF, JPEG, and PNG.
  • ImageWidth, ImageHeight - the dimensions of the image rendered, in pixels. If a TileLayer is used, the TileLayer sets this property.
  • ImageDPI - the "dots per inch" value to assume, defaults to 96.
  • BleedRatio - if greater than one, a ratio to expand the map area and image size by for rendering. The image returned is clipped from the center of the larger image. This is important when using tiled images to capture labels and point symbols that fall near tile boundaries. Even when using an ImageTilingFactor, you must set an appropriate value.
  • ImageTilingFactor - a value greater than one indicates that the image should be sliced up into an array of smaller images. The image is cut into ImageTilingFactor rows * ImageTilingFactor columns and ordered row by row.
  • Overlay - an image to overlay on top of the rendered map image.

The MapRequest has an instance method, Serialize, that serializes the request to a string. Under Silverlight there is only one version, but otherwise there are two. You should always use the method that takes the simplifyBaselineLayers argument and set it to true. This will significantly reduce the size of the serialized request.

The Map

The map object represents a map as a collection of Layers that reference a data source and have rendering instructions. The most common use of the map is within a MapRequest. Map layers can be modified to change how a map will be rendered.  If you are using the RIM controls, use the TileLayer.NotifyDescriptorChange() method to refresh the map display after making edits to the Map, map Layers, or layer Classifications.

Properties of the Map class include:

  • Units - indicates the unit of measure applicable to the map, i.e. feet, meters, or degrees. This must be appropriate to the projection. If the units are wrong, map scale computations will be invalid.
  • Projection - a reference to the coordinate system the map is displayed in. Data from layers in different projections will be transformed for correct display.
  • InitialExtents - the recommended area to display when the map is initially viewed.
  • BackgroundColor - the color to use for any part of the map where no features are rendered.
  • ID - the map ID used to refer to it in the map service.
  • Metadata - a collection of arbitrary name/value pairs. You can use this to include information useful to your applications.
  • Error - service methods that return a map will set this with an appropriate message if the map cannot be returned for some reason.
  • Layers - collection of Layer objects included in this map. Note that when a Map is used in a MapRequest, you can modify this collection or the individual Layers. New Layers should have IDs that are unique within the map.
  • Maximum Extents - an optional envelope that indicates the area from which features will be rendered.  There are two ways this may be used.
    • Set to world bounds in the map's projection, it prevents the renderer from generating queries with search envelopes that exceed world bounds.  Such envelopes can have unexpected results, particularly when the data is in different coordinate systems.  The templates used in Studio use MaximumExtents in this way.
    • Set to smaller bounds, it can limit features rendered to a particular geographical region.
    In either case, the limit is applied only to rendering, not to queries through the feature service.
  • MinimumBleedRatio - you can specify a minimum bleed ratio that will override a smaller bleed ratio in a MapRequest.  Bleed ratios are used to overfetch tile data to avoid clipping marker symbols or labels near the edge of tiles.  The recommended value is 1.0 + ([largest dimension of largest point symbol] / 128.0).  Maps with labeling will need even larger values.
  • TestForCrossingMaximumExtents - if this is true and MaximumExtents is set, the renderer will attempt to check whether shapes cross the edges of the extents.  To use this, the extents should be world bounds, therefore this is testing whether shapes cross the antimeridian (180th meridian). 
    A shape is assumed to cross if it is wider than half the world but less than the full width of the world.  The test is applied to the individual parts of multi-shapes.  This corrects common problems rendering geographic features that cross the antimeridian, but a side effect is that shapes greater than half the width of the world cannot be correctly rendered.  This is set true in the templates used in Studio.  

Map Layers

The Layer object references a source of spatial data and has instructions for rendering this data.
Properties of the Layer class include:

  • ConnectionSpecification - this is a ConnectionDataSourceSpecification object (defined in the Common library) that has the actual information about the data source. Properties include:
    • ConnectionType - the type of data source
    • Connection - a connection string. This is left blank when a Map is obtained using the GetBaselineMapDescriptionState method. When creating a new Layer you must specify this.
    • DataTable - the table or file that contains the data.
    • GeometryColumn - the column with spatial data.
    • Type - the WKT type of the geometry column.
    • Projection - the coordinate system the layer data is in.
    • WhereClause - optional attribute filtering for a data layer.
  • ID - the name of the layer, which must be unique within the map.
  • Visible - indicates whether the layer is rendered.
  • MinScale, MaxScale - the minimum and maximum scales at which the layer should be rendered. Use -1 for either to indicate that scale is not limited in that direction.
  • LayerState - Baseline indicates that the layer should be used in its baseline state. When a MapRequest is simplified during serialization, only the ID and Visible properties are serialized. If the Layer has had any property modified other than the value of Visible, this property should be set to Modified.
  • LabelColumn - a table column to use for labeling, if desired.
  • ClassificationColumn - a table column to classify by. See the Classification properties ExactValue, MinRange, and MaxRange properties below.
  • LineColorColumn, FillColorColumn - columns used to set line or fill colors from data.  The column may be a string column with hexadecimal values preceded by "#", or the column may be an integer column.  These columns are ignored for any layer classification that has UseStylePropertyDataColumns set false.  They are also ignored for any line or fill brushes that are not of the SolidColorBrush type.
  • Metadata - a collection of arbitrary name/value pairs. You can use this to include information useful to your applications.
  • Classifications - a collection of Classifications indicating how this layer is rendered.
  • DefaultClassificationStyle - a RenderStyle object that is used to provide default values for Classification.Style properties that are not set. If there are no Classifications, a single classification using this style is assumed. If a Classification has no style, this is used. When used with multiple Classifications, this allows only the properties that change to be set in each Classification's Style property.

Layer Classifications

Classifications contain rendering instructions for a layer. A Classification includes details about when a classification is applicable, as well as the actual rendering style.
Properties of the Classification class include:

  • ID - the name of a classification. This should be unique at a given scale, but two classifications that apply at scale ranges that do not overlap may have the same ID.
  • MinScale, MaxScale - the minimum and maximum scales at which the classification is applicable. Use -1 for either to indicate that scale is not limited in that direction.
  • ExactValue - the value of the Layer.ClassificationColumn for which this classification is applicable.
  • MinRange,MaxRange - the minimum and maximum values of a numeric Layer.ClassificationColumn for which this classification is applicable. Use -1 for either to indicate that application is not limited in that direction.
  • Metadata - a collection of arbitrary name/value pairs. You can use this to include information useful to your applications.
  • Style - the RenderStyle to apply to layer geometry when this classification is applicable. As noted above, this is merged with a layer's DefaultClassificationStyle.
  • UseStylePropertyDataColumns - indicates whether this classification uses the layer's LineColorColumn and FillColorColumn values.
  • ClassificationState - like Layer.LayerState, this is used to control serialization.  In a Modified layer with many classifications, most of which are unchanged, explicitly setting this to Classification.ClassificationStates.Baseline for unchanged Classifications will reduce the request size.  This affects the rendering order of Classifications- Baseline Classifications will render after others.

Classification Render Styles

The RenderStyle class contains the actual rendering instructions. There are several things to note about this class.

  • Many properties use a Nullable<T> struct to wrap a primitive.  When these are set null the DefaultClassificationStyle is applied.
  • Some properties are System.Windows.Media types that can be represented with XAML. These have corresponding string properties for the XAML, which are used for serialization. Under Silverlight, only the string properties are present.
  • When not under Silverlight, conversions between XAML string properties and System.Windows.Media objects are done using XAMLReader and XAMLWriter objects. This has some implications for serialization, see "Serialization Issues" below.

The RenderStyle class has a large number of properties and subclasses. They are listed here by usage. RenderStyle properties used to render lines and area shapes:

  • ShapeVisibility - indicates whether to render shapes at all.
  • FillBrush - the fill brush for area shapes.
  • LinePen - the pen for line shapes and area outlines.

RenderStyle properties used to render points:

  • PointSymbolVisibility - indicates whether to render a point symbol. Point symbols are rendered for point features, line center points, and the center points of polygon bounding boxes.
  • PointSymbol - a PointSymbolStyle object with the following properties:
    • Symbol - a DrawingGroup to render.  Note that this can only contain GeometryDrawing and DrawingGroup objects.  ImageDrawing, in particular, is NOT supported.
    • SizeDIU - size to scale the Symbol to.
    • OffsetDIU - offset of the Symbol from the point.
    • Rotation - any rotation to apply to the symbol, in degrees.
    • Opacity - opacity of the symbol.

RenderStyle properties used to render text (values from Layer.LabelColumn):

  • LabelVisibility - indicates whether to render a label. Labels are rendered at point locations as are point symbols.
  • Label - a LabelStyle object with the following properties:
    • Foreground - brush for label text.
    • Background - optional brush for a label background.
    • BackgroundOutline - optional pen for outlining the Background box.
    • FontName, FontStyle, FontWeight, EmSize - properties used to construct a font object for text.
    • RotateWithContent - if true, labels for line features follow line angles.
    • Position - position of text with relation to the labeling point.
    • OffsetDIU - offset of the text from the labeling point.
    • GlowColor, GlowSize, GlowOpacity - used to define a "glow" to apply to label text.  Glow is particularly recommended over Background when RotateWithContent is used.

The Map Response

The response to a map request is a serialized MapResponse. If a TileLayer is used, it handles the map response. If you call the map service directly, you will need to deserialize and handle the response.

Properties of the MapResponse class include:

  • Error - a message about any error that prevented map rendering.
  • Canceled - set true if a Cancel request was received before map rendering was complete.
  • ResponseEnvelope - the map area rendered.
  • ResponseScale - the map scale for the response.
  • ResponseMetersPerPixel - meters per pixel for the response.
  • ImageArray - array of bytes for an image when MapRequest.ImageTilingFactor was not used.
  • ImageTileArray - array of arrays of bytes for images when MapRequest.ImageTilingFactor was used. The images are listed row by row, from left to right and top to bottom.

Serialization Issues

RenderStyle objects can contain various WPF objects as XAML. XAML readers and writers can encounter objects that expect to be created within the context of single-threaded-apartment (STA) threads. For applications using the RIM controls this should not be a problem. In certain other contexts, it mat be necessary to create an STA thread to do serialization or deserialization. There are two considerations for such threads.

  • All WPF objects should be frozen before a deserialized object is returned from an STA thread. Call the Freeze method on every RenderStyle object within the object that has been deserialized.
  • You should not create a new thread every time you need to Serialize or Deserialize an object. The threads have the potential to bleed Winhandles, eventually causing them to fail. Instead use a single thread or a small pool of threads, using Dispatcher objects to assign work to the threads.

This issue applies to RenderStyle and all containing classes- Classification, Layer, Map, and MapRequest. It does not apply to the MapResponse.

Map Service Methods

The following methods are used to get Map objects or to request map images.

string GetBaselineMapDescriptionState(string mapID);

Returns a serialized Map object. Connection strings are removed from this representation.

string GetMap(string requestXml, Guid cancelWorkKey);

Returns a serialized MapResponse containing the requested map. requestXML is a serialized MapRequest. The server implementation is asynchronous. If you use an asynchronous client method, you can provide a Guid as the cancelWorkKey and the Guid can be used as an argument to CancelGetMap. Make sure you use a different Guid in each call to BeginGetMap. If you are not using asynchronous client processing you can pass Guid.Empty as the cancelWorkKey.

string GetMapWithSpecifiedCaching(string requestXml, MapCacheOptions cacheOption, string cacheName, Guid cancelWorkKey);

Much like GetMap, but allows you to specify the desired map caching behavior. Caching must be enabled for this to be of use.

void CancelGetMap(Guid cancelWorkKey);

Call this to cancel a pending map request when using asynchronous client methods. Your BeginGetMap callback handler will still be called but if the cancel request was received before the map request was completed, the Canceled flag will be set on the map response. If a cancel request is received after a map request is complete it is ignored.

For more on asynchronous client methods, see http://msdn.microsoft.com/en-us/library/ms228972.aspx.

Legend Icons

If you want legend icons for your maps you will need to make requests to the MapService's GetLegendIcon method.

string GetLegendIcon(string mapID, string requestXml, string layerID, string classID, double scale, int width, int height);

This returns a serialized MapResponse where most properties other than ImageArray are unset.

The arguments are:

  • mapID - the map ID.
  • requestXML - an optional MapRequest object. Use this to set the ImageType (otherwise it will be PNG) and to provide any layer customizations that should be applied. If you want a PNG and you are using the baseline layer, you can pass null for this.
  • layerID - the ID of the Layer to get an icon for.
  • classID - the ID of the Classification to get an icon for.
  • scale - the map scale to get an icon for.
  • width - the icon width.
  • height - the icon height.