I'm using Bing maps with WPF and C# and I'm trying to retrieve the children that were added into the map, primarily to get their coordinates to save into the database and calculate distance between two children on different map controls.
Below is how I'm adding the child 'pushpin' into one of the maps.
bmMapdestination.Children.Clear();
e.Handled = true;
var mousePosition = e.GetPosition(bmMapdestination);
Location pinLocation = bmMapdestination.ViewportPointToLocation(mousePosition);
Pushpin pin = new Pushpin() { Location = pinLocation , Name = "DestPin"};
bmMapdestination.Children.Add(pin);
CalculateDistance();
After a couple of days coding I've come up with a bit of code to retrieve pushpins from the Bing Maps control that works how I wanted it to, this works fine when extracting for one pushpin per map, but I'm sure it could be useful for more than one.
As shown below I've used a foreach method to get the Bing Maps children, which then allowed me to work with it.
public void CalculateDistance()
{
Location pinLocation = new Location();
foreach(Pushpin pin in bmMapdestination.Children)
{
pinLocation = pin.Location;
}
txtEditPickUpEditLocation.Text = pinLocation.Latitude.ToString()+","+pinLocation.Longitude.ToString();
}
Related
Is it possible to use the Map API with a custom designed map? I'd like to build an app using a map of the building I work in, with all the fancy map abilities: zoom, pan, pushpins, points of interest, etc.
Here is the code I'm using to replace the default map:
MapZoomLevelRange range;
range.Min = 0;
range.Max = 5;
LocalMapTileDataSource dataSource = new LocalMapTileDataSource("ms-appx:///Assets/Maps/{zoomlevel}/{x}/{y}.png");
MapTileSource tileSource = new MapTileSource(dataSource);
tileSource.ZoomLevelRange = range;
tileSource.Layer = MapTileLayer.BackgroundReplacement;
TestMap1.Style = MapStyle.None;
tileSource.IsFadingEnabled = false;
TestMap1.TileSources.Add(tileSource);
I am now working on restricting the size of the map to the number of tiles I have. Horizontally the map repeats over and over. Vertically, it only shows based on the height of the tiles available.
My question is similar to this but I am not sure how my code relates to the answers given in the other post.
I am using MapKit in Xamarin iOS to create a custom map for my Xamarin iOS project. I have a few different custom things happening at the moment, and am using Polygons annotations and now circles that are added to my map.
I have just started implementing adding MKCircle to my map, but when I try to add Circle Overlays to my map I am receiving this error:
System.ArgumentNullException: Value cannot be null. Parameter name: polygon
I think it is being I trying to return the same overlay to two renderers, but I am not sure how to ammend this. Here is my code:
for(int i=0; i < hazards.Count; i++) //This adds 3 circles in my example
{
LatLong ltlng = JsonConvert.DeserializeObject<LatLong>(hazards[i].coordinates);
coords[i].Latitude = Convert.ToDouble(ltlng.latitude);
coords[i].Longitude = Convert.ToDouble(ltlng.longitude);
var overlay = MKCircle.Circle(coords[i], Convert.ToDouble(hazards[i].radius));
nativeMap.AddOverlay(overlay); //this is the suspected problem
}
And my renderer code here:
MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlayWrapper)
{
if (!Equals(overlayWrapper, null))
{
var overlay = ObjCRuntime.Runtime.GetNSObject(overlayWrapper.Handle) as IMKOverlay;
polygonRenderer = new MKPolygonRenderer(overlay as MKPolygon)
{
FillColor = UIColor.Red,
StrokeColor = UIColor.Blue,
Alpha = 0.4f,
LineWidth = 9
};
}
return polygonRenderer;
}
Do I need to add something to my renderer code like this?:
circleRenderer = new MKCircleRenderer(overlay as MKCircle){};
It appears all your overlays are MKCircle based:
var overlay = MKCircle.Circle(coords[i]
In your GetOverlayRenderer you casting all overlays received as MKPolygon objects which will result in a null object.
polygonRenderer = new MKPolygonRenderer(overlay as MKPolygon)
You are then trying to create a MKPolygonRenderer render for each of your overlays which would not work if you actually did have an MKCircle-based overlay.
If all your overlays are MKCircle based, then yes use:
new MKCircleRenderer(overlay as MKCircle){};
Since the Map already shows the user location (with IsShowingUser) I just want to zoom to this location. Is this easily possible or do I need to get the location on every platform, since I don't find any GeoLocation object. Only the GeoCoder...
Is this not a common usecase to zoom to users position?
You will need to call MoveToRegion method with the position you are interested in.
You can use Geolocator Plugin for Xamarin to get the location in PCL project:
var locator = CrossGeolocator.Current;
var position = await locator.GetPositionAsync(10000);
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(position.Latitude, position. Longitude),
Distance.FromMiles(1)));
Updated: Xamarin Forms now includes by default Xamarin.Essentials: Geolocation
Center the map on your location:
var position = await locator.GetPositionAsync(5000);
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(position.Latitude, position.Longitude), Distance.FromMiles(1))
Zoom the map on its current position:
var zoomLevel = 9; // between 1 and 18
var latlongdegrees = 360 / (Math.Pow(2, zoomLevel));
map.MoveToRegion(new MapSpan (map.VisibleRegion.Center, latlongdegrees, latlongdegrees));
Ref: https://developer.xamarin.com/guides/xamarin-forms/working-with/maps/
Is this not a common usecase to zoom to users position?
Yes, it is. For iOS just use the MKMapView ShowUserLocation property.
From Apple documentary:
Setting this property to YES causes the map view to use the Core Location framework to find the current location and try to display it on the map.
Source: https://developer.apple.com/library/ios/documentation/MapKit/Reference/MKMapView_Class/#//apple_ref/occ/instp/MKMapView/showsUserLocation
So how can you do it in Xamarin?
You will need a custom renderer which extends Xamarin Forms MapRenderer. Get the native map and set the ShowUserLocation property to true.
Here is an example:
private void MoveToCurrentPosition()
{
var nativeMap = Control as MKMapView;
if (nativeMap == null)
return;
nativeMap.ShowsUserLocation = true;
}
Also set nativeMap.SetUserTrackingMode(MKUserTrackingMode.Follow, true); to automatically follow the user.
This may not work when the map is initialised, since iOS couldn't get the user location yet. So if you need to display the current user location when the map appears, just use an EventHandler for MKUserLocationEventArgs and use the DidUpdateUserLocation event. You can do it like this:
private EventHandler<MKUserLocationEventArgs> _didUpdateUserLocationEventHandler;
// In OnElementChanged:
_didUpdateUserLocationEventHandler = (_, __) =>
{
MoveToCurrentPosition();
nativeMap.DidUpdateUserLocation -= _didUpdateUserLocationEventHandler;
};
nativeMap.DidUpdateUserLocation += _didUpdateUserLocationEventHandler;
Do not forget to deregister this event. Use it just for a usual initialise behaviour. The user should be free to scroll on the map as he likes.
This is an issue I have been trying to tackle for a while and decided to reach out for help. I am creating an ESRI ArcGIS Desktop Add-In that allows the user to draw a polygon and then have it added to the map. I am able to capture the polygon and add it to the map, the issue is the transparency. Currently and by default it is 100% opacity and solid. I want to make it around 50% opacity so the user can see the data behind it.
Here is the code I have so far:
public static void AddPolygonToMap(IActiveView ActiveViewInstance, IGeometry NewGeo)
{
//Local Variable Declaration
var fillShapeElement = default(IFillShapeElement);
var element = default(IElement);
var graphicsContainer = default(IGraphicsContainer);
var simpleFilleSymbol = default(ISimpleFillSymbol);
var newRgbColor = default(IRgbColor);
var lineSymbol = default(ILineSymbol);
//Use the IElement interface to set the Envelope Element's geo
element = new PolygonElement();
element.Geometry = NewGeo;
//QI for the IFillShapeElement interface so that the symbol property can be set
fillShapeElement = element as IFillShapeElement;
//Create a new fill symbol
simpleFilleSymbol = new SimpleFillSymbol();
//Create a new color marker symbol of the color black;
newRgbColor = new RgbColor();
newRgbColor.Red = 0;
newRgbColor.Green = 0;
newRgbColor.Blue = 0;
//Create a new line symbol so that we can set the width outline
lineSymbol = new SimpleLineSymbol();
lineSymbol.Color = newRgbColor;
lineSymbol.Width = 2;
//Setup the Simple Fill Symbol
simpleFilleSymbol.Color = newRgbColor;
simpleFilleSymbol.Style = esriSimpleFillStyle.esriSFSHollow;
simpleFilleSymbol.Outline = lineSymbol;
fillShapeElement.Symbol = simpleFilleSymbol;
//QI for the graphics container from the active view allows access to basic graphics layer
graphicsContainer = ActiveViewInstance as IGraphicsContainer;
//Add the new element at Z order 0
graphicsContainer.AddElement((IElement)fillShapeElement, 0);
//Show the new graphic
ActiveViewInstance.Refresh();
}
I know that this is possible somehow and I am sure it's just a line or two missing but any help would be much appreciated.
V/r,
Josh
This looks to be a graphic element that you are creating. Graphic elements do not support transparency other than 100% transparent or 0% transparent. This is outlined in the following documentation:
IColor.Transparency Property
http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#//001w000000nt000000
For graphic elements, 0 for transparent and 255 for opaque are the only supported values.
I hope this helps!
I have an application with pinned secondary live tiles, they are showing days on the back of the tile and I would like to reduce the number of days each day. Now the problem is, that I don't want to change the other properties of the tile (so Title, Images, etc), only the content (a string) on the back: FlipTileData.BackContent
So I don't want to create new FlipTileData to pass that as a parameter for the Update method.
Second problem: How do I even know which tile is what I'm about to update?
I've tried this:
foreach (ShellTile tile in ShellTile.ActiveTiles) but tile has no attribute that gives me a help. Should I use NavigationUri to find out which tile is that?
Follow this example Working with Live Tiles in Windows Phone 7 and it should solve your problems.
Notice the x.NavigationUri.ToString().**Contains("Title=SecondaryTile")** on the code.
EDIT:
Combining a few lines of code from that website:
// modify Application Secondary Tile data
private void updateTile_Click(object sender, RoutedEventArgs e)
{
// get application specific tile - EXAMPLE
ShellTile Tile = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("Title=SecondaryTileEXAMPLE_TITLE"));
if (null != tile)
{
// create a new data for tile
StandardTileData data = new StandardTileData();
// tile foreground data
data.Title = "Title text here";
data.BackgroundImage = new Uri("/Images/Blue.jpg", UriKind.Relative);
data.Count = random.Next(99);
// to make tile flip add data to background also
data.BackTitle = "Secret text here";
data.BackBackgroundImage = new Uri("/Images/Green.jpg", UriKind.Relative);
data.BackContent = "Back Content Text here...";
// update tile
tile.Update(data);
}
}