国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

OSGB格式三維模型投影坐標轉(zhuǎn)換方法

2022-04-06 06:16程曉光王婉秋陸泉源
測繪工程 2022年2期
關(guān)鍵詞:數(shù)組頂點投影

程曉光,王婉秋,陸泉源

(飛燕航空遙感技術(shù)有限公司,南京 210001)

目前,基于傾斜攝影測量技術(shù)生產(chǎn)的三維模型已成為主要的測繪產(chǎn)品之一,其生產(chǎn)步驟包括密集點云提取、網(wǎng)格面模型構(gòu)建、紋理映射、成果編輯、成果導(dǎo)出等[1],較為復(fù)雜。ContextCapture[2]是目前傾斜攝影測量領(lǐng)域主要的三維建模軟件之一[1, 3],而OpenSceneGraph Binary(OSGB)是ContextCapture導(dǎo)出三維模型時最常用的格式之一,由開源三維圖形工具包OpenSceneGraph[4](OSG)推出,屬于二進制文件格式,帶有嵌入式鏈接紋理數(shù)據(jù),允許以細節(jié)層次(Level Of Detail,LOD)技術(shù)進行多級金字塔顯示[4]。

三維模型使用的空間參考系統(tǒng)以投影坐標系居多。根據(jù)國家標準[5-8],在基本比例尺地形圖和正射影像地圖中,大地基準采用2000國家大地坐標系,高程基準主要采用1985國家高程基準,除1∶1 000 000外的其它比例尺的投影方法均為3°或6°分帶的高斯-克呂格投影。此外,各大城市和地區(qū)還建立了地方獨立坐標系,目的是將高程歸化與投影變形的影響控制在微小范圍內(nèi),保證城市范圍內(nèi)長度變形最小,以滿足當(dāng)?shù)匾?guī)劃建設(shè)需要[9]。大多數(shù)地方獨立坐標系是在1954年北京坐標系或1980年西安坐標系的基礎(chǔ)上利用高斯-克呂格投影進行改化后建立的。常見改化包括將中央子午線移至測區(qū)中央,將投影面改為測區(qū)平均高程面、對原點縱橫坐標進行偏移等[9]。在三維模型交付時,除了國家標準投影坐標系外,還經(jīng)常需要以地方獨立坐標系交付。

使用三維建模軟件在不同投影坐標系下各生產(chǎn)一遍三維模型會造成巨大的工作量,且模型間可能存在偏差。如果ContextCapture在輸出模型時選擇的投影坐標系與空三使用的坐標系基于不同橢球體,則輸出模型的坐標易有較大誤差。有商業(yè)軟件可對三維模型進行投影坐標轉(zhuǎn)換,但轉(zhuǎn)換后的模型經(jīng)常存在紋理丟失、顯示閃爍等問題。

針對ContextCapture導(dǎo)出的OSGB格式的三維模型的投影坐標轉(zhuǎn)換問題,文中分析OSGB格式的三維模型的目錄和文件結(jié)構(gòu),提出一種簡單高效的投影坐標轉(zhuǎn)換方法,先使用OSG獲得待轉(zhuǎn)換坐標,再進行坐標轉(zhuǎn)換,最后利用文件坐標數(shù)據(jù)替換法保存三維模型,并給出示例代碼。該方法擴展性強,轉(zhuǎn)換后的模型無紋理丟失、無變形、無閃爍。

1 OSGB格式模型的目錄和文件結(jié)構(gòu)

在ContextCapture的生產(chǎn)項目定義中設(shè)置輸出格式為OSGB,劃分瓦片(Tile),使用LOD技術(shù),則輸出的三維模型存儲文件夾的結(jié)構(gòu)見圖1。Data文件夾下為各瓦片的子文件夾,每個子文件夾存儲該瓦片不同金字塔級別的OSGB文件,其中一個OSGB文件和子文件夾同名。但是該模式并不便于模型瀏覽。為此,一種常見的做法是在三維模型存儲文件夾下,額外放置S3C文件以對構(gòu)成場景的瓦片文件進行索引,方便瀏覽顯示。

