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
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:
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.
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