lawdao / MapDemo

仿微信发送位置

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MapDemo

仿微信发送位置

效果演示

效果演示

实现的功能

  1. 根据经纬度定位
  2. 根据所在的经纬度搜索附近的地点
  3. 根据关键字搜索地点
  4. 为地图增加标记
  5. 发送选择的地点位置信息

你能学到什么

  1. 高德地图的使用
  2. 如何定位(获取当前位置信息)
  3. 如何通过经纬度搜索附近的地点(也叫兴趣点poi)
  4. 如何通过关键字搜索附近的兴趣点

微信位置发送分析

  1. 进入发送页面后,自己当前位置有一个蓝色标记,它是不会变的,在蓝色的标记上有一个红色的小钉子,是用来显示你想要定位定到哪去,它在地图的**
  2. 地图下面有一个列表,是根据当前的经纬度搜索出来的兴趣点,也叫poi,默认选中第一个条目,也就是当前的位置
  3. 当你点击列表的条目时,此时地图会根据你点击的条目变换到你所点击的地点去,此时,被点击的条目被选中
  4. 当你手动的移动地图的时候,中间的红色小钉,不会动,当你移动完地图之后,红色小红钉会有一个上下移动的动画,表示你要定位到红色小红钉处,此时根据小红钉所处的经纬度来搜索附近的兴趣点(poi)
  5. 进入搜索页面之后,通过关键字搜索地点,搜索完成之后,展示在列表里,默认选中第一个,点击条目之后,根据经纬度继续搜索附近的poi,此时列表的第一项是被点击的条目,地图同时移动到被点击的地点处
  6. 点击发送后拿到当前被选中的条目的位置信息,然后发送

分析完了微信的,下面就开始我们自己的,跟着我走,实现你自己想要的模样吧

代码实现及步骤

1. 首页获取定位信息

public class MapUtils implements AMapLocationListener {
	    private AMapLocationClient locationClient = null;  // 定位
	    private AMapLocationClientOption locationOption = null;  // 定位设置

	    @Override
	    public void onLocationChanged(AMapLocation aMapLocation) {
	        mLonLatListener.getLonLat(aMapLocation);
	        locationClient.stopLocation();
	        locationClient.onDestroy();
	        locationClient = null;
	        locationOption = null;
	    }

	    private LonLatListener mLonLatListener;

	    public void getLonLat(Context context, LonLatListener lonLatListener) {
	        locationClient = new AMapLocationClient(context);
	        locationOption = new AMapLocationClientOption();
	        locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);// 设置定位模式为高精度模式
	        locationClient.setLocationListener(this);// 设置定位监听
	        locationOption.setOnceLocation(false); // 单次定位 每隔2秒定位一次
	        locationOption.setNeedAddress(true);//返回地址信息
	        mLonLatListener = lonLatListener;//接口
	        locationClient.setLocationOption(locationOption);// 设置定位参数
	        locationClient.startLocation(); // 启动定位
	    }

	    public interface LonLatListener {
	        void getLonLat(AMapLocation aMapLocation);
	    }

	}

2. 逆地理编码,经纬度转换

逆地理编码步骤:

  1. 创建GeocodeSearch实例
	geocoderSearch = new GeocodeSearch(getApplicationContext());
  1. 实现GeocodeSearch.OnGeocodeSearchListener监听
	//设置逆地理编码监听
	   	geocoderSearch.setOnGeocodeSearchListener(this);


		  /**
		     * 逆地理编码查询回调
		     *
		     * @param result
		     * @param i
		     */
		    @Override
		    public void onRegeocodeSearched(RegeocodeResult result, int i) {

		        if (i == 1000) {//转换成功
		            if (result != null && result.getRegeocodeAddress() != null
		                    && result.getRegeocodeAddress().getFormatAddress() != null) {
		                //拿到详细地址
		                addressName = result.getRegeocodeAddress().getFormatAddress(); // 逆转地里编码不是每次都可以得到对应地图上的opi

		                //条目中第一个地址 也就是当前你所在的地址
		                mAddressInfoFirst = new SearchAddressInfo(addressName, addressName, false, convertToLatLonPoint(mFinalChoosePosition));

		                //其实也是可以在这就能拿到附近的兴趣点的

		            } else {
		                ToastUtil.show(this, "没有搜到");
		            }
		        } else {
		            ToastUtil.showerror(this, i);
		        }

		    }

		    /**
		     * 地理编码查询回调
		     *
		     * @param geocodeResult
		     * @param i
		     */
		    @Override
		    public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

	    	}

通过RegeocodeResult拿到编码后的信息