圖1 OSGB格式的三維模型的目錄結(jié)構(gòu)

為降低內(nèi)存和磁盤使用,OSGB文件常采用4字節(jié)長度(單精度)而非8字節(jié)長度(雙精度)的浮點數(shù)來存儲頂點坐標。對中國境內(nèi)的高斯-克呂格投影來說,如果坐標以m為單位,則整數(shù)部分常會有6位或7位,但單精度浮點數(shù)只能保證7位十進制有效數(shù)字[10]。如果在OSGB文件中存儲頂點原始投影坐標,則容易造成坐標小數(shù)部分有效位數(shù)不夠。為此,在采用投影坐標系的情況下,OSGB文件一般對頂點坐標做偏移,以保證小數(shù)點后有足夠的有效數(shù)字。坐標偏移量存儲在metadata.xml的SRSOrigin標簽中。在metadata.xml中,投影坐標系信息存儲在SRS標簽,支持歐洲石油調(diào)查組織[11](European Petroleum Survey Group,EPSG)定義的坐標系編碼或眾知文本(Well-Known Text,WKT)。

單個OSGB文件存儲金字塔某級在特定空間范圍內(nèi)的模型,其基于OSG體系的典型組織結(jié)構(gòu)見圖2。下文如無特殊說明,則OSG類的默認命名空間是osg。位于金字塔最底層的模型的根節(jié)點為一個Geode類對象;利用四叉樹或八叉樹等[12]技術(shù)做模型分割的根節(jié)點為一個Group類對象;除最底層外,未做分割的模型的根節(jié)點為一個PagedLOD類對象。這其中涉及到的主要節(jié)點類之間的繼承關(guān)系見圖3。

圖2 典型OSGB文件的組織結(jié)構(gòu)

圖3 主要節(jié)點類之間的繼承關(guān)系(箭頭起點為父類,終點為子類)

2 投影坐標轉(zhuǎn)換方法

對OSGB格式的三維模型進行投影坐標轉(zhuǎn)換,可以先對模型頂點做坐標轉(zhuǎn)換,再重新映射紋理,最后保存模型到文件。但該方法非常復(fù)雜,實現(xiàn)難度大。最簡單直觀的思路是直接將OSGB文件中的投影坐標替換為轉(zhuǎn)換并偏移后的坐標,并修改metadata.xml和S3C文件中的坐標系及坐標偏移量信息。

2.1 待轉(zhuǎn)換坐標獲取

在Geometry類對象的屬性中,一般只有頂點數(shù)組含有需要轉(zhuǎn)換的坐標數(shù)據(jù)。PagedLOD類對象根據(jù)視點到物體中心的距離決定顯示哪種精細度的模型,而確定物體中心的方法由屬性“中心模式”給出,既可以是包圍球中心,也可以是用戶自定義中心,還可以是二者的結(jié)合。對于后兩種模式,需要對用戶自定義中心的坐標進行轉(zhuǎn)換,否則可能會造成模型顯示時被誤裁剪。文中定義三維模型需要轉(zhuǎn)換的坐標包括Geometry類對象的頂點坐標和PagedLOD類對象的用戶自定義中心坐標。

(1)

2.2 投影坐標轉(zhuǎn)換

將投影坐標轉(zhuǎn)換分為相同橢球體的投影坐標轉(zhuǎn)換和不同橢球體間的投影坐標轉(zhuǎn)換。前者的轉(zhuǎn)換框架可見圖4。后者采用七參數(shù)法[9]進行轉(zhuǎn)換,其中未假設(shè)3個旋轉(zhuǎn)角很小,轉(zhuǎn)換框架可見圖5。轉(zhuǎn)換前后高程坐標不變。

圖4 相同橢球體的投影坐標轉(zhuǎn)換框架

圖5 不同橢球體間的投影坐標轉(zhuǎn)換框架

2.3 轉(zhuǎn)換模型保存

(2)

