How to create a "rubber rectangle selection" in the bing maps - wpf

I am using Bing maps WPF control to render maps. My requirement is allow user to create a rectangle and based on the co-ordinates of the rectangle drawn I need to fetch the lat, long information.
I achieved by the following way.
private MapPolygon boundingRectangle;
My mouse_leftButtonDown code looks like
Point point = e.GetPosition(this);
this.mouseCordinates = new PointCollection();
this.mouseCordinates.Add(point);
mouse_leftButtonUp code looks like
var point = e.GetPosition(this);
this.mouseCordinates.Add(point);
var pt1 = this.mouseCordinates[0];
var pt3 = this.mouseCordinates[1];
var pt2 = new System.Windows.Point(pt3.X, pt1.Y);
var pt4 = new System.Windows.Point(pt1.X, pt3.Y);
var loc1 = this.ViewportPointToLocation(pt1);
var loc2 = this.ViewportPointToLocation(pt2);
var loc3 = this.ViewportPointToLocation(pt3);
var loc4 = this.ViewportPointToLocation(pt4);
this.Children.Remove(this.boundingRectangle);
this.boundingRectangle = new MapPolygon
{
Stroke = new SolidColorBrush(Colors.Chocolate),
StrokeThickness = 2,
Locations = new LocationCollection()
{
loc1,
loc2,
loc3,
loc4
}
};
this.BoundingBoxCoordinates = this.boundingRectangle.Locations;
this.Children.Add(this.boundingRectangle);
So on mouse up I got a shape which user drawn. But while drawing (I mean while dragging the mouse since no mouse movement event is handled) user is not able to see anything on the map. Only on the mouse up user can see the shape they drawn because the layer children is added after mouse up.
What I want is "rubber selection" rectangle meaning while drawing the shape using mouse drag user should see the shape. It should be lively.
As I am new to WPF and map I am still struggling to figure this out.
Please help me.

I've done a lot of work with the Bing Maps and the WPF control. I've put together a code sample that shows how to draw rectangles on the map using both the mouse and touch. The sample is a bit too long for a forum post. I've uploaded it to MSDN here: https://code.msdn.microsoft.com/Draw-Rectangles-on-Bing-ce083d0e

Related

Add Markers in WPF

