Xamarin IOS Draggable Google Map Marker - google-maps

I am trying to drag a marker (Google Map API iOS) in iOS. I am not sure where I am going wrong. I can see the marker on the google map but the marker is not dragging.
I have used a custom renderer partial view to show the map. Following is the code :
[assembly: ExportRenderer(typeof(RegisterFacilityIOSMapView), typeof(RegisterFacilityMapViewRenderer))]
namespace RadLoc.iOS.Renderers
{
public class RegisterFacilityMapViewRenderer : ViewRenderer
{
MapView mapView;
CLLocationManager LocMgr;
Marker marker;
CameraPosition camera;
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
try
{
LocMgr = CLLocationManagerSingleton.Instance;
camera = CameraPosition.FromCamera(latitude: LocMgr.Location.Coordinate.Latitude, longitude: LocMgr.Location.Coordinate.Longitude, zoom: 10);
mapView = MapView.FromCamera(CGRect.Empty, camera);
//mapView.MyLocationEnabled = true;
mapView.AddObserver(this, new NSString("My Location"), NSKeyValueObservingOptions.New, IntPtr.Zero);
mapView.UserInteractionEnabled = true;
SetNativeControl(mapView);
UIImage color = Marker.MarkerImage(UIColor.FromRGB(87, 188, 236));
var circleCenter = new CLLocationCoordinate2D(LocMgr.Location.Coordinate.Latitude, LocMgr.Location.Coordinate.Longitude);
marker = Marker.FromPosition(circleCenter);
marker.UserData = new Foundation.NSObject();
//marker.Position = circleCenter;
marker.Icon = color;
marker.Title = "My Loc";
marker.ZIndex = 9999;
marker.Draggable = true;
mapView.DraggingMarkerStarted += (s, ee) =>
{
};
mapView.DraggingMarkerEnded += (s, ee) =>
{
};
mapView.DraggingMarker += (s, ee) =>
{
};
marker.Map = mapView;
marker.Draggable = true;
}
catch (Exception ee)
{
}
}
}
}

Related

Context.drawImage not working after image.onload

I'm trying to build a free hand drawing application using the html canvas element , and so i'm trying to implement the 'Undo' feature which basically takes a snapshot of the current state of the canvas and then saves it on a list of some sort when the user draws something on the canvas, and when the user presses the undo button it pops the last state saved and draws in onto the canvas . I've tried calling context.drawImage() after image.onload as shown but still no use.
export class WhiteboardScreenComponent implements OnInit, AfterViewInit {
#ViewChild('myCanvas')
myCanvas: ElementRef<HTMLCanvasElement>;
painting: boolean = false;
strokeWidth: number = 2;
strokeColor: string = this.colors[this.selectedColor];
lineStyle: CanvasLineCap = 'round';
ctx: CanvasRenderingContext2D;
undoHistory: any[] = [];
constructor() { }
ngOnInit(): void { }
ngAfterViewInit(): void {
this.ctx = this.myCanvas.nativeElement.getContext('2d');
this.resizeCanvas();
this.myCanvas.nativeElement.addEventListener('mousedown', this.startPainting);
this.myCanvas.nativeElement.addEventListener('mouseup', this.finishPainting);
this.myCanvas.nativeElement.addEventListener('mousemove', this.draw);
}
startPainting = (e) => {
this.painting = true;
this.ctx.beginPath();
this.ctx.moveTo(e.clientX, e.clientY);
}
//saving the state of the canvas here
finishPainting = (e) => {
let src = this.myCanvas.nativeElement.toDataURL("image/png");
this.undoHistory.push(src);
this.ctx.closePath();
this.painting = false;
}
draw = (e) => {
if (!this.painting) return;
this.setProperties();
this.ctx.lineTo(e.clientX, e.clientY);
this.ctx.stroke();
}
setProperties(): void {
this.ctx.lineWidth = this.strokeWidth;
this.ctx.lineCap = this.lineStyle;
this.ctx.strokeStyle = this.strokeColor;
}
//fetching the last saved state and drawing it onto the canvas
undo(): void {
if (this.undoHistory.length > 0) {
let image = new Image();
image.onload = () => {
this.ctx.drawImage(image, 0, 0);
};
image.src = this.undoHistory.pop();
}
}
}
Before calling the drawImage() method, you're supposed to clear the screen , that can be accomplished by simply resizing the canvas to re-draw it, or calling clearRect().

