Xamarin.Forms.Maps安卓端如何将数据库数据填充到地图Pin标记
解决方案
实现步骤
核心思路是先预存所有点位的固定基础信息,改造数据库连接方法返回结构化的编号与告警等级的映射关系,等数据库异步读取完成后再给对应点位赋值并加载到地图,具体实现如下:
- 在MapPage类中定义成员变量存储预定义点位集合、数据库映射字典
- 改造数据库连接方法,返回结构化的映射结果,将异步返回类型从
async void改为Task避免执行时序问题 - 点位初始化阶段只填充固定属性,告警等级待数据库读取完成后赋值
- 在页面
OnAppearing生命周期方法中异步等待数据库读取完成,匹配赋值后加载到地图
完整代码示例
public partial class MapPage : ContentPage { // 存储所有预定义的点位基础信息 private List<CustomPin> _allBasePins = new List<CustomPin>(); // 存储数据库读取的CodeNum对应AlertLevel的映射关系 private Dictionary<int, int> _alertLevelMap = new Dictionary<int, int>(); public MapPage() { InitializeComponent(); // 预先初始化所有点位的固定属性 InitBasePins(); } // 初始化所有点位的固定基础信息,CodeNum提前和数据库记录对应 private void InitBasePins() { CustomPin pin1 = new CustomPin { Type = PinType.Place, Position = new Position(41.59043006333251, 24.766286971618303), Name = "Xamarin", Label = "р. Бяла", Address = "гр. Смолян", CodeNum = 1, // 与数据库中对应记录的CodeNum保持一致 AlertLevel = 0 // 先给默认值,后续从数据库赋值 }; CustomPin pin2 = new CustomPin { Type = PinType.Place, Position = new Position(41.56817473054596, 24.758451447799708), Label = "р. Черна", Name = "Xamarin", Address = "гр. Смолян", CodeNum = 2, AlertLevel = 0 }; // 继续添加剩余15个点位,CodeNum与数据库一一对应即可 // ... _allBasePins.Add(pin1); _allBasePins.Add(pin2); } // 重写页面显示后的生命周期方法 protected override async void OnAppearing() { base.OnAppearing(); // 等待数据库读取完成 _alertLevelMap = await DatabaseConnection(); // 遍历所有点位匹配赋值AlertLevel foreach(var pin in _allBasePins) { if(_alertLevelMap.ContainsKey(pin.CodeNum)) { pin.AlertLevel = _alertLevelMap[pin.CodeNum]; } } // 赋值完成后加载到地图 customMap.CustomPins = _allBasePins; foreach(var pin in _allBasePins) { customMap.Pins.Add(pin); } customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(41.567797926753485, 25.389703182725665), Distance.FromKilometers(70))); } // 改造后的数据库连接方法,返回CodeNum和AlertLevel的映射关系 public async Task<Dictionary<int, int>> DatabaseConnection() { Dictionary<int, int> resultMap = new Dictionary<int, int>(); string ConnectionString = "server=192.168.0.3;uid=username;port=3307;pwd=password;database=ardaforecast;"; // 使用using块自动释放资源 using (MySqlConnection Conn = new MySqlConnection(ConnectionString)) { try { await Conn.OpenAsync(); string query = "SELECT * FROM sel_alert_level s;"; using (MySqlCommand myCommand = new MySqlCommand(query, Conn)) { using (MySqlDataReader myReader = await myCommand.ExecuteReaderAsync()) { while (await myReader.ReadAsync()) { int codeNum = myReader.GetInt32(4); int level = myReader.GetInt32(3); resultMap[codeNum] = level; } } } } catch (Exception ex) { await DisplayAlert("数据库连接失败", ex.Message, "确定"); } } return resultMap; } }
说明
你现有的CustomMapRenderer.cs无需修改,已经可以正常读取CodeNum和AlertLevel属性显示到InfoWindow中。
内容的提问来源于stack exchange,提问作者RositsaV
相关产品推荐
相关产品推荐

