Bind map center and pushpin in windows phone 8 application - windows-phone-8

I am developing a windows phone 8 application, i have to implement a map control with a pushpin which will show current location of the users, i am assigning current location to my pushpin, now i want this pushpin to be in the center of the map. Can anyone help me out in binding the pushpin to the center of map.
<maps:Map x:Name="MyMap" Center="{Binding}" ZoomLevel="15">
<toolkit:MapExtensions.Children>
<toolkit:Pushpin x:Name="pushpin1" GeoCoordinate="{Binding}">
<toolkit:Pushpin.Template>
<ControlTemplate TargetType="toolkit:Pushpin">
<StackPanel>
<ContentPresenter x:Name="content" Content="{TemplateBinding Content}" HorizontalAlignment="Left"></ContentPresenter>
<Path Data="M0,0L1,1L2,0L2,0L1,0L0,0Z"
Fill="#00AAFF"
Stretch="Fill"
Margin="-2,0"
Height="120"
Width="30"
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Visibility, Mode=TwoWay}"
HorizontalAlignment="Left"
/>
</StackPanel>
</ControlTemplate>
</toolkit:Pushpin.Template>
</toolkit:Pushpin>
</toolkit:MapExtensions.Children>
</maps:Map>

You want use Bing map in Windows Phone 8 App? I have trouble with old Bing Map control in WP8 app. I wrote about it windows phone 8 old map vs new map. Best solution for WP 8 is new Nokia Map control.
In XAML:
xmlns:nokiamap="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Maps.Toolkit;assembly=Microsoft.Phone.Controls.Toolkit"
<nokiamap:Map Name="NokiaMap">
<toolkit:MapExtensions.Children>
<toolkit:Pushpin x:Name="MyPushpin"/>
</toolkit:MapExtensions.Children>
</nokiamap:Map>
//Init Pushpin
private Pushpin MyPushpin { get; set; }
ObservableCollection<DependencyObject> children = MapExtensions.GetChildren(NokiaMap);
var pin = children.FirstOrDefault(x => x.GetType() == typeof(Pushpin)) as Pushpin;
MyPushpin = pin;
// Start geolocator
public void StartGeolocator()
{
Geolocator geolocator = new Geolocator();
geolocator.DesiredAccuracy = PositionAccuracy.High;
geolocator.MovementThreshold = 10;
geolocator.PositionChanged += geolocator_PositionChanged;
geolocator.StatusChanged += geolocator_StatusChanged;
}
}
private void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
myGeoposition = new GeoCoordinate()
{
Latitude = args.Position.Coordinate.Latitude,
Longitude = args.Position.Coordinate.Longitude,
}
MyPushpin.GeoCoordinate = myGeoposition;
NokiaMap.SetView(myGeoposition, NokiaMap.ZoomLevel);
}
See your code Pushpin location binding in windows phone 8 app is not working
void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
Dispatcher.BeginInvoke(() =>
{
ObservableCollection<DependencyObject> children = MapExtensions.GetChildren(MyMap);
var pin = children.FirstOrDefault(x => x.GetType() == typeof(Pushpin)) as Pushpin;
pin.DataContext = args.Position.Coordinate;
//witout binding
//pin.GeoCoordinate = args.Position.Coordinate;
});
}

Related

Mark Mobile Location on Google Map using Xamarin.Android

