我正在尝试使用罗宾逊的投影从图像制作地图。 我们的想法是为图像提供与普通地图相同的行为,因此用户应该能够在地图上进行缩放和平移,它还应该能够使用图钉标记他想要的本地化。
为此,我创建了一个管理缩放和平移行为的类,以及一个管理投影的用户控件。
我现在遇到的问题是我无法修复图像上的图钉,当我缩放时它会失去它的位置。 此外,当地图比例超过1时,推针不会放在正确的位置。
如果有人知道如何解决此问题,请提供帮助。
这是类和用户控件的代码。
ZoomPan.cs
#region Properties
private Canvas m_Map;
private UIElement m_Pin;
private Point m_Origin;
private Point m_Start;
public bool IsMouseWheel = false;
#endregion
#region Method
/// <summary>
/// Initialize child Events.
/// </summary>
public void Initialize()
{
m_Map = this.Children[0] as Canvas;
m_Pin = this.Children[1];
if (this.Children.Count >= 0)
{
TransformGroup aMapGroup = new TransformGroup();
ScaleTransform aMapScale = new ScaleTransform();
aMapGroup.Children.Add(aMapScale);
TranslateTransform aMapTranslate = new TranslateTransform();
aMapGroup.Children.Add(aMapTranslate);
m_Map.RenderTransform = aMapGroup;
m_Map.RenderTransformOrigin = new Point(0.0, 0.0);
TransformGroup aPinGroup = new TransformGroup();
ScaleTransform aPinScale = new ScaleTransform();
aPinGroup.Children.Add(aPinScale);
TranslateTransform aPinTranslate = new TranslateTransform();
aPinGroup.Children.Add(aPinTranslate);
m_Pin.RenderTransform = aPinGroup;
m_Pin.RenderTransformOrigin = new Point(0.0, 0.0);
this.MouseWheel += child_MouseWheel;
this.MouseLeftButtonDown += child_MouseLeftButtonDown;
this.MouseLeftButtonUp += child_MouseLeftButtonUp;
this.MouseMove += child_MouseMove;
}
}
/// <summary>
/// Get Translate Transform.
/// </summary>
private TranslateTransform GetTranslateTransform(UIElement element)
{
return (TranslateTransform)((TransformGroup)element.RenderTransform)
.Children.First(tr => tr is TranslateTransform);
}
/// <summary>
/// Get Scale Transform.
/// </summary>
private ScaleTransform GetScaleTransform(UIElement element)
{
return (ScaleTransform)((TransformGroup)element.RenderTransform)
.Children.First(tr => tr is ScaleTransform);
}
/// <summary>
/// Set Translation.
/// </summary>
private double SetTranslation(double p_Max, double p_Vector)
{
if (p_Vector < -p_Max)
{
return -p_Max;
}
else
{
return p_Vector;
}
}
/// <summary>
/// Pan Child
/// </summary>
private void PanChild(double p_TranslateX, double p_TranslateY)
{
var transform = m_Pin.TransformToVisual(m_Map);
Point p = transform.Transform(new Point(0, 0));
p.ToString();
var aMapScale = GetScaleTransform(m_Map);
var aMapTranslation = GetTranslateTransform(m_Map);
var aPinScale = GetScaleTransform(m_Pin);
var aPinTranslation = GetTranslateTransform(m_Pin);
if (p_TranslateX < 0)
{
aMapTranslation.X = SetTranslation(this.ActualWidth * (aMapScale.ScaleX - 1), p_TranslateX);
aPinTranslation.X = SetTranslation(this.ActualWidth * (aMapScale.ScaleX - 1), p_TranslateX);
}
else
{
aMapTranslation.X = 0;
aPinTranslation.X = 0;
}
if (p_TranslateY < 0)
{
aMapTranslation.Y = SetTranslation(this.ActualHeight * (aMapScale.ScaleY - 1), p_TranslateY);
aPinTranslation.Y = SetTranslation(this.ActualWidth * (aMapScale.ScaleY - 1), p_TranslateY);
}
else
{
aMapTranslation.Y = 0;
aPinTranslation.Y = 0;
}
}
#endregion
#region Child Events
/// <summary>
/// On Mouse Wheele (Zoom).
/// </summary>
private void child_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (m_Map != null && m_Pin !=null)
{
IsMouseWheel = true;
var aMapScale = GetScaleTransform(m_Map);
var aMapTranslation = GetTranslateTransform(m_Map);
var aPinScale = GetScaleTransform(m_Pin);
var aPinTranslation = GetTranslateTransform(m_Pin);
double zoom = e.Delta > 0 ? .5 : -.5;
if (!(e.Delta > 0) && (aMapScale.ScaleX <= 1 || aMapScale.ScaleY <= 1))
{
return;
}
Point relative = e.GetPosition(m_Map);
double abosuluteX;
double abosuluteY;
abosuluteX = relative.X * aMapScale.ScaleX + aMapTranslation.X;
abosuluteY = relative.Y * aMapScale.ScaleY + aMapTranslation.Y;
if (aMapScale.ScaleX >= 7 || aMapScale.ScaleY >= 7)
{
if (e.Delta > 0)
{
return;
}
}
aMapScale.ScaleX += zoom;
aMapScale.ScaleY += zoom;
CUserControlMap.m_Zoom = (int)(aMapScale.ScaleX - 1) * 2;
double X = abosuluteX - relative.X * aMapScale.ScaleX;
double Y = abosuluteY - relative.Y * aMapScale.ScaleY;
PanChild(X, Y);
}
}
/// <summary>
/// Mouse Left Button Down (Translate).
/// </summary>
private void child_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (m_Map != null && m_Pin !=null)
{
var aMapScale = GetScaleTransform(m_Map);
if (aMapScale.ScaleX == 1 || aMapScale.ScaleY == 1)
{
return;
}
var aMapTranslation = GetTranslateTransform(m_Map);
m_Start = e.GetPosition(this);
m_Origin = new Point(aMapTranslation.X, aMapTranslation.Y);
this.Cursor = Cursors.CCursors.CursorHand;
m_Map.CaptureMouse();
}
}
/// <summary>
/// Mouse Left Button Up.
/// </summary>
private void child_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (m_Map != null && m_Pin !=null)
{
m_Map.ReleaseMouseCapture();
this.Cursor = Cursors.CCursors.CursorArrow;
}
}
/// <summary>
/// Mouse Move
/// </summary>
private void child_MouseMove(object sender, MouseEventArgs e)
{
if (m_Map != null && m_Pin != null)
{
if (m_Map.IsMouseCaptured)
{
var aMapScale = GetScaleTransform(m_Map);
var aMapTranslation = GetTranslateTransform(m_Map);
var aPinScale = GetScaleTransform(m_Pin);
var aPinTranslation = GetTranslateTransform(m_Pin);
Vector v = m_Start - e.GetPosition(this);
double X = m_Origin.X - v.X;
double Y = m_Origin.Y - v.Y;
PanChild(X, Y);
}
}
}
#endregion
}
MapControl.cs的代码
#region Properties
/// <summary> Latitude</summary>
public float Latitude = 0;
/// <summary> Longitude</summary>
public float Longitude = 0;
/// <summary> Longitude in Pixels</summary>
private static double s_kLongitudeInPixel = 0.81;
/// <summary> Latitude in Pixels</summary>
private static double s_kLatitudeInPixel = 0.71;
/// <summary> Middle of the map</summary>
private static double s_KMiddle = 206;
/// <summary> Pin Image</summary>
private Image m_Pin = new Image();
public static double m_Zoom = 0;
#endregion
#region Constructor
/// <summary>
/// Constructor
/// </summary>
public CUserControlMap()
{
InitializeComponent();
m_Pin.Source = Application.Current.TryFindResource("Pin") as BitmapImage;
m_Pin.Height = 24;
m_Pin.Width = 30;
m_Canvas.Children.Add(m_Pin);
m_Canvas.Initialize();
}
#endregion
#region Methods
/// <summary>
/// Add a pin to the current Localization
/// </summary>
public void SetCurrentLocalization(float p_latitude, float p_longitude)
{
double pointX = GetXFromLongitude(p_longitude);
double pointY = GetYFromLatitude(p_latitude);
m_Pin.Margin = new Thickness(pointX + 97 , pointY - 22, 0, 0);
}
/// <summary>
/// Get X from longitude
/// </summary>
private double GetXFromLongitude(float p_longitude)
{
return (p_longitude / s_kLongitudeInPixel) + (s_KMiddle / 2);
}
/// <summary>
/// Get Y from latitude
/// </summary>
private double GetYFromLatitude(float p_latitude)
{
return (m_Image.Height / 2) - (p_latitude / s_kLatitudeInPixel);
}
#endregion
#region Events
/// <summary>
/// Image Mouse Right Button Down
/// </summary>
private void Image_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
Point point = e.GetPosition(m_Image);
Longitude = (float)(point.X - s_KMiddle) * (float)s_kLongitudeInPixel;
Latitude = (float)(m_Image.Height / 2 - point.Y) * (float)s_kLatitudeInPixel;
SetCurrentLocalization((float)Latitude, (float)Longitude);
}
#endregion
答案 0 :(得分:0)
使用LayoutTransform而不是RenderTransform。 更多详情:http://msdn.microsoft.com/en-us/library/ms750596.aspx#layoutTransformsAndRenderTransformsSection