Rotating a picture marker symbol on a accelerated layer

2206
2
01-29-2013 08:48 AM
Labels (1)
AaronMorrisett
New Contributor II
Has anyone found a good way to rotate a PictureMarkerSymbol on a accelerated layer yet?

The only method I have found that would possible work is to write a new image to the HDD everytime it is rotated and then use the a new PictureMarkerSymbol with a source set to the URI of the new image.

I have been looking around trying to make ImageSources JSON serializable with no luck.

Any suggestions?

Regards,
    Aaron
0 Kudos
2 Replies
MichaelBranscomb
Esri Frequent Contributor
Hi,

Unfortunately we didn't manage to add an Angle property to PictureMarkSymbol in the last release - it's on the roadmap for a future release.

Are you looking to rotate the symbols to quite specific angles, or would you like to rotate based on an attribute value?

If it's the former case, then one to easily achieve this is to programmatically rotate the image and pass that in as the source of the PictureMarkerSymbol image. An extension of this approach is to actually construct the symbols dynamically and then render as images using RenderTargetBitmap and use that as the source of the PictureMarkerSymbol image.

For example:

// Create a diagonal linear gradient with four stops.   
// http://msdn.microsoft.com/en-us/library/system.windows.media.lineargradientbrush.aspx
LinearGradientBrush myLinearGradientBrush =
    new LinearGradientBrush();
myLinearGradientBrush.StartPoint = new Point(0, 0);
myLinearGradientBrush.EndPoint = new Point(1, 1);
myLinearGradientBrush.GradientStops.Add(
    new GradientStop(Colors.Yellow, 0.0));
myLinearGradientBrush.GradientStops.Add(
    new GradientStop(Colors.Red, 0.25));
myLinearGradientBrush.GradientStops.Add(
    new GradientStop(Colors.Blue, 0.75));
myLinearGradientBrush.GradientStops.Add(
    new GradientStop(Colors.LimeGreen, 1.0));

// Create an Ellipse Element
// http://msdn.microsoft.com/en-us/library/system.windows.shapes.ellipse.aspx
Ellipse myEllipse = new Ellipse();
myEllipse.Stroke = System.Windows.Media.Brushes.Black;
myEllipse.Fill = myLinearGradientBrush;
myEllipse.HorizontalAlignment = HorizontalAlignment.Left;
myEllipse.VerticalAlignment = VerticalAlignment.Center;
myEllipse.Width = 12;
myEllipse.Height = 25;

//Force render
myEllipse.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
myEllipse.Arrange(new Rect(myEllipse.DesiredSize));

// Render to an bitmap
// http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.rendertargetbitmap.aspx
RenderTargetBitmap render = new RenderTargetBitmap(200, 200, 150, 150, PixelFormats.Pbgra32);
render.Render(myEllipse);

// Use the bitmap as the source for a PMS
_pms = new PictureMarkerSymbol() 
{
    Source = render,
};

#. The following code would be run in a loop when creating multiple graphics:

graphic.Symbol = _pms;


In the latter case you could still use the above approach but it would incur an additional level of overhead because the potential for image reuse in the display is significantly reduced.

Perhaps you could also consider combining the above approach with a UniqueValueRender or ClassBreaksRender, with the symbol for each value/classbreak being a PictureMarkerSymbol.

Cheers

Mike
0 Kudos
AaronMorrisett
New Contributor II
Hi Mike, thank you for the answer.

I gave this a shot and it does seem to work on layers not placed on the AcceleratedLayerCollection however, when I do try it on that collection is says that the source of the PictureMarkerSymbol is not JSON serializable.  Can you confirm if that is what you see as well?

Regards,
    Aaron
0 Kudos