通用功能
取得當前攝影機位置與姿態
為了設定最佳觀看位置,有時需要取得攝影機位置與姿態,使用camera物件即可取得當前攝影機位置與姿態。
let camera = terrainview.camera;
/*--------------------------
呼叫camera物件即可得到:
pos: GeoPoint {x: 120.70791748262354, y: 24.134301636077225, z: 162.2240949762787}
up: Geo3DPoint {x: 0.04968821629881859, y: 0.07186868041753769, z: 0.9961756467819214}
v: Geo3DPoint {x: 0.5664713978767395, y: 0.8194365501403809, z: -0.08737295120954514}
----------------------------*/
坐標系轉換
需要轉換坐標系時,可使用GetEPSGEngine().Transfer()來轉換來源坐標。
let geo = new GeoPoint(parseFloat(120.70791748262354),parseFloat(24.134301636077225),parseFloat(162.2240949762787));
GetEPSGEngine().Transfer(4326,3857,geo);
/*--------------------------
處理完的結果會存回原本的geo物件內,呼叫geo物件即可看到處理結果。
----------------------------*/
設定地形的各種畫法
在地形繪製中,我們可以透過修改設定來傳達特定的訊息。
[info] 小提示: 由於地形著色設定參數眾多,如需詳細了解請前往 Reference 查閱。
預設
// ov.TerrainView.setDrawTerrainSetting.surface 可設定是否畫表面
terrainView.setDrawTerrainSetting = {
grid: false,
vertexWireframe: false,
slopeColorSetting: { isopen: false },
aspectColorSetting: { isopen: false },
heightColorSetting: { isopen: false },
wireframeColor: "#000000",
surface: true
};
框架
// ov.TerrainView.setDrawTerrainSetting.vertexWireframe 可設定是否畫框架
terrainview.drawTerrainSetting = {
grid: false,
vertexWireframe: true,
slopeColorSetting: { isopen: false },
aspectColorSetting: { isopen: false },
heightColorSetting: { isopen: false },
wireframeColor: "#FF0000",
surface: false
};
框線
// ov.TerrainView.setDrawTerrainSetting.grid 可設定是否畫框線
// ov.TerrainView.setDrawTerrainSetting.wireframeColor 可設定網格顏色
terrainview.setDrawTerrainSetting = {
grid: true,
vertexWireframe: false,
slopeColorSetting: { isopen: false },
aspectColorSetting: { isopen: false },
heightColorSetting: { isopen: false },
wireframeColor: "#0000FF",
surface: true
};
坡向填色
// ov.TerrainView.setDrawTerrainSetting.aspectColorSetting.isopen 可設定坡向填色,優先度最高
// ov.TerrainView.setDrawTerrainSetting.aspectColorSetting.colorset 可設定坡向填色分層顏色
// ov.TerrainView.setDrawTerrainSetting.aspectColorSetting.degreeset 可設定坡向填色分層坡向
// ov.TerrainView.setDrawTerrainSetting.wireframeColor 可設定網格顏色
terrainview.setDrawTerrainSetting = {
grid: false,
vertexWireframe: false,
slopeColorSetting: { isopen: false },
aspectColorSetting: { isopen: true },
heightColorSetting: { isopen: false },
wireframeColor: "#000000",
surface: true
};
坡度填色
// ov.TerrainView.setDrawTerrainSetting.slopeColorSetting.isopen 可設定坡度填色,優先度第二
// ov.TerrainView.setDrawTerrainSetting.slopeColorSetting.colorset 可設定坡度填色分層顏色
// ov.TerrainView.setDrawTerrainSetting.slopeColorSetting.degreeset 可設定坡度填色分層坡向
// ov.TerrainView.setDrawTerrainSetting.wireframeColor 可設定網格顏色
terrainview.setDrawTerrainSetting = {
grid: false,
vertexWireframe: false,
slopeColorSetting: { isopen: true },
aspectColorSetting: { isopen: false },
heightColorSetting: { isopen: false },
wireframeColor: "#000000",
surface: true
};
高度填色
// ov.TerrainView.setDrawTerrainSetting.heightColorSetting.isopen 可設定高度填色,優先度最低
// ov.TerrainView.setDrawTerrainSetting.heightColorSetting.colorset 可設定高度填色分層顏色
// ov.TerrainView.setDrawTerrainSetting.heightColorSetting.degreeset 可設定高度填色分層坡向
// ov.TerrainView.setDrawTerrainSetting.wireframeColor 可設定網格顏色
terrainview.setDrawTerrainSetting = {
grid: false,
vertexWireframe: false,
slopeColorSetting: { isopen: false },
aspectColorSetting: { isopen: false },
heightColorSetting: { isopen: true },
wireframeColor: "#000000",
surface: true
};
[info] 動手試試看: 程式碼連結:我是連結
等高線
// ov.TerrainView.setDrawTerrainSetting.contourSetting.isopen 可開關等高線
// ov.TerrainView.setDrawTerrainSetting.contourSetting.hideWhenMoving 移動時是否隱藏
// ov.TerrainView.setDrawTerrainSetting.contourSetting.interval 可設定等高線間距
// ov.TerrainView.setDrawTerrainSetting.contourSetting.color 可設定等高線顏色
// ov.TerrainView.setDrawTerrainSetting.contourSetting.alpha 可設定等高線不透明度
terrainview.setDrawTerrainSetting = {
contourSetting: {
isopen: true,
hideWhenMoving: true,
interval: 100,
color: "#FFFFFF",
alpha: 0.5
}
};
[info] 動手試試看: 程式碼連結:我是連結
太陽光照模式
太陽貼圖
是否畫太陽貼圖,預設為開
terrainview.enableSun = false;
光照開關
terrainview.enableLight = true;
在畫面中顯示一個當前太陽所在位置的方向指示
terrainview.enableDrawLightDirectionSketchMap = true;
調整光照設定
透過修改LightProperty
物件來變更光照設定。
[info] 小提示: 由於設定參數眾多,如需詳細了解請前往 Reference 查閱。
手動調整光照角度:
let light = terrainview.lightProperty; // 將設定物件儲存做更改。
light.azimuthAngle = 145; // 設定光照方位角。
light.zenithAngle = 79; // 設定光照仰角。
terrainview.lightProperty = light; // 將修改後的物件存回設定。
或是使用當前時間自動更新角度:
let light = terrainview.lightProperty; // 將設定物件儲存做更改。
light.isAutoUpdateByDate = true; // 開啟自動更新。
light.isAbs = true; // 開啟絕對位置。
terrainview.lightProperty = light; // 將修改後的物件存回設定。
亦可給予時間來達成天文曆的效果:
let time = new Date("2021-03-09T15:19:00"); // 給定日期與時間。
terrainview.date = time; // 將時間送入系統。
let light = terrainview.lightProperty; // 將設定物件儲存做更改。
light.isAutoUpdateByDate = true; // 開啟自動更新。
light.isAbs = true; // 開啟絕對位置。
terrainview.lightProperty = light; // 將修改後的物件存回設定。
[info] 動手試試看: 程式碼連結:我是連結
開啟建物陰影
使用enableShadow
可開啟建物陰影,陰影可隨光線移動而變化。
terrainview.enableShadow = true;
[info] 動手試試看: 程式碼連結:我是連結
開啟體積光散射
使用enableVolumetricLightScattering
可開啟體積光散射,預設為關。
terrainview.enableVolumetricLightScattering = true;
[info] 動手試試看: 程式碼連結:我是連結
海洋
海洋不需要增加額外圖層,會直接參考地形高層繪製(可支援海底地形)。
[info] 小提示: 本頁介紹的海洋功能可調整高度,如果需要貼合地表的水面功能,請參考:水遮罩
// 是否畫海洋,預設為關
// @property {Boolean} enableSea 開關海洋
// @name ov.TerrainView#enableSea
terrainview.enableSea = true;
// 設定海渲染品質,預設為normal
// ov.TerrainView.setSeaQuality(quality)
// @param {String} quality 海渲染品質,分成low, normal, high, very high
// @return {Boolean} 是否設定成功
terrainview.setSeaQuality("high");
// 設定海平面高度
// ov.TerrainView.setSeaAltitude(seaAltitude)
// @param {Number} seaAltitude 海平面高度,單位為公尺
terrainview.setSeaAltitude(3);
[info] 動手試試看: 程式碼連結:我是連結
測量功能
在任何量測功能被呼叫前,可以監聽MeasureCompleted
事件,當量測完成後便能收到MeasureCompleted
事件。
terrainview.addEventListener("MeasureCompleted",function(obj) {
// 收到測量結果後要做的事
});
進行任何量測前,都應該執行呼叫,以放棄未完成的量測。
terrainview.abortMeasure();
下面的所有操作,呼叫後用滑鼠根據操作點擊左鍵選擇量測範圍(長度),雙擊左鍵即可完成。
測量面積
terrainview.measureArea();
[info] 小提示: 由於設定參數眾多,如需詳細了解請前往 Reference 查閱。
測量高度
terrainview.measureHeight();
[info] 小提示: 由於設定參數眾多,如需詳細了解請前往 Reference 查閱。
測量空間距離
terrainview.measureSpatialLength();
[info] 小提示: 由於設定參數眾多,如需詳細了解請前往 Reference 查閱。
測量點到點距離
terrainview.measureSpatialPointToPointLength();
[info] 小提示: 由於設定參數眾多,如需詳細了解請前往 Reference 查閱。
測量地表距離
terrainview.measureSurfaceLength();
[info] 小提示: 由於設定參數眾多,如需詳細了解請前往 Reference 查閱。
[info] 動手試試看: 程式碼連結:我是連結
空間裁切盒
目前空間裁切盒只支援模型、模型集、點雲 三種模型,透過裁切可看到模型內的構成與被擋住的部分。
設定裁切空間,會直接清除舊的裁切空間。
// ov.TerrainView.setSliceSpace(param)
// @param {Object} param 參數,詳見文件
// @param {String} param.color 在螢幕畫出回饋的顏色
// @param {Number} param.colorOpacity 在螢幕畫出回饋顏色的不透明度
// @param {String} param.markTagColor 標示測量結果文字部份的顏色
// @param {Number} param.markTagColorOpacity 標示測量結果文字部份的顏色不透明度
// @param {Number} param.measureScale 測量結果要再乘以之Scale
// @param {Number} param.measureDecimalPoint 測量結果要留的小數點數
// @param {Array} param.planeEnableRotation 特定面不能旋轉
// @param {Array} param.planeEnableResize 特定面不能拉伸
// @param {Object} param.measuringTexture 裁切體上刻度圖參數
// @param {Object} param.sliceSpaceParam 直接指定裁切體幾何
terrainview.setSliceSpace(param);
編輯裁切空間,若還沒有設定過,則會直接完成輸入。
// ov.TerrainView.(param)
// @param {Object} param 參數,詳見文件
// @param {String} param.color 在螢幕畫出回饋的顏色
// @param {Number} param.colorOpacity 在螢幕畫出回饋顏色的不透明度
// @param {String} param.markTagColor 標示測量結果文字部份的顏色
// @param {Number} param.markTagColorOpacity 標示測量結果文字部份的顏色不透明度
// @param {Number} param.measureScale 測量結果要再乘以之Scale
// @param {Number} param.measureDecimalPoint 測量結果要留的小數點數
// @param {Array} param.planeEnableRotation 特定面不能旋轉
// @param {Array} param.planeEnableResize 特定面不能拉伸
terrainview.editSliceSpace(param);
移除裁切空間。
// ov.TerrainView.removeSliceSpace()
terrainview.removeSliceSpace();
[info] 動手試試看: 程式碼連結:我是連結
分析功能
視域分析
視域分析用於指定一個點去計算沒有被遮蔽的可視範圍,這裡介紹的是平面的視域分析。
// 新增視域分析
// ov.Analysis.addViewshedAnalysis(param)
// @param {Object} param 參數物件
// @param {GeoPoint} param.center 視域分析中心點
// @param {Number} param.distance 視域分析半徑
// @param {Boolean} param.absHeight 輸入中心點Z值是否為絕對高
// @param {String} param.color 顏色 (預設#00FFFF)
// @param {Number} param.alpha 透明度 (預設1.0,介於0~1.0)
// @param {Number} param.epsg 所輸入中心點的Epsg,若為null視為與地形相同
terrainview.analysis.addViewshedAnalysis({
center: new GeoPoint(121.689972, 24.215658, 2.3182),
distance: 870,
absHeight: true,
color: "#ffffff",
opacity: 1.0,
epsg: null
});
清除視域分析結果。
// 清除視域分析
// ov.Analysis.clearViewshedAnalysis()
terrainview.analysis.clearViewshedAnalysis();
[info] 動手試試看: 程式碼連結:我是連結
3D視域分析
視域分析用於指定一個點去計算沒有被遮蔽的可視範圍,這裡介紹的是立體的視域分析。
// 3D視域分析
// ov.Analysis.addViewshed3DAnalysis(param)
// @param {Object} param 參數物件
// @param {GeoPoint} param.center 視域分析中心點
// @param {Number} param.distance 視域分析半徑
// @param {Boolean} param.absHeight 輸入中心點Z值是否為絕對高
// @param {String} param.color 顏色 (預設#00FFFF)
// @param {Number} param.opacity 透明度 (預設1.0,介於0~1.0)
// @param {String} param.occludedColor 遮擋顏色 (預設#00FFFF)
// @param {Number} param.occludedOpacity 遮擋透明度 (預設0.3,介於0~1.0)
// @param {Number} param.epsg 所輸入中心點的Epsg,若為null視為與地形相同
// @param {Number} param.planeCenter 方位角
// @param {Number} param.horizontalAngle 水平展開角
// @param {Number} param.verticalAngle 垂直展開角
// @param {Number} param.sphereDetail 球體的網格數目
// @param {Boolean} param.underline 是否畫出底線
// @param {String} param.underlineColor 底線顏色
terrainview.analysis.addViewshedAnalysis({
center: new window.GeoPoint(120.973882, 23.97565, 1000),
distance: 2000,
absHeight: true,
color: "#FF0000",
opacity: 1,
occludedColor: "#00FFFF",
occludedOpacity: 0.3,
epsg: null,
planeCenter: 0,
horizontalAngle: 360,
verticalAngle: 180,
sphereDetail: 30,
underline: false,
underlineColor: "#0000FF"
});
清除視域分析結果:
// 清除視域分析
// ov.Analysis.clearViewshedAnalysis()
terrainview.analysis.clearViewshedAnalysis();
[info] 動手試試看: 程式碼連結:我是連結
天際線分析
// 天際線分析
// ov.Analysis.skylineAnalysis(param)
// @param {Object} param 參數物件
// @param {Number} param.lineWidth 線寬 (預設5)
// @param {String} param.lineColor 顏色 (預設#00FFFF)
terrainview.analysis.skylineAnalysis({
lineWidth: 3,
lineColor: "#00FFFF"
});
清除天際線分析結果:
// 清除天際線分析
// ov.Analysis.clearSkylineAnalysis()
terrainview.analysis.clearSkylineAnalysis();
[info] 動手試試看: 程式碼連結:我是連結
空域分析
給定一個多邊形範圍,計算出範圍內所屬空域。
var airspace; //空域手柄
var polygonset = new window.GeoPolygonSet(); // 新增一個多邊形
polygonset.Bounds.push(
new window.GeoPolygon([
new window.GeoPoint(121.02582333242975, 24.82093297861256, 1),
new window.GeoPoint(121.02749972594233, 24.825258393416362, 1),
new window.GeoPoint(121.02759462415491, 24.825195033627566, 1),
new window.GeoPoint(121.0259626208973, 24.820887078752634, 1)
])
);
// 空域分析
// ov.Analysis.addAirspace(param);
// @param {Object} param 參數
// @param {GeoPolygonSet} param.geo 幾何多邊形
// @param {Number} param.height 高度(m)
// @param {Number} param.level 海拔高度(m)
// @param {Number} param.angle 外擴角度(0°~45°)
// @param {Number} param.side 外擴角落邊數
// @param {String} param.color 顏色,預設#000000
// @param {String} param.opacity 透明度
// @param {Boolean} param.drawBound 繪製空域
// @returns {ov.AirspaceData} 空域手柄
var param = {};
param.geo = polygonset;
param.height = 50;
param.level = 0;
param.angle = 45;
param.side = 10;
param.color = "#FF0000";
param.opacity = 1;
param.drawBound = true;
airspace = terrainview.analysis.addAirspace(param);
清除空域分析:
airspaceModule.removeAirspace(airspace) // 參數填入儲存的空域手柄。
[info] 動手試試看: 程式碼連結:我是連結
標註功能
可於圖台上增加臨時的標註。
在任何量測功能被呼叫前,皆須監聽InputCompleted事件,當量測完成後便能收到InputCompleted事件。
terrainview.addEventListener("InputCompleted",function(obj) {});
下面的所有操作,呼叫後用滑鼠根據操作點擊左鍵選擇要標註的點,再次點擊左鍵完成輸入。
[info] 小提示: 由於設定參數眾多,如需詳細了解請前往 Reference 查閱。
放棄當前輸入
每次開始輸入前,都應該呼叫已中斷未完成的輸入。
terrainview.abortInput();
完成輸入
可以呼叫此函式完成輸入。
terrainview.completeInput();
球
terrainview.input3DBall();
三維點
terrainview.input3DPoint();
三維聚合線
terrainview.input3DPolyline();
矩形
terrainview.inputScreenRectangle();
地表圓
terrainview.inputSurfaceCircle();
地表點
terrainview.inputSurfaceCircle();
地表多邊形
terrainview.inputSurfacePolygon();
地表聚合線
terrainview.inputSurfacePolyline();
地表矩形
terrainview.inputSurfaceRectangle();
雙視窗同步
有時候我們可能需要比對不同地圖的資訊,這時就需要將視窗一分為二,同時載入不同來源的地圖,並且讓他們同時進行移動及縮放。
首先,我們需要新增兩個div
,並讓他們各佔畫面一半。
<div style="display: inline-flex; width:100vw;">
<div id="MyMap" style="overflow:hidden;height:100vh; flex: 1 1;">
</div>
<div id="MyMap2" style="overflow:hidden;height:100vh; flex: 1 1;">
</div>
</div>
第二步,我們需要為兩個div
綁上地形與各自的底圖。
let terrainview = new window.ov.TerrainView("MyMap");
let terrainview2 = new window.ov.TerrainView("MyMap2");
terrainview.openTerrain({
url: "http://127.0.0.1:8080",
identifier: "範例地形圖",
callback: openCallback,
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
terrainview2.openTerrain({
url: "http://127.0.0.1:8080",
identifier: "範例地形圖",
callback: openCallback2,
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
function openCallback(result) {
terrainview.setBaseLayer({
url: "BING_MAP",
identifier: "IMAGE",
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
}
function openCallback2(result) {
terrainview2.setBaseLayer({
url: "BING_MAP",
identifier: "VECTOR",
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
}
接著監聽terrainview
的CameraPosChanged
事件,當terrainview
攝影機位置有所變化時便會發出,接著改變terrainview2
的視野範圍。
var running = false;
terrainview.addEventListener("CameraPosChanged", function(p, u, v) {
if (running) return;
running = true;
terrainview2.gotoCamera(new ov.Camera(p, u, v), false);
running = false;
});
同樣的也綁定terrainview2
的CameraPosChanged
事件。
terrainview2.addEventListener("CameraPosChanged", function(p, u, v) {
if (running) return;
running = true;
terrainview.gotoCamera(new ov.Camera(p, u, v), false);
running = false;
});
兩段程式碼都使用了變數running
,是由於事件觸發時,一方會去將另一方的viewport
設成跟自己相同以達到同步目的。
當其中一者在改變另一方的Viewport
時,會使對方也發出CameraPosChanged
事件,如果沒有用此變數阻止,會導致不斷互相呼叫對方而陷入無窮迴圈。
[info] 動手試試看: 程式碼連結:我是連結