You are here: > ESRI Forums > arcgis server forums > Thread Replies

ArcGIS Server Forums

ArcGIS API for Silverlight forum

rotate a custom symbol   Klay Williams Apr 16, 2009
Re: rotate a custom symbol   Morten Nielsen Apr 16, 2009
Re: rotate a custom symbol   Klay Williams Apr 17, 2009
Re: rotate a custom symbol   Morten Nielsen Apr 17, 2009
Re: rotate a custom symbol   Morten Nielsen Apr 17, 2009
Re: rotate a custom symbol   Klay Williams Apr 17, 2009
Re: rotate a custom symbol   Morten Nielsen Apr 17, 2009
Re: rotate a custom symbol   Klay Williams Apr 20, 2009
Re: rotate a custom symbol   Morten Nielsen Apr 20, 2009
Re: rotate a custom symbol   Klay Williams Apr 21, 2009
Re: rotate a custom symbol   Morten Nielsen May 03, 2009
Re: rotate a custom symbol   Joshua Lapp May 26, 2009
Re: rotate a custom symbol   Morten Nielsen May 26, 2009
Re: rotate a custom symbol   james wu Jul 19, 2009
Re: rotate a custom symbol   Morten Nielsen Jul 20, 2009
Re: rotate a custom symbol   james wu Jul 20, 2009
Re: rotate a custom symbol   Morten Nielsen Jul 21, 2009
Re: rotate a custom symbol   james wu Jul 21, 2009
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject rotate a custom symbol 
Author Klay Williams 
Date Apr 16, 2009 
Message Is there a way to set the rotation of a custom map symbol programmatically?

I'm displaying points on a map that track the path of a vessel in the water. The points will be arrows, and I want to rotate the arrows so that they show the heading of the vessel at that point.

Below is an example of what I'm trying to accomplish. 
 
public void addPoint(double lng, double lat, double heading) {
    GraphicsLayer graphicsLayer = map.Layers["gfxLayer"] as GraphicsLayer;
    Graphic graphic = new Graphic() {
        Geometry = new MapPoint(lng, lat),
        Symbol = Arrow
    };

    // here is where I would imagine the
    // rotation being set, something like:
    // graphic.rotation = heading;

    graphicsLayer.Graphics.Add(graphic);
}
 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Morten Nielsen 
Date Apr 16, 2009 
Message The best approach would be to have a heading attribute on your graphic that you would use to bind a RotateTransform for a custom marker symbol template.
Unfortunately you cannot bind RotateTransform properties in Silverlight (You can in WPF), so the only way I see you can do this, is create a template on the fly from a string and load that for your symbol template.

Something along the lines of: 
 
string template = @"<ControlTemplate
	xmlns=""http://schemas.microsoft.com/client/2007""
	xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
	<Grid RenderTransformOrigin=""0.5,0.5"">
	<Grid.RenderTransform>
	<RotateTransform Angle=""ROTATION"" />
	</Grid.RenderTransform>
	<TextBlock Text=""->"" />
	</Grid>
	</ControlTemplate>";
MarkerSymbol arrow = new MarkerSymbol();
string template2 = template.Replace("ROTATION", heading);
arrow.ControlTemplate = System.Windows.Markup.XamlReader.Load(template2) as ControlTemplate;
graphic.symbol = arrow;
 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Klay Williams 
Date Apr 17, 2009 
Message Thanks for the response!

I really hope there's another way to achieve this (though I understand there may not be), because it seems very un-elegant to create a new ControlTemplate for each of a couple hundred points that make up the vessel track.

Again, very grateful for the response.
 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Morten Nielsen 
Date Apr 17, 2009 
Message I couldn't agree more. It's an annoying limitation in Silverlight. However, for what it's worth it's a lot easier to do this in WPF, where you are allowed to bind to dependency objects (see below).
SL3 should give us a lot more binding options, however I haven't been able to get this to work with the current beta. 
 
<ControlTemplate>
	<Image Source="{Binding Symbol.Source}" 
		Width="{Binding Symbol.Width}"
		Height="{Binding Symbol.Height}"
		RenderTransformOrigin="0.5,0.5">
		<Image.RenderTransform>
			<RotateTransform
				Angle="{Binding Path=Attributes.[Angle]}" />
		</Image.RenderTransform>
	</Image>
</ControlTemplate>
 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Morten Nielsen 
Date Apr 17, 2009 
Message It seems like this approach/hack might work as well for binding transforms on symbols:
http://www.cauldwell.net/patrick/blog/MVVMBindingToCommandsInSilverlight.aspx

I'll see if I can't cook up a code sample you can use (might take a while), but the general idea is that you create an attached property, add it to your template, and rotate the element when the property changes:

 
 