Custom marker at Windows Phone Map control

I use this code to add custom marker to BING map control. The Map component can't draw Image(), but text works fine. Am I wrong?
private void AddMarkerToMap(double Latitude, double Longitude, string Name)
{
Image markerImg = new Image { Width = 63, Height = 46 };
Uri imgUri = new Uri("Images/GeoPin.png", UriKind.RelativeOrAbsolute);
if (imgUri == null)
{
throw new Exception("Image can't be find");
}
markerImg.Source = new BitmapImage(imgUri);
markerImg.Tag = Name;
//markerImg.Tap += delegate
//{
// // handle tap
//};
var overlay = new MapOverlay
{
PositionOrigin = new Point(0.5, 0.5),
GeoCoordinate = new GeoCoordinate(Latitude, Longitude),
Content = markerImg,
//Content = Name,
};
var mapLayer = new MapLayer { overlay };
MyMap.Layers.Add(mapLayer);
}
If you want to add a pin to Map, use MapIcon class. This can display images as well as text.
private void AddMapIcon()
{
MapIcon MapIcon1 = new MapIcon();
MapIcon1.Location = new Geopoint(new BasicGeoposition() { Latitude = 47.620, Longitude = -122.349 });
MapIcon1.NormalizedAnchorPoint = new Point(0.5, 1.0);
MapIcon1.Title = "Space Needle";
MapIcon1.Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/customicon.png"));
MapControl1.MapElements.Add(MapIcon1);
}
Does MapIcon present in Windows Phone 8 SDK?
You could use the Phone.Controls.Toolkit in order to have a custom Pushpin as an image on your map.
Reference: Image as pushpin on maps - Windows phone 8

Add fixed MapLayer once

In my application I have a map for which the first thing I do (on launching) is to add a custom MapLayer (which I populate with many MapOverlays/pushpins).
When I browse to another page of the app and then return to the map page, everything (ie the MapLayer that was drawn on my map) is gone.
It takes time to add it all over again each time the user navigates to the map page so I would like it to be fixed, drawn/added just once.
Any suggestions?
edit, added the code [I removed some details, the structure remains the same]:
private async void drawStations()
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection("stasy.sqlite");
List<line1_stations> lines = await conn.QueryAsync<line1_stations>("select *...");
Microsoft.Phone.Maps.Controls.MapLayer layer = new Microsoft.Phone.Maps.Controls.MapLayer();
Pushpin p;
foreach (line1_stations a in lines)
{
double sLat = Convert.ToDouble(a.lat);
double sLon = Convert.ToDouble(a.lon);
p = new Pushpin();
p.Location = new GeoCoordinate(sLat, sLon);
p.Tap += img_Tap;
p.Content = "...";
p.Foreground = new SolidColorBrush(Colors.Transparent);
p.Width = 30;
p.Height = 30;
MapOverlay overlay1 = new MapOverlay();
overlay1.Content = p;
overlay1.GeoCoordinate = new GeoCoordinate(sLat, sLon);
overlay1.PositionOrigin = new Point(0.0, 1.0);
layer.Add(overlay1);
}
myMap.Layers.Add(layer);
}
You can try to create your MapLayer as a public property in App.xaml.cs and set it only when your app is running first time.
Then create an instance of app inside page with your map and add your MapLayer to your Map layers inside OnNavigatedTo event.
Define a flag in app level. here is the sample
// In App.xaml.cs
public static bool IsLaunched = false;
private void Application_Launching(object sender, LaunchingEventArgs e)
{
IsLaunched =true;
}
//In your map screen
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if(App.IsLaunched)
{
drawStations();
//Set App flage to false
App.IsLaunched = false;
}
}
private async void drawStations()
{
SQLiteAsyncConnection conn = new SQLiteAsyncConnection("stasy.sqlite");
List<line1_stations> lines = await conn.QueryAsync<line1_stations>("select *...");
Microsoft.Phone.Maps.Controls.MapLayer layer = new Microsoft.Phone.Maps.Controls.MapLayer();
Pushpin p;
foreach (line1_stations a in lines)
{
double sLat = Convert.ToDouble(a.lat);
double sLon = Convert.ToDouble(a.lon);
p = new Pushpin();
p.Location = new GeoCoordinate(sLat, sLon);
p.Tap += img_Tap;
p.Content = "...";
p.Foreground = new SolidColorBrush(Colors.Transparent);
p.Width = 30;
p.Height = 30;
MapOverlay overlay1 = new MapOverlay();
overlay1.Content = p;
overlay1.GeoCoordinate = new GeoCoordinate(sLat, sLon);
overlay1.PositionOrigin = new Point(0.0, 1.0);
layer.Add(overlay1);
}
myMap.Layers.Add(layer);
}