Sir,
Developed an application using Xamarin on Visual Studio 2017 where I need to locate the current location of mobile when user turn on Location on his android device and then mark that location on Google Map using MarkerOption. For this I have followed steps as guided in following video https://www.youtube.com/watch?v=rCZN1c2azyE. But didn't got current location on map.
Below is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Gms.Maps;
using Android.Locations;
using Android.Util;
using Android.Gms.Maps.Model;
namespace smvdappdev
{
[Activity(Label = "LOCATION MAP")]
//for google map, for gps location
public class UserLocationMap_Act : Activity, IOnMapReadyCallback, ILocationListener
{
//Map variable
private GoogleMap gooMap;
//Location
LocationManager locManager;
String provider;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
SetContentView(Resource.Layout.UserLocationMap);
//Back Button
ActionBar.SetDisplayHomeAsUpEnabled(true);
//Method for Map
SetUpMap();
locManager = (LocationManager)GetSystemService(Context.LocationService);
provider = locManager.GetBestProvider(new Criteria(), false);
Location location = locManager.GetLastKnownLocation(provider);
if (location == null)
{
System.Diagnostics.Debug.WriteLine("No location available!");
}
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Android.Resource.Id.Home:
Finish();
return true;
default:
return base.OnOptionsItemSelected(item);
}
}
//for setting map on fragment placed on activity page
private void SetUpMap()
{
if (gooMap == null)
{
FragmentManager.FindFragmentById<MapFragment>(Resource.Id.fragment1).GetMapAsync(this);
}
}
//to draw map on map display view
public void OnMapReady(GoogleMap googleMap)
{
this.gooMap = googleMap;
//LatLng latlng = new LatLng()
//MarkerOptions mo = new MarkerOptions();
//mo.SetPosition(new LatLng(Convert.ToDouble(32.73), Convert.ToDouble(74.86)));
//mo.SetTitle("Civil Secretarait Jammu");
//googleMap.AddMarker(mo);
googleMap.UiSettings.CompassEnabled = true;
googleMap.UiSettings.ZoomControlsEnabled = true;
googleMap.MoveCamera(CameraUpdateFactory.ZoomIn());
//throw new NotImplementedException();
}
//*** Here all code for getting location via GPS
protected override void OnResume()
{
base.OnResume();
provider = LocationManager.GpsProvider;
//if (locManager.IsProviderEnabled(provider))
//{
locManager.RequestLocationUpdates(provider, 2000, 1, this);
//}
//else
//{
// Log.Info(tag, provider + " is not available. Does the device have location services enabled?");
//}
}
protected override void OnPause()
{
base.OnPause();
locManager.RemoveUpdates(this);
}
public void OnProviderEnabled(string provider)
{
}
public void OnProviderDisabled(string provider)
{
}
public void OnStatusChanged(string provider, Availability status, Bundle extras)
{
}
public void OnLocationChanged(Location location)
{
Double lat, lng;
lat = location.Latitude;
lng = location.Longitude;
MarkerOptions mo = new MarkerOptions();
mo.SetPosition(new LatLng(lat, lng));
//Toast.MakeText(this, "Latitude:" + lat.ToString() + ", Longitude:" + lng.ToString(), ToastLength.Long).Show();
mo.SetTitle("You are here!");
gooMap.AddMarker(mo);
CameraPosition.Builder builder = CameraPosition.InvokeBuilder();
builder.Target(new LatLng(lat, lng));
CameraPosition camPos = builder.Build();
CameraUpdate camUpdate = CameraUpdateFactory.NewCameraPosition(camPos);
gooMap.MoveCamera(camUpdate);
}
}
}
You can just use gooMap.MyLocationEnabled = true. You need to check and request location permission first in order for this to work.
With MyLocationEnabled set to true, it will show a precision circle and a blue dot showing where you are.

Setting up WNS service for windows phone 8 get error after add <Identity> tag

