轉(zhuǎn)帖|其它|編輯:郝浩|2010-12-03 14:29:43.000|閱讀 2394 次
概述:在之前的文章中,介紹了兩篇關(guān)于GMap.NET這樣的開(kāi)源地圖控件,介紹了其一些基本信息以及如何進(jìn)行初步的應(yīng)用。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門(mén)軟控件火熱銷(xiāo)售中 >>
GMap.NET是一個(gè)強(qiáng)大、免費(fèi)、跨平臺(tái)、開(kāi)源的.NET控件,它在Windows Forms 和WPF環(huán)境中能夠通過(guò)Google, Yahoo!, Bing, OpenStreetMap, ArcGIS, Pergo, SigPac等實(shí)現(xiàn)尋找路徑、地理編碼以及地圖展示功能,并支持緩存和運(yùn)行在Mobile環(huán)境中。
GMap.NET是一個(gè)開(kāi)源的GEO地圖定位和跟蹤程序。就像谷歌地圖、雅虎地圖一樣,可以自動(dòng)計(jì)算兩地的距離,定位經(jīng)緯度,與Google地圖不同的是,該項(xiàng)目是建立在C#語(yǔ)言WinForm基礎(chǔ)上的??梢詫?duì)地圖放大縮小,進(jìn)行城市標(biāo)記等。
本文主要介紹應(yīng)用該控件來(lái)批量解析地址經(jīng)緯度坐標(biāo)。由于項(xiàng)目需要,我需要把數(shù)據(jù)庫(kù)里面的4千多條地址信息解析出經(jīng)緯度坐標(biāo),以供其他用途。經(jīng)緯度坐標(biāo)不要求非常精確,大體位置準(zhǔn)確即可。如果人工通過(guò)Googlemap或者其他途徑標(biāo)準(zhǔn),工作量非常大,而且也很枯燥。由于之前接觸過(guò)該控件,知道好像比較容易能夠解析獲取地址的經(jīng)緯度坐標(biāo),那么我們把數(shù)據(jù)庫(kù)信息逐一解析即可,這樣可以節(jié)省人力,更重要的是,可以避免做枯燥的工作。我們先看看程序的運(yùn)行效果,然后分析如何具體編碼實(shí)現(xiàn)。
開(kāi)始一段時(shí)間的效果圖:

基本完成的效果圖:

代碼實(shí)現(xiàn)如下所示,主要利用了背景工作線程BackgroundWorker來(lái)提高界面的友好響應(yīng)。
private BackgroundWorker work = new BackgroundWorker();
public FrmMainMap()
{
InitializeComponent();
work.WorkerReportsProgress = true;
work.DoWork += new DoWorkEventHandler(work_DoWork);
work.RunWorkerCompleted += new RunWorkerCompletedEventHandler(work_RunWorkerCompleted);
work.ProgressChanged += new ProgressChangedEventHandler(work_ProgressChanged);
}
void work_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar.Value = e.ProgressPercentage;
this.tsslTips.Text = e.UserState.ToString();
}
private void FrmMainMap_FormClosing(object sender, FormClosingEventArgs e)
{
work.DoWork -= new DoWorkEventHandler(work_DoWork);
work.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(work_RunWorkerCompleted);
}
void work_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
string tips = string.Format("更新完成, 共成功更新數(shù)據(jù) {0} 個(gè)", e.Result);
this.tsslTips.Text = tips;
this.progressBar.Value = 100;
MessageUtil.ShowTips(tips);
}
void work_DoWork(object sender, DoWorkEventArgs e)
{
string sql = "select t.ID, t.company_addr from tbpark_enterprise t where t.company_addr is not null and t.latitude is null ";
Database db = DatabaseFactory.CreateDatabase();
DbCommand command = db.GetSqlStringCommand(sql);
Dictionary<int, string> addrList = new Dictionary<int, string>();
using (IDataReader dr = db.ExecuteReader(command))
{
SmartDataReader reader = new SmartDataReader(dr);
while (reader.Read())
{
int id = reader.GetInt32("ID");
string addr = reader.GetString("company_addr");
work.ReportProgress(10, string.Format("正在處理地址[ {0} ]", addr));
if (!string.IsNullOrEmpty(addr))
{
int sindex = addr.IndexOfAny(new char[] { '(', '(' });
if (sindex > 0)
{
addr = addr.Substring(0, sindex);
}
if (!addrList.ContainsKey(id))
{
addrList.Add(id, addr);
}
}
}
}
work.ReportProgress(20, string.Format("獲取列表地址信息結(jié)束,正在獲取Google地圖坐標(biāo)..."));
int totoal = addrList.Count;
double step = Convert.ToDouble(100) / totoal;
int i = 1;
int successCount = 0;
foreach (int id in addrList.Keys)
{
int percent = Convert.ToInt32(step * i);
work.ReportProgress(percent, string.Format("正在獲取Google地圖坐標(biāo)...,已成功獲取 {0} 個(gè)", successCount));
try
{
string addr = addrList[id];
GeoCoderStatusCode unknow = GeoCoderStatusCode.Unknow;
PointLatLng? latLngFromGeocoder = Singleton<GMaps>.Instance.GetLatLngFromGeocoder(addr, out unknow);
if (latLngFromGeocoder.HasValue && (unknow == GeoCoderStatusCode.G_GEO_SUCCESS))
{
PointLatLng latLng = latLngFromGeocoder.Value;
sql = string.Format("Update tbpark_enterprise t set t.LATITUDE={0}, t.LONGITUDE={1} where t.ID={2}",
latLng.Lat, latLng.Lng, id);
command = db.GetSqlStringCommand(sql);
bool success = db.ExecuteNonQuery(command) > 0;
if (success)
{
successCount++;
}
}
else
{
LogHelper.Info(unknow.ToString());
}
}
catch (Exception ex)
{
LogHelper.Error(ex);
}
i++;
}
e.Result = successCount;
}
上面最為關(guān)鍵的部分代碼就是如何解析地址為坐標(biāo)的操作,判斷如果解析成功,則獲取相應(yīng)的地理坐標(biāo)即可,是下面這段:
string addr = addrList[id];
GeoCoderStatusCode unknow = GeoCoderStatusCode.Unknow;
PointLatLng? latLngFromGeocoder = Singleton<GMaps>.Instance.GetLatLngFromGeocoder(addr, out unknow);
if (latLngFromGeocoder.HasValue && (unknow == GeoCoderStatusCode.G_GEO_SUCCESS))
{
PointLatLng latLng = latLngFromGeocoder.Value;
sql = string.Format("Update tbpark_enterprise t set t.LATITUDE={0}, t.LONGITUDE={1} where t.ID={2}",
latLng.Lat, latLng.Lng, id);
command = db.GetSqlStringCommand(sql);
bool success = db.ExecuteNonQuery(command) > 0;
if (success)
{
successCount++;
}
}
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@ke049m.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載