dmptilethumbnail.cpp 7.5 KB
/**************************************************************************
* file:              dmptilethumbnail.cpp

* Author:            lijiahuan
* Date:              2021-12-23 15:33:50
* Email:             jiahuanl@chinadci.com
* copyright:         广州城市信息研究所有限公司
***************************************************************************/
#include "dmptilethumbnail.h"
#include <iostream>
#include <string>
#include <map>
#include <memory>
#include <math.h>


bool DmpTileThumbnail::ctreatWmtsThumbnail(DmpTileLayer *tileLayer)
{
   
   std::string path = tileLayer->getDataSource();
   path="/mnt/d/Code/tiles/qgis";
   std::string vendor=tileLayer->getVendor();
   std::string format=tileLayer->getFormat();

   DmpRectangle rectangle=tileLayer->extent();
   std::string lowerPoint=std::to_string(rectangle.xmin())+" "+std::to_string(rectangle.ymin());
   std::string upperPoint=std::to_string(rectangle.xmax())+" "+std::to_string(rectangle.ymax());
   Point minPoin{.x=107.78981494180618,.y=18.870480519260582};
   Point maxPoin{.x=120.43553603935675,.y=25.999868757737033};

   int tileMatrix=6;
   Point origin{.x=-400,.y=400};
   double resolution=0.02197265625009295*256;
   int minCol=floor(abs(origin.x-minPoin.x)/resolution);
   int minRow=floor(abs(origin.y-minPoin.y)/resolution);
   int maxCol=floor(abs(origin.x-maxPoin.x)/resolution);
   int maxRow=floor(abs(origin.y-maxPoin.y)/resolution);
   int width=maxCol-minCol;
   int heigth=minRow-maxRow;
   cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 256*(width+1), 256*(heigth+1));
   cairo_t *cr =cairo_create (surface);
   
   for( int i = 0 ; i <= width ; i++ )
   {
       for(int j=0;j<=heigth;j++)
       {  
           char* buff;
           int length;
           getTile(maxRow+j,minCol+i,tileMatrix,format,buff,length);        
        //    std::string filepath=path+"/"+std::to_string(tileMatrix)+"/"+std::to_string(minCol+i)+"/"+std::to_string(maxRow+j)+".png";          
        //    cairo_surface_t*  image = cairo_image_surface_create_from_png( filepath.c_str());

           st_png_data* pPngData;
           pPngData->pdata=(unsigned char*)buff;
           pPngData->length=length;
           cairo_surface_t*  image1 = cairo_image_surface_create_from_png_stream(cairo_read_func_mine,&pPngData);

           BufferCopy(image1,surface,cr,0,0);
           cairo_surface_write_to_png (surface, "./wmts1.png");
           BufferCopy(image1,surface,cr,i*256,j*256);
       }
   }
 
   cairo_destroy (cr);
   cairo_surface_write_to_png (surface, "./wmts.png");
   cairo_surface_destroy (surface);
   return true;
}
bool DmpTileThumbnail::ctreatTmsThumbnail()
{
   std::string path="/mnt/d/Code/tiles/qgis";
   std::string vendor="QGIS";
   Point origin{.x=-400,.y=400};
   Point minPoin{.x=107.78981494180618,.y=18.870480519260582};
   Point maxPoin{.x=120.43553603935675,.y=25.999868757737033};
   double resolution=0.02197265625009295*256;
   //    int minCol=floor(abs(origin.x-minPoin.x)/resolution);
   //    int minRow=floor(abs(origin.y-minPoin.y)/resolution);
   //    int maxCol=floor(abs(origin.x-maxPoin.x)/resolution);
   //    int maxRow=floor(abs(origin.y-maxPoin.y)/resolution);
   int minCol=51;
   int minRow=28;
   int maxCol=53;
   int maxRow=27;
   int width=maxCol-minCol;
   int heigth=minRow-maxRow;
   cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 256*(width+1), 256*(heigth+1));
   cairo_t *cr =cairo_create (surface);
   for( int i = 0 ; i <= width ; i++ )
   {
       for(int j=0;j<=heigth;j++)
       {          
           std::string filepath=path+"/6/"+std::to_string(minCol+i)+"/"+std::to_string(maxRow+j)+".png";
           cairo_surface_t*  image = cairo_image_surface_create_from_png( filepath.c_str());
           
           BufferCopy(image,surface,cr,i*256,j*256);
       }
   }
   cairo_destroy (cr);
   cairo_surface_write_to_png (surface, "./tms.png");
   cairo_surface_destroy (surface);
   return true;
}
bool DmpTileThumbnail::BufferCopy(cairo_surface_t *pClsCSFrom, cairo_surface_t *pClsCSTo, cairo_t *cr,int x,int y)
{
    if (pClsCSFrom == NULL||pClsCSTo == NULL)
    {
        return false;
    }
    if(cr==NULL)
    {
        cr =  cairo_create (pClsCSTo);
    }
    cairo_set_source_surface(cr, pClsCSFrom, x, y); 
    cairo_paint(cr);
   
    return true;
}
void DmpTileThumbnail::getTile(int row, int col, int level,  std::string& format,char* refbuff,int length)
{
    int packSize = 128;
    int rGroup = (int)row/packSize;
    rGroup = rGroup * packSize;
    int cGroup = (int)col/packSize;
    cGroup = cGroup*packSize;
    std::string path="/mnt/d/Code/tiles/gdmap/_alllayers";
    std::string bundleBase =GetBundlePath(level,rGroup,cGroup);
    std::string bundleFilePath = path+bundleBase + ".bundle";
    std::string bundlxFilePath = path+bundleBase + ".bundlx";
    
    int index = packSize * (col - cGroup) + (row - rGroup);

    //读取bundlx文件存储该切片的位置,计算偏移量
    std::ifstream freadx(bundlxFilePath,  std::ifstream::binary); 
    if(!freadx)   
    {
        
        return;
    }
    freadx.seekg(16+5*index, freadx.beg);
    char* buffer = new char[5];
    freadx.read(buffer,5);
    freadx.close();
    
    long offset = (long)(buffer[0]&0xff) 
                    + (long)(buffer[1]&0xff) * 256 
                    + (long)(buffer[2]&0xff) * 65536
                    + (long)(buffer[3]&0xff) * 16777216
                    + (long)(buffer[4]&0xff) * 4294967296L;
    delete [] buffer;
    //读取bundle文件获取切片
    std::ifstream fread(bundleFilePath, std::ifstream::binary); 
    if(!fread)   
    {
       
        return;
    }  
    fread.seekg(offset, fread.beg);
    char* buff = new char[4];
    fread.read(buff, 4);
    length = (long)(buff[0]&0xff) 
                 + (long)(buff[1]&0xff) * 256 
                 + (long)(buff[2]&0xff) * 65536
                 + (long)(buff[3]&0xff) * 16777216;
    delete[] buff;
    char* imgBuffer = new char[length];
    fread.read(imgBuffer, length);
    fread.close();
    refbuff=imgBuffer;
    delete[] imgBuffer;
}
std::string DmpTileThumbnail::GetBundlePath(int level, int rGroup, int cGroup)
{
    std::string l = std::to_string(level);
    int len = l.length();
    if (len < 2)
    {
        for (int i = 0; i < 2 - len; i++)
        {
            l = "0" + l;
        }
    }
    l = "L" + l;
    std::string r =IntToHexStr(rGroup);
    
    int rLength = r.length();
    if (rLength < 4)
    {
        for (int i = 0; i < 4 - rLength; i++)
        {
            r = "0" + r;
        }
    }
    r = "R" + r;

    std::string c = IntToHexStr(cGroup);
    int cLength = c.length();
    if (cLength < 4)
    {
        for (int i = 0; i < 4 - cLength; i++)
        {
            c = "0" + c;
        }
    }
    c = "C" + c;
    std::string rootPath;
    std::string bundlePath = rootPath + "/"+l+"/"+r+c;
    return bundlePath;
}
std::string DmpTileThumbnail::IntToFormatStr(const int num)
    {
        std::string str = std::to_string(num);    
        if(num>=0 && num<10)
        {
            str = "0"+str;
        }
	    return str;
    }

std::string DmpTileThumbnail::IntToHexStr(const int num)
    {
        char* buffer = new char[8];
        sprintf(buffer,"%x",num);
        std::string str = std::string(buffer);
        delete[] buffer;
        return str;
    }


cairo_status_t DmpTileThumbnail::cairo_read_func_mine (void *closure, unsigned char *data, unsigned int length)
{
	st_png_data* pPngData = (st_png_data*)closure;
	memcpy(data, pPngData->pdata + pPngData->length, length);
	pPngData->length += length;
	return CAIRO_STATUS_SUCCESS;
}