I am setting up windows phone 8.1 push notification with urbanairship. I have SID and Secret key for my app. But when i do following step mentioned in dev.windows WNS-->Live Service site:
To set your application's identity values manually, open the
AppManifest.xml file in a text editor and set these attributes of the
element using the values shown here.
my application is stop working. is any one provide me steps for set up WNS in windows phone 8.1 then it helps me a lot, I spend over the week on this and now really frustrating.
I got success with Push Notification in Windows Phone 8.1/ Windows Apps (Universal Apps). I have implemented sending Push Notification to devices from our own Web Service.
Step 1: Get the Client Secret and Package SID from the dev.windows.com >> Services >> Live Services. You'll need these later in Web Service.
Step 2: In your Windows App, you have to associate your app with the Store. For that, Right click on project >> Store >> Associate App with the Store. Log in with your Dev account and associate your app.
Step 3
You'll need a Channel Uri.
In the MainPage.xaml, add a Button and a Textblock to get your Channel Uri.
XAML Code looks like this:
<Page
x:Class="FinalPushNotificationTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FinalPushNotificationTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Push Notification" Margin="20,48,10,0" Style="{StaticResource HeaderTextBlockStyle}" TextWrapping="Wrap" />
<ScrollViewer Grid.Row="1" Margin="20,10,10,0">
<StackPanel x:Name="resultsPanel">
<Button x:Name="PushChannelBtn" Content="Get Channel Uri" Click="PushChannelBtn_Click" />
<ProgressBar x:Name="ChannelProgress" IsIndeterminate="False" Visibility="Collapsed" />
<TextBlock x:Name="ChannelText" FontSize="22" />
</StackPanel>
</ScrollViewer>
</Grid>
Step 4:
In the MainPage.xaml.cs page, Add the following code snippet i.e. for the Button Click Event. When you run your app, you'll get the Channel Uri in the Console Window. Note down this Channel Uri, you'll need that in Web Service.
private async void PushChannelBtn_Click(object sender, RoutedEventArgs e)
{
var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
ChannelText.Text = channel.Uri.ToString();
Debug.WriteLine(channel.Uri);
}
Step 5:
Now You need a Web Service to send push notification to your device. For that Right Click on your project in Solution Explorer. Add >> New Project >> Visual C# >> Web >> ASP.NET Web Application. Click OK, On Template select Empty. After that Add a new Web Form in your Web Application. Name it SendToast.
Step 6:
Now In the SendToast.aspx.cs, you need to implement methods and functions to get the Access Token using Package SID, Client Secret and Channel Uri. Add your Package SID, Cleint Secret, and Channel Uriin respective places.
The complete code looks like the following code snippet:
using Microsoft.ServiceBus.Notifications;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace SendToast
{
public partial class SendToast : System.Web.UI.Page
{
private string sid = "Your Package SID";
private string secret = "Your Client Secret";
private string accessToken = "";
[DataContract]
public class OAuthToken
{
[DataMember(Name = "access_token")]
public string AccessToken { get; set; }
[DataMember(Name = "token_type")]
public string TokenType { get; set; }
}
OAuthToken GetOAuthTokenFromJson(string jsonString)
{
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
var ser = new DataContractJsonSerializer(typeof(OAuthToken));
var oAuthToken = (OAuthToken)ser.ReadObject(ms);
return oAuthToken;
}
}
public void getAccessToken()
{
var urlEncodedSid = HttpUtility.UrlEncode(String.Format("{0}", this.sid));
var urlEncodedSecret = HttpUtility.UrlEncode(this.secret);
var body =
String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", urlEncodedSid, urlEncodedSecret);
var client = new WebClient();
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
string response = client.UploadString("https://login.live.com/accesstoken.srf", body);
var oAuthToken = GetOAuthTokenFromJson(response);
this.accessToken = oAuthToken.AccessToken;
}
protected string PostToCloud(string uri, string xml, string type = "wns/toast")
{
try
{
if (accessToken == "")
{
getAccessToken();
}
byte[] contentInBytes = Encoding.UTF8.GetBytes(xml);
WebRequest webRequest = HttpWebRequest.Create(uri);
HttpWebRequest request = webRequest as HttpWebRequest;
webRequest.Method = "POST";
webRequest.Headers.Add("X-WNS-Type", type);
webRequest.Headers.Add("Authorization", String.Format("Bearer {0}", accessToken));
Stream requestStream = webRequest.GetRequestStream();
requestStream.Write(contentInBytes, 0, contentInBytes.Length);
requestStream.Close();
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
return webResponse.StatusCode.ToString();
}
catch (WebException webException)
{
string exceptionDetails = webException.Response.Headers["WWW-Authenticate"];
if ((exceptionDetails != null) && exceptionDetails.Contains("Token expired"))
{
getAccessToken();
return PostToCloud(uri, xml, type);
}
else
{
return "EXCEPTION: " + webException.Message;
}
}
catch (Exception ex)
{
return "EXCEPTION: " + ex.Message;
}
}
protected void Page_Load(object sender, EventArgs e)
{
string channelUri = "Your Channel Uri";
if (Application["channelUri"] != null)
{
Application["channelUri"] = channelUri;
}
else
{
Application.Add("channelUri", channelUri);
}
if (Application["channelUri"] != null)
{
string aStrReq = Application["channelUri"] as string;
string toast1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?> ";
string toast2 = #"<toast>
<visual>
<binding template=""ToastText01"">
<text id=""1"">Hello Push Notification!!</text>
</binding>
</visual>
</toast>";
string xml = toast1 + toast2;
Response.Write("Result: " + PostToCloud(aStrReq, xml));
}
else
{
Response.Write("Application 'channelUri=' has not been set yet");
}
Response.End();
}
}
}
Run your web application, you'll get the Result OK response if it successfully sends push notification.
Let me know if you need working sample project.
Hope this helps.
Thanks!

