作用:在地理信息的实际项目中,会碰到将坐标解析成地名的需求。需要用到GIS平台的空间分析功能。
开发环境:VS2005 + Mapxtreme2005
using System;
using System.Collections.Generic;
using System.Text;
using MapInfo.Data;
using MapInfo.Geometry;
using MapInfo.Mapping;
using MapInfo.Engine;
namespace MapXtremeApp
{
class MapSearch
{
int MinUnitRadius = 10; //单位搜索的起始半径
int MinRoadRadius = 20; //道路搜索起始半径
int MaxRadiusWidth = 200; //最大搜索半径
int AddRadiusWidth = 20; //搜索半径增幅
///
/// 搜索最近的点目标
///
/// 地图
/// 经度
/// 纬度
/// 搜索的图层
/// 出参,搜索到的单位名称
///
public int SearchUnit(Map map, double x, double y, string[] UnitLayers, ref string Unit)
{
bool bFirst = true;
double distemp = 0; double disLowerest = 0;
double searchradius = 0;
FeatureGeometry fg = new MapInfo.Geometry.Point(map.GetDisplayCoordSys(), x, y);
for (searchradius = MinUnitRadius; searchradius < MaxRadiusWidth; searchradius += AddRadiusWidth)
{
Distance dis = new Distance(searchradius, DistanceUnit.Kilometer);
SearchInfo si = MapInfo.Data.SearchInfoFactory.SearchWithinDistance(fg, dis, ContainsType.Centroid);
si.QueryDefinition.Columns = null;
for (int i = 0; i < UnitLayers.Length; i++)
{
string tabalias = UnitLayers[i].ToString();
MapInfo.Data.Table tab = MapInfo.Engine.Session.Current.Catalog.GetTable(tabalias);
if (tab == null)
return -1;
IResultSetFeatureCollection irfc = MapInfo.Engine.Session.Current.Catalog.Search(tab, si);
if (irfc.Count > 0)
{
foreach (Feature ftr in irfc)
{
MapInfo.Geometry.CoordSys CoordSys = map.GetDisplayCoordSys();
distemp = CoordSys.Distance(DistanceType.Spherical, DistanceUnit.Kilometer, CoordSys, ftr.Geometry.Centroid, fg.Centroid);
if (searchradius <= MinUnitRadius && ftr[1].ToString() != "")//起始半径内搜索
{
Unit = ftr[1].ToString();
return 0;
}
else//扩大搜索范围,选择最近的单位
{
if (bFirst || distemp < disLowerest)
{
disLowerest = distemp;
Unit = ftr[1].ToString();
bFirst = false;
}
}
}
}
}
}
if (Unit == "")
return -1;
return 1;
}
public int SearchRoad(Map map, double x, double y, string[] RoadLayers, ref string Road)
{
double searchradius = 0;
int icount = 0;//道路计数器
FeatureGeometry fg = new MapInfo.Geometry.Point(map.GetDisplayCoordSys(), x, y);
for (searchradius = MinRoadRadius; Road == "" && searchradius < MaxRadiusWidth; searchradius += AddRadiusWidth)
{
FeatureGeometry buffer = fg.Buffer(searchradius, DistanceUnit.Kilometer, 99);
SearchInfo si = MapInfo.Data.SearchInfoFactory.SearchIntersectsGeometry(buffer, IntersectType.Geometry);
si.QueryDefinition.Columns = null;
for (int i = 0; i < RoadLayers.Length; i++)
{
string tabalias = RoadLayers[i].ToString();
MapInfo.Data.Table tab = MapInfo.Engine.Session.Current.Catalog.GetTable(tabalias);
if (tab == null)
return -1;
IResultSetFeatureCollection irfc = MapInfo.Engine.Session.Current.Catalog.Search(tab, si);
if (irfc.Count > 0)
{
if (searchradius <= MinRoadRadius)//起始半径内搜索
{
foreach (Feature ftr in irfc)
{
icount++;
if (icount == 1)//第一个道路
Road = ftr[1].ToString();
else
Road += "、" + ftr[1].ToString();
}
}
else//扩大搜索范围
{
foreach (Feature ftr in irfc)
{
if (ftr[1].ToString() != "")
{
Road = ftr[1].ToString();
return 1;
}
}
}
}
}
}
if (searchradius <= MinRoadRadius + AddRadiusWidth)//精确搜索有了至少一个结果
{
if (icount > 1)//该位置是多条道路交叉处
Road += "交界处";
return 0;
}
if (Road == "")
return -1;
return 1;
}
public bool SearchRegion(Map map, double x, double y,string[] RegionLayers, ref string Region)
{
FeatureGeometry fg = new MapInfo.Geometry.Point(map.GetDisplayCoordSys(), x, y);
SearchInfo si = MapInfo.Data.SearchInfoFactory.SearchIntersectsGeometry(fg, IntersectType.Geometry);
si.QueryDefinition.Columns = null;
for (int i = 0; i < RegionLayers.Length; i++)
{
string tabalias = RegionLayers[i].ToString();
MapInfo.Data.Table tab = MapInfo.Engine.Session.Current.Catalog.GetTable(tabalias);
if (tab == null)
return false;
IResultSetFeatureCollection irfc = MapInfo.Engine.Session.Current.Catalog.Search(tab, si);
if (irfc.Count > 0)
{
for (int j = 0; j < irfc.Count; j++)
{
Region = irfc[j][1].ToString();
}
return true;
}
}
return false;
}
public bool PosAnalysis(Map map, double x, double y, string[] UnitLayers, string[] RoadLayers, string[] RegionLayers, ref string PosReport)
{
string strUnit = "";
string strRoad = "";
string strRegion = "";
if (SearchUnit(map, x, y, UnitLayers, ref strUnit) == 1)
strUnit += "附近";
if (SearchRoad(map, x, y, RoadLayers, ref strRoad) == 1)
strRoad += "附近的";
SearchRegion(map, x, y, RegionLayers, ref strRegion);
if (strRegion != "")
{
PosReport = strRegion + strRoad + strUnit;
return true;
}
return false;
}
}
}