在坐標轉(zhuǎn)換和偏移完成后,需要將轉(zhuǎn)換后模型保存到OSGB文件。理論上,可以調(diào)用osgDB::Registry類實例的writeNode函數(shù)將模型保存為OSGB文件。但這樣做存在格式兼容性風(fēng)險。如果ContextCapture不能支持所有版本的OSGB格式,則該方法生成的OSGB文件可能不能被ContextCapture準確讀取。

一種簡單的方法是直接對原始OSGB文件進行坐標數(shù)據(jù)替換。在OSGB文件的數(shù)據(jù)流中,一個Geometry類對象的頂點坐標連續(xù)放置,可被視為一個浮點型數(shù)組,而PagedLOD類對象的用戶自定義中心坐標可被視為一個具有3個元素的浮點型數(shù)組。設(shè)轉(zhuǎn)換前的數(shù)組為Asrc,存儲了N個三維坐標,元素數(shù)目為3N,對應(yīng)的轉(zhuǎn)換和偏移后的數(shù)組為Adst,則以字節(jié)為單位的Asrc和Adst的大小nLength均為12N(單精度浮點型)或24N(雙精度浮點型)。通過在文件數(shù)據(jù)流中比較長度為nLength的連續(xù)內(nèi)存的值是否和Asrc相同來確定數(shù)據(jù)替換位置,在找到替換位置后,用Adst的值覆蓋原始數(shù)據(jù)。

3 實現(xiàn)方法

利用C++和開源軟件開發(fā)OSGB模型的投影坐標轉(zhuǎn)換軟件,其中Qt[13]用作編程框架,OpenSceneGraph 3.7[4]用于三維模型讀取,PROJ 6.0[14]用于地圖投影,GDAL 3.0[15]用于坐標系設(shè)置,Eigen3[16]用于矩陣運算。

3.1 坐標轉(zhuǎn)換流程

圖 6為設(shè)計的坐標轉(zhuǎn)換流程。

圖6 模型投影坐標轉(zhuǎn)換流程

3.2 轉(zhuǎn)換前模型解析

3.2.1 源坐標系解析

如果模型源坐標系以EPSG編碼的形式提供,可調(diào)用OGRSpatialReference類的importFromEPSG函數(shù)導(dǎo)入編碼對應(yīng)的坐標系;如果模型源坐標系以WKT文本的形式提供,可調(diào)用OGRSpatialReference類的importFromWkt函數(shù)導(dǎo)入WKT對應(yīng)的坐標系。

3.2.2 OSGB文件解析

要讀取OSGB文件中的模型,可先調(diào)用osgDB::readNodeFile函數(shù)獲得Node類型的模型對象。之后,要獲取待轉(zhuǎn)換坐標,需要對OSG定義的類NodeVisitor進行派生并重寫相應(yīng)的apply虛函數(shù)。示例代碼如下:

class CTVisitor: public NodeVisitor {

public:

virtual void apply(Geode &node);

virtual void apply(Group &node);

}

對Geometry類對象的解析可放在void CTVisitor::apply(Geode &node)中,示例如下:

for(int n = 0; n < node.getNumDrawables(); n++){

Drawable *pDb = node.getDrawable(n);

if(pDb->className()== string("Geometry")){

ref_ptr pGm =(Geometry*)pDb;

//pVt為頂點坐標數(shù)組指針

Vec3Array *pVt =dynamic_cast

(pGm->getVertexArray().get());

}

}

traverse(node);

如果模型采用雙精度浮點數(shù)存儲頂點坐標,則需要將上述代碼中的Vec3Array替換為Vec3dArray。對PagedLOD類對象的解析可放在void CTVisitor::apply(Group &node)中,示例如下:

if(node.className()== string("PagedLOD")){

PagedLOD lod =(PagedLOD)node;

if((lod.getCenterMode()== LOD::USER_ DEFINED_CENTER)||(lod.getCenterMode()== LOD::UNION_OF_BOUNDING_SPHERE_AND _USER_DEFINED)){

//cent為用戶自定義中心坐標

Vec3 cent = lod.getCenter();

}

}

traverse(node);

3.3 投影坐標轉(zhuǎn)換

