Xamarin Android Google Map - Add marker where user clicks - google-maps

In Xamarin Forms, I am using a custom renderer in Android for a map I have implemented using Android.Gms.Maps I want to write functionality that adds a marker in the area a user clicked on the map.
public async void OnMapReady(GoogleMap googleMap)
{
map.MapClick+= HandleMapClick;
}
In my HandleMapClick() function, how do I use the addMarker() function to add a marker to the area which a user clicked on the map?

The GoogleMap.MapClickEventArgs contains a "Point" that contains the lat/long of the user' click. Create a MarkerOption, assign it that point and add it to your map.
googleMap.MapClick += (object sender, GoogleMap.MapClickEventArgs e) =>
{
using (var markerOption = new MarkerOptions())
{
markerOption.SetPosition(e.Point);
markerOption.SetTitle("StackOverflow");
// save the "marker" variable returned if you need move, delete, update it, etc...
var marker = googleMap.AddMarker(markerOption);
}
};

Related

How can I refresh google map programmatically after using animateCamera()?

newPosition = new CameraPosition(new LatLng(latitude, longitude), zoomLevel, tilt, currentBearing);
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(newPosition);
googleMap.animateCamera(cameraUpdate);
When I zoom in or move the camera to another point using animateCamera(), it takes a long time for it to refresh the map (it looks blurry). But if I tap the screen or slightly move the camera manually after animation ends, it immediately refreshes.
it looks like this after moving the camera
I want it to refresh and look like this after animation
I searched it in google maps documents but I didn't find a method for refreshing the map. Is there a way to refresh it programmatically?
I fixed this by calling moveCamera() when the animation ends. I am moving the camera to the same location just to make google maps load the map immediately. Couldn't find a better way.
CameraPosition newPosition = newCameraPosition(newLatLng(latitude,longitude), zoomLevel, tilt, currentBearing);
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(newPosition);
googleMap.animateCamera(cameraUpdate, new GoogleMap.CancelableCallback() {
#Override public void onCancel() {}
#Override
public void onFinish() {
googleMap.moveCamera(cameraUpdate);
}
});

How to show the path and distance on Google Map - Xamarin

I have a page(fragment) that shows google maps together with 1 marker icon. So now i would like to pass source and destination coordinates to this map so that it can show the shortest route together with the distance in Km. E.g i want the map to show the blue path in the image below :
Here is my code :
private void SetUpMap()
{
if (GMap == null)
{
ChildFragmentManager.FindFragmentById<MapFragment>(Resource.Id.googlemap).GetMapAsync(this);
}
}
public void OnMapReady(GoogleMap googleMap)
{
this.GMap = googleMap;
GMap.UiSettings.ZoomControlsEnabled = true;
LatLng latlng = new LatLng(Convert.ToDouble(gpsLatitude), Convert.ToDouble(gpsLongitude));
CameraUpdate camera = CameraUpdateFactory.NewLatLngZoom(latlng, 15);
GMap.MoveCamera(camera);
MarkerOptions options = new MarkerOptions()
.SetPosition(latlng)
.SetTitle("Chennai");
GMap.AddMarker(options);
}
I got my answer from this post :
Adding polyline between two locations google maps api v2
I converted the java code to C# and it worked fine.

How to add a dynamic PushPin to map in WP8.1

I'm currently trying to develop an simple application that allows user to add new pushpins. I'm currently using following code to add new pushpins,
Pushpin pushpin1 = new Pushpin();
pushpin1.GeoCoordinate = MyGeoPosition;
pushpin1.Content = "My car";
MapOverlay overlay1 = new MapOverlay();
overlay1.Content = pushpin1;
overlay1.GeoCoordinate = MyGeoPosition;
layer1.Add(overlay1);
myMap.Layers.Add(layer1);
But, to use this code, I need the latitude and longitude of the location that user has selected. So how can I get the latitude and longitude of the location that user has selected. (Simply geo-coordinate) I know I need to write a event handler, But I don't know the way that it has to be implemented... Thank you...
Try This
MapA = new Map();
MapA.Tap += MapA_Tap;
void MapA_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
GeoCoordinate location = MapA.ConvertViewportPointToGeoCoordinate(e.GetPosition(MapA));
//display pushpin by using location.latitude and location.longitude
}
There are multiple map events like
CenterChaged, MapTapped
you can handle those events to add your push pin. here is MapTapped example
async private void map_MapTapped(MapControl sender, MapInputEventArgs args)
{
var MyGeoPosition = args.Location;
//....
}

