`

googleMap(其二)获取手机所在地的经纬度

 
阅读更多
上文说到获取手机所在地的经纬度,那么有几种方式呢?通过GPS,network.而地位API中提供了LocationManager,以及Location。其中LocationManager用来获得位置服务,Location用来获取位置。具体代码如下:


private GeoPoint getGeoPoint(){
        LocationManager locationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
        Location location=locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        return new GeoPoint((int)location.getLatitude(),(int)location.getLongitude());
    }


从这里我们可以知道一个经纬度对象GeoPoint,它接受2个整形的经纬度值。在这里我们是使用GPS获取当前经纬度,如果用network呢?那么久换LocationManager.NETWORK_PROVIDER

当然,我们可能要考虑到更多的情况,比如说GPS模式是关闭的,那么如何启动它?很简单,我们只要判断是否启用了GPS,如果没有则跳到Settings中进行启用。代码如下:


boolean flag=locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if(!flag){
            Intent intent=new Intent(Settings.ACTION_SECURITY_SETTINGS);
        }


以上是获得当前手机所在地的经纬度。

当然当我们行走时候,位置是不断变化的,我们怎么才能够检测到位置的变化,并显示出来呢?

我们这里需要用到位置监听器LocationListener,当然,我们会查询出最佳的数据,因此需要设置Criteria

代码如下:



//获得最佳服务
    private Criteria getCriteria(){
        Criteria criteria=new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);// 高精度
        criteria.setAltitudeRequired(false);//海拔
        criteria.setBearingRequired(false);//地轴线
        criteria.setCostAllowed(false); //付费
        criteria.setPowerRequirement(Criteria.POWER_LOW);//电量低
        return criteria;
    }


实例化LocationListener,在不同的回调函数中处理,这里我们只处理位置变化回调函数onLocationChanged,具体代码如下:



//位置监听器,监听位置的改变
    LocationListener locationListener=new LocationListener(){
        //当位置变化时候激发
        @Override
        public void onLocationChanged(Location location) {
            //根据位置获取经纬度对象
            getGeoPoint(location);
        }
        //GPS,或者network可时候激发
        @Override
        public void onProviderDisabled(String provider) {
            
            
        }
        //GPS,或者network不可时候激发
        @Override
        public void onProviderEnabled(String provider) {
            
            
        }
        //GPS,或者network状态改变时候激发
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            switch(status){
            case LocationProvider.OUT_OF_SERVICE:
                 //不在服务
                break;
            case LocationProvider.TEMPORARILY_UNAVAILABLE:
                //暂不可用
                break;
            case LocationProvider.AVAILABLE :
                 //可用
                break;
                 
            }
            
        }
    };


既然定义好了监听处理类后,我们就可以在LocationManager中注册这个监听:



private void registeListener(){
        LocationManager locationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
        if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
            //如果GPS不可用,则跳转到Settings中进行设置
            Intent intent=new Intent(Settings.ACTION_SECURITY_SETTINGS);
            startActivity(intent);
        }
        //查询最设和的服务信息    
        String provider=locationManager.getBestProvider(getCriteria(), true);
        //设置位置监听器,间隔5秒改变一次
        locationManager.requestLocationUpdates(provider, 5000, 0, locationListener);
    }



这里locationManager.requestLocationUpdates(provider, 5000, 0, locationListener); 第一个参数是位置提供器,第2个是多少毫米请求一次,第3个是移动最小距离(米),第4个就是监听类了。

当然,我们可以取消位置监听:locationManager.removeUpdates(locationListener);

既然可以动态获取手机经纬度,那么怎么把经纬度解析成我们实际地址呢?
我们可以采用Geocoder类的getFromLocation方法解析位置信息,然后返回一系列地址信息List<Address>,再根据最符合的Address获取国家、州县、街道等等地址信息,代码如下:



//根据经纬度获得地址(国家,州县,街道等等)
    private void showAddressFromGeoPoint(GeoPoint gPoint) throws IOException{
        StringBuilder sb=new StringBuilder();
        Geocoder geoCode=new Geocoder(this,Locale.getDefault());
        List<Address> addresses=geoCode.getFromLocation(gPoint.getLatitudeE6()/1E6, gPoint.getLongitudeE6()/1E6, 1);
        if(addresses.size()>0){
            Address address=addresses.get(0);
            for(int i=0;i<address.getMaxAddressLineIndex();i++){
                sb.append(address.getAddressLine(i)+"\n");
            }
            sb.append(address.getLocality()+"\n");
            sb.append(address.getPostalCode()+"\n");
            sb.append(address.getCountryName()+"\n");
            
            Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
        }
    }



以上是把经纬度、位置等信息解析成地址,那么反过来,我们是不是可以根据地址名称获得经纬度位置,然后在地图上标识起来呢?当然可以,现在就来根据实际地址获取经纬度吧:

跟上述方式一样,调用Geocoder的getFromLocationName方法,获得地址列表,然后取出最佳的地址,再获取经纬度,代码如下:



//根据地址获取经纬度信息GeoPoint
    private GeoPoint getGeoPointFromAddressName(String locationName) throws IOException{
        Geocoder geoCode=new Geocoder(this,Locale.getDefault());
        List<Address> addresses=geoCode.getFromLocationName(locationName, 1);
        if(addresses!=null){
         double lati=addresses.get(0).getLatitude();
         double longi=addresses.get(0).getLongitude();
            return new GeoPoint((int)(lati*1E6),(int)(longi*1E6));
        }
            return null;
    }



如果,我想知道,我是否逼近了某个区域范围,然后手机就发出通知,这个怎么办?

逼近某个范围,就是有一个经纬度对象GeoPoint 固定,另外一个GeoPoint 不断靠近变化,要测量这2个点的距离,可以使用Location的distanceBetween方法。具体代码如下:


//计算2点距离,经纬度
    private float getDistance(GeoPoint startPoint,GeoPoint endPoint){
        float []results=new float[3];
        Location.distanceBetween(startPoint.getLatitudeE6()/1E6, startPoint.getLongitudeE6()/1E6, 
                endPoint.getLatitudeE6()/1E6, endPoint.getLongitudeE6()/1E6,
                results);
            return results[0]; 
    }



上述代码就实现了2个点距离检测,然后我们可以根据判断2点距离是否在某一距离范围内,代码如下:


//判断是否在多少米范围内
    private boolean isNearAround(GeoPoint startPoint,GeoPoint endPoint,float meter){
         float distance=getDistance(startPoint,endPoint);
         return (meter-distance>0)?true:false;
    }


以上就是逼近某地范围的方法,但是你可能会想,我们的位置如果是变化的呢?所以你就必须在位置变化时候更新GeoPoint ,位置变化监听器LocationListener有个onLocationChanged方法回调每次变化的位置,当然你看了以上说明后自然知道怎么调用了。

再来几个开发中常会遇到问题吧。

我们怎么获取手机屏幕上一点对应的经纬度?(手机屏幕点转化为经纬度),或者某一经纬度怎么对应手机屏幕上一点的位置?

我们可以使用Projection类的fromPixels,以及toPixels方法分别转化为屏幕一点,以及屏幕一点的经纬度,当然获取 Projection是需要我们地图对象的getProjection方法,具体代码如下:



//屏幕上一点获得经纬度
    private GeoPoint FormScreenPoint(Point screen){
        Projection projection=mapView.getProjection();
        GeoPoint gpoint=projection.fromPixels(screen.x, screen.y);
        return gpoint;
    }
    
    //根据经纬度定位到手机屏幕上一点
    private Point FromGeoPoint(GeoPoint gPoint){
        Point out =new Point();
        Projection projection=mapView.getProjection();
        projection.toPixels(gPoint, out);
        return out;
    }



有了前面几项基础知识后,我们可以更深入发展了,就想之前提及的,在手机屏幕上绘制一个图层,标记一张图片或者一些信息,然后我们点击这个标记,他会提示一些信息。
这里主要就是如何解决标记到地图的问题了
这里使用到一个类Overlay,这个可作为地图上的标记,因此我们首先基础这个标记,然后绘制自己的图钉(图片),再重写它的onTouchEvent方法,以便点击这个图层时候提示信息,当然我们可以传递经纬度对象GeoPoint进去,以便在地图中显示:



//自定义图层标记
    private class MyOverLay extends Overlay{
        GeoPoint in=null;
        public MyOverLay(GeoPoint in){
            this.in=in;
        }
        //在自定义绘制图层的方法中添加图钉(一张图片)
        @Override
        public boolean draw(Canvas canvas,MapView mapView,
                    boolean shadow,long when){
            //经纬度转化屏幕一点
            Point out=new Point();
            Projection proj=mapView.getProjection();
            proj.toPixels(in, out);
            
            //获得图片并调用canvas绘制图片,其中第3个参数为Y轴坐标具体看图
            Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
            canvas.drawBitmap(bitmap, out.x, out.y-50, null);
            return true;
        }
        
        @Override
        public boolean onTouchEvent(MotionEvent e,MapView mapView){
             if(e.getAction()==MotionEvent.ACTION_UP){
                 //根据屏幕一点获取经纬度
                 GeoPoint gpoint=mapView.getProjection().fromPixels((int)e.getX(), (int)e.getY());
                 //然后显示经纬度
                 String msg="您点击的地方经度为:"+gpoint.getLatitudeE6()/1E6+",纬度为:"+gpoint.getLongitudeE6()/1E6;
                 Toast.makeText(getApplication(), msg, Toast.LENGTH_LONG).show();
                 
                 //当然,您可以使用传递过来的对象,比如GeoPoint获取一些其他自定义对象信息,比如说什么地方,什么公司以及风景区等
                 
             }
            return true;
        } 
    }



我们可以看到我们绘制了一个图形,以及重写了触摸的方法,在触摸时候提示信息,接下来,我们必须把它“钉”在地图上进行显示,当然了,默认MapView都自动加载了图层,我们只需调用
List<Overlay> overlays=mapView.getOverlays(); 方法获得图层列表,然后把我们自定义的图层添加进去即可,代码如下:



 //在屏幕上打上标记(图钉)
    private void putOverLay(GeoPoint in){
//        /定义标记
        MyOverLay myOverLay=new MyOverLay(in);
        List<Overlay> overlays=mapView.getOverlays();
        overlays.clear();
        overlays.add(myOverLay);
        mapView.invalidate();
    }


这里解析一个问题,我们说是canvas.drawBitmap(bitmap, out.x, out.y-50, null);中第3个参数是要减去50呢?你看看这幅图就明白了,需要减去高才可以使图钉的指针正好对应屏幕的某点。



完成。假如你完全理解上面一系列东西,那么LBS已经有了基础。
分享到:
评论

相关推荐

    受激拉曼散射计量【Stimulated-Raman-Scattering Metrology】 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    MMC整流器技术解析:基于Matlab的双闭环控制策略与环流抑制性能研究,Matlab下的MMC整流器技术文档:18个子模块,双闭环控制稳定直流电压,环流抑制与最近电平逼近调制,优化桥臂电流波形,高效

    MMC整流器技术解析:基于Matlab的双闭环控制策略与环流抑制性能研究,Matlab下的MMC整流器技术文档:18个子模块,双闭环控制稳定直流电压,环流抑制与最近电平逼近调制,优化桥臂电流波形,高效并网运行。,MMC整流器(Matlab),技术文档 1.MMC工作在整流侧,子模块个数N=18,直流侧电压Udc=25.2kV,交流侧电压6.6kV 2.控制器采用双闭环控制,外环控制直流电压,采用PI调节器,电流内环采用PI+前馈解耦; 3.环流抑制采用PI控制,能够抑制环流二倍频分量; 4.采用最近电平逼近调制(NLM), 5.均压排序:电容电压排序采用冒泡排序,判断桥臂电流方向确定投入切除; 结果: 1.输出的直流电压能够稳定在25.2kV; 2.有功功率,无功功率稳态时波形稳定,有功功率为3.2MW,无功稳定在0Var; 3.网侧电压电流波形均为对称的三相电压和三相电流波形,网侧电流THD=1.47%<2%,符合并网要求; 4.环流抑制后桥臂电流的波形得到改善,桥臂电流THD由9.57%降至1.93%,环流波形也可以看到得到抑制; 5.电容电压能够稳定变化 ,工作点关键词:MMC

    Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基

    Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构,Simulink建模,MPPT最大功率点追踪,扰动观察法采用功率反馈方式,若ΔP>0,说明电压调整的方向正确,可以继续按原方向进行“干扰”;若ΔP<0,说明电压调整的方向错误,需要对“干扰”的方向进行改变。 ,Boost升压;光伏并网结构;Simulink建模;MPPT最大功率点追踪;扰动观察法;功率反馈;电压调整方向。,光伏并网结构中Boost升压MPPT控制策略的Simulink建模与功率反馈扰动观察法

    STM32F103C8T6 USB寄存器开发详解(12)-键盘设备

    STM32F103C8T6 USB寄存器开发详解(12)-键盘设备

    2011-2020广东21市科技活动人员数

    科技活动人员数专指直接从事科技活动以及专门从事科技活动管理和为科技活动提供直接服务的人员数量

    Matlab Simulink仿真探究Flyback反激式开关电源性能表现与优化策略,Matlab Simulink仿真探究Flyback反激式开关电源的工作机制,Matlab Simulimk仿真

    Matlab Simulink仿真探究Flyback反激式开关电源性能表现与优化策略,Matlab Simulink仿真探究Flyback反激式开关电源的工作机制,Matlab Simulimk仿真,Flyback反激式开关电源仿真 ,Matlab; Simulink仿真; Flyback反激式; 开关电源仿真,Matlab Simulink在Flyback反激式开关电源仿真中的应用

    基于Comsol的埋地电缆电磁加热计算模型:深度解析温度场与电磁场分布学习资料与服务,COMSOL埋地电缆电磁加热计算模型:温度场与电磁场分布的解析与学习资源,comsol 埋地电缆电磁加热计算模型

    基于Comsol的埋地电缆电磁加热计算模型:深度解析温度场与电磁场分布学习资料与服务,COMSOL埋地电缆电磁加热计算模型:温度场与电磁场分布的解析与学习资源,comsol 埋地电缆电磁加热计算模型,可以得到埋地电缆温度场及电磁场分布,提供学习资料和服务, ,comsol;埋地电缆电磁加热计算模型;温度场分布;电磁场分布;学习资料;服务,Comsol埋地电缆电磁加热模型:温度场与电磁场分布学习资料及服务

    ibus-table-chinese-yong-1.4.6-3.el7.x64-86.rpm.tar.gz

    1、文件内容:ibus-table-chinese-yong-1.4.6-3.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/ibus-table-chinese-yong-1.4.6-3.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊

    基于51单片机protues仿真的汽车智能灯光控制系统设计(仿真图、源代码)

    基于51单片机protues仿真的汽车智能灯光控制系统设计(仿真图、源代码) 一、设计项目 根据本次设计的要求,设计出一款基于51单片机的自动切换远近光灯的设计。 技术条件与说明: 1. 设计硬件部分,中央处理器采用了STC89C51RC单片机; 2. 使用两个灯珠代表远近光灯,感光部分采用了光敏电阻,因为光敏电阻输出的是电压模拟信号,单片机不能直接处理模拟信号,所以经过ADC0832进行转化成数字信号; 3. 显示部分采用了LCD1602液晶,还增加按键部分电路,可以选择手自动切换远近光灯; 4. 用超声模块进行检测距离;

    altermanager的企业微信告警服务

    altermanager的企业微信告警服务

    MyAgent测试版本在线下载

    MyAgent测试版本在线下载

    Comsol技术:可调BIC应用的二氧化钒VO2材料探索,Comsol模拟二氧化钒VO2的可调BIC特性研究,Comsol二氧化钒VO2可调BIC ,Comsol; 二氧化钒VO2; 可调BIC

    Comsol技术:可调BIC应用的二氧化钒VO2材料探索,Comsol模拟二氧化钒VO2的可调BIC特性研究,Comsol二氧化钒VO2可调BIC。 ,Comsol; 二氧化钒VO2; 可调BIC,Comsol二氧化钒VO2材料:可调BIC技术的关键应用

    C++学生成绩管理系统源码.zip

    C++学生成绩管理系统源码

    基于Matlab与Cplex的激励型需求响应模式:负荷转移与电价响应的差异化目标函数解析,基于Matlab与CPLEX的激励型需求响应负荷转移策略探索,激励型需求响应 matlab +cplex 激励

    基于Matlab与Cplex的激励型需求响应模式:负荷转移与电价响应的差异化目标函数解析,基于Matlab与CPLEX的激励型需求响应负荷转移策略探索,激励型需求响应 matlab +cplex 激励型需求响应采用激励型需求响应方式对负荷进行转移,和电价响应模式不同,具体的目标函数如下 ,激励型需求响应; matlab + cplex; 负荷转移; 目标函数。,Matlab与Cplex结合的激励型需求响应模型及其负荷转移策略

    scratch介绍(scratch说明).zip

    scratch介绍(scratch说明).zip

    深度学习模型的发展历程及其关键技术在人工智能领域的应用

    内容概要:本文全面介绍了深度学习模型的概念、工作机制和发展历程,详细探讨了神经网络的构建和训练过程,包括反向传播算法和梯度下降方法。文中还列举了深度学习在图像识别、自然语言处理、医疗和金融等多个领域的应用实例,并讨论了当前面临的挑战,如数据依赖、计算资源需求、可解释性和对抗攻击等问题。最后,文章展望了未来的发展趋势,如与量子计算和区块链的融合,以及在更多领域的应用前景。 适合人群:对该领域有兴趣的技术人员、研究人员和学者,尤其适合那些希望深入了解深度学习原理和技术细节的读者。 使用场景及目标:①理解深度学习模型的基本原理和结构;②了解深度学习模型的具体应用案例;③掌握应对当前技术挑战的方向。 阅读建议:文章内容详尽丰富,读者应在阅读过程中注意理解各个关键技术的概念和原理,尤其是神经网络的构成及训练过程。同时也建议对比不同模型的特点及其在具体应用中的表现。

    day02供应链管理系统-补充.zip

    该文档提供了一个关于供应链管理系统开发的详细指南,重点介绍了项目安排、技术实现和框架搭建的相关内容。 文档分为以下几个关键部分: 项目安排:主要步骤包括搭建框架(1天),基础数据模块和权限管理(4天),以及应收应付和销售管理(5天)。 供应链概念:供应链系统的核心流程是通过采购商品放入仓库,并在销售时从仓库提取商品,涉及三个主要订单:采购订单、销售订单和调拨订单。 大数据的应用:介绍了数据挖掘、ETL(数据抽取)和BI(商业智能)在供应链管理中的应用。 技术实现:讲述了DAO(数据访问对象)的重用、服务层的重用、以及前端JS的继承机制、jQuery插件开发等技术细节。 系统框架搭建:包括Maven环境的配置、Web工程的创建、持久化类和映射文件的编写,以及Spring配置文件的实现。 DAO的需求和功能:供应链管理系统的各个模块都涉及分页查询、条件查询、删除、增加、修改操作等需求。 泛型的应用:通过示例说明了在Java语言中如何使用泛型来实现模块化和可扩展性。 文档非常技术导向,适合开发人员参考,用于构建供应链管理系统的架构和功能模块。

    清华大学104页《Deepseek:从入门到精通》

    这份长达104页的手册由清华大学新闻与传播学院新媒体研究中心元宇宙文化实验室的余梦珑博士后及其团队精心编撰,内容详尽,覆盖了从基础概念、技术原理到实战案例的全方位指导。它不仅适合初学者快速了解DeepSeek的基本操作,也为有经验的用户提供了高级技巧和优化策略。

    MXTU MAX仿毒舌自适应主题源码 苹果CMSv10模板.zip

    主题说明: 1、将mxtheme目录放置根目录 | 将mxpro目录放置template文件夹中 2、苹果cms后台-系统-网站参数配置-网站模板-选择mxpro 模板目录填写html 3、网站模板选择好之后一定要先访问前台,然后再进入后台设置 4、主题后台地址: MXTU MAX图图主题,/admin.php/admin/mxpro/mxproset admin.php改成你登录后台的xxx.php 5、首页幻灯片设置视频推荐9,自行后台设置 6、追剧周表在视频数据中,节目周期添加周一至周日自行添加,格式:一,二,三,四,五,六,日

    基于matlab平台的数字信号处理GUI设计.zip

    运行GUI版本,可二开

Global site tag (gtag.js) - Google Analytics