近期考虑实现GeoTiff遥感影像的CGCS2000地理坐标系支持了,原本只支持Web墨卡托投影,现在有两种坐标系了必然就涉及到坐标系的识别。
坐标系在技术实现上是个复杂的概念,有很多参数,在GeoTiff中解析出来也少不了麻烦,加上官方的GeoTiff标准规范已经是1995年最后修订了,网上能找到的资料很少,讨论学习的人也非常少,为我的研究学习进一步增加了难度。
在GeoTiff中与空间坐标信息直接相关的有6个标签:
ModelPixelScaleTag、ModelTiepointTag、ModelTransformationTag、GeoKeyDirectoryTag、GeoDoubleParamsTag、GeoAsciiParamsTag
。
其中ModelPixelScaleTag和ModelTiepointTag要同时存在组合使用,ModelTransformationTag跟他们的作用相同但很少使用。
GeoKeyDirectoryTag、GeoDoubleParamsTag、GeoAsciiParamsTag三个标签要同时组合使用。
坐标系转换逻辑
1.通过tiff的标签34735 (87AF.H)、34736 (87BO.H)、34737 (87B1.H)分别读取出GeoKeyDirectoryTag、GeoDoubleParamsTag、GeoAsciiParamsTag三个标签的值
GeoKeyDirectoryTag相当于一个字典目录,记录了本geotiff中包括哪些空间信息,每项空间信息都有一个唯一的标签。根据这个标签可以到GeoDoubleParamsTag或GeoAsciiParamsTag中找到相应标签具体的值。当标签的值很小,只有2个byte的时候也会直接存放在GeoKeyDirectoryTag中以节省空间。
2.跳过GeoKeyDirectoryTag的头部分6个byte,读取出标签个数
GeoKeyDirectoryTag是一个字典目录,前6个byte存放的分别为:版本号(通常为1)、键集修订版本号(通常为1)和键码修订版本号。紧接着2个byte就是标签的数量了。
GeoKeyDirectoryTag数据结构
3.以8byte为一组循环读取GeoKeyDirectoryTag的内容部分
每8个byte为一组标签,根据上一步读取的标签数量不断循环读取。
这8个byte又分为4个部分:KeyID、标记位置、数据数量、值或偏移。
如果“标记位置“值为0,则最后这两个byte就是值,常见编程语言中表示为short类型,在golang中为int16类型。
如果“标记位置“值为34736,则值在GeoDoubleParamsTag的值中。
如果“标记位置“值为34736,则值在GeoAsciiParamsTag的值中,每个值用”|“分割,所以取出值后最后一个|可以丢弃。
每个标签的数据结构
4.解析坐标系epsg编号
虽然GeoTiff中有很多表示坐标信息的参数,但能唯一表达坐标系的通常采用epsg编号,其他字符串有很多种表达方式,很复杂不便于识别和记忆。