Click to pushpins and display more details of that item in Windows Phone 8

I'm working on a simple map app for windows phone 8. I set multiple pushpins by using windows phone toolkit. I want to show more details info when a pushpin item is tapped.
Here is my code.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<maps:Map Name="MyMap"
CartographicMode="Road" ColorMode="Light"
LandmarksEnabled="True" PedestrianFeaturesEnabled="True">
<toolkit:MapExtensions.Children>
<toolkit:MapItemsControl Name="allDatas">
<toolkit:MapItemsControl.ItemTemplate>
<DataTemplate>
<toolkit:Pushpin GeoCoordinate="{Binding Coordinate}"
Content="{Binding Name}"
Background="Green"
Foreground="Black"
Tap="Pushpin_Tap"/>
</DataTemplate>
</toolkit:MapItemsControl.ItemTemplate>
</toolkit:MapItemsControl>
</toolkit:MapExtensions.Children>
</maps:Map>
</Grid>
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
ObservableCollection<Data> datas = new ObservableCollection<Data>()
{
new Data() { Coordinate = new GeoCoordinate(22.832991,89.539921), Name = "H", Details = "Hospital", Address = "Address of Hospital" },
new Data() { Coordinate = new GeoCoordinate(22.845489,89.539406), Name = "P", Details = "Fire Station", Address = "Address of Fire"},
new Data() { Coordinate = new GeoCoordinate(22.818019,89.54563), Name = "F", Details = "Police Station", Address = "Address of Police"}
};
ObservableCollection<DependencyObject> children = MapExtensions.GetChildren(MyMap);
var obj = children.FirstOrDefault(x => x.GetType() == typeof(MapItemsControl)) as MapItemsControl;
obj.ItemsSource = datas;
}
private void Pushpin_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
Pushpin pushpin = sender as Pushpin;
if (pushpin.Content != null)
{ //Here i want to show details
MessageBox.Show(pushpin.Content.ToString());
}
}
You can do this:
pushpin.Tap += delegate
{
if (AppSettings["PushpinOpen"] == true)
{
pushpin.Content = attraction.Content;
AppSettings["PushpinOpen"] = attraction.Title;
AppSettings.Save();
}
else
{
pushpin.Content = attraction.Title;
AppSettings.Remove("PushpinOpen");
}
};
You don't have to do it with IsolatedStorageSettings (AppSettings, in this case). You just need to check if the pushpin is already opened, and if it isn't, you can change the content of the pushpin into more detailed information.
private void Pushpin_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var element = (FrameworkElement)sender;
Data data = (Data)element.DataContext;
MessageBox.Show(data.Address);
}
It may be a little bit late, but I tried to achieve the same. Show more data on pushpin Tap.
I found a working answer here altought it is an answer for a bit different question.

WP8 MediaLibrary, view photo in LongListMultiSelector

I need to show all photo present in a my device (WP8) in a LongListMultiSelector.
i use this method
MediaPlayer.Queue.ToString();
MediaLibrary mediaLibrary;
PictureAlbum cameraRoll = null;
foreach (MediaSource source in MediaSource.GetAvailableMediaSources())
{
if (source.MediaSourceType == MediaSourceType.LocalDevice)
{
mediaLibrary = new MediaLibrary(source);
PictureAlbumCollection allAlbums = mediaLibrary.RootPictureAlbum.Albums;
foreach (PictureAlbum album in allAlbums)
{
if (album.Name == "Camera Roll")
{
cameraRoll = album;
}
}
}
}
List<BitmapImage> lstBitmapImage = new List<BitmapImage>();
foreach (Picture p in cameraRoll.Pictures)
{
BitmapImage b = new BitmapImage();
b.SetSource(p.GetThumbnail());
lstBitmapImage.Add(b);
}
PhotoHubLLS.ItemsSource = lstBitmapImage;
In a XAML i have this image setting
<Image HorizontalAlignment="Left" Margin="6,6,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Source="{Binding}"/>
It all works perfectly, but I have some questions.
I would like to Zoom on single picture, on image tap i'm insert this code
FrameworkElement fe = sender as FrameworkElement;
if (fe != null)
{
CurrentPicture = fe.DataContext as Picture;
}
but is null a datacontext because I used "Source".
how can I do?
It depends on which event you've wired up. If you're handling the SelectionChanged event, you can retrieve the BitmapImage (not Picture) from the AddedItems collection in the SelectionChangedEventArgs event arguments parameter:
private void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
BitmapImage bmp = e.AddedItems[0] as BitmapImage;
}
}
Alternatively if you're handling the Tap event of the Image element in the LongListSelector's ItemTemplate, then you can retrieve the BitmapImage from the sender parameter:
Image imgElement = sender as Image;
BitmapImage bmp = imgElement.Source as BitmapImage;

