读取shp文件,根据shp文件中的经纬度数据调用高德api查找地址,并将地址写入shp中

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上的代码。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值