How can I use Writablebitmap in ScheduledTask in windows phone 8?

I want to update my live tile by creating and saving a writable bitmap image in scheduled task agent.my code works inside the app but in background task, it breaks into the debugger
I'm using this simple code:
protected override void OnInvoke(ScheduledTask task)
{
#if DEBUG_AGENT
ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(30));
#endif
CreateWideTile();
NotifyComplete();
}
and my code to create and save image is this:
private void CreateWideTile()
{
int width = 691;
int height = 336;
string imagename = "WideBackground";
WriteableBitmap b = new WriteableBitmap(width, height);
var canvas = new Grid();
canvas.Width = b.PixelWidth;
canvas.Height = b.PixelHeight;
var background = new Canvas();
background.Height = b.PixelHeight;
background.Width = b.PixelWidth;
//Created background color as Accent color
SolidColorBrush backColor = new SolidColorBrush(Colors.Red);
background.Background = backColor;
var textBlock = new TextBlock();
textBlock.Text = "Example text";
textBlock.FontWeight = FontWeights.Normal;
textBlock.TextAlignment = TextAlignment.Left;
textBlock.Margin = new Thickness(20, 20, 0, 0);
textBlock.TextWrapping = TextWrapping.Wrap;
textBlock.Foreground = new SolidColorBrush(Colors.White); //color of the text on the Tile
textBlock.FontSize = 30;
canvas.Children.Add(textBlock);
b.Render(background, null);
b.Render(canvas, null);
b.Invalidate(); //Draw bitmap
//Save bitmap as jpeg file in Isolated Storage
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream imageStream = new IsolatedStorageFileStream("/Shared/ShellContent/" + imagename + ".jpg", System.IO.FileMode.Create, isf))
{
b.SaveJpeg(imageStream, b.PixelWidth, b.PixelHeight, 0, 100);
}
}
}
when I test the app, after executing background task, an error comes that point to Debugger.Break();
private static void UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
Debugger.Break();
}
}
I don't understand the reason. my code works in foreground app but not in background ...
any solution ????
You should use dispatcher, because WriteableBitmap.Render should be used in the UI thread:
protected override void OnInvoke(ScheduledTask task)
{
Deployment.Current.Dispatcher.BeginInvoke( () =>
{
CreateWideTile();
NotifyComplete();
} );
}

how to add image to the location over a map (windows phone 8)

i am following the example
Nokia blog but my problem is ,
1> i need to add image to the location point instead of color
2> i want to show detail information in the popup like Google map
May this help you.
Here i had use textblock to show custom data. Background image for a stack panel
Private void ShoeCustomPushPuin()
{
Pushpin pushPin = null;
StackPanel stackPanel = null;
TextBlock txtblkDownloadSpeed = null;
TextBlock txtblkUploadSpeed = null;
GeoCoordinate cordinates = null;
try
{
cordinates = new GeoCoordinate();
pushPin = new Pushpin();
stackPanel = new StackPanel();
txtblkDownloadSpeed = new TextBlock();
txtblkUploadSpeed = new TextBlock();
cordinates.Latitude = Your latitude value;
cordinates.Longitude = your longitude value;
txtblkUploadSpeed.Text = your data;
txtblkDownloadSpeed.Text =your data;
ImageBrush imgbrush= new ImageBrush
{
ImageSource = new BitmapImage(new Uri("your background image path", UriKind.Relative)),
};
stackPanel.Background = imgbrush;
stackPanel.Children.Add(txtblkDownloadSpeed);
stackPanel.Children.Add(txtblkUploadSpeed);
pushPin.Content = stackPanel;
pushPin.GeoCoordinate = cordinates;
MapOverlay overlay = new MapOverlay
{
GeoCoordinate = cordinates,
Content = pushPin
};
MapLayer layer = new MapLayer();
layer.Add(overlay);
mapHistory.Center = cordinates;
mapHistory.Layers.Add(layer);
}
catch (Exception ex)
{
}
}