作用:在地理信息的实际项目中,会碰到将坐标解析成地名的需求。需要用到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; //搜索半径增幅
       
        /// <summary>
        /// 搜索最近的点目标
        /// </summary>
        /// <param name="map">地图</param>
        /// <param name="x">经度</param>
        /// <param name="y">纬度</param>
        /// <param name="UnitLayers">搜索的图层</param>
        /// <param name="Unit">出参,搜索到的单位名称</param>
        /// <returns>0,精确目标;1, 近似目标;-1,搜索失败</returns>
        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;
        }

    }
}