arcgis 切片分析录入mongodb

news/2025/3/17 14:14:18/

arcgis的切片数据录入mongodb,这样可以支持自定义的server发步

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

松散型

也就是我们常见的文件式的切片管理方式,将 Arcgis Server 切出来的切片图片按照行列号的规范,存储在相应的文件夹中。

循环所有.png文件路径,存入mongodb数据库

for (let i = 0; i < total; i++){console.log("循环录入文件:" + i + "/" + total + "\t" + filesPaths[i]);let filePath = filesPaths[i];let data = fs.readFileSync(filePath);filePath = filePath.replace(/\\/g, '/');filePath = filePath.replace(rootFolder + '/', '');//L08\R00000061\C000000D3.pngvar infoString = filePath.replace(".png", "");let level = parseInt(infoString.split('/')[0].replace("L", ""));let row = parseInt(infoString.split('/')[1].replace("R", ""), 16);let column = parseInt(infoString.split('/')[2].replace("C", ""), 16);let b3dmData = { 'level': level, 'row': row, 'column': column, 'fullPath': filePath, 'data': data };b3dmDataSet.push(b3dmData);if (i != 0 && i % 10000 == 0){await collection.insertMany(b3dmDataSet);b3dmDataSet = [];let proc = (i / total).toFixed(2) * 100;console.log('已完成 ' + proc + '%');} else if (i == filesPaths.length - 1){await collection.insertMany(b3dmDataSet);b3dmDataSet = [];await client.close();console.log('已完成 100%');}}

早期紧凑型

将切好的切片转化成.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个字节的长度数据,再随后根据这个长度读取真实的切片数据。

假设已知切片的级别、行号和列号,求对应的 bundlx 文件:目录名:L开头,并加上级别,级别不足2位的,高位补0,例如:L01,L19等。文件名:R开头,加上4位16进制数(行号组最小行号),再加上字母C,最后加上4位16进制数(列号组最小列号),例如:R0080C0080.bundlx行号组最小行号、列号组最小列号 的计算:
(1)因为一个 bundle 文件中最多可以存储 128×128 个切片,所以,行号/128,向下取整,得到切片所在的“行号组的序数 r”(即第 r 组);列号/128,向下取整,得到切片所在的“列号组的序数 c”(即第 c 组);r * 128,得到所在行组的最小行号 rrrr;c * 128,得到所在列组的最小列号 cccc;
(2)将 rrrr 和 cccc 转成 16 进制数,并转化为长度为4的字符串(不足4位时,高位补0);找到 bundlx 文件:
(3)拼接出文件名:R{rrrr}C{cccc}.bundlx
(4)拼接出路径:_alllayers\level\R{rrrr}C{cccc}.bundlx--------------------------------假设已知切片的级别、行号和列号,求对应的切片数据:(1)求切片的序数:
行号 - 行号组最小行号(即:行号-rrrr),得到切片在当前行号组的序数 m;
列号 - 列号组最小列号(即:列号-cccc),得到切片在当前列号组的序数 n;m + 128 *n,得到切片在 bundle 文件中的序数 index(即:切片是 bundle 中总共的16384 张切片中的第 index 张切片);(2)求切片的位置(偏移量):
因为在 bundlx 文件中,每张切片的位置信息用5字节表示,且头部有16个起始字节,所以,前(16 + 5 * index)个字节需要忽略;之后的5字节是切片的位置信息,如下解析切片的位置信息:
偏移量 offset = 第0字节 + 第1字节 * 256 + 第2字节 * 256 * 256 + 第3字节 * 256 * 256 * 256 + 第4字节 * 256 * 256 * 256 * 256。(3)求切片的长度:
因为切片之前4个字节,是切片的长度信息,所以 用 offset 之后的四个字节来计算切片的长度,如下:
切片长度 length = 第0字节 + 第1字节 * 256 + 第2字节 * 65536 + 第3字节 * 16777216(4)读取切片
offset 之后 length 个字节,就是切片的图片流。

以下是为了将arcgis切片数据存入mongodb中的核心代码

filepath为各个索引文件路径

b3dmDataSet为要存入mongodb的数据集

//读取索引文件let indexData = fs.readFileSync(filePath);//读取数据文件let imgdata = fs.readFileSync(filePath.replace(".bundlx", ".bundle"));filePath = filePath.replace(/\\/g, '/');filePath = filePath.replace(rootFolder + '/', '');let level = parseInt(filePath.split('/')[0].replace("L", ""));let filename = filePath.split('/')[1].split('.')[0];let minRow = parseInt(filename.split('C')[0].replace("R", ""), 16);let minColumn = parseInt(filename.split('C')[1].replace("C", ""), 16);for (var rowindx = minRow; rowindx < minRow + size; rowindx++){for (var colindx = minColumn; colindx < minColumn + size; colindx++){var currentImageData = [];//读取数据{//计算切片序号var indexQP = (rowindx - minRow) + (colindx - minColumn) * size;//计算切片偏移量var offset = 0;{//需要忽略的长度var hLength = 16 + (5 * indexQP);//计算切片偏移量offset = //indexData.readUInt16LE(hLength);indexData[hLength] +(indexData[hLength + 1] * 256) +(indexData[hLength + 2] * 256 * 256) +(indexData[hLength + 3] * 256 * 256 * 256) +(indexData[hLength + 4] * 256 * 256 * 256 * 256);}//计算切片长度var qpLenth = imgdata[offset] +(imgdata[offset + 1] * 256) +(imgdata[offset + 2] * 256 * 256) +(imgdata[offset + 3] * 256 * 256 * 256);currentImageData = imgdata.slice(offset + 4, offset + 4 + qpLenth);}if (currentImageData.length > 0){let b3dmData = { 'level': level, 'row': rowindx, 'column': colindx, 'fullPath': filePath, 'data': currentImageData };b3dmDataSet.push(b3dmData);}}}

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

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

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

 


http://www.ppmy.cn/news/1579824.html

相关文章

Embedding模型与向量数据库

在上篇博文中使用Spring Boot整合DeepSeek实现了AI对话&#xff0c;目前如果我们要构建一个个性化的具有私有领域知识的专用AI助手&#xff0c;一般会有两种方式&#xff1a; 大模型微调&#xff1a;一种在预训练大模型的基础上&#xff0c;使用特定任务的数据对模型进行进一步…

【孟德尔随机化】Leave-one-out analysis的异常点,判断

下面Leave-one-out analysis的结果&#xff0c;第一条线代表去掉rs174564的结果&#xff0c;一些文献把这种情况判断为异常点/离群点&#xff0c;我们接下来看看其他结果 散点图的结果&#xff0c;最旁边的就是rs174564&#xff0c;这个SNP的点 在看下RadialMR的结果&#xff0…

3.16学习总结

学习了Java的知识点 基本数据类型 byte占1字节&#xff0c;储存范围-128~127 short占2字节&#xff0c;储存范围-32768~32767 int占4字节&#xff0c;储存范围-2147483648~2147483647 long占8字节&#xff0c;储存范围是-9223372036854775808~9223372036854775807 float占…

极限入门题解析

Exercises and Solutions Evaluate the limit: lim ⁡ n → ∞ ( 1 1 2 1 3 ⋯ 1 n ) 1 n \lim_{n \rightarrow \infty} \left(1 \frac{1}{2} \frac{1}{3} \cdots \frac{1}{n}\right)^{\frac{1}{n}} n→∞lim​(121​31​⋯n1​)n1​ Solution: 1 ≤ lim ⁡ n → ∞…

Linux入门 全面整理终端 Bash、Vim 基础命令速记

Linux入门 2025 超详细全面整理 Bash、Vim 基础命令速记 刚面对高级感满满的 终端窗口是不是有点懵&#xff1f;于是乎&#xff0c;这份手册就是为你准备的高效学习指南&#xff01;我把那些让人头大的系统设置、记不住的命令都整理成了对你更友好的格式&#xff0c;让你快速学…

C语言之文件

文章目录 前言 一、文件的基本操作 1、用只读模式打开文件流 2、用w只写模式打开并创建文件 3、给文件改名 4、删除文件 二、文本文件写操作 三、文本文件读操作 四、二进制文件写操作 五、二进制文件读操作 六、文件复制 七、文件光标 总结 前言 文件处理在C语言中…

微软.NET框架下通信技术理解与实践

微软.NET框架下的Remoting和Web Service两项技术的理解以及它们在实际应用中的分析。 一.NET Remoting 理解 .NET Remoting是一种用于在不同应用程序域&#xff08;AppDomain&#xff09;或进程之间进行通信的技术。它允许对象跨越应用程序域、进程甚至计算机边界进行交互。…

网络安全 与 加密算法

计算机中的网络安全 在本篇中介绍了以下几个方面: 机密性 密码学 对称加密算法(DES, 3DES, AES) 公开秘钥算法 RSA大素数的获取 完整性 散列函数(MD5, SHA-1, 并没有提及算法实现) 报文鉴别(MAC) 数字签名 端点鉴别 应用 SSL(TCP网络安全) 运行时安全 防火墙的基本知…