四叉树编码
求矩阵四叉树的四进制和十进制Morton码
求矩阵四叉树的四进制和⼗进制Morton码Yogurt是⼀名学GIS的学⽣,今天要跟⼤家分享的是四叉树这种空间索引⽅式的Morton编码⽅法,接下来我将在⼩课堂中简单介绍⼀下空间索引以及其⼏种编码⽅式~~---------------------------------------------------------yogurt⼩课堂开课啦--------------------------------------------------------GIS所涉及到的都是有关空间的数据信息,即也属于所谓的⼤数据了,那么怎么将客观的物体对象存储到计算机中,以及怎么从计算机中读取所需要的数据呢?⾸先我们要知道计算机的存储器有内存和外存,内存空间⼩但是读写快,外存空间⼤却读写慢,访问外存所花费的时间是访问内存的⼗万倍以上!在GIS的实际应⽤中⼤量的数据都是存储在外存上的,想象⼀下如果这些数据全都杂乱⽆章的堆放在那⾥,那么每需要查询⼀个数据就需要扫描整个数据⽂件,这样访问磁盘的代价是⾮常⼤的,严重影响了系统效率!所以,我们必须记录好每个数据存放的位置,以便于组织和管理,在这个过程中就需要⽤到索引技术啦!【(这⾥引⾃我⽼师的课件哈,低调低调)从传统的索引技术观点来看,可以把空间索引技术⼤致分为四⼤类:基于R树,基于Hashing,基于⼆叉树,基于空间填充。
在建⽴索引时,按照划分区域是否与空间对象的分布特征有关的标准,空间索引⼜可以分为两⼤类:⽆关的(⽹格索引、四叉树),有关的(BSP树、KD树、KDB树、R树及其变种树)。
我们来看看⼏种索引⽅法的实际应⽤:(1)ESRI的ArcSDE采⽤的是固定格⽹索引;(2)⽬前国内外主要的空间数据库如ESRI的ArcView,Mapinfo公司的Maoinfo和Informix的GeoSpatial DataBlade采⽤的是R树系列作为空间索引的⽅式;(3)Oracle公司的Spatial同时采⽤固定格⽹索引以及R树索引;(4)中国地质⼤学的MapGIS和中科院的SuperMap采⽤的是四叉树。
地理信息系统-四叉树编码
地理信息系统-四叉树编码
四叉树编码是一种地理信息系统中常用的空间索引方法。
在使用地理信息系统时,我们需要对空间数据进行快速的查询和检索,四叉树编码可以将地理空间划分为一系列的正方形,方便快速查询和检索数据。
四叉树编码是一种基于二叉树的空间索引方法,它将空间划分为一系列的子区域,每个子区域被划分为四个更小的正方形,这些正方形被称为四叉树节点。
每个节点都有一个唯一的编码,这个编码可以用来表示该节点所代表的区域的位置和大小。
四叉树编码可以极大地提高地理数据的查询效率。
在地理信息系统中,我们需要处理海量的空间数据,如果每次查询都需要扫描整个数据集,那么效率必然非常低下。
通过四叉树编码,我们可以将空间数据划分成一系列的小区域,每次查询只需要搜索与查询条件相交或包含的子区域,可以极大地缩短查询时间。
四叉树编码的应用非常广泛,如数字地图制作、地理信息系统、图像处理等领域。
在数字地图制作中,我们可以使用四叉树编码将地图划分为一系列的小区域,通过快速查找与当前屏幕区域相交或包含的区域,可以提高地图的显示效率和响应速度。
在地理信息系统中,四叉树编码可以帮助我们快速查询包含某一位置点的所有区域,方便我们进行地理数据分析和决策支持。
在图像处理中,四叉树编码可以用于图像压缩和分级显示,可以使得图像数据的存储和传输更加高效。
地理信息系统四叉树编码例题和答案
地理信息系统四叉树编码例题和答案地理信息系统中的四叉树编码是一种空间数据索引方法,用于将地理空间数据划分为四个子区域,并为每个子区域分配一个唯一的编码。
这种编码方法可以有效地支持空间数据的存储和查询。
以下是一个四叉树编码的例题和答案示例:题目:假设一个地理空间区域被四叉树编码划分为四个子区域,编码规则为NW、NE、SW、SE,分别代表西北、东北、西南、东南四个方向。
其中,初始区域编码为""(空字符串),请根据以下步骤计算最终的编码:1. 将初始区域划分为四个子区域,并为每个子区域分配对应的编码。
2. 对每个子区域按照步骤1的方法,再次划分为四个子区域,并为每个子区域分配编码。
3. 重复步骤2,直到达到指定的划分层数。
假设指定的划分层数为2,求最终的编码结果。
答案:按照题目所给的初始编码为""开始计算。
第一层划分:- 西北子区域编码为"" + "NW" = "NW"- 东北子区域编码为"" + "NE" = "NE"- 西南子区域编码为"" + "SW" = "SW"- 东南子区域编码为"" + "SE" = "SE"第二层划分:- 西北子区域的西北子区域编码为"NW" + "NW" = "NWNW"- 西北子区域的东北子区域编码为"NW" + "NE" = "NWNE"- 西北子区域的西南子区域编码为"NW" + "SW" = "NWSW"- 西北子区域的东南子区域编码为"NW" + "SE" = "NWSE"- 依此类推,计算其他子区域的编码。
地理信息系统-四叉树编码
• 位图的读入 • 程序的简介 • 程序的流程 • 程序的结果
• 位图的结构
位图的读入
BITMAPFILEHEADER 位图文件头
BITMAPIFOHEADER 位图信息头
颜色表
24bit的位图没有颜色表
位图数据
位图的读入
• 位图读入的基本流程
读方式打开文件
跳过文件头结构
读入信息头结构
存放结点信息
struct LinkStack{ PNode top;};
链栈结构
• 数据说明
程序的简介
QuadTree类 QuadTree
class QuadTree{ public: PLinkStack createEmptyStack_link(); //生成空栈 void push (PLinkStack plstack,MortonAndPixel x); //元素入栈 void pop(PLinkStack plstack); //元素出栈 MortonAndPixel CatchTop(PLinkStack plstack); //获取栈顶元素 int GetT(long Num);//获取结点循环次数 int GetHang(long morton);//morton码反算得到行 int GetLie(long morton);//morton码反算得到列 }
移动栈顶指针 元素Next指针=NULL 是 结束
程序的流程
• 解码示意
解码入新栈 取栈顶元素
栈顶指针
16 4 12 2 8 0 4 1 0 0 Morton码 属性值
16 12
取下一个元素
16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Morton码 4 2 2 2 2 0 0 0 0 1 1 1 1 0 0 0 0 属性值
四叉树C 实现代码
m_nTreeDepth = TreeDepth; CreateBranch( &m_pHeadNode, TreeDepth, 0); } //virtual void CreateNode( QuadTreeNode<T> * ptempNode ) const = 0; };
m_nTreeDepth = 0; m_pHeadNode = NULL; }
~QuadTree() {
void (QuadTree::*func)(QuadTreeNode<T> *) ; func = &QuadTree::DestroyNode; PostOrderOperation( m_pHeadNode, func ); }
QuadTreeNode* ptempNode = m_pHeadNode; for( int i=0; i<code.GetLength(); i++ ) {
ptempNode = ptempNode->GetChild( code[i] ); if( ptempNode==NULL )
return false; } Op( ptempNode ); return true; }
case ChildType::LR: return &m_pLowerRight; break; } }
};
template<class T> class QuadTree { public:
int m_nTreeDepth; //树的深度 QuadTreeNode<T> *m_pHeadNode; //树的头部 QuadTree() {
四叉树编码
0 1 0 5
0 1 3 0 0 5
0
0
1
0
0
3
5
0
根据填充后的尺寸确定level
nxn level=log(n) / log(2)
Pixel
根据level的值创建多个数组 数组level1 数组level2 数组level3
数组内储存 NextIndex 2x2 4x4 8x8
底层数组leveln长度等于填充后的栅格长度 数组leveln
1
0
3
2
依次向上层数组录入数据 数组level1 数组level2 数组level3
2x2 4x4 8x8
数组leveln
2^nx2^n
索引值的获取 像素值相同的点不会录入到最终压缩编码中 数组遍历的方向是从末端向前
像素相同
像素不同
不录入QTree
录入QTree
索引值的获取 int QtreeTemp QtreeTemp从末端开始计数,记录了每个不相同像素单元 的位置,是最终压缩编码的反向索引
遍历次数少 只遍历了两次 一次在录入数据到数组,一次在转录数据到最终压缩编码
像素相同 像素不同
QtreeTemp不变
QtreeTemp+4
转录到最终压缩编码 正向遍历,判断当前数组的值,转录下层数组
有像素值说明下层对应的像素值相同 有索引值说明下层对应的像素值不同
数组level1 像素值 索引值
数组level2
不录入
录入
数组leveln
快速获取索引 使用QtreeTemp记录压缩编码的反向索引
2^nx2^n
数组level1
2x2 4x4 8x8
第18讲游程编码四叉树编码
游程编码
• 长度编码对图3-6(a)只用了40个整数就可以表示,而如果用前述 的直接编码却需要64个整数表示,可见游程长度编码压缩数据是 十分有效又简便的。事实上,压缩比的大小是与图的复杂程度成 反比的,在变化多的部分,游程数就多,变化少的部分游程数就 少,图件越简单,压缩效率就越高。
• 游程长度编码在栅格加密时,数据量没有明显增加,压缩效率较 高,且易于检索,叠加合并等操作,运算简单,适用于机器存贮 容量小,数据需大量压缩,而又要避免复杂的编码解码运算增加 处理和操作时间的情况。
• 是最有效的栅格数据压缩编码方法之一。
6
常规四叉树编码:
7
例题:
8
常规四叉树编码特点:
9
练习:
将删格图像信息进行编码存储, 要求,先用游程编码表示,再
用常规四叉树编码表示。
10
练习:将下列数据用游程编码表示。
11
删格数据类型
1
游程编码
• 游程长度编码是栅格数据压缩的重要编码方法,它 的基本思路是:对于一幅栅格图像,常常有行(或 列)方向上相邻的若干点具有相同的属性代码,因 而可采取某种方法压缩那些重复的记录内容。其编 码方案是,只在各行(或列)数据的代码发生变化 时依次记录该代码以及相同代码重复的个数,从而 实现数据的压缩。
4
例题:5Biblioteka 常规四叉树编码:• 思路:把地理空间定量划分为可变大小的网格,每个网格具有相 同的属性
• 原理:将二维区域按照四个象限进行递归分割,直到子象限的数 值单调为止。
• 其基本思想是首先把一幅图象或一幅栅格地图等分成四部分,如 果检查到某个子区的所有格网都含有相同的值(灰度或属性值), 那么这个子区域就不再往下分割;否则,把这个区域再分割成四 个子区域,这样递归地分割,直至每个子块都只含有相同的灰度 或属性值为止。
基于四叉树的气象图像的编码与压缩
公 式 () 为灰度 图像 : 1变
Y 一 0 2 R + 0 5 G + 0 1 B . 99 . 87 .1 4 ( 1)
R 【 11
Rl
R2
图 3 用 四 叉 树 表 示 图 像 修 剪 过 程
21 0 1年 3月
内 蒙 古 科 技 与 经 济
I n rM o g l ce c c n l g n e n o i S in e Te h o o y& Ec n my t lNo.2 a 31
第 5 总第 2 1 期 3 期
层 大 气 湍 流 资 料 包 含 着 丰 富 的 气 象 信 息 , 着 遥 感 随
探 测 和 气 象 事 业 的 发 展 , 些 资 料 的 应 用 越 来 越 广 这 泛 和 深 入 。 于 这 类 资 料 的 数 据 量 大 , 贮 存 和 运 输 由 给 带 来 了 困难 , 此 , 像 处 理 和 数 据 压 缩 的 问 题 就 显 因 图
R31
笔 者 采 用 四叉 树 的 树 形 结 构 对 图 像 分 割 , 用 利 了树 的 非 线 性 结 构 有 效 地 解 决 了 基 于 区 域 分 割 过 程
R4
R32 , ’
中对 图 像 的 分 裂 与 合 并 算 法 问 题 。
1 四 叉 树 结 构 及 对 图 像 的 表 示 对 于 图 像 的 分 割 , 们 主 要 是 提 取 出 目标 区 域 , 我
基 于 四 叉 树 的 气 象 图 像 的 编码 与 压 缩
张德 龙 , 杜 宇 , 于薄 天 , 杨 鹏
( 蒙 古 气 象 信 息 中心 , 蒙 古 呼 和 浩 特 内 内 001) 10 0 摘 要 : 对 地 理 信 . 图像 处 理 中 图 像 的 编 码 与 压 缩 问 题 , 论 了 用 四 又 树 结 构 对 图像 的 表 示 , 针 g - 讨 以 及 在 表 示 过 程 中 利 用 算 法 对 树 枝 进 行 剪 枝 、 码 、 缩 方 法 。 方 法 的 基 本 思 想 是 , 果 当 前 原 始 子 块 的 编 压 该 如
线性四叉树
及其属性。
编码流程图
Morton码=0
行列号(i,j)
提取栅格
是
完全相同
Morton=Morton+4 否
左上角栅格入栈
四个栅格均入栈
是
压栈
否
移动栈顶指针 是
Morton码<N*N 否
结束
二、线性四叉树的编码方法
2. 伪码法
• 从表1 可以看出, MD 码正是自下而上合并生成四叉树过程的序编号, 按自
线性四叉树
• From:GIS • Date:2013-11-12
线性四叉树
1
线性四叉树的定义
2
线性四叉树编码方法
3
线性四叉树的作用
一、线性四叉树的定义
• 线性四叉树只存储最后叶结点信息, 包括叶结点的位置、 大小和灰度。
• 线性四叉树叶结点的编号需要遵循一定的规则,这种编号 称为地址码,它隐含了叶结点的位置和深度信息。最常用 的地址码是四进制或十进制的Morton码。
二、线性四叉树的编码方法
1. 线性表法
•
对栅格数据按行顺序进行扫描, 顺序计算每个格网单元的MD 码, 这
需要开辟大小为
ห้องสมุดไป่ตู้
字节的线性表, 用于存储格网单元的MD
码及其属性。在提取格网单元的属性值和计算格网单元对应的MD 码后,
存入该表, 并对表按MD码的大小进行升级排序, 然后检查区域内相邻4
个栅格单元( 或子区) 的属性值。若相同, 则合并,仅记录最小的MD 码
历完后, A 数组各单元均得到相应的值, 且其下标恰为升序的MD 码。这种方
法与线性表法相比, 减少了MD 码的排序过程, 在运行速度上有所提高, 但其
常规四叉树编码方法
四叉树编码是一种用于二维空间数据的存储和编码方法。
它将一个二维空间划分为四个象限,然后递归地对每个象限进行划分。
这种方法在GIS、图像处理、计算机图形学等领域广泛应用。
常规的四叉树编码方法可以按照以下步骤进行:
1. 根节点的编码:根节点是整个二维空间的代表,其编码通常采用整数表示。
假设整个空间的编码为0,四个象限的编码分别为00、01、10和11。
2. 子节点编码:每个象限被进一步划分为四个更小的子象限,每个子象限的编码由其父节点的编码加上一个特定的偏移量得到。
例如,假设父节点编码为01,其对应四个子节点的编码分别为010、011、100和101。
3. 节点数据存储:每个节点存储其编码以及该节点所代表的区域的数据信息(如坐标、属性等)。
对于叶节点,它们存储的是实际的数据信息;对于非叶节点,它们存储的是子节点的信息。
4. 数据检索:通过目标数据的坐标,可以找到包含该坐标的最低层的叶节点,然后通过路径反转可以得到该坐标对应的编码,从而找到数据。
这种四叉树编码方法的主要优点是它可以有效地表示和检索二维空间中的数据,并且可以很容易地进行空间数据的插入、删除和更新操作。
然而,它的主要缺点是当空间数据分布不均匀时,可能会出现数据存储的不均衡现象。
四叉树编码的栅格矩阵
四叉树编码的栅格矩阵1.引言1.1 概述概述部分的内容:引言部分将介绍本文的主题——四叉树编码的栅格矩阵,并对文章的结构和目的进行概述。
四叉树编码是一种常用的数据表示和压缩方法,它在许多领域都有广泛的应用,其中包括地理信息系统(GIS)。
栅格矩阵是GIS中最常用的数据结构之一,它将地理空间划分为规则的网格,并为每个网格单元分配一个数值。
四叉树编码可以帮助优化栅格矩阵的存储和处理效率,提高地理数据的压缩比和查询速度。
本文将首先介绍四叉树编码的基本原理和常见的编码方式,包括树的构建和节点的表示方法。
然后,我们将详细讨论栅格矩阵的定义和特点,包括不同分辨率的栅格矩阵和多层次的四叉树结构。
通过将四叉树编码与栅格矩阵相结合,可以实现对地理数据的高效存储和查询。
在结论部分,我们将探讨四叉树编码在栅格矩阵中的具体应用,并总结四叉树编码的优势和局限性。
通过深入研究四叉树编码的栅格矩阵,我们可以更好地理解和应用这一方法,为地理信息系统的设计和开发提供参考和指导。
总之,本文旨在阐述四叉树编码在栅格矩阵中的应用,通过探讨其原理和特点,帮助读者理解和应用这一方法。
希望本文能为相关领域的研究人员和开发人员提供有益的信息和思路。
1.2文章结构文章结构部分的内容如下:1.2 文章结构本文分为引言、正文和结论三个部分。
引言部分主要包括三个小节:概述、文章结构和目的。
在概述中,将介绍四叉树编码和栅格矩阵的概念,以及它们在计算机科学和图像处理领域的重要性。
文章结构小节将简要介绍本文的整体架构和各个部分的内容。
目的小节则说明本文的写作目的和意义,以期给读者一个清晰的阅读导向。
正文部分分为两个小节:四叉树编码和栅格矩阵。
在四叉树编码小节中,将详细介绍四叉树编码的原理、特点和应用领域。
同时,也会探讨四叉树编码在栅格矩阵中的具体应用,以及其在栅格数据处理中的作用。
在栅格矩阵小节中,将介绍栅格矩阵的定义、数据结构和基本操作。
此外,还会讨论栅格矩阵与四叉树编码之间的关系,以及它们在地理信息系统中的应用案例。
栅格数据存储压缩编码方法
栅格数据存储压缩编码方法(3)、块式编码(4)、四叉树编码(1)、链式编码:由某一原点开始并按某些基本方向确定的单位矢量链。
基本方向可定义为:东=0,南=3,西=2,北=1等,还应确定某一点为原点。
(2)、行程编码:只在各行(或列)数据的代码发生变化时依次记录该代码以及相同代码重复的个数,即按(属性值,重复个数)编码(3)、块式编码:块式编码是将行程编码扩大到二维的情况,把多边形范围划分成由像元组成的正方形,然后对各个正方形进行编码。
(4)、四叉树编码而块状结构则用四叉树来描述,将图像区域按四个大小相同的象限四等分,每个象限又可根据一定规则判断是否继续等分为次一层的四个象限,无论分割到哪一层象限,只要子象限上仅含一种属性代码或符合既定要求的少数几种属性时,则停止继续分割。
否则就一直分割到单个像元为止。
而块状结构则用四叉树来描述。
按照象限递归分割的原则所分图像区域的栅格阵列应为2n2n(n为分割的层数)的形式。
下面就着重介绍四叉树编码。
直接栅格编码是最简单最直观而又非常重要的一种栅格结构编码方法,通常称这种编码为图像文件或栅格文件。
直接编码就是将栅格数据看作一个数据矩阵,逐行(或逐列)逐个记录代码,可以每行都从左到右逐象元记录,也可奇数行从左到右,而偶数行由右向左记录,为了特定目的还可采用其它特殊的顺序,右图直接编码可表示为矩阵:四叉树编码又称为四分树、四元树编码。
它是一种更有效地压编数据的方法。
它将2n2n像元阵列的区域,逐步分解为包含单一类型的方形区域,最小的方形区域为一个栅格像元。
图像区域划分的原则是将区域分为大小相同的象限,而每一个象限又可根据一定规则判断是否继续等分为次一层的四个象限。
其终止判据是,不管是哪一层上的象限,只要划分到仅代表一种地物或符合既定要求的几种地物时,则不再继续划分否则一直分到单个栅格像元为止。
所谓四叉树结构,即把整个2n2n像元组成的阵列当作树的根结点,n为极限分割次数,n+1为四分树的最大高度或最大层数。
四叉树编码的原理
四叉树编码的原理四叉树编码是一种基于四叉树数据结构的编码方法,用于将离散的二维或三维数据转换为紧凑的表示形式。
在四叉树编码中,原始数据被逐步划分成四个象限,每个象限对应树的一个节点,并且每个节点可以进一步划分为四个象限。
该过程一直持续下去,直到达到满足一些停止条件为止。
1.数据划分:将原始数据空间划分为四个象限,即左上、右上、左下和右下四个子空间。
这样每个象限对应一个节点,初始时整个数据空间即为根节点。
2.判断停止条件:在划分过程中,需要判断是否满足停止条件。
停止条件可以根据需要来定义,常见的停止条件有:达到指定精度级别、区域内数据数量小于等于一些阈值、区域内数据的方差小于等于一些阈值等。
3.编码存储:对于每个节点,可以使用二进制或其他编码方法将该节点的信息进行存储。
常见的编码方式有:使用一个二进制位表示是否存在子节点,使用一个二进制字符串表示节点的象限等。
4.递归划分:如果不满足停止条件,则对当前节点所代表的子空间进行递归划分,即将当前节点划分为四个子节点,并对每个子节点执行步骤1-4通过以上步骤,原始数据空间将被逐步划分成若干个子空间,并对应存储为一棵四叉树。
根据实际需求,可以选择不同的停止条件和编码方式,以达到合理的数据表示和存储效率。
1.紧凑性:四叉树编码将大规模离散数据转换为紧凑的表示形式,可以有效减少存储空间的占用。
2.数据查询效率高:四叉树编码可以通过树结构快速定位到感兴趣的数据节点,提高数据的查询效率。
3.空间适应性好:四叉树编码可以根据数据的空间分布特点进行不规则的划分,适应各种数据的特征。
4.隐式多分辨率:通过停止条件的设定,四叉树编码可以实现多分辨率表示,即不同精度级别的数据可以通过同一棵四叉树进行表示。
然而,四叉树编码也存在一些限制和挑战:1.数据分布不均匀:如果数据分布不均匀,划分结果可能导致一些节点过大或者过小,影响查询的效率和存储的紧凑性。
2.存储空间需求不确定:由于四叉树编码是根据停止条件进行划分的,当停止条件不同或者随着数据的更新而改变时,存储空间的需求也会相应发生变化。
2.第二章空间数据结构(6学时)(四叉树编码)解析
represent: an area feature a closed ring of lines
8 1 1 1 1 1 2 2 2
2.链式编码(Chain Codes)
+
又称弗里曼链码 (Freeman 1961), 多边形边界可以表示 为由某一原点开始并 按某些基本方向确定 的单位矢量链。基本 方向:东=0,南=3, 西=2,北=1
1 (N)
2 (W)
0 (E)
3 (S)
02 1 02 1 03 3 03 32 2 3 24 3 0 3 05 1 0 12 0 12 02 33 0 32 22 3 2 3 22 1 24 3 2 3 22 12 2 12 22 1 2 13
以像元为序。不同层上同一像元位置上的各属性值表示为一 个列数组。 以层为基础。每一层又以像元为序记录它的坐标和属性值。 以层为基础。但每一层内以多边形为序记录多边形的属性值 和充满多边形的各像元的坐标。
栅格数据文件
像元1 X坐标 层1
栅格数据文件
像元1 像元2 X,Y,属性值 X,Y,属性值 … X,Y,属性值
把2n×2n象元组成的阵列当作树根,树的高度为n,每 个节点分别代表南西(SW)、南东(SE)、北西(NW)、 北东(NE)。四个分支中要么是树叶、树叉。树叶代表一 种代码。树叉继续再分。
对一幅2n×2n的栅格阵列,最大深度为n,层次可能为0,1,…,n
(3)线性四叉树编码: (马里兰大学的GIS系统)
有毒气体扩散分析
基于对象(object-based)的模型强调了离散对 象,将研究的整个地理空间看成一个空间域,地理实 体和现象作为独立的对象分布在该空间域中,根据 它们的边界线以及它们的组成或者与它们相关的其 它对象,可以详细地描述离散对象。 任何现象,无论大小,都可以被确定为一个对 象(Object),且假设它可以从概念上与其邻域现象 相分离。在欧氏(Euclidean)空间中主要有点对象、 线对象、多边形对象和体。 composed of identifiable entities Discrete data. Examples roads,rivers, land parcels,island boreholes
四叉树c++实现代码
一个四叉树的实现代码class QuadTreeCode{public:vector<int> m_Numbers;/*判断两个四叉树码是否相等*/bool operator ==( QuadTreeCode& tempTree ){if ( m_Numbers.size()!=tempTree.m_Numbers.size() ) {return false;}else{for ( int i=0; i<m_Numbers.size(); i++ ){if ( m_Numbers[i]!=tempTree.m_Numbers[i]){return false;}}}return true;}/*返回四叉树码的长度*/int GetLength(){return m_Numbers.size();}int operator[](int Index){return m_Numbers[Index];}};enum ChildType{UL = 0,UR = 3,LL = 1,LR = 2};template<class T>class QuadTreeNode{public:T *m_pData;QuadTreeNode *m_pUpperLeft,*m_pUpperRight,*m_pLowerLeft,*m_pLowerRight;QuadTreeCode m_Code; //节点在树中位置的编码QuadTreeNode (){m_pData = NULL;m_pUpperLeft = m_pUpperRight = m_pLowerLeft = m_pLowerRight = NULL;}~QuadTreeNode (){delete m_pData;}/*返回子成员的地址*/QuadTreeNode ** GetChild( ChildType ctype ){switch( ctype ){case ChildType::UL:return &m_pUpperLeft;break;case ChildType::UR:return &m_pUpperRight;break;case ChildType::LL:return &m_pLowerLeft;break;case ChildType::LR:return &m_pLowerRight;break;}}template<class T>class QuadTree{public:int m_nTreeDepth; //树的深度QuadTreeNode<T> *m_pHeadNode; //树的头部QuadTree(){m_nTreeDepth = 0;m_pHeadNode = NULL;}~QuadTree(){void (QuadTree::*func)(QuadTreeNode<T> *) ;func = &QuadTree::DestroyNode;PostOrderOperation( m_pHeadNode, func );}/*后序遍历方式操作四叉树*/void PostOrderOperation( QuadTreeNode<T> * ptempNode, void (QuadTree<T>::*NodeOp)( QuadTreeNode<T> * ) ){if( ptempNode!=NULL ){PostOrderOperation( ptempNode->m_pLowerLeft, NodeOp );PostOrderOperation( ptempNode->m_pLowerRight, NodeOp );PostOrderOperation( ptempNode->m_pUpperLeft, NodeOp );PostOrderOperation( ptempNode->m_pUpperRight, NodeOp );(this->*NodeOp) ( ptempNode );}}void DestroyNode( QuadTreeNode<T> * ptempNode ){delete ptempNode;}/*创建树枝*/void CreateBranch( QuadTreeNode<T>**ppNode , int TreeDepth, int CurrentDepth )if( CurrentDepth>TreeDepth ){return;}else{QuadTreeNode<T> *pNewNode = new QuadTreeNode<T>;*ppNode = pNewNode;QuadTreeNode<T> **pTempNode;CreateBranch( pNewNode->GetChild(ChildType::UL), TreeDepth, CurrentDepth+1 );CreateBranch( pNewNode->GetChild(ChildType::UR), TreeDepth, CurrentDepth+1 );CreateBranch( pNewNode->GetChild(ChildType::LL), TreeDepth, CurrentDepth+1 );CreateBranch( pNewNode->GetChild(ChildType::LR), TreeDepth, CurrentDepth+1 );}}/*按照四叉树码进行操作*/bool OperateNodeByCode( QuadTreeCode code, void (*Op)( QuadTreeNode<T> *) ) {QuadTreeNode* ptempNode = m_pHeadNode;for( int i=0; i<code.GetLength(); i++ ){ptempNode = ptempNode->GetChild( code[i] );if( ptempNode==NULL )return false;}Op( ptempNode );return true;}/*近创建内存结构,数据内容并未赋值*/void CreateTree( int TreeDepth ){m_nTreeDepth = TreeDepth;CreateBranch( &m_pHeadNode, TreeDepth, 0);}//virtual void CreateNode( QuadTreeNode<T> * ptempNode ) const = 0;};。
GIS原理课件4.8四叉树编码
36
2
37
2
38
0
39
0
栅格数据
00
0
00 00
0
00 22 00 00 00
11
1
11 22
2
22 22 00 00 00
44
4
44 44
4
44 44 44 44 44
44
4
44 44
4
44 44 44 44 44
将按照二M进D码制顺的序行,列检号查相两邻两四交个叉单元的属性值, 再相同将则其合转并换,为存储十最进小制M数D码及属性值,不同则存储所有单元。
MD码 0 4 8 12 16 20 24 28 32 33 34 35 36 37 38
……
属性值
0 1 0 2 4 4 4 4 2 2 0 0 2 2 0 ……
栅格数据
00
0
00 00
0
00 22 00 00
0
00
11
1
11 22
2
22 22 00 00
0
00
44
4
44 44
4
44 44
4
44 44
MD码 0 4 8 12 16 32 33 34 35 36 37
…… 48 52 56 60
属性值
0 1 0 2 4 2 2 0 0 2 2 …… 4 4 4 4
栅格数据
00
0
00 00
0
00 22 00 00
0
00
11
1
11 22
2
22 22 00 00
0
00
4444
44
4444
线性四叉树快速动态编码及其实现
结点的编码( 即地址码) 遵循一定的规则, 隐含了 叶结点 的位置信息和 大小。地址码 可以按四进
制、八进制数编码, 但为了使用方便, 通常采用十 进制数的 Morton 码( 简称 M D 码) 。对 8 8 栅格 数据, 其 MD 码编码规则如表 1 所示。 1. 1 线性表法[ 2]
2. 1. 1 提取格网单元 按 MD 码的顺序, 依次从栅格数据中以 2 2
的窗口( 如图 1 中栅格数据上的粗线框所示) 提取 4 个格网单元的属性值, 这 4 个单元所对应的栅
格数据的行列号由 M D 码反 求。由于 M D 码是 由行 号 和列 号的 二 进制 数 两两 交 叉组 合 的结 果[ 3] , 因此可以由 M D 码的二进制数采用位运算 规则分解出行列号( 如图 2 所示) , 其中奇位和偶
从表 1 可以看出, MD 码正是自下而上合并 生成四叉树过程的顺序编号, 按自然数顺序的线 性表扫描即可产生四叉树。事先开辟一个大小为 2n 2n 的 一 维 数 组A ( 需 要 2n 2n 字 节 的 内
存) , 按行号顺序对栅格数据进行扫描, 把行、列号 转换成伪码, 由伪 码计算对应的 M D 码, 并将格 网属性值直接赋给以 MD 码 为下标的 A 数组单 元, 即 A ( MD ) = V ( i , j ) 。当对所有的格网单元 遍历完后, A 数组各单元均得到相应的 值, 且其 下标恰为升序 的 MD 码。这种方法 与线性表法 相比, 减少了 M D 码的排 序过程, 在 运行速度上 有所提高, 但其他缺点依然存在, 仍然需要大量的 内存和运行时间。
对栅格数据按行顺序进行扫描, 顺序计算每 个格网单元的 MD 码, 这需要开辟大小为5 2n 2n 字节的线性表, 用于存 储格网单元的 M D 码 及其属性。在提取格网单元的属性值和计算格网
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
if(fi!=curary[i]) {
break; }
} if(i==arysize*arysize) {
printf("%d,%f",level,fi); printf("\n"); return; }
二、 实现
本程序实现将一个(2������ ∗ 2������,k>1,不足则补网)数组(一维数组表示),打印 出每个字块的等级和值。
//实现四叉树编码
#include"stdio.h" void Qutree(int arysize,int level,float curary[] )//arysize 表示矩阵长度,level 表示等级,curary[]表示当前矩阵 {
}
level++; Qutree(arysize,level,ary1); Qutree(arysize,level,ary2); Qutree(arysize,level,ary3); Qutree(arysizein() {
//float aa[16]={1,1,2,2,1,1,3,3,4,2,1,2,3,4,3,4}; //Qutree(4,0,aa);
float aa[64]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1};
Qutree(8,0,aa); return 0;
}
参考资料:地理信息系统原理与算法(吴立新,史文中编著)
四叉树编码
一、 原理
四叉树编码的基本思想是:首先将把一副图像或栅格地图(2������ ∗ 2������,k>1,不足则 补网)等分成四个一级字块,顺序为左上,右上,左下,右下;然后逐块检查其 中所有格网属性值(或灰度值),若相同,则该字块不再分;若不同,则将该子 块进一步分成四个二级子块;如此递归地分割,直到每个子块的属性或灰度均相 等为止。
ary2[i*arysize+j]=curary[i*(arysize*2)+(arysize+j)]; //左下
ary3[i*arysize+j]=curary[(arysize+i)*(arysize*2)+j]; //右下
ary4[i*arysize+j]=curary[(arysize+i)*(arysize*2)+(arysize+j)]; }
else
{ arysize/=2; float *ary1=new float[arysize*arysize]; float *ary2=new float[arysize*arysize]; float *ary3=new float[arysize*arysize]; float *ary4=new float[arysize*arysize]; for(i=0;i<arysize;i++) { for(int j=0;j<arysize;j++) { //左上 ary1[i*arysize+j]=curary[i*(arysize*2)+j]; //右上