1.首先是读取shp文件
这里的shp只读取了面(不包括内环的面),提取面的第一个点的经纬度进行地址查找
public List<Polygon> ReadShp(BinaryReader br)
{
List<Polygon> polygons = new List<Polygon>();
// BinaryReader br = new BinaryReader(openFileDialog1.OpenFile());
br.ReadBytes(24);//filecode、unused、24开始是文件长度
int filelength = br.ReadInt32();//文件长度
int filebanben = br.ReadInt32();//文件版本
int shapetype = br.ReadInt32();//shp文件的几何类型
double Xmin = br.ReadDouble();//该shp文件中x的最小范围
double Ymin = br.ReadDouble();//该shp文件中y的最小范围
double Xmax = br.ReadDouble();//该shp文件中x的最大范围
double Ymax = br.ReadDouble();//该shp文件中的Y最大范围
br.ReadBytes(32);
switch (shapetype)
{
case 5:
// polygons.Clear();
while (br.PeekChar() != -1)//返回下一个可用字符
{
Polygon polygon = new Polygon();
//polygon.parts = new ArrayList();
//polygon.points = new ArrayList();
uint recordnum = br.ReadUInt32();//当前记录段所在的序号
int datalength = br.ReadInt32();//当前这个记录段的记录长度
int shapetype2 = br.ReadInt32();//几何类型
for (int i = 0; i < 4; i++)//当前面的envelope
{
polygon.box[i] = br.ReadDouble();
}
polygon.numparts = br.ReadInt32();//当前记录部分的总数
polygon.numpoints = br.ReadInt32();//当前记录的坐标的点的总数
for (int i = 0; i < polygon.numparts; i++)//读取每个子部分的初始坐标在point数组中的位置,后面根据这个部分的初始位置读取该部分的坐标
{
int part = br.ReadInt32();
polygon.parts.Add(part);
}
for (int i = 0; i < polygon.numparts; i++)//分别读取每个面
{
int startpoint;
int endpoint;
if (i == polygon.numparts - 1)
{
startpoint = polygon.parts[i];
endpoint = polygon.numpoints;
}
else
{
startpoint = polygon.parts[i];
endpoint = polygon.parts[i + 1];
}
for (int j = startpoint; j < endpoint; j++)
{
point point1 = new point();
point1.x = br.ReadDouble();//经度,纬度
point1.y = br.ReadDouble();
polygon.points.Add(point1);
}
polygons.Add(polygon);
}
}
break;
default:
break;
}//switch
// 转换坐标,将经纬度坐标转换成高德地图的坐标
for (int i = 0; i < polygons.Count; i++)
{
for (int j = 0; j < polygons[i].points.Count; j++)
{
point p = new point();
p = polygons[i].points[j];
Gps gps = new Gps(p.y, p.x);//纬度经度
gps.convertgpstogcj01();
polygons[i].points[j].y = gps.getlat();
polygons[i].points[j].x = gps.getlog();
}
}
return polygons;
}
2.根据经纬度查找地址
public class Amap//调用高德api
{
const string key = "132976335b****f3d6455f91bb8a98d4";//这里需要自己去申请百度地图申请key
public static string GetLocationByLngLat(double lng, double lat, int timeout = 10000)
{
string url = $"http://restapi.amap.com/v3/geocode/regeo?key={key}&location={lng},{lat}";//访问高德地图
return GetLocationByUrl(url, timeout);
}
private static string GetLocationByUrl(string url, int timeout)//通过经纬度查找具体地址
{
string strReult = "";
try
{
HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
req.ContentType = "multipart/form-data";//提交的数据的类型
req.Accept = "*/*";//接收的数据类型
req.UserAgent = "";
req.Timeout = timeout;
req.Method = "GET";
req.KeepAlive = true;
HttpWebResponse response = req.GetResponse() as HttpWebResponse;
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);//读取数据流
{
strReult = sr.ReadToEnd();//读取所有字符
}
//截取返回的字符串,获得地址
int formatted_addressIndex = strReult.IndexOf("formatted_address");
int cutIndex = strReult.Length- formatted_addressIndex - 34-21;
int subIndex = formatted_addressIndex + 20;
return strReult.Substring(subIndex, cutIndex);
//return strReult;
}
catch (Exception)
{
strReult = "";
}
return strReult;
}
}
3.将获得的地址写入对应的dbf
BinaryReader br = new BinaryReader(openFileDialog1.OpenFile());
List<Polygon> polygons = ReadShp(br);
//根据根据经纬度查找地址
List<int> id = new List<int> { };
var odbf = new DbfFile(Encoding.GetEncoding(936));
odbf.Open(dbfpath, FileMode.Open);//打开dbf
var orce = new DbfRecord(odbf.Header);
for (int i = 0; i < odbf.Header.RecordCount; i++)
{
id.Add(Convert.ToInt32(odbf.Read(i).ToString()));
}
odbf.Close();
odbf = new DbfFile(Encoding.GetEncoding(936));//编码问题啊!!!!
odbf.Open(dbfpath, FileMode.Create);//打开dbf
odbf.Header.AddColumn(new DbfColumn("ID", DbfColumn.DbfColumnType.Number, 10, 0));
odbf.Header.AddColumn(new DbfColumn("address", DbfColumn.DbfColumnType.Character, 100, 0));
orce = new DbfRecord(odbf.Header);
for (int i=0;i<polygons.Count;i++)
{
string address= Amap.GetLocationByLngLat(polygons[i].points[0].x, polygons[i].points[0].y,10000);
textBox1.Text += address;
orce[odbf.Header.ColumnCount - 2] = id[i].ToString();
orce[odbf.Header.ColumnCount - 1] = address;
odbf.Write(orce, true);
}
odbf.Close();
文章有参考其他博客及GItHub上的代码。