3.3.1 大地坐標與投影坐標間的轉(zhuǎn)換

大地坐標與投影坐標間的轉(zhuǎn)換采用pj_transform函數(shù),該函數(shù)定義如下:

int pj_transform(projPJ src, projPJ dst, long pt_count, int pt_offset, double *x, double *y, double *z)

其中,src為源坐標系對象,dst為目標坐標系對象,pt_count為待轉(zhuǎn)換點數(shù),pt_offset為首個待轉(zhuǎn)換點在數(shù)組中的序號,x,y,z分別為存儲三維坐標的數(shù)組的地址。在PROJ中,大地和投影坐標系對象需用PROJ字符串定義。大地坐標系的PROJ字符串為:

QString("+proj=longlat +ellps=%1 +no_defs +type= crs").arg(strEllps)

高斯-克呂格投影坐標系的PROJ字符串為:

QString("+proj=tmerc +lat_0=0 +lon_0=%1 +k=1 +x_0=%2 +y_0=%3 +ellps=%4 +units=m +no_defs +type=crs").arg(dCentLon).arg(dFalseEast).arg(dFalseNorth).arg(strEllps)

其中,strEllps為大地坐標系使用的橢球體的字符串,1954年北京坐標系是“krass”,1980年西安坐標系是“IAU76”,2000國家大地坐標系是“GRS80”;dCentLon為中央子午線以角度制表示的經(jīng)度,dFalseEast為以m為單位的東偏,dFalseNorth為以m為單位的北偏。之后,調(diào)用pj_init_plus函數(shù),輸入?yún)?shù)為坐標系的PROJ字符串,即可獲得projPJ類型的坐標系對象。

3.3.2 大地坐標與空間直角坐標間的轉(zhuǎn)換

從大地坐標轉(zhuǎn)換到空間直角坐標采用pj_geodetic_to_geocentric函數(shù),該函數(shù)定義如下:

int pj_geodetic_to_geocentric(double a, double es, long pt_count, int pt_offset, double *x, double *y, double *z)

從空間直角坐標轉(zhuǎn)換到大地坐標采用pj_geocentric_to_geodetic函數(shù),該函數(shù)定義如下:

int pj_geocentric_to_geodetic(double a, double es, long pt_count, int pt_offset, double *x, double *y, double *z)

其中,a為橢球體半長軸,es為第一偏心率平方,pt_count為待轉(zhuǎn)換點數(shù),pt_offset為首個待轉(zhuǎn)換點在數(shù)組中的序號,x,y,z分別為存儲三維坐標的數(shù)組的地址。

3.4 轉(zhuǎn)換后模型生成

在生成轉(zhuǎn)換后模型時,需要確保轉(zhuǎn)換前后目錄結(jié)構(gòu)不變,OSGB文件名和相對路徑不變。

3.4.1 metadata.xml生成

在轉(zhuǎn)換后模型的metadata.xml中,對于EPSG已定義的投影坐標系,可將SRS標簽值設(shè)置為坐標系的EPSG編碼;對于EPSG未定義的投影坐標系,可先調(diào)用OGRSpatialReference類的SetWellKnownGeogCS函數(shù)設(shè)置大地坐標系,再調(diào)用SetTM函數(shù)設(shè)置中央子午線經(jīng)度、中央緯線緯度、中央子午線縮放因子、東偏、北偏等參數(shù),調(diào)用SetProjCS函數(shù)設(shè)置坐標系名稱,調(diào)用exportToWkt函數(shù)獲得坐標系的WKT,最后將SRS標簽值設(shè)置為WKT。SRSOrigin標簽值為Δxdst,Δydst,Δzdst。

3.4.2 OSGB文件生成

設(shè)Asrc的數(shù)組指針為pSrc,Adst的數(shù)組指針為pDst,以字節(jié)為單位的OSGB文件大小為nOsgbSize。先將轉(zhuǎn)換前的OSGB文件全部讀入unsigned char類型、大小為nOsgbSize的數(shù)組中。設(shè)數(shù)組指針為pszOsgb,則坐標數(shù)據(jù)替換的示例代碼如下:

