问题描述
我正在开发一个 xamarin 表单应用程序,目前使用适用于 Android 的 xamarin 表单地图跟踪我的位置,并且根据我与放置在地图上的自定义图钉的接近程度,大小会根据我的接近程度而改变。 基本上,如果在几米内,图标是 32x32,更远的是 24x24。 我创建了一个自定义地图渲染器,它可以从 JSON 文件中放置我的图钉,这没问题。 当我的地图表单页面在我的模拟器和实际的 android 设备中加载时,这些方法会运行并根据我的位置获取我的接近度,并适当地改变地图图钉的大小。 但是,这在我四处走动时不起作用。 出于某种原因,除非我调用 Content=customMap,否则当我的位置更改时,我重写的 CreateMarker 方法不会触发。这样做只会导致我的地图一遍又一遍地加载,基本上不会工作。 我的关于页面中有一个名为 UpdateMap3() 的方法,该方法在用户位置更改时调用。但是,如前所述,当应用程序运行时,当我靠近图钉时,我无法让图钉更新它们的大小。
我在下面包含了我的表单页面代码,在下面包含了标记,最后在下面包含了我的地图渲染器。 任何帮助将不胜感激。 谢谢
using System;
using System.IO;
using System.Reflection;
using Xamarin.Forms;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Forms.Maps;
using Xamarin.Essentials;
using distance = Xamarin.Forms.Maps.distance;
using Google.Protobuf.WellKNownTypes;
using static Google.Protobuf.Reflection.FieldDescriptorProto.Types;
namespace MAPS.Views
{
public partial class AboutPage : ContentPage
{
IlocationUpdateService loc;
public AboutPage()
{
InitializeComponent();
// Task.Delay(2000);
UpdateMap();
}
async void OnActionSheetCancelDeleteClicked()
{
bool answer = await displayAlert("Location Request","Please enable location services to use this app","Settings","Cancel");
if (answer == true)
{
DependencyService.Get<ILocSettings>().OpenSettings();
}
}
protected override void OnAppearing()
{
base.OnAppearing();
bool gpsstat = DependencyService.Get<ILocSettings>().isGpsAvailable();
if (gpsstat == false)
{
OnActionSheetCancelDeleteClicked();
}
loc = DependencyService.Get<IlocationUpdateService>();
loc.LocationChanged += (object sender,ILocationEventArgs args) =>
{
String lat1 = args.Latitude.ToString();
String lng1 = args.Longitude.ToString();
//String lat1 = "55.099300";
// String lng1 = "-8.279740";
UpdateMap3(lat1,lng1); ;
};
loc.GetUsedLocation();
}
protected override void Ondisappearing()
{
base.Ondisappearing();
loc = null;
}
List<Place> placesList = new List<Place>();
private async void UpdateMap()
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(AboutPage)).Assembly;
Stream stream = assembly.GetManifestResourceStream("MAPS.Places.json");
string text = string.Empty;
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
var resultObject = JsonConvert.DeserializeObject<Places>(text);
var request = new Xamarin.Essentials.GeolocationRequest(GeolocationAccuracy.Best,TimeSpan.FromSeconds(30));
var location = await Geolocation.GetLocationAsync(request);
CustomMap customMap = new CustomMap()
{
IsShowingUser = true
};
customMap.CustomPins = new List<CustomPin>(); // put this before the foreach
foreach (var place in resultObject.results)
{
Location location1 = new Location(place.geometry.location.lat,place.geometry.location.lng);
// string color = getdist(location1,location);
string color = "purple";
if (color == "purple")
{
CustomPin pin = new CustomPin()
{
Type = PinType.Place,Position = new Position(place.geometry.location.lat,place.geometry.location.lng),Label = place.id,Address = place.vicinity+"*",Name = "Xamarin",icon = "icon.png",Url = "http://xamarin.com/about/"
};
customMap.Pins.Add(pin);
}
else
{
CustomPin pin = new CustomPin()
{
Type = PinType.Place,Address = place.vicinity,icon = "pin.png",Url = "http://xamarin.com/about/"
};
customMap.Pins.Add(pin);
}
}
customMap.MovetoRegion(MapSpan.FromCenterandRadius(new Position(location.Latitude,location.Longitude),distance.FromKilometers(0.15))); ;
Content = customMap;
}
public string getdist(Location loc,Xamarin.Essentials.Location currentLoc)
{
string color = "red";
// bool geo = false;
double latEnd = loc.lat;
double lngEnd = loc.lng;
/// Position(currentLoc.lat,currentLoc.lng);
double dist = currentLoc.Calculatedistance(latEnd,lngEnd,distanceUnits.Kilometers);
if (dist < 0.05) //5m distance
{
color = "purple";
}
else
{
color = "red";
}
return color;
}
public void getNewPins()
{
InitializeComponent();
}
public void getPin()
{
var pr = new PopUp();
}
private async void UpdateMap3(String lat,String lng)
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(AboutPage)).Assembly;
Stream stream = assembly.GetManifestResourceStream("MAPS.Places.json");
string text = string.Empty;
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
var resultObject = JsonConvert.DeserializeObject<Places>(text);
CustomMap customMap = new CustomMap()
{
IsShowingUser = true
};
customMap.CustomPins = new List<CustomPin>(); // put this before the foreach
foreach (var place in resultObject.results)
{
Location location1 = new Location(place.geometry.location.lat,place.geometry.location.lng);
Xamarin.Essentials.Location location = new Xamarin.Essentials.Location(Convert.Todouble(lat),Convert.Todouble(lng));
string color = getdist(location1,location);
if (color == "purple")
{
CustomPin pin2 = new CustomPin()
{
Type = PinType.Place,Url = "http://xamarin.com/about/"
};
customMap.CustomPins = new List<CustomPin> {pin2};
customMap.Pins.Add(pin2);
}
else
{
CustomPin pin2 = new CustomPin()
{
Type = PinType.Place,Url = "http://xamarin.com/about/"
};
customMap.CustomPins = new List<CustomPin> { pin2 };
customMap.Pins.Add(pin2);
// Content.IsEnabled = true;
// customMap.CustomPins.Remove(pin);
}
}
// customMap.Pins.Clear();
// customMap.MovetoRegion(MapSpan.FromCenterandRadius(new Position(Convert.Todouble(lat),Convert.Todouble(lng)),distance.FromKilometers(0.15))); ;
// Content = customMap;
// customMap.Pins.Add(pins);
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MAPS;assembly=MAPS"
x:Class="MAPS.Views.AboutPage" Title="Explore">
<StackLayout>
<local:CustomMap x:Name="customMap" IsShowingUser="True"
MapType="Street" />
</StackLayout>
</ContentPage>
下面是我的 Android 自定义渲染器
using Android.Content;
using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using Android.Widget;
using MAPS;
using MAPS.Droid;
using MAPS.Views;
using Newtonsoft.Json;
using Rg.Plugins.Popup;
using Rg.Plugins.Popup.Animations;
using Rg.Plugins.Popup.Contracts;
using Rg.Plugins.Popup.Enums;
using Rg.Plugins.Popup.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.Android;
using static MAPS.Droid.CustomMapRenderer;
[assembly: ExportRenderer(typeof(CustomMap),typeof(CustomMapRenderer))]
namespace MAPS.Droid
{
public class CustomMapRenderer : Xamarin.Forms.Maps.Android.MapRenderer,GoogleMap.IInfoWindowAdapter
{
List<CustomPin> customPins;
public string popInfo;
public CustomMapRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
NativeMap.InfoWindowClick -= OnInfoWindowClick;
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
customPins = formsMap.CustomPins;
Control.GetMapAsync(this);
}
}
protected override void OnMapReady(GoogleMap map)
{
base.OnMapReady(map);
NativeMap.InfoWindowClick += OnInfoWindowClick;
NativeMap.SetInfoWindowAdapter(this);
}
protected override MarkerOptions CreateMarker(Pin pin)
{
var marker = new MarkerOptions();
// CustomPin p = new CustomPin();
//foreach (var cp in customPins)
//{
// if (cp.Position == pin.Position)
// {
// p = cp;
// }
//}
marker.SetPosition(new LatLng(pin.Position.Latitude,pin.Position.Longitude));
marker.SetTitle(pin.Label);
// marker.SetIcon(BitmapDescriptorFactory.FromFile(p.icon));
if (pin.Address.Contains('*'))
{
marker.SetIcon(BitmapDescriptorFactory.Fromresource(Resource.Drawable.pin2));
}
else
{
marker.SetIcon(BitmapDescriptorFactory.Fromresource(Resource.Drawable.pin));
}
marker.Visible(true);
var a = NativeMap.AddMarker(marker);
a.ShowInfoWindow();
// marker.SetSnippet(pin.Address.Replace("*"," "));
return marker;
}
void OnInfoWindowClick(object sender,GoogleMap.InfoWindowClickEventArgs e)
{
getPlaceData(markerdata.markerData.title,markerdata.markerData.lat,markerdata.markerData.lng);
showPopUp();
}
public Android.Views.View GetInfoContents(Marker marker)
{
return null;
}
public void myMod(Marker marker)
{
}
public Android.Views.View GetInfoWindow(Marker marker)
{
markerdata.markerData.title = marker.Title;
markerdata.markerData.lat = marker.Position.Latitude.ToString("0.#####");
markerdata.markerData.lng = marker.Position.Longitude.ToString("0.#####");
// ds.Id = marker.Id;
// getPlaceData(marker.Title,marker.Position.Latitude.ToString("0.#####"),marker.Position.Longitude.ToString("0.#####"));
// showPopUp();
return null;
}
public string Number;
private async void showPopUp()
{
var Pr = new Views.PopUp();
var scaleAnimation = new ScaleAnimation
{
PositionIn = MoveAnimationoptions.Right,PositionOut = MoveAnimationoptions.Left
};
Pr.Animation = scaleAnimation;
await PopupNavigation.PushAsync(Pr);
}
CustomPin GetCustomPin(Marker annotation)
{
return null;
}
private void getPlaceData(String name,String Lat,String Lng)
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(AboutPage)).Assembly;
Stream stream = assembly.GetManifestResourceStream("MAPS.Places.json");
string text = string.Empty;
using (var reader = new StreamReader(stream))
{
text = reader.ReadToEnd();
}
var resultObject = JsonConvert.DeserializeObject<Places>(text);
foreach (var place in resultObject.results)
{
if((name==place.id)&&(Lat ==place.geometry.location.lat.ToString("0.#####"))&&(Lng ==place.geometry.location.lng.ToString("0.#####")))
{
getData.Instance.Id = place.id;
getData.Instance.lat = place.geometry.location.lat.ToString("0.#####");
getData.Instance.lng = place.geometry.location.lng.ToString("0.#####");
getData.Instance.marker2 = place.name;
getData.Instance.family = place.family;
getData.Instance.origin = place.Origin;
getData.Instance.date = place.Date;
getData.Instance.commonName = place.CommonName;
// getData.Instance.title = marker.Title;
}
}
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)