gpt4 book ai didi

c# - 为什么在某个特定场景中,Bing map 上仅显示我的一部分 Pin 图?

转载 作者:行者123 更新时间:2023-12-04 08:07:36 24 4
gpt4 key购买 nike

在我的应用程序中,用户可以加载一个文本文件(以分号分隔),该文件描述了要在 Bing map 上转换为 [Push] Pins 的位置特征,或者加载预先存在的 map 数据(来自本地数据库)到同样的目的。
在从数据库加载的情况下,它工作得很好, map 上会为数据库中的每个相应记录显示一个 Pin,例如:
enter image description here
但是,当我从文本文件的内容中填充数据库,然后根据这些值创建 Pin 图时, map 上只会显示 pin 的一个子集——实际上通常只是前两个!
但是,当我从数据库加载相同的 map 时,所有内容都按原样显示。
从文本文件生成新记录后,我检查了数据库,所有记录确实都在那里(包括坐标(纬度和经度值)。两种情况下的代码似乎相同。但它没有显示所有针...
文本文件内容是这样的(这就是创建上面显示的 map 的原因):

Paris, France;;Paris;France;75000
Florence, Italy;;Florence;Italy;50100
Chelsea, London, England;23 Tedworth Square;Chelsea London;England;SW3 4DY
Kaltenleutgeben, Austria;;Kaltenleutgeben;Austria;2380
Vienna, Austria;;Vienna;Austria;1010
Weggis, Switzerland;;Weggis;Switzerland;6006
Heidelberg, Germany;;Heidelberg;Germany;69115
Munich, Germany;;Munich;Germany;80331
为了深入了解细节,以下是从文本文件加载 map 数据的主窗体中的代码,例如上面显示的那个:
private void toolStripMenuItemCreateMapAndLocsFromFile_Click(object sender, EventArgs e)
{
bool pushpinsAdded = false;
string _currentMap = string.Empty;
RemoveCurrentPushpins();

using (var frmCre8MapAndLocsFromFile = new mdlDlgCreateMapAndLocsFromTSVFile())
{
if (frmCre8MapAndLocsFromFile.ShowDialog() == DialogResult.OK)
{
_currentMap = mdlDlgCreateMapAndLocsFromTSVFile.CurrentMap;
foreach (Pushpin pin in frmCre8MapAndLocsFromFile.Pins)
{
this.userControl11.myMap.Children.Add(pin);
pushpinsAdded = true; // redundant after the first assignment
}
}
}
if (pushpinsAdded)
{
RightsizeZoomLevelForAllPushpins();
}
lblMapName.Text = currentMap;
lblMapName.Visible = true;
}
这是来自 mdlDlgCreateMapAndLocsFromTSVFile 的相关代码(是的,它的名字有误,因为我从 TSV 切换到了 SCSV),它在上面被调用:
private void btnOpenTSVFile_Click(object sender, EventArgs e)
{
string pathToFile = string.Empty;
string line = string.Empty;
int counter = 0;
openTSVFileDlg.Filter = "scsv files (*.scsv)|*.scsv|txt files (*.txt)|*.txt|All files (*.*)|*.*";

if (openTSVFileDlg.ShowDialog() == DialogResult.OK)
{
pathToFile = openTSVFileDlg.FileName;
fileNameOnly = Path.GetFileName(pathToFile);
fileNameOnly = Path.ChangeExtension(fileNameOnly, null);
CurrentMap = fileNameOnly;
if (SCSVFileAlreadyLoaded(fileNameOnly))
{
MessageBox.Show(String.Format("The file/table {0} has already been loaded/populated", fileNameOnly));
return;
}
StreamReader file = new StreamReader(pathToFile);
while ((line = file.ReadLine()) != null)
{
if (counter == 0)
{
InsertMapRecord(fileNameOnly);
}
counter++;
InsertMapDetailRecord(fileNameOnly, line);
}
}
}
InsertMapDetailRecord() 是将图钉添加到列表中的方法,它是:
private void InsertMapDetailRecord(string fileNameOnly, string line)
{
string keyRecordElements = string.Empty;
string[] lineElements;
lineElements = line.Split(';');
string locationName = lineElements[0].Trim();
string address = lineElements[1].Trim();
string city = lineElements[2].Trim();
string st8 = lineElements[3].Trim();
string zip = lineElements[4].Trim();
keyRecordElements = string.Format("{0} {1} {2} {3}", address, city, st8, zip).Trim();
if (MissingValues(lineElements))
{
MessageBox.Show("Could not insert record - one or more key values missing");
return;
}

if (InsertIntoCartographerDetail(fileNameOnly, locationName, address, city, st8, zip))
{
AddPushpin(keyRecordElements, locationName);
}
else
{
MessageBox.Show("insert failed");
}
}
AddPushpin() 是:
private async void AddPushpin(string _fullAddress, string _location)
{
iContentCounter = iContentCounter + 1;
// from https://stackoverflow.com/questions/65752688/how-can-i-retrieve-latitude-and-longitude-of-a-postal-address-using-bing-maps
var request = new GeocodeRequest();
request.BingMapsKey = "Gr8GooglyMoogly";
request.Query = _fullAddress;

var result = await request.Execute();
if (result.StatusCode == 200)
{
var toolkitLocation = (result?.ResourceSets?.FirstOrDefault())
?.Resources?.FirstOrDefault()
as BingMapsRESTToolkit.Location;
var latitude = toolkitLocation.Point.Coordinates[0];
var longitude = toolkitLocation.Point.Coordinates[1];
var mapLocation = new Microsoft.Maps.MapControl.WPF.Location(latitude, longitude);
this.Pin = new Pushpin() { Location = mapLocation, ToolTip = _location, Content = iContentCounter
};
if (null == this.Pins)
{
this.Pins = new List<Pushpin>();
}
this.Pins.Add(Pin); // specific to this form
UpdateDetailRecWithCoords(_location, latitude, longitude);
this.DialogResult = DialogResult.OK;
}
}
同样,就填充数据库而言,这完成了它应该做的事情,包括详细信息表的纬度和经度字段,但是在模式对话框关闭时焦点传递回主窗体后, map 上只显示两个图钉。
以下是调用 mdlDlgFrm_LoadExistingMap 的主窗体中的代码:
private void loadExistingMapToolStripMenuItem_Click(object sender, EventArgs e)
{
bool pushpinsAdded = false;
RemoveCurrentPushpins();
using (var frmLoadExistingMap = new mdlDlgFrm_LoadExistingMap())
{
if (frmLoadExistingMap.ShowDialog() == DialogResult.OK)
{
foreach (Pushpin pin in frmLoadExistingMap.Pins)
{
this.userControl11.myMap.Children.Add(pin);
pushpinsAdded = true;
}
}
}
if (pushpinsAdded)
{
RightsizeZoomLevelForAllPushpins();
}
lblMapName.Text = currentMap;
lblMapName.Visible = true;
}
这是来自 mdlDlgFrm_LoadExistingMap 表单的代码,其中:
private void btnLoadSelectedMap_Click(object sender, EventArgs e)
{
string latitudeAsStr = string.Empty;
string longitudeAsStr = string.Empty;
List<MapDetails> lstMapDetails = new List<MapDetails>();
MapDetails md;
const int LOC_NAME = 0;
const int ADDRESS = 1;
const int CITY = 2;
const int ST8 = 3;
const int ZIP = 4;
const int NOTES = 5;
const int LATITUDE = 6;
const int LONGITUDE = 7;

mapName = cmbxMaps.Text.Trim();
if (mapName == string.Empty)
{
MessageBox.Show("Select a map from the combo box");
cmbxMaps.Focus();
return;
}
try
{
Form1.currentMap = mapName;
string qry = "SELECT LocationName, Address1, City, StateOrSo, PostalCode, " +
"MapDetailNotes, Latitude, Longitude " +
"FROM CartographerDetail " +
"WHERE FKMapName = @FKMapName";
var con = new SqliteConnection(connStr);
con.Open();
SqliteCommand cmd = new SqliteCommand(qry, con);
cmd.Parameters.AddWithValue("@FKMapName", mapName);
var reader = cmd.ExecuteReader();
while (reader.Read())
{
md = new MapDetails();
md.LocationName = reader.GetValue(LOC_NAME).ToString().Trim();
md.Address = reader.GetValue(ADDRESS).ToString().Trim();
md.City = reader.GetValue(CITY).ToString().Trim();
md.StateOrSo = reader.GetValue(ST8).ToString().Trim();
md.PostalCode = reader.GetValue(ZIP).ToString().Trim();
md.MapDetailNotes = reader.GetValue(NOTES).ToString();
latitudeAsStr = reader.GetValue(LATITUDE).ToString();
if (string.IsNullOrEmpty(latitudeAsStr))
{
md.Latitude = 0.0;
}
else
{
md.Latitude = Convert.ToDouble(reader.GetValue(LATITUDE).ToString());
}
longitudeAsStr = reader.GetValue(LONGITUDE).ToString();
if (string.IsNullOrEmpty(longitudeAsStr))
{
md.Longitude = 0.0;
}
else
{
md.Longitude = Convert.ToDouble(reader.GetValue(LONGITUDE).ToString());
}
lstMapDetails.Add(md);
}
AddPushpinsToListOfPushpins(lstMapDetails);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
this.Close();
}

// AddPushpins (plural)
private void AddPushpinsToListOfPushpins(List<MapDetails> lstMapDetails)
{
string fullAddress;

foreach (MapDetails _md in lstMapDetails)
{
fullAddress = string.Format("{0} {1} {2} {3}", _md.Address, _md.City, _md.StateOrSo, _md.PostalCode).Trim();
AddPushpinToListOfPushpins(_md.LocationName, fullAddress, _md.MapDetailNotes, _md.Latitude, _md.Longitude);
}
}

// AddPushpin (singular)
private async void AddPushpinToListOfPushpins(string location, string fullAddress, string mapDetailNotes, double latitude, double longitude)
{
iContentCounter = iContentCounter + 1;
string toolTip = string.Empty;
// if already have the record, including the coordinates, no need to make the REST call
if ((latitude != 0.0) && (longitude != 0.0))
{
if (mapDetailNotesExist(location))
{
toolTip = String.Format("{0}{1}{2}{1}{3},{4}{1}{5}", location, Environment.NewLine, fullAddress, latitude, longitude, mapDetailNotes.Trim());
}
else
{
toolTip = String.Format("{0}{1}{2}{1}{3},{4}", location, Environment.NewLine, fullAddress, latitude, longitude);
}
var _mapLocation = new Microsoft.Maps.MapControl.WPF.Location(latitude, longitude);
this.Pins.Add(new Pushpin()
{
Location = _mapLocation,
ToolTip = toolTip,
Content = iContentCounter
});
}
else
{
// from https://stackoverflow.com/questions/65752688/how-can-i-retrieve-latitude-and-longitude-of-a-postal- address-using-bing-maps
var request = new GeocodeRequest();
request.BingMapsKey = "Gr8GooglyMoogly";
request.Query = fullAddress;

var result = await request.Execute();
if (result.StatusCode == 200)
{
var toolkitLocation = (result?.ResourceSets?.FirstOrDefault())
?.Resources?.FirstOrDefault()
as BingMapsRESTToolkit.Location;
var _latitude = toolkitLocation.Point.Coordinates[0];
var _longitude = toolkitLocation.Point.Coordinates[1];
var mapLocation = new Microsoft.Maps.MapControl.WPF.Location(_latitude, _longitude);
this.Pins.Add(new Pushpin()
{
Location = mapLocation,
ToolTip = String.Format("{0}{1}{2}{1}{3},{4}{1}{5}", location, Environment.NewLine, fullAddress, _latitude, _longitude, mapDetailNotes),
Content = iContentCounter
});
UpdateLocationWithCoordinates(location, _latitude, _longitude);
}
}
}
在我看来,无论是从文件创建 map 还是从数据库加载 map ,创建 Pin 图然后在 map 中显示它们的代码都是相同的。那么为什么行为不同呢?
更新
举一个更具体的例子,当通过包含如下内容的文件(前几行的摘录)创建 map 时:
July 15 & 16, 1895 - Music Hall, Cleveland, Ohio;; Cleveland;Ohio;44101
July 18, 1895 - Soo Opera House or Hotel Iroquois, Sault Ste. Marie, Michigan;;Sault Ste. Marie;Michigan;49783
July 19, 1895 - Casino Room, Grand Hotel, Mackinac, Michigan;;Mackinac;Michigan;49757
July 20, 1895 - Grand Opera House, Petoskey, Michigan;;Petoskey;Michigan;49770
July 22, 1895 - First Methodist Church, Duluth, Minnesota;;Duluth;Minnesota;55802
July 23, 1895 - Hotel West & Reception and Supper, Minneapolis, Minnesota;;Minneapolis;Minnesota;55111
July 24, 1895 - People's Church, St. Paul, Minnesota;;St. Paul;Minnesota;55101
July 27, 1895 - Luncheon and Manitoba Club Supper, Winnipeg, Canada;;Winnipeg;Canada;R0G 0A1
...我一开始就得到了这个(只有一个子集,并且所有这些都具有相同的内容编号):
enter image description here
...但是当我此后立即通过“加载现有”加载 map 时,我得到了一切:
enter image description here
?
更新 2
感谢“The Bing Maps Whisperer”,Reza Aghaei,它现在可以工作了:
enter image description here

最佳答案

以下是我认为您需要应用的修复程序:

  • 更改 AddPushpin签名到 async Task AddPushpin(...)
  • 然后在 InsertMapDetailRecord将调用更改为 await AddPushpin(...);
  • 更改 InsertMapDetailRecord签名到 async Task InsertMapDetailRecord(...)
  • 更改 btnOpenTSVFile_Click签名到 async void btnOpenTSVFile_Click
  • 然后在 btnOpenTSVFile_Click换电话 InsertMapDetailRecordawait InsertMapDetailRecord()

  • 我也猜你应该:
  • AddPushpin方法,删除 this.DialogResult = DialogResult.OK;
  • btnOpenTSVFile_Click , 添加 this.DialogResult = DialogResult.OK;在 while 循环结束之后。

  • 使用异步/等待
    基本上在方法中时 void M(...)你想调用一个方法 DoSomething(...)返回 Task ,将调用更改为 await DoSomething(...); .然后如果方法 M是一个事件处理器,把签名改成 async void M(...) , 否则如果是正常方法,则将签名更改为 async Task M(...) .
    设置 DialogResult
    我认为您需要更改签名以及设置对话框结果的行的原因:在 AddPushpin , 您正在设置 DialogResult OK,这意味着在添加第一个图钉后,包含对话框( mdlDlgCreateMapAndLocsFromTSVFile )将关闭,您开始查看 Pins 属性(仍在场景后面被填充,然后在添加前几个图钉后有机会被添加到 Pins 属性,您处理 mdlDlgCreateMapAndLocsFromTSVFile 并且不会再向 map 添加图钉。
    变量范围
    我们没有看到整个代码,但要注意变量/字段的范围。作为警告,在整个方法中访问类字段不是一个好主意,它们不是局部变量,当您更改这些值时,其他方法也可以看到更改。

    关于c# - 为什么在某个特定场景中,Bing map 上仅显示我的一部分 Pin 图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66147896/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com