簡體   English   中英

Cesium如何在縮放/縮放時縮放多邊形以匹配緯度位置

[英]Cesium how to scale a polygon to match Lat-Lon positions while zoom-in/zoom-out

我正在尋找Cesium Guru,以尋求所需的幫助。 我是Cesium的新手,但是我一直在使用教程和繼承的一些現有代碼。

在我的Cesium應用中,輸入我的地址,然后視圖放大到我的街道。 好極了! 然后將其放大,以便可以在房屋周圍繪制多邊形。 現有的代碼可以很好地做到這一點。 但是, 當我縮小然后再次放大時,我的多邊形不會一直保持到我家的Lat-Lon位置

Cesium是否包含將像素縮放為經緯度坐標的實用工具,還是我需要使用諸如distanceToBoundingSphere(boundingSphere)之類的東西自己計算? 我只想要x,y坐標; 我根本不在乎身高。

我一直在演示和教程中四處逛逛,到目前為止,還沒有找到我想找的東西。 也許我找到了一些接近的東西,但我還不知道我是否找到了它。 救命!

=========================== CODE ===================== =============

收集多邊形的位置:

當用戶將鼠標拖動到新點時,singleClick僅捕獲該點的坐標並繪制一條折線。 因此,有一束折線和每個點的坐標集合。

    positionHandler.setInputAction(function (click) {
        cartesian = scene.camera.pickEllipsoid(click.position, ellipsoid);
        if (cartesian) {
            var setCartographic = ellipsoid.cartesianToCartographic(cartesian);
            asset.latlonalt.push(
                Cesium.Math.toDegrees(setCartographic.latitude).toFixed(15),
                Cesium.Math.toDegrees(setCartographic.longitude).toFixed(15),
                Cesium.Math.toDegrees(setCartographic.height).toFixed(15)
            );
            lla.push(Cesium.Math.toDegrees(setCartographic.longitude), Cesium.Math.toDegrees(setCartographic.latitude));
            if (lla.length >= 4) {
                self.loggingMessage((lla.length / 2) + ' Points Added');
            }
            Cesium.sampleTerrain(terrainProvider, 11, [cartographic])
                .then(function (updatedPositions) {
                    asset.latlonalt[2] = updatedPositions[0].height;
                    stage = 1;
                });
        }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

然后,DoubleClick獲取在singleClick函數中捕獲的坐標,並調用self.createAsset('add',asset)創建多邊形。

    positionHandler.setInputAction(function (doubleClick){
        if (asset.shape == 'Polygon') {
            var len = asset.latlonalt.length;
            if(len > 9) {
                asset.rad = (len / 3);
                console.log("Creating Asset");
                self.loggingMessage("Creating Asset");
                socket.emit('newElement', asset.cType, asset);
                self.createAsset('add', asset);
                viewer.entities.remove(entity);
                viewer.entities.remove(newCircle);
                viewer.entities.remove(newPolygon);
                viewer.entities.remove(newOutline);
                positionHandler = positionHandler && positionHandler.destroy();
            }else{
                console.log('3+ Positions Required');
                loggingMessage('3+ Positions Required.');
            }
        }
    }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)

創建多邊形:

            var newPolygon = viewer.entities.add({
                name : asset.id,
                polygon : {
                    hierarchy : Cesium.Cartesian3.fromDegreesArray(vertices),
                    material : rgba[0],
                    outline : true,
                    outlineColor : rgba[1]
                }
            });
            var newLabel = viewer.entities.add({
                position: Cesium.Cartesian3.fromDegrees(asset.latlonalt[1], asset.latlonalt[0], 1000),
                name: asset.id,
                label: {
                    text: asset.name,
                    font : '16px Helvetica'
                }
            });
            var newPoint = viewer.entities.add({
                position: Cesium.Cartesian3.fromDegrees(asset.latlonalt[1], asset.latlonalt[0], 0),
                name: asset.id,
                point : {
                pixelSize : 5,
                    color : Cesium.Color.RED,
                    outlineColor : Cesium.Color.RED,
                    outlineWidth : 2
                }
            });
            self.currentGeometry[asset.id] = {shape: newPolygon, label: newLabel, point: newPoint};

看來我們正在使用Terrain(我認為)。

地形圖

我應該對哪些數字感興趣:

在此處輸入圖片說明

收集坐標時,只有第一個z不為零:

在此處輸入圖片說明

我采用該值並填充其他z值:

在此處輸入圖片說明

現在,我已經添加了z值,在createAsset方法中出現了一些錯誤。 我需要跟蹤該問題才能看到結果。 現在,它看起來像這樣:

在此處輸入圖片說明

確實很大,輪廓沒有被去除。

一個問題有很多事情要做,但是我將嘗試解決這個關鍵問題。

首先, Cartesian3類本身。 在內部,構造之后,此類包含x, y, z成員x, y, z成員包含類似於314923.1值。 您可能應該將它們視為黑匣子,不透明值。 實際上,它們表示距行星中心的笛卡爾位置(以米為單位),這是渲染引擎所需的,但通常對人類制圖師沒有用。 要理解的關鍵是z總是會填充一個真實值,但這並不意味着在創建該值時是否考慮了高度。

有一個單獨的類Cartographic ,其中包含熟悉的經度(弧度),緯度(弧度)和海拔(以米為單位)值。 通常,在將它們傳遞給渲染引擎之前,必須將其轉換為Cartesian3 此轉換需要了解Ellipsoid (默認為WGS84橢球體),因此,零高度值表示該橢球體上的一個點(通常意味着在打開地形時該點位於地下)。

各種輔助函數采用通用值(例如,度數的經度/緯度)並轉換為這兩種格式中的任一種。 這些輔助功能中的一些會忽略高度參數,而其他一些功能會包含它。 這兩個類的文檔列舉了這些幫助器。

當關閉地形時,通過鼠標單擊來獲取精確的經度/緯度很簡單,但由於使用了透視3D相機,因此在打開地形時更為復雜。 在沒有地形的情況下,您可以像在上面的第一個代碼示例中所做的那樣僅調用scene.camera.pickEllipsoid ,並獲得確切的位置。 但是,當地形處於打開狀態時,即使單擊平坦的平原也會計算出錯誤的坐標,從而在您要查看的地形的下方和后面找到一個地下點。

隨意搜索並沒有找到正確的代碼,但是這里似乎已經將黃金標准烘焙到了現有的相機控制器中 看起來像這樣:

    var depthIntersection;
    if (scene.pickPositionSupported) {
        depthIntersection = scene.pickPosition(mousePosition, scratchDepthIntersection);
    }

    var ray = camera.getPickRay(mousePosition, pickGlobeScratchRay);
    var rayIntersection = globe.pick(ray, scene, scratchRayIntersection);

    var pickDistance = defined(depthIntersection) ?
        Cartesian3.distance(depthIntersection, camera.positionWC) :
        Number.POSITIVE_INFINITY;
    var rayDistance = defined(rayIntersection) ?
        Cartesian3.distance(rayIntersection, camera.positionWC) :
        Number.POSITIVE_INFINITY;

    if (pickDistance < rayDistance) {
        return Cartesian3.clone(depthIntersection, result);
    }

    return Cartesian3.clone(rayIntersection, result);

此代碼嘗試采用兩種方法:與以前一樣,嘗試拾取橢球,並且還嘗試從“深度緩沖區”中進行拾取,“深度緩沖區”是3D圖形系統的一部分,允許Cesium檢查多邊形有多遠從相機渲染時。 將兩個結果進行比較,然后以更接近相機的為准。 這完全避免了sampleTerrain調用的需要,因為鼠標位置已被用來直接拾取渲染多邊形的空間中的笛卡爾點(可能是地形,甚至可能是建築物的頂部,等等)。

在您的下一個代碼塊中,您使用asset.latlonalt填充lonlat ,但是然后將alt硬編碼為01000而不是來自相同的數據結構。 這可能是丟失高度信息的地方,如果它是從那里開始的(不是,如果您只是選擇橢球體,則不是),盡管稍后可能由sampleTerrain添加它。請注意sampleTerrain是異步的從服務器加載的地形圖)。 如果您決定嘗試深度選擇技術,它將直接產生Cartesian3 ,因此您不必擔心轉換它或保留海拔等問題。

最后的評論是,最新版本的GroundPrimitive確實支持GroundPrimitive ,該多邊形可以使多邊形覆蓋在地形上 這樣一來,您就不必從“拾取”正確的lon / lat(考慮到透視地形)中解脫出來,而是可以將多邊形放置在塊狀表面上並且不會穿過。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM