Android 中使用地图加载wms服务(高德地图,谷歌地图,天地图)_android 高德wmts-程序员宅基地

技术标签: 技术  地图添加wms  

转载请注明出处:http://blog.csdn.net/zkjthinking/article/details/77278838

由于公司需求需要在移动平台上加载自己发布的wms 服务:

  • 高德地图加载wms
  • 谷歌地图加载wms
  • 天地图加载wms或者wmts

目前就做了这几个地图上面加载wms 服务的需求,所有只在这里写这三种;
1.高德地图加载wms:
代码:

//加载自定义wms在你的Activity 中加载 amap为mapview.getAmap();
HeritageScopeTileProvider tileProvider = newHeritageScopeTileProvider();
aMap.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));

然后我们看这个自定义类中怎么写吧

public class HeritageScopeTileProvider extends UrlTileProvider {
    
    private String mRootUrl;
    //默认瓦片大小
    private static int titleSize = 256;//a=6378137±2(m)
    //基本参数
    private final double initialResolution= 156543.03392804062;//2*Math.PI*6378137/titleSize;
    private final double originShift      = 20037508.342789244;//2*Math.PI*6378137/2.0; 周长的一半

    private final double HALF_PI = Math.PI / 2.0;
    private final double RAD_PER_DEGREE = Math.PI / 180.0;
    private final double HALF_RAD_PER_DEGREE = Math.PI / 360.0;
    private final double METER_PER_DEGREE = originShift / 180.0;//一度多少米
    private final double DEGREE_PER_METER = 180.0 / originShift;//一米多少度


    public HeritageScopeTileProvider() {
        super(titleSize, titleSize);
        //地址写你自己的wms地址
        mRootUrl = "http://xxxxxx自己的/wms?LAYERS=cwh:protect_region_38_20160830&FORMAT=image%2Fpng&TRANSPARENT=TRUE&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A900913&BBOX=";
    }


    public HeritageScopeTileProvider(int i, int i1) {
        super(i, i1);
    }

    @Override
    public URL getTileUrl(int x, int y, int level) {

        try {
            String url = mRootUrl + TitleBounds(x, y, level);
            return new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        return null;
    }


    /**
     * 根据像素、等级算出坐标
     *
     * @param p
     * @param zoom
     * @return
     */
    private double Pixels2Meters(int p, int zoom) {
        return p * Resolution(zoom) - originShift;
    }

    /**
     * 根据瓦片的x/y等级返回瓦片范围
     *
     * @param tx
     * @param ty
     * @param zoom
     * @return
     */
    private String TitleBounds(int tx, int ty, int zoom) {
        double minX = Pixels2Meters(tx * titleSize, zoom);
        double maxY = -Pixels2Meters(ty * titleSize, zoom);
        double maxX = Pixels2Meters((tx + 1) * titleSize, zoom);
        double minY = -Pixels2Meters((ty + 1) * titleSize, zoom);

        //转换成经纬度
        minX=Meters2Lon(minX);
        minY=Meters2Lat(minY);
        maxX=Meters2Lon(maxX);
        maxY=Meters2Lat(maxY);
        PositionModel position1 = PositionUtil.gcj_To_Gps84(minY,minX);
        minX = position1.getWgLon();
        minY = position1.getWgLat();
        PositionModel position2 = PositionUtil.gcj_To_Gps84(maxY,maxX);
        maxX = position2.getWgLon();
        maxY = position2.getWgLat();

        minX=Lon2Meter(minX);
        minY=Lat2Meter(minY);
        maxX=Lon2Meter(maxX);
        maxY=Lat2Meter(maxY);

        return minX + "," + Double.toString(minY) + "," + Double.toString(maxX) + "," + Double.toString(maxY) + "&WIDTH=256&HEIGHT=256";
    }
    /**
     * 计算分辨率
     *
     * @param zoom
     * @return
     */
    private double Resolution(int zoom) {
        return initialResolution / (Math.pow(2, zoom));
    }

    /**
     * X米转经纬度
     */
    private double Meters2Lon(double mx) {
        double lon = mx * DEGREE_PER_METER;
        return lon;
    }
    /**
     * Y米转经纬度
     */
    private double Meters2Lat(double my) {
        double lat = my * DEGREE_PER_METER;
        lat = 180.0 / Math.PI * (2 * Math.atan(Math.exp(lat * RAD_PER_DEGREE)) - HALF_PI);
        return lat;
    }
    /**
     * X经纬度转米
     */
    private double Lon2Meter(double lon) {
        double mx = lon * METER_PER_DEGREE;
        return mx;
    }
    /**
     * Y经纬度转米
     */
    private double Lat2Meter(double lat) {
        double my = Math.log(Math.tan((90 + lat) * HALF_RAD_PER_DEGREE)) / (RAD_PER_DEGREE);
        my = my * METER_PER_DEGREE;
        return my;
    }

}

看下效果
这里写图片描述

2.谷歌地图:
谷歌地图要想在Android 中使用,必须要下载谷歌的三驾马车,google play商店, google service, google服务框架,如果需要还要有个google 账号。下载个go 谷歌安装器自动帮你安装;这里写图片描述
有了这些东西在手机然后下面的代码跑起来才会起作用:
代码:

  //google tilelayer 添加的方式;
GoogleHeritageScopeTileProvider tileProvidergoogle = new GoogleHeritageScopeTileProvider();
        mMap.addTileOverlay(new com.google.android.gms.maps.model.TileOverlayOptions().tileProvider(tileProvidergoogle));

看下自定义的代码

public class GoogleHeritageScopeTileProvider extends UrlTileProvider {
    

    private String mRootUrl;
    //默认瓦片大小
    private static int titleSize = 256;//a=6378137±2(m)
    //基本参数
    private final double initialResolution= 156543.03392804062;//2*Math.PI*6378137/titleSize;
    private final double originShift      = 20037508.342789244;//2*Math.PI*6378137/2.0; 周长的一半

    private final double HALF_PI = Math.PI / 2.0;
    private final double RAD_PER_DEGREE = Math.PI / 180.0;
    private final double HALF_RAD_PER_DEGREE = Math.PI / 360.0;
    private final double METER_PER_DEGREE = originShift / 180.0;//一度多少米
    private final double DEGREE_PER_METER = 180.0 / originShift;//一米多少度


    public GoogleHeritageScopeTileProvider() {
        super(titleSize, titleSize);
        mRootUrl = "http://xxxxx你自己要加载/wms?LAYERS=cwh:protect_region_38_20160830&FORMAT=image%2Fpng&TRANSPARENT=TRUE&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A900913&BBOX=";
    }


    public GoogleHeritageScopeTileProvider(int i, int i1) {
        super(i, i1);
    }

