明确下定义,数方瓦片也叫五层十五级瓦片。现记录下如何在World Wind Android中加载数方瓦片的方法。

原理

加载数方瓦片最核心的方法是WorldWindAndroid加载图片的方法,更加详细的使用说明请访问worldwind官网。核心代码如下:

Sector sector = new Sector(tilesLat, tilesLon, delt, delt);
 FileInputStream fis = null;
 try {
     fis = new FileInputStream(path);
 } catch (FileNotFoundException e) {
     e.printStackTrace();
 }
 Bitmap bitmap = BitmapFactory.decodeStream(fis);

 if (bitmap != null) {
     tilesLayer = new RenderableLayer(name);                                                 //瓦片图层
     SurfaceImage surfaceImage = new SurfaceImage(sector, ImageSource.fromBitmap(bitmap));
     tilesLayer.setDisplayName(name);
     tilesLayer.addRenderable(surfaceImage);
     worldWindow.getLayers().addLayer(index, tilesLayer);
 }
 worldWindow.requestRedraw();

准备工作

那么如何应用到程序中呢?请往下看。前提是已经学会如何加载影像的方法,如果未学会,可能会有些困难。
接下来给程序添加存储读写权限的获取。
1.在AndroidManifest.xml中添加读写权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

2.在application中添加如下代码。这里是解决安卓高版本读写异常的问题,有兴趣的同学可以深度研究下。

android:preserveLegacyExternalStorage="true"
android:requestLegacyExternalStorage="true"

3.在Android6.0以上的版本中,需要在代码中动态获取读取权限。代码如下:

/*
* 动态申请权限
 * */
private void myRequetPermission() {
    ActivityCompat.requestPermissions(this, new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    }, 100);
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 100) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED &&
                ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {//读写权限被获取
            Toast.makeText(MainActivity.this,"读写权限获取成功",Toast.LENGTH_LONG).show();
            //加载数方瓦片的使用方法
            AddTilesUtils.addTilesImage(worldWindow,tilesLayer,"5",4381,11623,TILE_FILE_DIR,"tilesLayer",1);
        }else {
            Toast.makeText(MainActivity.this,"读写权限获取失败",Toast.LENGTH_LONG).show();
        }
    }
}

这些都准备好后,开始进行数方瓦片的加载。

瓦片加载

接下来,就需要结合五层十五级的知识点(尤其是划分标准),进行瓦片加载。
1.瓦片加载的方法:AddTilesUtils.java

package org.clisia.ksh.worldwinddemo;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

import gov.nasa.worldwind.WorldWind;
import gov.nasa.worldwind.WorldWindow;
import gov.nasa.worldwind.geom.Sector;
import gov.nasa.worldwind.layer.RenderableLayer;
import gov.nasa.worldwind.render.ImageSource;
import gov.nasa.worldwind.shape.SurfaceImage;

public class AddTilesUtils {
    /*
    @param:worldWindow:三维球
    @param:tilesLayer:瓦片图层
    @param:level:加载的数方瓦片的层级(这个需要根据实际的层级进行确定)
    @param:row:瓦片的行号
    @param:col:瓦片的列号
    @param:path:瓦片的地址
    @param:name:瓦片图层名
    @param:index:瓦片图层所在三维球上层次位置*/
    /*------------------------五层十五级瓦片的加载---------------------------------*/
    public static void addTilesImage(WorldWindow worldWindow, RenderableLayer tilesLayer,String level,
                                     int row, double col, String path, String name,int index) {
        double delt;
        //根据输入的层级进行图片的位置、大小确认
        switch (l) {
            case "1":
                delt = 0.001;
                break;
            case "2":
                delt = 0.0025;
                break;
            case "3":
                delt = 0.005;
                break;
            case "4":
                delt = 0.01;
                break;
            case "5":
                delt = 0.025;
                break;
            case "6":
                delt = 0.05;
                break;
            case "7":
                delt = 0.1;
                break;
            case "8":
                delt = 0.25;
                break;
            case "9":
                delt = 0.5;
                break;
            case "A":
                delt = 1;
                break;
            case "B":
                delt = 2.5;
                break;
            case "C":
                delt = 5;
                break;
            case "D":
                delt = 10;
                break;
            case "E":
                delt = 25;
                break;
            case "F":
                delt = 50;
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + l);
        }

        double tilesLat = (row) * delt - 90;
        double tilesLon = (col) * delt - 180;
        Sector sector = new Sector(tilesLat, tilesLon, delt, delt);

        FileInputStream fis = null;
        try {
            fis = new FileInputStream(path);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Bitmap bitmap = BitmapFactory.decodeStream(fis);

        if (bitmap != null) {
            tilesLayer = new RenderableLayer(name);                                                 //瓦片图层
            SurfaceImage surfaceImage = new SurfaceImage(sector, ImageSource.fromBitmap(bitmap));
            tilesLayer.setDisplayName(name);
            tilesLayer.addRenderable(surfaceImage);
            worldWindow.getLayers().addLayer(index, tilesLayer);
        }
        worldWindow.requestRedraw();
    }
}

2.使用
在合适的位置进行使用。

AddTilesUtils.addTilesImage(worldWindow,tilesLayer,"5",4381,11623,TILE_FILE_DIR,"tilesLayer",1);

3.参数说明
worldWindow:三维球
tilesLayer:瓦片图层
level:加载的数方瓦片的层级(这个需要根据实际的层级进行确定)
row:瓦片的行号
col:瓦片的列号
path:瓦片的地址,现在是读取手机本地上的图片,也可以读取网络地址图片
name:瓦片图层名
index:瓦片图层所在三维球上层次位置

4.效果展示
Android WorldWind的使用与加载数方瓦片-LMLPHP

05-08 12:33