Mapsui: CenterCrossWidget - required

Created on 9 Sep 2018  路  15Comments  路  Source: Mapsui/Mapsui

Hi Team,

as we discussed in #504 with @charlenni , will be nice... is needed to have a widget which will give us a Center Cross above all layers, and from the code will be possibility to get the position (geo-position) of it on the map easily.

Our solution now (top secret ;) ):
```c#
public static Bitmap RedCrossBmp(int pixels)
{
var b = new Bitmap(pixels + 1, pixels + 1);
using (var g = Graphics.FromImage(b))
{
var pen = new Pen(Color.Red, 1);
g.DrawLine(pen,0,pixels/2,pixels+1,pixels/2);
g.DrawLine(pen,pixels/2,0,pixels/2,pixels+1);
}
return b;
}

private static readonly Bitmap RedCross = RedCrossBmp(10);

internal static int GetBitmapId(byte[] bitmap)
{
var imageMS = new MemoryStream();

System.Drawing.Image.FromStream(new MemoryStream(bitmap)).Save(imageMS, System.Drawing.Imaging.ImageFormat.Png);

if (imageMS.Length <= 0)
    throw new Exception();

imageMS.Position = 0;

return BitmapRegistry.Instance.Register(imageMS);

}

private static IStyle CreateRedCrossStyle()
{
var bitmapId = GetBitmapId(RedCross.ToByteArray(System.Drawing.Imaging.ImageFormat.Png));

return new SymbolStyle
{
    BitmapId = bitmapId,
    SymbolType = SymbolType.Bitmap,
    SymbolScale = 1
};

}

private WritableLayer RedCrossLayer;
private Point RedCrossLocation = null;

RedCrossLayer = new WritableLayer
{
Name = "RedCrossPointLayer",
Style = CreateRedCrossStyle()
};
RedCrossLayer.Transformer.FromCRS = "EPSG:4326";
MapControl.Map.Layers.Add(RedCrossLayer);

RedCrossLocation = null;

MapControl.Map.Viewport.ViewportChanged += Map_CurrentExtentChanged; //https://github.com/Mapsui/Mapsui/issues/398

private void Map_CurrentExtentChanged(object sender, PropertyChangedEventArgs e)
{
try
{
if (MapControl?.Map?.Viewport == null || !MapControl.Map.Viewport.Initialized) return; //https://github.com/Mapsui/Mapsui/issues/399

    var worldLocation = MapControl.Map.Viewport.Center;

    if (RedCrossLayer != null && worldLocation != null)
    {
        {
            var mapLocation = new Point(worldLocation.X, worldLocation.Y);
            //here Transformation of the mapLocation values from one CRS to another - if required; eg. base map layer (OSM) "EPSG:3857"->"EPSG:4326" used coordinate system

            if (RedCrossLocation == mapLocation) return;

            RedCrossLocation = mapLocation;
        }

        RedCrossLayer.Clear();

        //var symbolStyle = CreateRedCrossStyle(); -> Memory Leaking! #503
        //
        var feature = new Feature
        {
            Geometry = worldLocation,
        //  Styles = new StyleCollection
        //  {
        //      symbolStyle,
        //  }
        };

        RedCrossLayer.Add(feature);
    }
}
catch(Exception ex) { /*ex.Message*/ }

}

//later somewhere in the code
point = RedCrossLayer.GetFeatures().First(f => f != null).Geometry as Mapsui.Geometries.Point
```

Many Thanks,
艁ukasz

question

Most helpful comment

For me, the widget works perfectly! :)

map.Widgets.Add(new Mapsui.Widgets.CenterCross.CenterCrossWidget(map) { Color = Color.Red, Halo = Color.Transparent, Height = 10, Width = 6 });
and then I can do:
var RedCrossLocation = MapControl.Map.Viewport.Center;

Or (not nice ;) )
map.Widgets.Add(new Mapsui.Widgets.CenterCross.CenterCrossWidget(map) { Color = Color.Red, Halo = Color.Transparent, Height = 10, Width = 6, Envelope = map.Viewport.Extent });
and then I can do:
var RedCrossLocation = MapControl.Map.Widgets.Find(w => w is Mapsui.Widgets.CenterCross.CenterCrossWidget).Envelope.GetCentroid();

Best Regards,
艁ukasz

All 15 comments

oo, if you have any ideas on how the above solution could be improved, do not hesitate to comment and give a clue, advice

thanks!

The red cross is always right in the center of the map right? So, why don't you split your requirements into two parts:

  • Get the position of the center of the map (and perhaps MapInfo from the center of the map)
  • Draw a red cross on the center of the MapControl. There might be something available in WinForms for that.

You're probably right, it could be one of the solutions, another one might be a widget (as I ask in this issue)
Such a widget could be used outside of WinForms also, am I right?

Yes. But a custom widget is only possible in v2.

1.4.* :(

"a custom widget" ? What do you mean?

I'm asking you to create and implement a default/build-in CenterCross widget in the Mapsui, available for all.
Those widgets that are already available (ScaleBarWidget, ZoomInOutWidget), can't there be one more?

I did exactly what Paul says and it works quite well. Simply overlay a text element on top of the map. The user moves the map underneath and I get the map position from the map's center.

yes, sure it is one of solutions of the case and I'm not saying I will not do this but still I request for the widget in Mapsui, not my own solution on my side in my code :)

There will only be bug fixes in 1.4, so this will have to wait for 2.0.

Yupiii :)

Many Thanks!

I'm looking forward to the next release of Mapsui 1.4

I released 1.4.8 with @charlenni s center cross widget.

That's a great addition! Is there a way to change the image for the cross?

CenterCrossWidget is the cross image ;)
I don't think the image should be changed, that would be too much for that specific widget ;)

Again MANY THANKS guys!

For me, the widget works perfectly! :)

map.Widgets.Add(new Mapsui.Widgets.CenterCross.CenterCrossWidget(map) { Color = Color.Red, Halo = Color.Transparent, Height = 10, Width = 6 });
and then I can do:
var RedCrossLocation = MapControl.Map.Viewport.Center;

Or (not nice ;) )
map.Widgets.Add(new Mapsui.Widgets.CenterCross.CenterCrossWidget(map) { Color = Color.Red, Halo = Color.Transparent, Height = 10, Width = 6, Envelope = map.Viewport.Extent });
and then I can do:
var RedCrossLocation = MapControl.Map.Widgets.Find(w => w is Mapsui.Widgets.CenterCross.CenterCrossWidget).Envelope.GetCentroid();

Best Regards,
艁ukasz

@jin-khera-eastpoint This is not planned. 1.4 should only get bugfixes. In 2.0 you could add this widget as a custom widget and change it too your liking.

Was this page helpful?
0 / 5 - 0 ratings