Symbol template (you might want to change the angle binding expression to grab it from your attribute):
<ControlTemplate
	xmlns="http://schemas.microsoft.com/client/2007"
	xmlns:local="clr-namespace:myNamespace;assembly=myAssembly"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
	<Image Source="{Binding Symbol.Source}" 
		local:RotatingSymbol.Angle="{Binding Symbol.Angle}"
		Opacity="{Binding Symbol.Opacity}"
		Stretch="Fill"
		Width="{Binding Symbol.Width}"
		Height="{Binding Symbol.Height}" >
		<Image.RenderTransform >
			<RotateTransform />
		</Image.RenderTransform>
	</Image>
</ControlTemplate>

and in your class RotatingSymbol.cs class:

public static readonly DependencyProperty AngleProperty =
	DependencyProperty.RegisterAttached("Angle", typeof(double), typeof(MarkerSymbol),
	new PropertyMetadata(OnAngleChanged));

private static void OnAngleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
	if (d is UIElement)
	{

		UIElement elm = d as UIElement;
		elm.RenderTransform = new RotateTransform() { Angle = (double)e.NewValue };
	}
}

public static double GetAngle(DependencyObject d)
{
	return (double)d.GetValue(AngleProperty);
}

public static void SetAngle(DependencyObject d, double value)
{
	d.SetValue(AngleProperty, value);
}
 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Klay Williams 
Date Apr 17, 2009 
Message You're my hero. :)

Thanks for all the effort you've put forth to get an answer to this question. I'm guessing that lots of others will need to do something similar, so I'm sure they'll benefit as well.

I like the look of this latest hack much better. It allows the template to be a template (and not a one-off configuration for each symbol).

I'm going to give this approach a shot as soon as I can get back to coding.

Thanks again! 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Morten Nielsen 
Date Apr 17, 2009 
Message Yeah its definitely a lot cleaner, but compared to how you would do it in WPF, horrible to say the least :) 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Klay Williams 
Date Apr 20, 2009 
Message Ok, I'm feeling kinda slow right now.

I'm trying to parse through your example, and there are a few things I don't get. I'll go ahead and ask the questions, and if you feel like answering them, great. If not, I understand that too.

First, I'm populating the points on the map manually. I'm using Javascript to request a set of points from a SQL database and adding them one by one to the graphics layer (as opposed to using a MapService). Can I still use the binding trick you demonstrated?

Second, I'm very new to Silverlight, and I'm not sure on the XAML syntax (still haven't found that magic reference that's made it all clear yet). Is the "local:RotatingSymbol.Angle" an attached property? If so, did you just make up the names, or are they derived elsewhere?

Third, is RotatingSymbol.cs part of the business model? I'm not sure which of my classes would play the same role.

Again, any more help would be appreciated.

Thanks!

 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Morten Nielsen 
Date Apr 20, 2009 
Message 1) Yes you can still do that. But JavaScript? Seriously? :-)
2) Yes it was an attached property I just made up, that takes care of tracking if the rotation changes, and then setting it on the symbol manually. 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Klay Williams 
Date Apr 21, 2009 
Message Honestly, I'm using Javascript because that's what I know. It's simpler for me to use Javascript and PageMethods to link Silverlight to the server than it is to write a whole WCF service/contract layer to do so. Maybe when I'm more comfortable with WCF, I'll move to that.

Incidentally, I'm having a hard time making sense of the code you've generously provided, since my grasp of XAML is so limited. I've looked through the tutorials from Microsoft and primers on various sites, but I still haven't found the one that makes it all click. Any suggestions?

Thanks again! 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Morten Nielsen 
Date May 03, 2009 
Message Just a follow-up... there is a description of how to use attached properties to bind an attribute to the rotation here: http://www.sharpgis.net/post/2009/05/03/Using-surrogate-binders-in-Silverlight.aspx 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Joshua Lapp 
Date May 26, 2009 
Message Morten,
I'm trying to implement the "attached property" solution in order to create a PictureMarkerSymbol that rotates based on an attribute. I have a few questions and wanted to see if you had a working example that I could take a look at before I fire away with my questions. 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Morten Nielsen 
Date May 26, 2009 
Message You cannot rotate a PictureMarkerSymbol, because there is no where to attach the property to the symbol. Instead you should create a custom marker symbol and place the attached property in its template.

See the Custom symbols sample in the SDK for an example on how to define a symbol template:
http://resources.esri.com/help/9.3/arcgisserver/apis/silverlight/samples/start.htm#CustomSymbols 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author james wu 
Date Jul 19, 2009 
Message I have created an MarkerSymbol that can bind to
othere controls, so the symbol can scale when zoom.
but I can't bind the value to the rotate value, I
want to bind each symbol with a angle, since so many
times search, haven't found any idea.