3. 通过经纬度信息搜索poi

  /**
     * 开始进行poi搜索
     * 通过经纬度获取附近的poi信息
     * <p>
     * 1、keyword 传 ""
     * 2、poiSearch.setBound(new PoiSearch.SearchBound(lpTemp, 5000, true)); 根据
     */
    protected void doSearchQueryByPosition() {

        currentPage = 0;
        query = new PoiSearch.Query("", "", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国)
        query.setPageSize(20);// 设置每页最多返回多少条poiitem
        query.setPageNum(currentPage);// 设置查第一页

        LatLonPoint llPoint = convertToLatLonPoint(mFinalChoosePosition);

        if (llPoint != null) {
            poiSearch = new PoiSearch(this, query);
            poiSearch.setOnPoiSearchListener(this);  // 实现  onPoiSearched  和  onPoiItemSearched
            poiSearch.setBound(new PoiSearch.SearchBound(llPoint, 5000, true));//
            // 设置搜索区域为以lpTemp点为圆心,其周围5000米范围
            poiSearch.searchPOIAsyn();// 异步搜索
        }
    }

4. 通过关键字搜索poi

  /**
     * 按照关键字搜索附近的poi信息
     *
     * @param key
     */
    protected void doSearchQueryByKeyWord(String key) {
        currentPage = 0;
        query = new PoiSearch.Query(key, "", city);// 第一个参数表示搜索字符串,第二个参数表示poi搜索类型,第三个参数表示poi搜索区域(空字符串代表全国)
        query.setPageSize(20);// 设置每页最多返回多少条poiitem
        query.setPageNum(currentPage);// 设置查第一页
        query.setCityLimit(true); //限定城市

        if (lp != null) {
            poiSearch = new PoiSearch(this, query);
            poiSearch.setOnPoiSearchListener(this);   // 实现  onPoiSearched  和  onPoiItemSearched
            poiSearch.setBound(new PoiSearch.SearchBound(lp, 5000, true));//
            // 设置搜索区域为以latLonPoint点为圆心,其周围5000米范围
            poiSearch.searchPOIAsyn();// 异步搜索
        }
    }

通过poiSearch.setOnPoiSearchListener(this)实现对搜索结果的监听,在onPoiSearched(),onPoiItemSearched()回调里处理返回的结果

5. 处理拿到的poi信息

@Override
	    public void onPoiSearched(PoiResult result, int rcode) {

	        if (rcode == 1000) {
	            if (result != null && result.getQuery() != null) {// 搜索poi的结果
	                if (result.getQuery().equals(query)) {// 是否是同一条
	                    poiResult = result;
	                    poiItems = poiResult.getPois();// 取得第一页的poiitem数据,页数从数字0开始

	                    List<SuggestionCity> suggestionCities = poiResult
	                            .getSearchSuggestionCitys();// 当搜索不到poiitem数据时,会返回含有搜索关键字的城市信息

	                    //搜索到数据
	                    if (poiItems != null && poiItems.size() > 0) {

	                        mData.clear();

	                        //先将 逆地理编码过的当前地址 也就是条目中第一个地址 放到集合中
	                        mData.add(mAddressInfoFirst);

	                        SearchAddressInfo addressInfo = null;

	                        for (PoiItem poiItem : poiItems) {

	                            addressInfo = new SearchAddressInfo(poiItem.getTitle(), poiItem.getSnippet(), false, poiItem.getLatLonPoint());

	                            mData.add(addressInfo);
	                        }
	                        if (isHandDrag) {
	                            mData.get(0).isChoose = true;
	                        }
	                        addressAdapter.notifyDataSetChanged();

	                    } else if (suggestionCities != null
	                            && suggestionCities.size() > 0) {
	                        showSuggestCity(suggestionCities);
	                    } else {
	                        ToastUtil.show(ShareLocationActivity.this,
	                                "对不起,没有搜索到相关数据");
	                    }
	                }
	            } else {
	                Toast.makeText(this, "对不起,没有搜索到相关数据!", Toast.LENGTH_SHORT).show();
	            }
	        }

	    }

6. 移动地图

  1. 设置监听
	 //对amap添加移动地图事件监听器
	 aMap.setOnCameraChangeListener(this);
  1. 实现监听
	 /**
		     * 移动地图时调用
		     *
		     * @param cameraPosition
		     */
		    @Override
		    public void onCameraChange(CameraPosition cameraPosition) {

		    }

		    /**
		     * 地图移动结束后调用
		     *
		     * @param cameraPosition
		     */
		    @Override
		    public void onCameraChangeFinish(CameraPosition cameraPosition) {

		        //每次移动结束后地图中心的经纬度
		        mFinalChoosePosition = cameraPosition.target;

		        centerImage.startAnimation(centerAnimation);


		        if (isHandDrag || isFirstLoad) {//手动去拖动地图

		            // 开始进行poi搜索
		            getAddressFromLonLat(cameraPosition.target);
		            doSearchQueryByPosition();

		        } else if (isBackFromSearch) {
		            //搜索地址返回后 拿到选择的位置信息继续搜索附近的兴趣点
		            isBackFromSearch = false;
		            doSearchQueryByPosition();
		        } else {
		            addressAdapter.notifyDataSetChanged();
		        }
		        isHandDrag = true;
		        isFirstLoad = false;
	    	}

About

仿微信发送位置


Languages

Language:Java 100.0%