for(int n = 0; n < nOsgbSize-nLength; n++){

int b = memcmp(pszOsgb + n, pSrc, nLength);

if(b == 0){

memcpy(pszOsgb + n, pDst, nLength);

break;

}

}

最后將pszOsgb內(nèi)的數(shù)據(jù)保存到轉(zhuǎn)換后目錄下的OSGB文件。

3.4.3 S3C文件坐標系設(shè)置

雖然S3C文件也存儲坐標系信息,但由于新版S3C文件的格式已做加密,難以用編程的方法修改其坐標系信息。因此,先將轉(zhuǎn)換前的S3C文件復(fù)制到轉(zhuǎn)換后目錄下,再利用CC_S3CComposer.exe將S3C文件中的坐標系信息替換為metadata.xml中的坐標系信息。

4 軟件實例

圖7是軟件界面,支持中國常用大地坐標系基礎(chǔ)上的高斯-克呂格投影;支持自定義和自動計算輸出坐標偏移量;支持手動和文件輸入橢球體轉(zhuǎn)換七參數(shù)。

圖7 軟件界面

在Intel Core i5-2300的CPU、24GB內(nèi)存的臺式機上,軟件將具有6個瓦片、1179個OSGB文件的三維模型從2000國家大地坐標系基礎(chǔ)上120°中央子午線的投影坐標系轉(zhuǎn)換到1954年北京大地坐標系基礎(chǔ)上120.75°中央子午線的投影坐標系,耗時20.214 s,平均單個OSGB文件耗時17 ms。在利用CC_S3CComposer.exe更新S3C文件的坐標系信息后,可以用ContextCapture Viewer[1]打開轉(zhuǎn)換后的模型,幾何無變形,紋理無缺失,顯示無閃爍。為了對比,由人工在目標坐標系下重新生產(chǎn)三維模型。通過在軟件轉(zhuǎn)換后模型和人工重新生產(chǎn)的模型上選取同名特征點并查詢其坐標,發(fā)現(xiàn)坐標一致。

5 結(jié)束語

文中提出的投影坐標轉(zhuǎn)換方法簡單高效,對OSGB文件的格式要求不高,不受是否采用LOD技術(shù)、有無紋理貼圖、紋理壓縮比例、切塊方式等因素的影響。由于OSG基本支持所有主流的三維模型格式,所以文中方法容易擴展到其它二進制的三維模型格式。此外,坐標數(shù)據(jù)替換法也適用于其它需要對模型坐標進行修改的情況。

文中方法未修改Geometry類對象的法向量,但理論上,修改頂點坐標之后需要重新計算法向量。雖然在第4節(jié)例子中不更新法向量在視覺上沒有明顯影響,但更新模型法向量仍是一個改進方向。

猜你喜歡
數(shù)組頂點投影
全息? 全息投影? 傻傻分不清楚
JAVA稀疏矩陣算法
過非等腰銳角三角形頂點和垂心的圓的性質(zhì)及應(yīng)用(下)
過非等腰銳角三角形頂點和垂心的圓的性質(zhì)及應(yīng)用(上)
基于最大相關(guān)熵的簇稀疏仿射投影算法
JAVA玩轉(zhuǎn)數(shù)學(xué)之二維數(shù)組排序
找投影
找投影
更高效用好 Excel的數(shù)組公式
尋找勾股數(shù)組的歷程
新闻| 从江县| 盖州市| 安仁县| 电白县| 胶州市| 弋阳县| 林周县| 龙井市| 太保市| 新和县| 襄城县| 固原市| 泰和县| 吴堡县| 延川县| 九台市| 修水县| 宁国市| 西峡县| 建德市| 江西省| 上饶县| 辉县市| 垣曲县| 永昌县| 丽水市| 金川县| 尉犁县| 沾化县| 大同县| 封开县| 三原县| 佳木斯市| 吉隆县| 德兴市| 永州市| 荆州市| 栖霞市| 肥东县| 沧州市|