does anybody know how to do it? thanks. 
 
<esriSymbols:MarkerSymbol x:Name="AnotherSymbol" OffsetX="15" OffsetY="15">
                <esriSymbols:MarkerSymbol.ControlTemplate>
                    <ControlTemplate>
                        <Canvas Width="{Binding 
AnotherSymbol.Height}" Height="{Binding 
AnotherSymbol.Height}" Background="Azure" 
RenderTransformOrigin="0.5,0.5">

                            <Canvas.RenderTransform>
                                <RotateTransform Angle="40"/>
                            </Canvas.RenderTransform>
                            <Ellipse Width="
{Binding AnotherSymbol.Height}" Height="{Binding 
AnotherSymbol.Height}" Stroke="Brown" Fill="Aqua">
</Ellipse>
                            <Line X1="0" 
Y1="{Binding Value, ElementName=SliderHalf}" 
X2="{Binding Value, ElementName=SliderFull}" 
Y2="{Binding Value, ElementName=SliderHalf}" 
Stroke="Black" StrokeThickness="2" />
                            <Line X1="{Binding 
Value, ElementName=SliderHalf}" Y1="0" X2="{Binding 
Value, ElementName=SliderHalf}" Y2="{Binding Value, 
ElementName=SliderFull}" Stroke="Black" 
StrokeThickness="2" />
                        </Canvas>
                    </ControlTemplate>
                </esriSymbols:MarkerSymbol.ControlTemplate>
            </esriSymbols:MarkerSymbol>
 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Morten Nielsen 
Date Jul 20, 2009 
Message You can only bind DepedencyProperties, and the angle property is not a DP. As mentioned above, you can use the workaround by using a custom attached property that will trigger the rotation. 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author james wu 
Date Jul 20, 2009 
Message Hi, as you metioned, I have using a custom attached property, but it doesn't work.

What I want is set each marksymbol with different
angle, for example, I have made a AnotherSymbol,
each AnotherSymbolI want to Specify a independent
angle, and the angle is set only when a set angle
function is called.

Thanks for your help.

PS: the attached file is my project 
 
<esriSymbols:MarkerSymbol x:Name="AnotherSymbol" OffsetX="15" OffsetY="15">
                <esriSymbols:MarkerSymbol.ControlTemplate>
                    <ControlTemplate>
                        <Canvas Width="{Binding Symbol.Height}" Height="{Binding Symbol.Height}" Background="Azure" RenderTransformOrigin="0.5,0.5"
                                local:SurrogateBind.Value="{Binding Path=Angle}"
                                local:SurrogateBind.Target="RenderTransform.Angle">
                            <Canvas.RenderTransform>
                                <RotateTransform />
                            </Canvas.RenderTransform>
                            <Ellipse Width="{Binding Symbol.Height}" Height="{Binding Symbol.Height}" Stroke="Brown" Fill="Aqua"></Ellipse>
                            <Line X1="0" Y1="{Binding Value, ElementName=SliderHalf}" X2="{Binding Value, ElementName=SliderFull}" Y2="{Binding Value, ElementName=SliderHalf}" Stroke="Black" StrokeThickness="2" />
                            <Line X1="{Binding Value, ElementName=SliderHalf}" Y1="0" X2="{Binding Value, ElementName=SliderHalf}" Y2="{Binding Value, ElementName=SliderFull}" Stroke="Black" StrokeThickness="2" />
                        </Canvas>
                    </ControlTemplate>
                </esriSymbols:MarkerSymbol.ControlTemplate>
            </esriSymbols:MarkerSymbol>

and in my xaml.cs
public class SomeValues
        {
            public double OHeight { get; set; }
            public double OWidth { get; set; }
            public string TxtInfo { get; set; }
            public double Angle
            {
                get;
                set;
            }
        }
        private SomeValues _vals;
and in the .ctor
            _vals = new SomeValues()
            {
                OHeight = 36.0,
                OWidth = 36.0,
                TxtInfo = "Hello world",
                Angle = 40
            };

            this.DataContext = _vals;
 
  SilverlightApplication1.rar (opens in new window)
 
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author Morten Nielsen 
Date Jul 21, 2009 
Message this.DataContext won't work. Symbol's doesn't have a datacontext. Instead you need to set some attributes on your Graphic, and using the dictionary converter to bind an attribute to the symbol (basically the datacontext of the symbol will be the graphic). 
   
Report Inappropriate Content • Top • Print • This Forum is closed for replies.    
Subject Re: rotate a custom symbol 
Author james wu 
Date Jul 21, 2009 
Message thanks Morten, I have solved the problem. The way I used is like http://resources.esri.com/arcgisserver/apis/silverlight/index.cfm?fa=codeGalleryDetails&scriptID=16467 , custom each symbol's template.