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

1.搜索地址功能实现

1.1功能描述

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

1.2实现效果演示

功能菜单:
在这里插入图片描述

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

2.搜索地址的核心方法代码

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

/// <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方法代码:

/// <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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiangcns

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值