arcgis 切片分析录入mongodb

[复制链接]
发表于 2025-10-13 21:41:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
将arcgis的切片数据录入mongodb,如允许以支持自界说的server发步

以下是对3种arcgis切片规则的分析
疏松型

也就是我们常见的文件式的切片管理方式,将 Arcgis Server 切出来的切片图片按照行列号的规范,存储在相应的文件夹中。
循环全部.png文件路径,存入mongodb数据库
  1. for (let i = 0; i < total; i++)
  2.                     {
  3.                         console.log("循环录入文件:" + i + "/" + total + "\t" + filesPaths[i]);
  4.                         let filePath = filesPaths[i];
  5.                         let data = fs.readFileSync(filePath);
  6.                         filePath = filePath.replace(/\\/g, '/');
  7.                         filePath = filePath.replace(rootFolder + '/', '');
  8.                         //L08\R00000061\C000000D3.png
  9.                         var infoString = filePath.replace(".png", "");
  10.                         let level = parseInt(infoString.split('/')[0].replace("L", ""));
  11.                         let row = parseInt(infoString.split('/')[1].replace("R", ""), 16);
  12.                         let column = parseInt(infoString.split('/')[2].replace("C", ""), 16);
  13.                         let b3dmData = { 'level': level, 'row': row, 'column': column, 'fullPath': filePath, 'data': data };
  14.                         b3dmDataSet.push(b3dmData);
  15.                         if (i != 0 && i % 10000 == 0)
  16.                         {
  17.                             await collection.insertMany(b3dmDataSet);
  18.                             b3dmDataSet = [];
  19.                             let proc = (i / total).toFixed(2) * 100;
  20.                             console.log('已完成 ' + proc + '%');
  21.                         } else if (i == filesPaths.length - 1)
  22.                         {
  23.                             await collection.insertMany(b3dmDataSet);
  24.                             b3dmDataSet = [];
  25.                             await client.close();
  26.                             console.log('已完成 100%');
  27.                         }
  28.                     }
复制代码
早期紧凑型

将切好的切片转化成.bundle和.bundlex的两种文件格式存储。

  •         此中bundle文件用以存储切片数据,bundlx 是 bundle 文件中切片数据的索引文件;
  •         一个 bundle 文件中最多可以存储128×128(16384)个切片;
  •         在 bundlx 文件中用固定的字节数量(5字节)标识一个切片在 bundle 文件中的状态(偏移量);每个 bundlx 文件都是一样的巨细:81952字节,起始16字节和文件竣事16字节与索引无关,剩余的81920字节数据以5个字节的频率重复,构成了一个对bundle文件的索引【注:16384 * 5 = 81920】;这5个字节标示了切片数据的偏移量。
  •         在 bundle 文件中,每2个切片数据之间相隔了4个字节;这4个字节恰好是以低位到高位的方式标示了后续这个切片数据的长度。
  •         切片数据的长度(4字节)和数据偏移(5字节)是无符号的整数。
  •         bundlx 文件的文件名,包罗了切片的行列信息,而它所在的文件夹名称(目次名称),则包罗切片的级别信息。
因此,我们假如知道了一个切片的级别、行号、列号,就可以找到相应的 bundlx 文件,并通过 bundlx 起首找到bundle中切片内容的偏移,然后从bundle文件中取出4个字节的长度数据,再随后根据这个长度读取真实的切片数据。
  1. 假设已知切片的级别、行号和列号,求对应的 bundlx 文件:
  2. 目录名:L开头,并加上级别,级别不足2位的,高位补0,例如:L01,L19等。
  3. 文件名:R开头,加上4位16进制数(行号组最小行号),
  4.            再加上字母C,最后加上4位16进制数(列号组最小列号),
  5.            例如:R0080C0080.bundlx
  6.           
  7. 行号组最小行号、列号组最小列号 的计算:
  8. (1)因为一个 bundle 文件中最多可以存储 128×128 个切片,所以,
  9.         行号/128,向下取整,得到切片所在的“行号组的序数 r”(即第 r 组);
  10.         列号/128,向下取整,得到切片所在的“列号组的序数 c”(即第 c 组);
  11.         r * 128,得到所在行组的最小行号 rrrr;
  12.         c * 128,得到所在列组的最小列号 cccc;
  13. (2)将 rrrr 和 cccc 转成 16 进制数,并转化为长度为4的字符串(不足4位时,高位补0);
  14. 找到 bundlx 文件:
  15. (3)拼接出文件名:R{rrrr}C{cccc}.bundlx
  16. (4)拼接出路径:_alllayers\level\R{rrrr}C{cccc}.bundlx
  17. --------------------------------
  18. 假设已知切片的级别、行号和列号,求对应的切片数据:
  19. (1)求切片的序数:
  20. 行号 - 行号组最小行号(即:行号-rrrr),得到切片在当前行号组的序数 m;
  21. 列号 - 列号组最小列号(即:列号-cccc),得到切片在当前列号组的序数 n;
  22. m + 128 *n,得到切片在 bundle 文件中的序数 index(即:切片是 bundle 中总共的16384 张切片中的第 index 张切片);
  23. (2)求切片的位置(偏移量):
  24. 因为在 bundlx 文件中,每张切片的位置信息用5字节表示,且头部有16个起始字节,所以,前(16 + 5 * index)个字节需要忽略;之后的5字节是切片的位置信息,如下解析切片的位置信息:
  25. 偏移量 offset = 第0字节 + 第1字节 * 256 + 第2字节 * 256 * 256 + 第3字节 * 256 * 256 * 256 + 第4字节 * 256 * 256 * 256 * 256。
  26. (3)求切片的长度:
  27. 因为切片之前4个字节,是切片的长度信息,所以 用 offset 之后的四个字节来计算切片的长度,如下:
  28. 切片长度 length = 第0字节 + 第1字节 * 256 + 第2字节 * 65536 + 第3字节 * 16777216
  29. (4)读取切片
  30. offset 之后 length 个字节,就是切片的图片流。
