前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从零开始搭建一个GIS开发小框架(三)——扩展功能:搜索地址

从零开始搭建一个GIS开发小框架(三)——扩展功能:搜索地址

作者头像
天堂向左
发布2022-06-14 15:46:01
7220
发布2022-06-14 15:46:01
举报
文章被收录于专栏:天堂向左程序员向右

1

概述

Introduction to new functions

"搜索地址"功能是GIS项目最基本的功能,根据地址文字片段以模糊查找的方式寻找精确坐标。

在输入框中输入一个地址(要稍微级别高一点的地标类,比如达到POI点这个级别,太小的地址可能找不到),OpenCycleMap地图我没有找到搜索地址的API接口,于是调用高德的搜索API(不需要高德的底图),因为高德返回的是gcj02坐标,OpenCycleMap使用的是wgs84坐标,所以要将gcj02坐标转wgs84坐标,再定位到底图上。

2

搜索地址实现

Search address function

功能菜单:

输入POI地址,点击确定,通过高德API获得gcj02坐标,换算为wgs84坐标,在底图上定位到该坐标,并增加一个Marker标记,下图是搜索的示例,大家看看算的准不准。

3

核心功能代码

Code

核心动作:调取高德API,送地址参数,拿回火星坐标,转换成wgs84坐标,在地图上定位。

代码语言:javascript
复制
/// <summary>
/// 由地址获得经纬度,再显示地图位置。
/// </summary>
/// <param name="place">地址文字描述</param>
private void AddLocation(string place)
{
    String addressStr = "http://restapi.amap.com/v3/geocode/geo?key=这里是用户的key大家自己申请&s=rsv3&city=027&address=";
    String getAddress = addressStr + place;

    //url 你的WebApi 地址重要!!!
    Uri uri = new Uri(getAddress);
    //WebClient:获取webaapi中的数据。
    using (WebClient c = new WebClient())
    {
        //c.Headers["Type"]:获取数据的方式
        c.Headers["Type"] = "GET";
        //c.Headers["Accept"]:获取数据的格式
        c.Headers["Accept"] = "application/json";
        //c.Encoding:数据的编码格式。
        c.Encoding = Encoding.UTF8;
        //DownloadDataCompleted:在多线程情况下,能进行webApi数据传输。
        c.DownloadStringCompleted += (senderobj, es) =>
        {
            if (es.Result != null)
            {
                //把webApi之中获取的json数据 序列化成dataTable
                AddressSearchResult ad = JsonConvert.DeserializeObject<AddressSearchResult>(es.Result);
                if (ad.geocodes != null)
                {
                    if (ad.geocodes.Length > 0)
                    {
                        string[] s = ad.geocodes[0].location.Split(',');

                        //增加一个转换(gcj02坐标转wgs84坐标)
                        Cor hx = new Cor();
                        hx.lat = double.Parse(s[1]);
                        hx.lng = double.Parse(s[0]);
                        Cor x = Transformer.gcj02towgs84(hx);  //火星标转换为84

                        PointLatLng cp = new PointLatLng(x.lat,x.lng);   //lng是经度,lat是纬度  武汉
                        MainMap.Zoom = 16;
                        MainMap.Position = cp;
                        this.lbZoomStatus.Text = MainMap.Zoom.ToString();

                        #region 标记点

                        //创建标记,并设置位置及样式
                        GMapMarker marker = new GMarkerGoogle(new PointLatLng(cp.Lat, cp.Lng), GMarkerGoogleType.blue_pushpin);

                        marker.ToolTipMode = MarkerTooltipMode.OnMouseOver;
                        marker.ToolTipText = ad.geocodes[0].formatted_address;
                        marker.Tag = JsonConvert.SerializeObject(ad, Formatting.Indented);

                        //将标记添加到图层
                        overlay.Markers.Add(marker);
                        #endregion
                    }
                    else
                    {
                        System.Windows.MessageBox.Show("没有找到该地址,geo数组长度为0");
                    }
                }
                else
                {
                    System.Windows.MessageBox.Show("没有找到该地址,geo对象为空");
                }
            }
        };
        //把当前webApi地址释放掉。
        c.DownloadStringAsync(uri);
    }
}

火星标转换为84方法代码:

代码语言:javascript
复制
/// <summary>
/// 火星转84
/// 该方法经过实战测试计算比较准确  naki  2022.4.19
/// </summary>
/// <param name="hx"></param>
/// <returns></returns>
public static Cor gcj02towgs84(Cor hx)
{
    if (OutOfChina(hx))
    {
        return hx;
    }
    double dlat = transformlat(hx.lng - 105.0, hx.lat - 35.0);
    double dlng = transformlng(hx.lng - 105.0, hx.lat - 35.0);
    double radlat = hx.lat / 180.0 * pi;
    double magic = Math.Sin(radlat);
    magic = 1 - ee * magic * magic;
    double sqrtmagic = Math.Sqrt(magic);
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);
    dlng = (dlng * 180.0) / (a / sqrtmagic * Math.Cos(radlat) * pi);
    Cor wgs84;
    double mglat = hx.lat + dlat;
    double mglng = hx.lng + dlng;
    wgs84.lat = hx.lat * 2 - mglat;
    wgs84.lng = hx.lng * 2 - mglng;
    return wgs84;
}

/*辅助函数*/
//转换lat
private static double transformlat(double lng, double lat)
{
    double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat +
0.1 * lng * lat + 0.2 * Math.Sqrt(Math.Abs(lng));
    ret += (20.0 * Math.Sin(6.0 * lng * pi) + 20.0 *
            Math.Sin(2.0 * lng * pi)) * 2.0 / 3.0;
    ret += (20.0 * Math.Sin(lat * pi) + 40.0 *
            Math.Sin(lat / 3.0 * pi)) * 2.0 / 3.0;
    ret += (160.0 * Math.Sin(lat / 12.0 * pi) + 320 *
            Math.Sin(lat * pi / 30.0)) * 2.0 / 3.0;
    return ret;
}

/*辅助函数*/
//转换lng
private static double transformlng(double lng, double lat)
{
    double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng +
0.1 * lng * lat + 0.1 * Math.Sqrt(Math.Abs(lng));
    ret += (20.0 * Math.Sin(6.0 * lng * pi) + 20.0 *
            Math.Sin(2.0 * lng * pi)) * 2.0 / 3.0;
    ret += (20.0 * Math.Sin(lng * pi) + 40.0 *
            Math.Sin(lng / 3.0 * pi)) * 2.0 / 3.0;
    ret += (150.0 * Math.Sin(lng / 12.0 * pi) + 300.0 *
            Math.Sin(lng / 30.0 * pi)) * 2.0 / 3.0;
    return ret;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 天堂向左程序员向右 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档