首页 / 浏览问题 / 组件GIS / 问题详情
java组件生成矢量切片失败
20EXP 2022年04月26日
scales = mapCacheBuilder.globalLevelToScale(ints,map.getPrjCoordSys(),TileSize.SIZE256);
mapCacheBuilder.setOutputScaleCaptions(scales);
mapCacheBuilder.setBounds(map.getBounds());
mapCacheBuilder.setFillMargin(true);
boolean f = mapCacheBuilder.build(true,true)

f = false生成失败,要怎么改?

1个回答

您好,估计您的描述,建议您打开桌面的生成矢量切片,对比一下桌面需要设置哪些值,以及mapcachebuilder有哪些值是默认的,根据您的需求来设置这些值。

希望可以帮助到您。
3,355EXP 2022年04月26日
先和桌面对比的,就在比例尺和层级这一块没有办法

您好,有以下两点回答:

1.setOutputScaleCaptions是方法设置地图缓存比例尺的别名。一般设置为比例尺大小倒数的字符串,如1:10000为10000。当设置的别名不唯一时,程序抛出异常。且2.0到4.0版本的缓存比例尺的别名必须采用底层计算好的默认值。如果您不想用底层计算好的默认值,可以用setVersion(MapCacheVersion version)设置一个版本,且MapCacheVersion 枚举的默认值为 Version_50;

2.用setOutputScales(double[] value)设置地图缓存的比例尺数组,且OutputScales中的比例尺必须 >= 1:2000000000,否则缓存生成失败。当缓存比例尺数组中有一个非法(数值非法或地图固定比例尺显示,出缓存时比例尺数组不是子集)时,缓存生成失败

关于第一点,我设置过Version为Version_50,且确定过别名的唯一性。

关于第二点,所有的比例尺都是大于1:2000000000的,而且特意取消过地图固定比例尺显示,然而并没有什么用。

我之后把代码修改成了这样

HashMap<Double, String> globalLevelScales = mapCacheBuilder.getGlobalLevelScales();
HashMap<Double,String> scales = new HashMap<>();
for(double scale:globalLevelScales.keySet()){
    int level = Integer.parseInt(globalLevelScales.get(scale));
    if(level<=cacheConfig.getMaxLevel()&&level>=cacheConfig.getMinLevel()){
        scales.put(scale,globalLevelScales.get(scale));
    }
}
//scales = mapCacheBuilder.globalLevelToScale(ints,map.getPrjCoordSys(),TileSize.SIZE256);
mapCacheBuilder.setOutputScaleCaptions(scales);

生成是可以生成切片了,但是发现有些切片能够查看,有些切片不能查看。进一步比较发现,不能查看的切片的styles文件夹内的style.json大小为8kb,而桌面生成的style.json有193kb。

导致这个出现的原因是什么?

java组件生成时的层级设置和桌面勾选的一样,将style.json(8kb)替换为桌面的style.json(193kb)后,java组件生成切片也能够在桌面中查看到内容了
我觉得最好的解决办法就是给出一段实例代码,要能够自由设置所有可以设置的属性,且不会有这样那样的问题。

这个示例的代码并没有什么用,直接失败,没有最新的示例吗?

	    MapCacheBuilder builder = new MapCacheBuilder();
	    com.supermap.mapping.Map tempMap=new com.supermap.mapping.Map(workspace);	     
	    tempMap.open(workspace.getMaps().get(0));
	    builder.setMap(tempMap);
        builder.setOutputFolder(outPutPath);	   

	    if ((scales == null) || (scales.length < 1))
	    {
	      builder.setOutputScales(DEFAULT_MAP_CACHE_SCALES);
	    }
	    else
	    {
	      builder.setOutputScales(scales);
	    }
	    if (bounds == null) {
	      tempMap.viewEntire();
	      tempMap.refresh();
	      builder.setBounds(tempMap.getBounds());
	    } else {
	      builder.setBounds(bounds);
	    }
	    boolean flag = builder.build();

直接指出我的代码错误的地方好了