I need to add markers to my map. Problem: I'm using WPF, not WinForms.
GMapMarker marker = new GMapMarker(new PointLatLng(-25.966688, 32.580528));
gmap.Markers.Add(marker);
Now according to this question the solution is:
marker.Shape = new MarkerShape(....);
Could someone explain to me, how to I initalize this shape?
Thanks!
I resolved the problem with:
marker.Shape = new Ellipse
{
Width = 10,
Height = 10,
Stroke = Brushes.Black,
StrokeThickness = 1.5
};
That's a little black circle.
You have to add a new UserControl - your own, and inside the control put a image you like (for example pin image). Note that all the events (like Click event) must be implement inside a control.
After that you can add the marker like:
GMapMarker marker = new GMapMarker(new PointLatLng(##, ##));
marker.Shape = new PinControl();
gmap.Markers.Add(marker);

Cropping an arbitrary wpf geometry

The background to my problem is that I have a bunch of geometries (huge amount, think map over a larger area) split across multiple wpf geometry instances (originally they were PathGeometry, but to reduce memory usage I pre-process them and create StreamGeometries during load). Now what I want to do is to generate tiles from these geometries.
Basically I would like to take a larger geometry object and "cut out" a rectangle of it (my tile) so I get several smaller geometries. Something like the image below:
Notice that I want the result to be a new geometry, not a rendering. I know I can achieve the visual result by applying a clip to a UIElement or by pushing a clip to a drawingvisual.
I've tried using Geometry.Combine with one of the arguments being the clip rectangle, but I can't get it to do what I want (I typically only get the clip rect back, or an empty geometry, depending on which combine mode I use).
Alternatively, if this cannot be done using WPF, is there any other (third party is ok) general purporse geometry API for .NET that can do these kind of operations? Or maybe this can be implemented using other parts of the WPF geometry API?
Code shows the bottom right rectangle like in your "smaller tiles" visualisation:
var geometry = MyOriginalPath.Data.Clone();
var bounds = geometry.Bounds;
var rectangleGeometry = new RectangleGeometry(bounds);
var halfWidth = bounds.Width * 0.5;
var halfHeight = bounds.Height * 0.5;
var bottomQuarter = new RectangleGeometry(
new Rect(bounds.X + halfWidth, bounds.Y + halfHeight,
halfWidth, halfHeight));
var combinedGeometry = new CombinedGeometry(GeometryCombineMode.Exclude,
rectangleGeometry, bottomQuarter);
combinedGeometry = new CombinedGeometry(GeometryCombineMode.Exclude,
geometry, combinedGeometry);
MyBottomQuarterPath.Data = combinedGeometry;
Regards Dave

Bing Map Silverlight control can't pan when user clicks on UIElement (Tunnelling Bubbling)

I am using the Silverlight Bing Maps control in an application. There is a canvas hosted over the map with various UIElements.
A problem I am currently observing is the map mouse-down pans the map correctly, unless the mouse-down originates on a UIElement (Element in question is a MapPolyLine).
UIElements are added to the map with the following code
var outlineBottom = new MapPolyline {
Stroke = new SolidColorBrush(bottomColor),
StrokeThickness = width * TrailBottomLineWidthMultiplier,
Opacity = 1, //opacity,
StrokeMiterLimit = 1,
Locations = locations
};
This results in a poly line of thickness ~5px being added to the map. When the user mouse-downs on the map but the mouse pointer is over the line, it cannot be panned.
How can I stop the MapPolyline above swallowing mouse events so the map can be panned?
Try setting UIElement.IsHitTestVisible = false on your MapPolyline.

Draw custom pushpin in code without using an image

I need to draw a pushpin for the Bing Silverlight control that can have the head be a variable color. I can draw a nice dot like this:
Dim marker As Ellipse = New Ellipse
marker.Fill = New SolidColorBrush(Color.FromArgb(255, 11, 255, 0))
marker.Stroke = New SolidColorBrush(Colors.Gray)
marker.Width = 10
marker.Height = 10
I'll be making dozens of pushpins, each with a slightly different color for the Fill. How can I add the pointy part? I would like to have some amount of flaring out at the top so that it looks more like a pushpin and less like a lollipop.
Examples in C# are welcome as well.
Maybe there's a reason you need it to be a custom one rather than using the built-in pushpin objects, but if not, you can set the background color on those pushpins like so:
myPushpin.Background = new SolidColorBrush(Colors.Gray);
As far as actually drawing your own, I'm not as sure. Could you draw some sort of a triangle?

Should I be using AdornerLayer to avoid clipping my adorner off-screen?

I'm writing some WPF code involving Adorners. I'm using Josh Smith's UIElementAdorner.cs (found in the project on his Infragistics Blog). I'm adorning with a blurb of information text. I need to place my adorner smartly, so that it does not clip off the screen.
What's the best way to find out if I'm going to clip?
I'm using the following code to create and place my adorner. I have a funny feeling that basing whether or not I'll clip on the AdornerLayer isn't the best option.
var infoBubble = new InfoBubble {InformationText = #"I like cheese."};
var adornedElementRect = new Rect(Target.DesiredSize);
var layer = AdornerLayer.GetAdornerLayer(Target);
var adorner = new UiElementAdorner<Control>(Target) { Child = infoBubble };
adorner.Measure(new Size(layer.ActualWidth, layer.ActualHeight));
var adornerRect = new Rect(adorner.DesiredSize);
var top = -1*(adornerRect.Height);
var left = adornedElementRect.Width/2;
// Using layer to judge where to place the adorner
var upperLeftPoint = Target.TranslatePoint(new Point(left, top), layer);
var lowerRightPoint = Target.TranslatePoint(new Point(left + adornerRect.Width,
top + adornerRect.Height), layer);
if (upperLeftPoint.Y < 0) top -= upperLeftPoint.Y; // shift down by Y
if (lowerRightPoint.X > layer.ActualWidth)
left -= (lowerRightPoint.X - layer.ActualWidth); // shift left
Keep in mind that this code is contained in a TargetedTriggerAction that designers (aka users of Blend) are expected to use when they want information blurbs above certain UI elements. Thus, this code will know very little about the element to be adorned or its environment.
Yes, is the best answer I can discern.
According to further reading and some experimentation, when calling GetAdornerLayer we receive the lowest layer above the target control in the visual tree. This means we could get a layer below the AdornerDecorator's layer defined in a Window's template. That lower AdornerDecorator could have ClipToBounds="True" (I have no idea why, but it could).
Knowing this information, I can be relatively certain that the AdorneLayer I'm drawing into is the best bounding box for whatever I'm drawing. I could have the ability to draw outside this box (for example if ClipToBounds were False on a AdornerDecorator lower than the Window's), but I shouldn't count on that ability.

Resources