Get marker position before dragging primefaces

I want to store the previous location before dragging a marker using PrimeFaces GMap - Draggable Markers
How to do it ?
showcase : GMap - Draggable Markers :
http://www.primefaces.org/showcase/ui/gmapDraggableMarkers.jsf
You could store copies of the original Marker objects and then, in the onMarkerDrag handler, you could find the original Marker that corresponds to the one passed by the MarkerDragEvent.
I say "copies" because it is possible that Primefaces modifies the LatLng of original Marker instead of creating a new one (most likely). You can use the "data" or "title" attributes to give them IDs and correctly match the copied Markers.
I can probably explain this with code, let me know if you need help.
Edit:
To meet your requirement, I would adapt the Primefaces showcase example as follows (notice that it requires the Marker's title to be unique. If this is not possible, implement this using the data attribute of the Marker class.):
package org.primefaces.examples.view;
//...
public class MapBean implements Serializable {
private MapModel draggableModel;
private Map<String, LatLng> positions = new HashMap<String, LatLng>(); // new
public MapBean() {
draggableModel = new DefaultMapModel();
positions.put("Konyaalti", new LatLng(36.879466, 30.667648));
positions.put("Ataturk Parki", new LatLng(36.883707, 30.689216));
positions.put("Karaalioglu Parki", new LatLng(36.879703, 30.706707));
positions.put("Kaleici", new LatLng(36.885233, 30.702323));
for (Map.Entry<String, LatLng> e : positions.entrySet()) {
Marker m = new Marker(e.getValue(), e.getKey());
m.setDraggable(true);
draggableModel.addOverlay(m);
}
}
public void onMarkerDrag(MarkerDragEvent event) {
marker = event.getMarker();
addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO, "Marker Dragged", "Lat:" + marker.getLatlng().getLat() + ", Lng:" + marker.getLatlng().getLng()));
// update position and get the old one
LatLng oldPosition = positions.put(marker.getTitle(), marker.getLatlng());
// ...
}
// ...
}

WP8 Deleting Images from Map (Error when navigating back to page)

I have a Map that has several Images placed on it (inside the page_loaded event)
MapLayer pinLayer = new MapLayer();
MapOverlay pin50 = new MapOverlay();
pin50.GeoCoordinate = new GeoCoordinate(49.42563670946435, -0.44644108276367537);
Canvas myCanvas50 = new Canvas();
// The image is defined globally
pin50.PositionOrigin = new Point(0.5, 0.5);
image50.Source = new BitmapImage(new Uri("Images/Destroyer.png", UriKind.Relative));
image50.Opacity = 1;
Point point50 = new Point(1.0, 1.0);
Canvas.SetLeft(image50, point50.X);
Canvas.SetTop(image50, point50.Y);
myCanvas50.Children.Add(image50); // <=== ERROR OCCURS HERE
// Making an event handler for the image so that we can 'tap' on it
image50.DoubleTap += image50_DoubleTap;
pin50.Content = myCanvas50;
pinLayer50.Add(pin50);
map_J.Layers.Add(pinLayer);
It works fine for all of the Images, however when I click on an Image it navigates to a new page and gives a description of the Image that was clicked on.
The problem is that when a user navigates back to this map (by intuitively pressing the hardware BACK BUTTON) the app crashes due to the error "Element is already the child of another element."
I'm guessing that the page is still loaded so when it is navigated back to it gets 're-loaded' so can't add the same Image to the same canvas etc.
I tried adding the following to clear all information from the map before navigating away from the page but it doesn't help:
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
var toRemove = new List<MapLayer>();
foreach (MapLayer lyr in map_J.Layers)
{
toRemove.Add(lyr);
}
// now do the actual removal
foreach (var child in toRemove)
{
map_J.Layers.Remove(child);
}
}
Any ideas? Is there a better way to handle the reloading of the map/elements?
I would recommend clearing the map layers everytime the user leaves the page.
Add this code to the main tag in the XAML code of the view:
<phone:PhoneApplicationPage
...
Unloaded="PhoneApplicationPage_Unloaded" >
And this event code behind:
private void PhoneApplicationPage_Unloaded(object sender, RoutedEventArgs e)
{
map_J.Layers.Clear();
}