Workspace workspace = new Workspace();
WorkspaceConnectionInfo workspaceConnectionInfo = new WorkspaceConnectionInfo();
if(slice.getWorkspacepath().endsWith(".sxwu")){
    workspaceConnectionInfo.setType(WorkspaceType.SXWU);
}else if(slice.getWorkspacepath().endsWith(".smwu")){
    workspaceConnectionInfo.setType(WorkspaceType.SMWU);
}else {
    throw new Exception("请选择SXWU和SMWU类型的工作空间");
}
workspaceConnectionInfo.setServer(slice.getWorkspacepath());
boolean open = workspace.open(workspaceConnectionInfo);
if(!open){
    throw new Exception("打开工作空间失败");
}
//检查工作空间内是否有地图
Maps maps = workspace.getMaps();
if(maps==null||maps.getCount()==0){
    throw new Exception("工作空间内没有地图");
}
int n=-1;
for(int i=0;i<maps.getCount();i++){
    if(maps.get(i).equalsIgnoreCase(slice.getMap())){
       n=i;
       break;
    }
}
if(n==-1){
    throw new Exception("工作空间内未找到"+slice.getMap()+"地图");
}
Map map = new Map();
map.setWorkspace(workspace);
if(!map.open(maps.get(n))){
    throw new Exception(maps.get(n)+"地图打开失败");
}
MapCacheBuilder mapCacheBuilder = new MapCacheBuilder();
//设置参数
mapCacheBuilder.setMap(map);
Layers layers = map.getLayers();
for(int i=0;i<layers.getCount();i++){
    Layer layer = layers.get(i);
    Dataset dataset = layer.getDataset();
    if(dataset==null){
        throw new Exception(layer.getName()+"对应的数据集为空");
    }
    if(!dataset.isOpen()){
        throw new Exception(dataset.getDatasource().getAlias()+"数据源的"+dataset.getName()+"数据集打开失败");
    }
}
//抽稀、添加所有属性字段值、缓冲范围、分离数据与风格参数设置
//默认是不抽稀、不添加字段、缓存范围为16,分离数据与风格
String path1= UUID.randomUUID().toString()+".sci";
String str="";
try{
    mapCacheBuilder.toConfigFile(path1);
    //修改sci文件
    FileReader reader = new FileReader(path1);
    StringBuilder sb = new StringBuilder();
    char[] chars = new char[1024];
    int length=0;
    while ((length = reader.read(chars))!=-1){
       sb.append(chars);
    }
    str = sb.toString();
    //抽稀
     if(!cacheConfig.isMVTSimplifyGeometry()){
         str = str.replace("<sml:MVTSimplifyGeometry>TRUE</sml:MVTSimplifyGeometry>","<sml:MVTSimplifyGeometry>FLASE</sml:MVTSimplifyGeometry>");
     }
     //添加所有属性字段值
    if(cacheConfig.isMVTWithAllField()){
                    str = str.replace("<sml:MVTWithAllField>FALSE</sml:MVTWithAllField>","<sml:MVTWithAllField>TRUE</sml:MVTWithAllField>");
    }
    //缓冲范围
    int mvtTileBuffer = cacheConfig.getMVTTileBuffer();
    if(mvtTileBuffer!=16){
       str = str.replace("<sml:MVTTileBuffer>16</sml:MVTTileBuffer>","<sml:MVTTileBuffer>"+mvtTileBuffer+"</sml:MVTTileBuffer>");
    }
     //分离数据与风格
     if(!cacheConfig.isMVTWithoutFilter()){
        str = str.replace("<sml:MVTWithoutFilter>TRUE</sml:MVTWithoutFilter>","<sml:MVTWithoutFilter>FALSE</sml:MVTWithoutFilter>");
     }
     reader.close();
}finally {
    java.io.File file = new File(path1);
    if(file.exists()){
        file.delete();
    }
}
String path2 = UUID.randomUUID().toString()+".sci";
java.io.File file2 = new File(path2);
boolean newFile = file2.createNewFile();
try{
    FileWriter writer = new FileWriter(path2);
    writer.write(str);
    writer.flush();
    writer.close();
    boolean b = mapCacheBuilder.fromConfigFile(path2);
    if(!b){
        throw new Exception("加载配置失败");
    }
}finally {
    if(newFile){
        file2.delete();
    }
}
File out = new File(slice.getOutputpath());
if(!out.exists()||!out.isDirectory()){
    throw new Exception("文件夹"+out+"不存在");
}
String outputdir=slice.getOutputpath()+File.separator+UUID.randomUUID().toString();
new File(outputdir).mkdirs();
String cachename= map.getName();
mapCacheBuilder.setCacheName(cachename);
mapCacheBuilder.setTilingMode(MapTilingMode.LOCAL);
mapCacheBuilder.setOutputFolder(outputdir);
mapCacheBuilder.setTransparent(true);
//固定为矢量切片
mapCacheBuilder.setTileFormat(TileFormat.PBF);
//生成字体缓存文件
mapCacheBuilder.setMVTStyleWithoutFont(cacheConfig.isMVTStyleWithoutFont());
//版本号
Enum[] mapCacheVersions = MapCacheVersion.getEnums(MapCacheVersion.class);
MapCacheVersion mapCacheVersion = null;
for (Enum e:mapCacheVersions
) {
    if(e.toString().equals(cacheConfig.getMapCacheVersion())){
        mapCacheVersion = (MapCacheVersion) e;
        break;
    }
}
if(mapCacheVersion==null){
    mapCacheBuilder.setVersion(MapCacheVersion.VERSION_50);
}else {
    mapCacheBuilder.setVersion(mapCacheVersion);
}
//设置存储类型
StorageType storageType = null;
Enum[] storageTypes = StorageType.getEnums(StorageType.class);
for (Enum e:storageTypes
) {
    if(e.toString().equals(cacheConfig.getStorageType())){
        storageType = (StorageType) e;
        break;
    }
}
if(storageType==null){
    mapCacheBuilder.setStorageType(StorageType.Compact);
}else {
    mapCacheBuilder.setStorageType(storageType);
}
//设置DPI
if(mapCacheBuilder.getVersion()==MapCacheVersion.VERSION_50){
    //mapCacheBuilder.setDPI(cacheConfig.getDPI());
}
mapCacheBuilder.setBuildTriangleListFile(cacheConfig.isBuildTriangleListFile());
int[] ints = new int[cacheConfig.getMaxLevel()-cacheConfig.getMinLevel()+1];
for(int i=0;i<ints.length;i++){
    ints[i] = cacheConfig.getMinLevel()+i;
}
mapCacheBuilder.setTileSize(TileSize.SIZE256);
HashMap<Double, String> globalLevelScales = mapCacheBuilder.getGlobalLevelScales();
HashMap<Double,String> scales = new HashMap<>();
for(double scale:globalLevelScales.keySet()){
    int level = Integer.parseInt(globalLevelScales.get(scale));
    if(level<=cacheConfig.getMaxLevel()&&level>=cacheConfig.getMinLevel()){
        scales.put(scale,globalLevelScales.get(scale));
    }
}
mapCacheBuilder.setOutputScaleCaptions(scales);
map.viewEntire();
map.refresh();
mapCacheBuilder.setBounds(map.getBounds());
mapCacheBuilder.setFillMargin(true);
mapCacheBuilder.addSteppedListener(new CacheSteppedListener());
boolean build = mapCacheBuilder.build(cacheConfig.isBuildVectorTile(), cacheConfig.isBuildStyle());

您好,从您的代码逻辑上来看的话,是没有问题的,只是有些值可能没有判断
我这边使用这个demo是可以的
哪些值可能没有判断?至于这个demo瓦片类型都没有设置,我觉得没有什么参考意义(我要生成的是矢量瓦片),我之前使用这个demo失败是因为,我在设置比例尺的时候参考了builder.setOutputScales(DEFAULT_MAP_CACHE_SCALES),结果就直接build失败返回false。

java组件和桌面生成的切片到底能不能保证一样(包括里面的配置文件、样式等),如果可以请告诉我,要怎么设置,如果不可以也请跟我说不行。
抱歉刚刚我看错了,所以现在就是这个比例尺的原因是吧,您可以尝试其他的比例尺,切缓存的时候试着读取下地图图层的比例尺呢

为您找了几个不同工作空间的地理坐标系的地图,您可以看见在生成矢量缓存的时候出现的层级列表都是大同小异,我这边咨询了其他的同事也都是说桌面的这个比例尺是固定的,您可以按照这个来写出您自己的层级列表,希望可以帮助到您。

...