最近利用空闲的时间,写了一个坐标解析的类。
作用:在地理信息的实际项目中,会碰到将坐标解析成地名的需求。需要用到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;
- }
- }
- }