Trying to properly rotate shapes on map

Topics: WPF
Apr 7, 2011 at 11:55 AM

I have some markers, which are polygons (squares).  I am importing these from some other files and am calculating their coordinates. Now they don't fit 100% and sometimes they need to be resized and rotated a bit. 

My plan was to iterate through polygons, translate their latlng point paths to local coordinates, do the rotation on local coordinates and translate them all back to latlng and aply them to marker polygon paths. 

Problem is this:

 

PointLatLng point = new PointLatLng(15, 15);
GPoint pointLocal = MainMap.FromLatLngToLocal(point);
PointLatLng originalPoint = MainMap.FromLocalToLatLng(pointLocal.X, pointLocal.Y);

//their values are:
//point => {Lat=13, Lng=15}
//pointLocal => {X=18175317,Y=15554996}
//originalPoint => {Lat=-74,4712712901167, Lng=179,999989271164}

 

Why is this happening, why are the final values different than the originals? How should I do the conversion properly?

 

As a workaround to this issue I tried rotating the LatLngs directly doing it like this:

 

double lng_ = Math.Cos(angle) * (point.Lng - center.Lng) - Math.Sin(angle) * (point.Lat - center.Lat) + center.Lng;
double lat_ = Math.Sin(angle) * (point.Lng - center.Lng) + Math.Cos(angle) * (point.Lat - center.Lat) + center.Lat;
marker.Polygon[i] = new PointLatLng(lat_, lng_);

 

But the results are not really squares anymore because the rotation somehow deformed them. (See the rotated "squares" in the left part of the image compared to the nonrotated perfect squares on the right). Is it because I'm doing calculations with LatLng degrees or am I calculating it wrong?

Radioman, any advice? 

Shrani.si

Coordinator
Apr 7, 2011 at 12:21 PM

instead of changing polygon coordinates, you can simply 'rotate' it while rendering, in wpf you need to change RenderTranform property:

GMapMarker mark = new GMapMarker(objects.Select(p => p.Point).First());
{
   mark.Polygon.AddRange(objects.Select(p => p.Point));
   mark.RegeneratePolygonShape(MainMap);
   mark.Shape.RenderTransform = new RotateTransform(0);

   mark.Shape.MouseMove += new MouseEventHandler(Shape_MouseMove);
   mark.Shape.IsHitTestVisible = true;
}
MainMap.Markers.Add(mark);

void Shape_MouseMove(object sender, MouseEventArgs e)
{
   ((sender as UIElement).RenderTransform as RotateTransform).Angle++;
}

Apr 7, 2011 at 12:53 PM

Sorry, I forgot to to explain that the purpose of my doing is to be able to fit objects from inaccurate maps on a real map and then export their (corrected) points as true LatLngs. So I definitely need the LatLng's of the rotated points but that's not really trivial with a RenderTransform, is it? How should I approach this?

Coordinator
Apr 7, 2011 at 1:16 PM

it seems a bug in wpf version, need to make some corrections

Coordinator
Apr 7, 2011 at 1:47 PM

quick solution would be:

remove this line from GMap.NET.WindowsPresentation\GMapControl.cs, FromLatLngToLocal: ret.Offset(-(int)MapTranslateTransform.X, -(int)MapTranslateTransform.Y);

add this to GMap.NET.WindowsPresentation\GMapMarker.cs, UpdateLocalPosition:

GPoint p = Map.FromLatLngToLocal(Position);
 p.Offset(-(int)Map.MapTranslateTransform.X, -(int)Map.MapTranslateTransform.Y); // <--
...

Seems to work correctly, i'll check it more in detail later, thanks

Coordinator
Apr 7, 2011 at 6:42 PM

pushed fix to server, thanks

Apr 8, 2011 at 8:35 AM

Thanks for fixing the conversion to local point.

 

My shapes are still getting deformed when rotating them by recalculating rotated coordinates, maybe it's an accuracy problem?

Coordinator
Apr 8, 2011 at 8:44 AM

do you rotate local coordinates and then convert them back to geo?

Apr 14, 2011 at 12:19 PM

Hey again.

Yes I tried it like that, but to do that I have to do geo -> local -> rotation -> geo and in this process double is cast to int 2 times and since these are small objects it could be the reason of my problems. I am trying to find an easy way of doing this but without losing precision with int casts. The methods that do this are buried quite deep, do you have any suggestions for a workaround? 

I've tried also doing the conversion of geo coordinates to (x,y) by using the Inverse of Gudermannian function to convert latitude as wiki says but I must not be doing it right since the results are much worse. Do you have a formula which would convert the lats and lngs to some generic (x,y) where I could do the rotation and then convert back?

Coordinator
Apr 14, 2011 at 12:30 PM

does your rotation function of local coordinates is correct? Did you rotate each object around it's own local center?