    @Override
    public URL getTileUrl(int x, int y, int level) {

        try {
            String url = mRootUrl + TitleBounds(x, y, level);
            return new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        return null;
    }


    /**
     * 根据像素、等级算出坐标
     *
     * @param p
     * @param zoom
     * @return
     */
    private double Pixels2Meters(int p, int zoom) {
        return p * Resolution(zoom) - originShift;
    }

    /**
     * 根据瓦片的x/y等级返回瓦片范围
     *
     * @param tx
     * @param ty
     * @param zoom
     * @return
     */
    private String TitleBounds(int tx, int ty, int zoom) {
        double minX = Pixels2Meters(tx * titleSize, zoom);
        double maxY = -Pixels2Meters(ty * titleSize, zoom);
        double maxX = Pixels2Meters((tx + 1) * titleSize, zoom);
        double minY = -Pixels2Meters((ty + 1) * titleSize, zoom);

        //转换成经纬度
        minX=Meters2Lon(minX);
        minY=Meters2Lat(minY);
        maxX=Meters2Lon(maxX);
        maxY=Meters2Lat(maxY);
        PositionModel position1 = PositionUtil.gcj_To_Gps84(minY,minX);
        minX = position1.getWgLon();
        minY = position1.getWgLat();
        PositionModel position2 = PositionUtil.gcj_To_Gps84(maxY,maxX);
        maxX = position2.getWgLon();
        maxY = position2.getWgLat();

        minX=Lon2Meter(minX);
        minY=Lat2Meter(minY);
        maxX=Lon2Meter(maxX);
        maxY=Lat2Meter(maxY);

        return minX + "," + Double.toString(minY) + "," + Double.toString(maxX) + "," + Double.toString(maxY) + "&WIDTH=256&HEIGHT=256";
    }

    /**
     * 计算分辨率
     *
     * @param zoom
     * @return
     */
    private double Resolution(int zoom) {
        return initialResolution / (Math.pow(2, zoom));
    }

    /**
     * X米转经纬度
     */
    private double Meters2Lon(double mx) {
        double lon = mx * DEGREE_PER_METER;
        return lon;
    }

    /**
     * Y米转经纬度
     */
    private double Meters2Lat(double my) {
        double lat = my * DEGREE_PER_METER;
        lat = 180.0 / Math.PI * (2 * Math.atan(Math.exp(lat * RAD_PER_DEGREE)) - HALF_PI);
        return lat;
    }

    /**
     * X经纬度转米
     */
    private double Lon2Meter(double lon) {
        double mx = lon * METER_PER_DEGREE;
        return mx;
    }

    /**
     * Y经纬度转米
     */
    private double Lat2Meter(double lat) {
        double my = Math.log(Math.tan((90 + lat) * HALF_RAD_PER_DEGREE)) / (RAD_PER_DEGREE);
        my = my * METER_PER_DEGREE;
        return my;
    }


}

效果
这里写图片描述

3.天地图加载wms或者wmts;

//必须符合人家这个发布的规定,不符合加不上去的
String url = "http://t7.tianditu.com/DataServerT=vec_c&x=13394&y=2704&l=14";
mTianDiTuMap.setCustomTileService(url);

看下源码吧
这里写图片描述

这里写图片描述
这里写图片描述
好了,可以看到加载的话,只能符合人家的规范。若不是,好像并没有好的解决方案。

总结: 从高德地图和谷歌地图添加wms,这里是不是有一些惊奇的发现了,这个添加的方式基本相同(甚至类名和方法名都相同),知道一种另一个也就会添加了。还有些更多的可以自己看看人家源码;当然高德和Google在国内都是使用GCJ-02坐标系。就是我们常说的“火星坐标系”,至于天地图这个加载wms和wmts 的方式必须符合人家的发布规定。我并没有找到可靠的在高德和谷歌地图加载wmts 的方法,如果我如果那位大牛知道。麻烦告诉我感激不尽。
demo 地址https://github.com/zkjmyy/MapForWms

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zkjthinking/article/details/77278838

智能推荐

Go开发抽奖项目(iris+xorm+redigo+订单高并发)_抽奖系统 iris-程序员宅基地

文章浏览阅读751次。前后端需求后端管理需求优惠券表_抽奖系统 iris

前端第四天 盒子模型/浮动与定位_盒子模型怎么样给大盒子中的小盒子添加效果-程序员宅基地

文章浏览阅读1.1k次。盒子模型、盒子模型其实,CSS就三个大模块:盒子模型、浮动、定位,其余的都是细节。要求这三部分,无论如何也要学的非常精通。 所谓盒子模型就是把HTML页面中的元素看作是一个矩形的盒子,也就是一个盛装内容的容器。每个矩形都由元素的内容、内边距(padding)、边框(border)和外边距(margin)组成。这里略过老旧的ie盒子模型(IE6以下),对不起,我都没见过IE5的浏览器。 首先,我们来看一张图,来体会下什么是盒子模型。所有的文档元素(标签)都会生成一个矩形框,我们成为元._盒子模型怎么样给大盒子中的小盒子添加效果

推荐几款适用于uniapp开发【全端支持】的UI框架,方便开发_uniappui框架排行-程序员宅基地

文章浏览阅读1.9w次,点赞9次,收藏55次。1、uview https://www.uviewui.com/尤其针对底部tabbar动态显示,给出了优化方案,采用还是原生得tabbar基础组件:表单组件:数据组件:反馈组件:布局组件:导航组件:其他组件:2、Thor UI组件库 https://thorui.cn/doc/组件列表:3、 GraceUI http://grace.hcoder.net/manual/info/167-110.html组件列表:..._uniappui框架排行

制备pdms膜的方法_光栅式PDMS薄膜在透明窗口的超高发射率-程序员宅基地

文章浏览阅读2.2k次。研究背景辐射冷却是通过地球表面和深空之间的辐射热传递在大气条件下提供被动冷却。在空气透过区域中选择性发射辐射的材料通过发射表面辐射大于吸收的辐射能量的总和能够产生被动辐射冷却,聚二甲基硅氧烷(PDMS)由于其在中红外光谱区域具有良好的光学性能,且易于制备,是一种重要的辐射冷却材料。尽管已有文献报道了表面改性可以提高PDMS膜的中红外发射率,但通过全局优化仍有进一步提高的空间。韩国KAIS..._pdms红外发射率

CSS3中设置文本行高的属性是`line-height`。_css3 line-height-程序员宅基地

文章浏览阅读136次。属性是用来控制文本行高的。可以使用长度值、百分比值、无单位的数值以及特殊值来指定行高的大小。通过合理地设置行高,可以改善文本的可读性和排版效果。属性可以接受不同类型的值,包括长度值、百分比值和无单位的数值。CSS3是一种用于设置网页样式的技术,它提供了丰富的属性来控制文本的显示和布局。值可以让浏览器自动计算适当的行高,通常为字体的默认行高。属性用于设置文本行与行之间的高度,影响行间距的大小。属性还可以使用特殊的值来设置行高。使段落的行高为当前字体大小的1.5倍。(使用默认的行高)。(恢复为父元素的值)。_css3 line-height

win10睡眠状态下唤醒花屏_win10睡眠唤醒花屏-程序员宅基地

文章浏览阅读5.2k次。原因是前一天更新过Windows,显卡驱动版本过高与自身电脑并不适配。一、下载一个驱动精灵体检之后进入驱动管理,再显卡那里根据他的提示下载最合适的显卡并安装即可。有一点恶心的是会有捆绑安装二、独自安装首先再Intel官网上下载驱动的时候会让你选择需要下载什么驱动,如果不确定的话当时可以下载一个SSU.exe(Intel的)来帮助你决定,下载下来即可。右键我的电脑->管理->硬件管理-&..._win10睡眠唤醒花屏

随便推点

Class和类名称之间的宏定义作用_class 宏 类名-程序员宅基地

文章浏览阅读2.9k次。#if defined __DRAW_IMPL__ #if(defined_AFXDLL&&!defined__STAT_WITH_DLLMFC__) #define__DRAW_API_declspec(dllexport) #else #define__DRAW_API #endif//_AFXDLL#else #if(defined_AFXDLL&&!def..._class 宏 类名

【easyui】动态显示datagrid列_动态的显示datagrid中的columns中的field-程序员宅基地

文章浏览阅读2.2k次。以前做法$("#datagridId").datagrid("hideColumn", "columnField"); // 设置隐藏列现在做法{ field: 'option', title: '操作', align: 'center', width: 80,_动态的显示datagrid中的columns中的field

Halcon_halcon 提取骨架-程序员宅基地

文章浏览阅读1.6k次。HalconHalconHalcon基础入门一_halcon 提取骨架

Websocket如何获取httpSession,区分不同客户端_websocket session-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏11次。我们知道websocket协议与http协议有些不同,websocket有自带的Session,但是跟http的Session是不一样的,而我们做有些web项目的时候,又需要知道当前是哪个用户,用以处理该用户的业务逻辑,或者是对该用户进行授权之类的,所以必须需要获取并知道http的Session,具体方法如下:我们先附上代码,根据代码来讲解(具体解释在第三点):2.1. 我们需要先创建..._websocket session

【文档】web系统非功能性需求_网站非功能性需求-程序员宅基地

文章浏览阅读8.9k次。1.系统平均响应时间 响应时间就是用户感受软件系统为其服务所耗费的时间。 响应时间可细分为: (1)服务器端响应时间,这个时间指的是服务器完成交易请求执行的时间,不包括客户端到服务器端的反应(请求和耗费在网络上的通信时间),这个服务器端响应时间可以度量服务器的处理能力。 (2)网络响应时间,这是网络硬件传输交易请求和交易结束所耗费的时间。 (3)客户端响应时间,这是客户端在构建请求和展现_网站非功能性需求

WCF 大数据传输问题_wcf 往前台传数据,记录多了,好像没有传过去-程序员宅基地

文章浏览阅读2.7k次。当客户端传输的参数中有字节流或者是长度过大的时候,wcf就会报错。出现maxReceivedMessageSize异常解    当使用WCF的客户端调取的数据过多时,会出现这个异常。一般情况下,系统默认值是65536,大约容纳100-200条左右的数据。那么就需要我们手动改参数WebConfig配置文件 ,以下就是我防止传输参数过大做的配置。下面一一讲解_wcf 往前台传数据,记录多了,好像没有传过去

推荐文章

热门文章

相关标签