扩展切片格式

发送反馈


切片格式类定义了具体的瓦片存储与组织方式,包括比例尺、瓦片拆分与目录组织、命名等。根据扩展需要,对这些内容一一定义,就完成了对整个瓦片格式的定义。

扩展形式如下:

public class NationalCacheStandardTileset extends AbstractImageTileset {
...
}

需要实现 AbstractImageTileset 类中未实现的方法,具体包括:

字段/方法 描述
protected boolean doUpdateMetaData(ImageMetaData metaData, TileVersionList tileVersions) 更新瓦片的元信息
public void put(ImageTileInfo tileInfo) 创建或更新一个瓦片
public ImageTileInfo get(Tile tile) 获取一个瓦片
public String getName() 获取存储的片集的名称

切片格式类主要定义了具体的瓦片存储与组织方式,包括比例尺、瓦片拆分与目录组织、命名等,对应《地理信息公共服务平台——电子地图数据规范》中的瓦片结构定义如下:

在扩展类中,按照上述结构,定义瓦片的命名和存储规则并创建存储路径,部分代码如下:

    //根据规范,设置支持的比例尺。
    private static final double nationalCacheStandardScale[] = new double[] { 295829355.45, 147914677.73, 73957338.86, 36978669.43, 18489334.72, 9244667.36,
            4622333.68, 2311166.84, 1155583.42, 577791.71, 288895.85, 144447.93, 72223.96, 36111.98, 18055.99, 9028.00, 4514.00, 2257.00, 1128.50, 564.25 };
    //规范中定义的目录结构。
    private static final String levelStr = "L";
    private static final String rowStr = "R";
    private static final String colStr = "C";
    //规范中支持的瓦片后缀。
    private static final String pngFormat = "png";
    private static final String jpgFormat = "jpg";
    private static final String dotStr = ".";
    //创建存储瓦片的目录。
    public NationalCacheStandardTileset(File cacheFile) {
        if (!cacheFile.exists()) {
            cacheFile.mkdirs();
        }
        if (!cacheFile.isDirectory()) {
            throw new IllegalArgumentException("cacheFile is not a directory!");
        }
        this.cacheFile = cacheFile;
        this.cacheName = cacheFile.getName();
    }

更新切片的元信息

doUpdateMetaData 方法用于更新 Tileset 的元信息,由于该规范中并没有这个概念,所以此方法不用实现。

        @Override
    protected boolean doUpdateMetaData(ImageMetaData metaData, TileVersionList tileVersions) {
        return false;
    }

追加或更新一个切片

因为分布式切图服务采取了纯色瓦片优化策略来提升切图和存储的效率,所以在存储一张瓦片的时候,需要判断获取的瓦片是否为纯色瓦片,如果是纯色的瓦片需要转化并存储为瓦片文件(即一个 image)。

    @Override
    public void put(ImageTileInfo tileInfo) throws PutTileFailedException {
        checkTile(tileInfo);
        byte[] data = tileInfo.tileData;
        if (data == null) {
            return;
        }
                //分布式切图中生成的纯色图片都是用一段信息来表示的,这里先判断是否是纯色图片,如果是纯色就使用工具方法获取这段信息代表的图片。
        if (MBTilesUtil.isDistributedPureImage(data)) {
            data = MBTilesUtil.transformPureImageToCommonImageData(data);
        }
        storeTileData(tileInfo, data);
    }

获取一个切片

通过 get(Tile tile)方法可以获取一张生成的瓦片,并按照指定的规范命名。

    @Override
    public ImageTileInfo get(Tile tile) {
        checkTile(tile);
        ImageTileInfo tileInfo = new ImageTileInfo();
        tileInfo.resolution = tile.resolution;
        tileInfo.scaleDenominator = tile.scaleDenominator;
        tileInfo.x = tile.x;
        tileInfo.y = tile.y;
        //获取生成的瓦片。
        File imgFile = getPNGImageFile(tile);
        String format = null;
        if (!imgFile.exists()) {
            // png 后缀的文件找不到则尝试去找 jpg 后缀的图片
            String fileName = imgFile.getName().split("\\.")[0] + dotStr + jpgFormat;
            imgFile = new File(imgFile.getParentFile(), fileName);
            format = new String(jpgFormat);
        } else {
            format = new String(pngFormat);
        }
        //找到瓦片后,根据规范命名。
        if (imgFile.exists()) {
            tileInfo.tileData = getImageData(imgFile, format);
        }
        return tileInfo;
    }

获取存储的切片集的名称

通过 getName()方法可以获取存储的瓦片集的名称,由前缀和瓦片路径创建时的名称缓存文件名组成。

    @Override
    public String getName() {
        if (this.cacheFile != null && this.cacheFile.exists()) {
            return namePrefix + cacheFile.getName();
        }
        return null;
    }

完整的扩展示例类如下:

NationalCacheStandardTileset.java