/// <inheritdoc cref="MapDecoration.OnRender(Graphics, MapViewport)"/> protected override void OnRender(Graphics g, MapViewport mvp) { var image = NorthArrowImage ?? DefaultNorthArrowBitmap; var mapSize = mvp.Size; //Get rotation var ptTop = mvp.ImageToWorld(new PointF(mapSize.Width / 2f, 0f), true); var ptBottom = mvp.ImageToWorld(new PointF(mapSize.Width / 2f, mapSize.Height * 0.5f), true); var dx = ptTop.X - ptBottom.X; var dy = ptBottom.Y - ptTop.Y; var length = Math.Sqrt(dx * dx + dy * dy); var cos = dx / length; var rot = -90 + (dy > 0 ? -1 : 1) * Math.Acos(cos) / GeoSpatialMath.DegToRad; var halfSize = new Size((int)(0.5f * Size.Width), (int)(0.5f * Size.Height)); //var oldTransform = g.Transform; var clip = g.ClipBounds; var newTransform = new Matrix(1f, 0f, 0f, 1f, clip.Left + halfSize.Width, clip.Top + halfSize.Height); newTransform.Rotate((float)rot); // Setup image attributes var ia = new ImageAttributes(); var cmap = new [] { new ColorMap { OldColor = Color.Transparent, NewColor = OpacityColor(BackgroundColor) }, new ColorMap { OldColor = Color.Black, NewColor = OpacityColor(ForeColor) } }; ia.SetRemapTable(cmap); g.Transform = newTransform; var rect = new Rectangle(-halfSize.Width, -halfSize.Height, Size.Width, Size.Height); g.DrawImage(image, rect, 0, 0, image.Size.Width, image.Size.Height, GraphicsUnit.Pixel, ia); //g.Transform = oldTransform; }