1. 程式人生 > >SuperMap iObjects .NET 製作2.5D資料詳解(一)

SuperMap iObjects .NET 製作2.5D資料詳解(一)

作者:為夢齊舞

目前騰訊搜搜、百度地圖等多家地圖廠商都已推出2.5D地圖檢視模式,只要把檢視級別縮放到較小的區域,就可以看到該區域樓體的形狀,使用者可以由此更好的辨認位置,確認自己的出行目的地,如下圖所示:
這裡寫圖片描述

很多使用者都會有這樣的疑問,在SuperMap中我們能否製作出類似百度的2.5D地圖呢?答案都是肯定的,下面就讓我們來一步一步瞭解SuperMap iObjects .NET 製作2.5D資料的步驟。

一、 資料準備:我們首先準備一份小區的向量資料。
這裡寫圖片描述

二、 製作頂面:根據圖1和圖2的對比,我們不難發現2.5D資料只是將資料向Y方向偏移了一定的距離, 那讓我們來直接平移一下,看一下效果。
這裡寫圖片描述


我們可以發現直接平移後的資料和百度地圖還是有一定差距的,也就是兩份資料中間的部分缺失掉了,如果我們把中間的部分補起來,是否就可以達到和百度地圖一樣的效果呢?

三、 製作側面:那麼現在問題來了,如何能夠生成中間部分的資料呢?我們不難發現,其實這兩份資料有一個共同的特點,就是每個點的座標只有Y方向有特定數值的拉高,X座標不變,我們可以根據這個特點,向上構造側面,取底面的第一個和第二個點,我們把它命名為A點和B點,以A點為起點,那麼第二個點就是A點Y值拉伸的點A1,第三個點為B點拉伸的點B1,第四個點為B點,按照順時針方向構造點集,生成側面。如下圖:
這裡寫圖片描述
以此類推,生成其他的面片,來構造側面,生成頂面和側面的程式碼如下:
這裡寫圖片描述


其中ati變數為拉伸的高度,生成結果:
這裡寫圖片描述
做到這一步,跟百度地圖的效果已經很相近了,但是如圖6和圖7所示,側面出現了面與面壓蓋的問題,看起來還是存在視覺差異。那麼如何解決這個問題呢?

四、 側面壓蓋:既然小的面片出現了壓蓋,那麼我們直接將面片合併為一個整面,是否可以解決壓蓋問題呢?
這裡寫圖片描述

這裡寫圖片描述

五、 製作稜角:走到這一步,我們發現效果還是不太好,如果每個稜角,能夠標示出來,是否效果還會好一些呢?稜角的提取還是和之前的思路一致,直接使用拉伸前的點和拉伸後的點構造稜角線。
這裡寫圖片描述
雖然稜角線是有了,但是出現了很多多餘的稜角線,從第三步的截圖中我們也可以發現,側面其實也存在很多冗餘的資料,那些資料在頂面的背後,不能被看見,這樣的就是稜角線和側面都存在資料冗餘。

六、 去除冗餘資料:頂面、側面和稜角的關係,大家都能從圖中看出,被頂面包含的稜角和側面其實是我們不需要的;對於側面,我們可以將頂面和側面做擦除運算,對於稜角線,可以使用運算結果和稜角線做相交;這樣就可以解決冗餘資料的問題了,下面我們來看一下程式碼實現和效果。
這裡寫圖片描述

七、合併資料:工作進行到這一步,大致就已經完成了,但是這些資料是由側面、頂面、稜角邊,三份資料組成的,這樣管理資料將會非常頭痛,我們是否可以設法將這三份資料合併為一個數據集來存放呢?那麼問題就又來了,線資料和麵資料怎麼合併啊?我們這時可以將側面轉換為線,然後將結果追加到稜角線中,再拓撲生成面數據集就可以解決以上問題。(PS:這裡不要使用線資料集轉面數據功能,可能結果會出現資料丟失的問題)
這裡寫圖片描述

八、 區分物件型別:接著步驟7的思路,我們是否也有要頂面和側面也合併呢?這時會發現頂面和側面是有一定區別的,就百度地圖來看,他們設定的顏色不一樣,合併後如何解決這個問題呢?我們可以建立一個名稱為isSide的Boolean型別欄位,來標識是底面還是側面,就可以輕鬆解決這個問題了。
這裡寫圖片描述
這裡寫圖片描述

九、效果展示:通過以上的步驟,我們製作的2.5D資料就全部完成了,只需要使用欄位isSide製作專題圖即可。下面我們來看一下最終的效果。
這裡寫圖片描述