how to add google map in windows phone 8 app

I am developing an app which uses Map service for Windows Phone 8.
I followed a link
http://themightyhedgehog.blogspot.de/2013/01/how-to-use-google-maps-in-your-own.html
and tries to develop an app containing Google Map.
But I got an error in Xaml on line
MapAppScope:BindingHelpers.TileSource="{Binding GoogleMap}"
and the error I got are:
BuildingHelpers is not supported in Silverlight.
The attachable property 'TileSource' was not found in type 'BuildingHelpers'.
The Namespace prefix "MapAppScope" is not defined.
In Xaml:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Microsoft_Phone_Controls_Maps:Map
Name="MyMap"
Grid.Column="1"
LogoVisibility="Collapsed"
d:LayoutOverrides="GridBox"
MapAppScope:BindingHelpers.TileSource="{Binding GoogleMap}"
Margin="0,0,0,2">
<Microsoft_Phone_Controls_Maps:Map.Mode>
<MSPCMCore:MercatorMode/>
</Microsoft_Phone_Controls_Maps:Map.Mode>
</Microsoft_Phone_Controls_Maps:Map>
</Grid>
In .CS:
namespace Google_Map_App
{
public enum GoogleType
{
Street = 'm',
Hybrid = 'y',
Satellite = 's',
Physical = 't',
PhysicalHybrid = 'p',
StreetOverlay = 'h',
WaterOverlay = 'r'
}
public class Google : TileSource
{
public Google()
{
MapType = GoogleType.Street;
UriFormat = #"http://mt{0}.google.com/vt/lyrs={1}&z={2}&x={3}&y={4}";
}
public GoogleType MapType { get; set; }
public override Uri GetUri(int x, int y, int zoomLevel)
{
return new Uri(
string.Format(UriFormat, (x % 2) + (2 * (y % 2)),
(char)MapType, zoomLevel, x, y));
}
}
public static class BindingHelpers
{
//Used for binding a single TileSource object to a Bing Maps control
#region TileSourceProperty
// Name, Property type, type of object that hosts the property, method to call when anything changes
public static readonly DependencyProperty TileSourceProperty =
DependencyProperty.RegisterAttached("TileSource", typeof(TileSource),
typeof(BindingHelpers), new PropertyMetadata(SetTileSourceCallback));
// Called when TileSource is retrieved
public static TileSource GetTileSource(DependencyObject obj)
{
return obj.GetValue(TileSourceProperty) as TileSource;
}
// Called when TileSource is set
public static void SetTileSource(DependencyObject obj, TileSource value)
{
obj.SetValue(TileSourceProperty, value);
}
//Called when TileSource is set
private static void SetTileSourceCallback(object sender, DependencyPropertyChangedEventArgs args)
{
var map = sender as Map;
var newSource = args.NewValue as TileSource;
if (newSource == null || map == null) return;
// Remove existing layer(s)
for (var i = map.Children.Count - 1; i >= 0; i--)
{
var tileLayer = map.Children[i] as MapTileLayer;
if (tileLayer != null)
{
map.Children.RemoveAt(i);
}
}
var newLayer = new MapTileLayer();
newLayer.TileSources.Add(newSource);
map.Children.Add(newLayer);
}
#endregion
}
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
}
}
Note that using Google Maps tiles in the Bing Maps WP8 or Windows 8 control is against the terms of use of both the Bing Maps and Google Maps API's. Any app found in the app store doing this will be removed.