美文网首页
通过GeoServer发布ArcGIS Server切片/Ces

通过GeoServer发布ArcGIS Server切片/Ces

作者: lforrrrawx | 来源:发表于2020-01-21 12:38 被阅读0次

    首先吐槽下GeoServer(其实是GeoWebCache)的切片保存路径竟然如此奇葩,且不可配置,即不能迁移到其他系统,也不能发布其他系统生产的切片(虽然GeoWebCache有对ArcGIS Server切片的插件,但那个东西却无法和GeoServer集成)。这种情况似乎将在下个版本(GeoServer2.17/GeoWebCache1.17)中有所改善,加入了对TMS切片的支持,其切片路径是我们熟悉的{z}/{x}/{y},但这并不能满足我们的需求,首先它是TMS切片,与WMTS切片在y方向相反;其次我们想要的就是随心所欲。

    看来短时间内指望GeoServer在这方面有所改观是不太可能了,于是,只好自己来写一个扩展吧,希望可以让GeoServer实现通过配置路径模板的方式来适应其他类型切片,如ArcGIS或者Cesiumlab。

    1、首先下载插件(今天才发现,简书竟然不能上传文件,先上传到百度云吧)

    链接:https://pan.baidu.com/s/16R5yIxh5Jz32fyi08qCixA

    提取码:rn1p

    将下载到的custom-filestroe-1.0-SNAPSHOT.jar,放到<geoserver>\webapps\geoserver\WEB-INF\lib中,重启geoserver。

    2、配置BlobStore,在Add  new BlobStore页面选择Custom FileStore,页面如下。

    通过设置路径模板参数来匹配切片路径,如ArcGIS Server的切片路径是这样的:LayerName\L03\R00000002\C00000005.png,那么这里需要这样填写:{layer}\L{level:%02d}\R{row:%08x}\C{col:%08x}

    而Cesiumlab切片路径是这样的:LayerName\{z}\{x}\{y}.png,则这里需要这样赶写:{layer}\{level:%d}\{col:%d}\{row:%d}

    3、发布切片。在geoserver中的geowebcache.xml文件中添加一个wmsLayer:

    <wmsLayer>

          <blobStoreId>arcgis</blobStoreId>

          <enabled>true</enabled>

          <name>33</name>

          <mimeFormats>

            <string>image/jpeg</string>

          </mimeFormats>

          <gridSubsets>

            <gridSubset>

              <gridSetName>EPSG:900913</gridSetName>

              <extent>

                <coords>

                  <double>8176078.237521</double>

                  <double>704818.027536</double>

                  <double>1.5037685885628E7</double>

                  <double>7086873.419584</double>

                </coords>

              </extent>

            </gridSubset>

          </gridSubsets>

          <wmsUrl>

            <string>http://localhost:8081/geoserver/wms?</string>

          </wmsUrl>

        </wmsLayer>

    其中,blobStoreId是第二步中所配置的BlobStore的Identifier;name为图层名称;mimeFormats为切片的mineType;gridSubsets配置EPSG和对应的坐标范围。

    4、浏览。在GeoServer的Tile Layers页面找到刚刚配置的图层。

    在PreView下拉列表中选择对应的EPSG/mineType,跳转到预览页面,如下:

    此插件应该能自动匹配大多数切片路径,但像GeoServer这样奇葩的路径,这里不!兼!容!

    5、核心代码 :该插件代码非常简单,简单到不好意思将其作为一个项目开源出来,就把其核心代码贴到下面吧:

    public File tilePath(TileObject tile, MimeType mimeType) {

    final long[] tileIndex = tile.getXYZ();

    long x = tileIndex[0];

    int z = (int) tileIndex[2];

    long y =0;

    try {

    y = getY(tile.getLayerName(), tile.getGridSetId(), x, tileIndex[1], z);

    }catch (GeoWebCacheException e) {

    e.printStackTrace();

    return null;

    }

    StringBuilder path =new StringBuilder(256);

    String fileExtension = mimeType.getFileExtension();

    path.append(cacheRoot);

    path.append(File.separatorChar);

    String layer = tile.getLayerName();

    String[] wl = layer.split(":");

    String templatePath ="";

    if(wl.length ==2){

    templatePath =template.replace("{workspace}",wl[0]);

    templatePath =template.replace("{layer}",wl[1]);

    }

    else{

    templatePath =template.replace("{workspace}","");

    templatePath =template.replace("{layer}",layer);

    }

    templatePath = templatePath.replace("{gridset}", tile.getGridSetId());

    long shift = z /2;

    long half =2 << shift;

    int digits =1;

    if (half >10) {

    digits = (int) (Math.log10(half)) +1;

    }

    long halfx = x / half;

    long halfy = y / half;

    templatePath = templatePath.replace("{halfx}",zeroPadder(halfx, digits));

    templatePath = templatePath.replace("{halfy}",zeroPadder(halfy, digits));

    String levelPattern ="\\{level:([^}]*)\\}";

    String levelTemplate = getString(templatePath,levelPattern);

    String rowPattern ="\\{row:([^}]*)\\}";

    String rowTemplate = getString(templatePath,rowPattern);

    String colPattern ="\\{col:([^}]*)\\}";

    String colTemplate = getString(templatePath,colPattern);

    String level = String.format(levelTemplate, z);

    templatePath = templatePath.replace(levelTemplate, level.substring(7,level.length() -1));

    String row = String.format(rowTemplate, y);

    templatePath = templatePath.replace(rowTemplate, row.substring(5,row.length() -1));

    String col = String.format(colTemplate, x);

    templatePath = templatePath.replace(colTemplate, col.substring(5,col.length() -1));

    path.append(templatePath);

    path.append('.');

    path.append(fileExtension);

    File tileFile =new File(path.toString());

    if(!tileFile.exists()){

    if(fileExtension.toLowerCase() =="jpeg"){

    tileFile =new File(path.toString().replace("jpeg","jpg"));

    }

    }

    return tileFile;

    }

    本想基于GeoServer2.17版本开发,但2.17版本在BlobStore方面做了比较大的修改,因此只好基于现有版本GeoServer2.16开发。

    谨以此篇为自己2019年的工作画一个句号,并恭祝大家2020年万事如意!

    相关文章

      网友评论

          本文标题:通过GeoServer发布ArcGIS Server切片/Ces

          本文链接:https://www.haomeiwen.com/subject/uorszctx.html