osmdroid 中使用ArcgisServer地图服务

osmdroid

osmdroid是一个开源项目,其目的是提供比安卓原生的MapView更为强大的地图组件库。osmdroid支持多种在线或者离线的瓦片地图源以及地图覆盖管理器,用于绘制图标、几何图形以及GPS定位。

osmdroid相比于Android原生MapView的优势在于其丰富的瓦片地图源和地图覆盖管理器了。相比于Arcgis Android Runtime SDK这种专业的GIS开发包在功能上的劣势非常明显,但也有其优势也很明显——轻量。一个使用了Arcgis Android Runtime SDK的APP,如果完整支持arm64-v8a、armeabi-v7a、armeabi、x86的话,apk文件至少60M,仅支持armeabi-v7a也在30M以上,而使用osmdroid的APP的APK通常只有几M。

ArcgisServer的地图服务

Arcgis可以说是GIS领域最强大的软件,没有之一。Esri公司也是一家值得尊重的公司,一直在致力于GIS领域新技术的开发以及Arcgis和互联网新科技的融合。ArcgisServer提供了目前市场上最强大最丰富的的GIS领域的服务,包括地图服务,瓦片服务,矢量切片服务,要素服务,分析服务,几何网络服务等等等。

osmdroid主要是一个MapView,矢量切片这种新技术完全不支持,瓦片服务本来就支持,只有地图服务,osmdroid原本不支持,但有潜力。这里说的潜力,是因为Arcgis的地图服务是通过export接口返回的一张图片,在数据源上与瓦片地图没有区别。

以瓦片的形式请求地图服务

在ArcgisServer地图服务的地图请求链接一般形式如下:http://192.168.1.28:6080/arcgis/rest/services/NHCT/MapServer/export?bbox=114.36767578125,30.519681272749406,114.3731689453125,30.524413269923976&bboxSR=4326&size=256,256&format=png24&transparent=true&dpi=96&f=image,其中bbox表示请求的地图的范围,size表示请求的图片的大小,format表示请求的图片的格式,transparent表示没有数据的部分是否透明,如果format不为png时,transparent参数无效。f表示以图片的形式返回,另外还有json和html的形式。

我们要以瓦片的形式请求地图服务,重点就在算出每个请求瓦片的bbox,其逻辑代码如下。

public static BoundingBox tile2boundingBox(final int x, final int y, final int zoom) 
{
    BoundingBox bb = new BoundingBox(tile2lat(y, zoom), tile2lon(x + 1, zoom), tile2lat(y + 1, zoom), tile2lon(x, zoom));
    return bb;
}

public static double tile2lon(int x, int z) {
    return x / Math.pow(2.0, z) * 360.0 - 180;
}

public static double tile2lat(int y, int z) {
    double n = Math.PI - (2.0 * Math.PI * y) / Math.pow(2.0, z);
    return Math.toDegrees(Math.atan(Math.sinh(n)));
}

当然如果是莫卡托投影的,就不是经纬度了

public  double[] getBoundingBox(int x, int y, int zoom) {
    double tileSize = MAP_SIZE / Math.pow(2, zoom);
    double minx = TILE_ORIGIN[ORIG_X] + x * tileSize;
    double maxx = TILE_ORIGIN[ORIG_X] + (x + 1) * tileSize;
    double miny = TILE_ORIGIN[ORIG_Y] - (y + 1) * tileSize;
    double maxy = TILE_ORIGIN[ORIG_Y] - y * tileSize;

    double[] bbox = new double[4];
    bbox[MINX] = minx;
    bbox[MINY] = miny;
    bbox[MAXX] = maxx;
    bbox[MAXY] = maxy;

    return bbox;
}

然后照着请求瓦片一样请求就可以了

@Override
public String getTileURLString(long pMapTileIndex) {
    String baseUrl = getBaseUrl();
    if (forceHttps)
        baseUrl = baseUrl.replace("http://", "https://");
    if (forceHttp)
        baseUrl = baseUrl.replace("https://", "http://");
    StringBuilder sb = new StringBuilder(baseUrl);
    if (!baseUrl.endsWith("/"))
        sb.append("/");
    sb.append("export?").append("bbox=");
    if (srs.equals("EPSG:900913")) {
        double[] bbox = getBoundingBox(MapTileIndex.getX(pMapTileIndex), MapTileIndex.getY(pMapTileIndex), MapTileIndex.getZoom(pMapTileIndex));
        sb.append(bbox[MINX]).append(",");
        sb.append(bbox[MINY]).append(",");
        sb.append(bbox[MAXX]).append(",");
        sb.append(bbox[MAXY]);
    } else {
        BoundingBox boundingBox = tile2boundingBox(MapTileIndex.getX(pMapTileIndex), MapTileIndex.getY(pMapTileIndex), MapTileIndex.getZoom(pMapTileIndex));
        sb.append(boundingBox.getLonWest()).append(",");
        sb.append(boundingBox.getLatSouth()).append(",");
        sb.append(boundingBox.getLonEast()).append(",");
        sb.append(boundingBox.getLatNorth());
    }
    sb.append("&bboxSR=").append(srs.replace("EPSG:","")).append("&size=").append(getTileSizePixels()).append(",").append(getTileSizePixels());
    sb.append("&format=png24").append("&transparent=true").append("&dpi=96").append("&f=image");
    String str = sb.toString();
    return str;
}

这个思路不是我的,而是在osmdroid中自带一个osmdroid-wms的子项目,我心想WMS和ArcgisServer的地图服务原理一致,前者可以后者当然也可以,所以就仔细阅读了一下osmdroid-wms的源码,参照WMSTileSource类写了一个ArcgisServer地图服务的DataSource,核心代码就是上面那些了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,123评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,031评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,723评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,357评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,412评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,760评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,904评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,672评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,118评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,456评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,599评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,264评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,857评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,731评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,956评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,286评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,465评论 2 348

推荐阅读更多精彩内容