在GIS中,地标或者道路等信息查找是一项很重要的功能,类似于我们查找数据库记录那样,需要模糊进行匹配,一般来说,找到需要的地标或者道路等地图元素后,双击可以定位到地图的具体位置,并放大地图,类似于Google Map的Fly to功能。
本文先介绍MapX如何在地图中查找所需要的地图元素。
由于地图的信息是按照层来存储的,所以我们查找信息的时候,也是按照一层层来进行检索,由于MapInfo的地图一般有很多层,每层进行遍历会比较花费时间,所以一般的专业系统,都只是关系一部分层,我们通常在配置文件中指定感兴趣的层名集合,然后查找的时候,在这些层中查找,这样可以提高检索的速度。
我们看看操作层的代码,是如何实现的。
foreach (string layer in layerNameArray)
{
if (string.IsNullOrEmpty(layer))
continue;
try
{
#region 每层的查询
string condition = string.Format("NAME like \"%{0}%\"", SearchLocation);
MapXLib.Layer mapLayer = TarMap.Layers._Item(layer);
if (mapLayer != null)
{
feature = mapLayer.Search(condition, null);
int count = feature.Count;
if (feature != null)
{
MapXLib.Dataset ds = TarMap.DataSets.Add(MapXLib.DatasetTypeConstants.miDataSetLayer, mapLayer, layer,
0, 0, 0, Missing.Value, false);
Dictionary<string, ResultOfSearching> resultList = new Dictionary<string, ResultOfSearching>();
//To Do 遍历特性代码,待续
TarMap.DataSets.RemoveAll();
}
}
#endregion
}
catch (Exception ex)
{
LogHelper.Error(ex);
}
}
{
if (string.IsNullOrEmpty(layer))
continue;
try
{
#region 每层的查询
string condition = string.Format("NAME like \"%{0}%\"", SearchLocation);
MapXLib.Layer mapLayer = TarMap.Layers._Item(layer);
if (mapLayer != null)
{
feature = mapLayer.Search(condition, null);
int count = feature.Count;
if (feature != null)
{
MapXLib.Dataset ds = TarMap.DataSets.Add(MapXLib.DatasetTypeConstants.miDataSetLayer, mapLayer, layer,
0, 0, 0, Missing.Value, false);
Dictionary<string, ResultOfSearching> resultList = new Dictionary<string, ResultOfSearching>();
//To Do 遍历特性代码,待续
TarMap.DataSets.RemoveAll();
}
}
#endregion
}
catch (Exception ex)
{
LogHelper.Error(ex);
}
}
查找的时候,我们得到了每个Feature,然后对Feature的ID和Name进行判断查找,如何有匹配的,就表示找到了一个对象,如果最后一个也没有,那么本次地图查找应该没有匹配的元素了,Feature的查找代码如下所示
#region 遍历特性
for (int i = 1; i < feature.Count; i++)
{
try
{
object objLocation = ds.get_Value(feature[i], "Name");
object objID = ds.get_Value(feature[i], "Id");
string strLocation = (objLocation == null) ? "" : objLocation.ToString();
string strID = (objID == null) ? "" : objID.ToString();
if (!resultList.ContainsKey(strID) && feature[i].FeatureID != 0)
{
ResultOfSearching searchInfo = new ResultOfSearching();
searchInfo.FeatureID = feature[i].FeatureID;
searchInfo.ID = strID;
searchInfo.Layer = layer;
searchInfo.Location = feature[i].Name;
if (!resultList.ContainsKey(strID))
{
resultList.Add(strID, searchInfo);
}
if (!allResultList.ContainsKey(strID))
{
allResultList.Add(strID, searchInfo);
}
}
}
catch(Exception ex)
{
//LogHelper.Error(ex);
}
}
#endregion
for (int i = 1; i < feature.Count; i++)
{
try
{
object objLocation = ds.get_Value(feature[i], "Name");
object objID = ds.get_Value(feature[i], "Id");
string strLocation = (objLocation == null) ? "" : objLocation.ToString();
string strID = (objID == null) ? "" : objID.ToString();
if (!resultList.ContainsKey(strID) && feature[i].FeatureID != 0)
{
ResultOfSearching searchInfo = new ResultOfSearching();
searchInfo.FeatureID = feature[i].FeatureID;
searchInfo.ID = strID;
searchInfo.Layer = layer;
searchInfo.Location = feature[i].Name;
if (!resultList.ContainsKey(strID))
{
resultList.Add(strID, searchInfo);
}
if (!allResultList.ContainsKey(strID))
{
allResultList.Add(strID, searchInfo);
}
}
}
catch(Exception ex)
{
//LogHelper.Error(ex);
}
}
#endregion
我们遍历每层,对每层的Feature的信息进行查找,把结果放到集合中,当我们返回集合的时候,我们就可以把搜索到的信息显示在树形控件中了。
if (searchResult != null && searchResult.Count > 0)
{
this.tvwResult.BeginUpdate();
TreeNode node = null;
foreach (ResultOfSearching info in searchResult.Values)
{
if (!string.IsNullOrEmpty(info.Location))
{
node = tvwResult.Nodes.Add(info.Location);
node.Tag = info;
}
}
this.tvwResult.EndUpdate();
this.tssl_Status.Text = string.Format("从地图上找到 {0} 结果", searchResult.Count);
}
else
{
this.tssl_Status.Text = "地图上找不到您需要的数据";
}
{
this.tvwResult.BeginUpdate();
TreeNode node = null;
foreach (ResultOfSearching info in searchResult.Values)
{
if (!string.IsNullOrEmpty(info.Location))
{
node = tvwResult.Nodes.Add(info.Location);
node.Tag = info;
}
}
this.tvwResult.EndUpdate();
this.tssl_Status.Text = string.Format("从地图上找到 {0} 结果", searchResult.Count);
}
else
{
this.tssl_Status.Text = "地图上找不到您需要的数据";
}
最后我们看到查找信息的界面如下所示