复制代码
以下是为了将arcgis切片数据存入mongodb中的焦点代码
filepath为各个索引文件路径
b3dmDataSet为要存入mongodb的数据集
  1.                         //读取索引文件
  2.                         let indexData = fs.readFileSync(filePath);
  3.                         //读取数据文件
  4.                         let imgdata = fs.readFileSync(filePath.replace(".bundlx", ".bundle"));
  5.                         filePath = filePath.replace(/\\/g, '/');
  6.                         filePath = filePath.replace(rootFolder + '/', '');
  7.                         let level = parseInt(filePath.split('/')[0].replace("L", ""));
  8.                         let filename = filePath.split('/')[1].split('.')[0];
  9.                         let minRow = parseInt(filename.split('C')[0].replace("R", ""), 16);
  10.                         let minColumn = parseInt(filename.split('C')[1].replace("C", ""), 16);
  11.                         for (var rowindx = minRow; rowindx < minRow + size; rowindx++)
  12.                         {
  13.                             for (var colindx = minColumn; colindx < minColumn + size; colindx++)
  14.                             {
  15.                                 var currentImageData = [];
  16.                                 //读取数据
  17.                                 {
  18.                                     //计算切片序号
  19.                                     var indexQP = (rowindx - minRow) + (colindx - minColumn) * size;
  20.                                     //计算切片偏移量
  21.                                     var offset = 0;
  22.                                     {
  23.                                         //需要忽略的长度
  24.                                         var hLength = 16 + (5 * indexQP);
  25.                                         //计算切片偏移量
  26.                                         offset = //indexData.readUInt16LE(hLength);
  27.                                             indexData[hLength] +
  28.                                             (indexData[hLength + 1] * 256) +
  29.                                             (indexData[hLength + 2] * 256 * 256) +
  30.                                             (indexData[hLength + 3] * 256 * 256 * 256) +
  31.                                             (indexData[hLength + 4] * 256 * 256 * 256 * 256);
  32.                                     }
  33.                                     //计算切片长度
  34.                                     var qpLenth = imgdata[offset] +
  35.                                         (imgdata[offset + 1] * 256) +
  36.                                         (imgdata[offset + 2] * 256 * 256) +
  37.                                         (imgdata[offset + 3] * 256 * 256 * 256);
  38.                                     currentImageData = imgdata.slice(offset + 4, offset + 4 + qpLenth);
  39.                                 }
  40.                                 if (currentImageData.length > 0)
  41.                                 {
  42.                                     let b3dmData = { 'level': level, 'row': rowindx, 'column': colindx, 'fullPath': filePath, 'data': currentImageData };
  43.                                     b3dmDataSet.push(b3dmData);
  44.                                 }
  45.                             }
  46.                         }
复制代码

10.3以后的紧凑型(未验证)

将切好的切片转化成.bundle的格式来存储。

  • 切片的索引、切片的偏移和切片的图片流都一定包罗在这一.bundle文件中;
  • 头信息:.bundle文件起始 64 字节 是 bundle 的文件头信息;
  • 位置信息:头信息之后,记录了 16384 张切片的位置;每个位置信息,用8个字节表现;仅前4字节有用,从低位到高位;后4字节可忽略;
  • 图片流信息:位置信息之后,是图片流信息;每个切片图,先以4字节记录切片的长度,而后紧跟图片的流信息。
  • .bundle文件的文件名以及所在文件夹的名称,包罗切片的级别、行列信息。
  1. 假设已知切片的级别、行号和列号,求对应的 bundle 文件:
  2. 求取方式同 “假设已知切片的级别、行号和列号,求对应的 bundlx 文件”。
  3. --------------------------------
  4. 假设已知切片的级别、行号和列号,求对应的切片数据:
  5. (1)求切片的序数:
  6. 行号 - 行号组最小行号(即:行号-rrrr),得到切片在当前行号组的序数 m;
  7. 列号 - 列号组最小列号(即:列号-cccc),得到切片在当前列号组的序数 n;
  8. 128 * m + n,得到切片在 bundle 文件中的序数 index(即:切片是 bundle 中总共的16384 张切片中的第 index 张切片);
  9. (2)求切片的位置(偏移量):
  10. 因为每张切片的位置用8字节表示,且头信息占64字节,所以,前(64 + 8 * index)个字节需要忽略;之后的8字节是切片的位置信息(仅前4字节有用),如下解析切片的位置信息:
  11. 偏移量 offset = 第1字节 + 第2字节 * 256 + 第3字节 * 65536 + 第4字节 * 16777216。
  12. (3)求切片的长度:
  13. 因为切片之前4个字节,是切片的长度信息,所以 用(offset-4)之后的四个字节来计算切片的长度,如下:
  14. 切片长度 length = 第0字节 + 第1字节 * 256 + 第2字节 * 65536 + 第3字节 * 16777216
  15. (4)读取切片
  16. offset 之后 length 个字节,就是切片的图片流。
复制代码
 
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表