氣象模組使用教學
[info] 小提示:
程式碼連結:https://doc-3dgdp.colife.org.tw/samplecode/#src/testweb/weather-sample/
取得即時氣象圖
使用此功能可以從氣象局公開資料中取得即時氣象圖,參數中的觀測API代碼及API Key請開發人員至氣象局資料開放平台中取得。
[info] 小提示:
[warning] 注意事項:
記得要去氣象局申請 API Key 才能使用 Sample 來做測試。
首先要先撰寫一個最基本的圖台,並在介面上新增一個選單用來控制要取得哪種類型的氣象圖。
其中每個項目的value為每個種類氣象圖的觀測API代碼。
[warning] 注意事項:
並不是所有氣象局資料開放平台中的觀測資料都適用於圖台,請依需求審慎選擇圖資,並於正式上線使用前做好測試。
index.html
:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<meta charset="utf-8" />
<script src="https://sample.pilotgaea.com.tw/demo/index/src/PGWebJS/13.0/PGWeb3D.min.js"></script>
<link
rel="stylesheet"
type="text/css"
href="https://sample.pilotgaea.com.tw/demo/index/src/PGWebJS/13.0/css/PGWeb3D.css"
/>
<link
rel="stylesheet"
type="text/css"
href="https://sample.pilotgaea.com.tw/demo/index/css/main.css"
/>
<link rel="stylesheet" type="text/css" href="./load.css" />
</head>
<body>
<div
id="MyControl"
style="
position: absolute;
z-index: 1;
color: white;
background-color: black;
"
>
<div>
即時氣象圖:
<select id="source">
<option value="O-A0038-001">溫度分布</option>
<option value="O-A0058-005">雷達回波整合(較大範圍)</option>
<option value="O-A0058-006">雷達回波整合(鄰近區域)</option>
<option value="O-B0028-003">紅外線彩色衛星雲圖-東亞</option>
</select>
<button id="Start">取得最新資料</button>
<button id="Clear">清除</button>
</div>
<div>
API Key:<input type="text" placeholder="請至官網 https://opendata.cwa.gov.tw/申請" id="apiKeyInput" style="width: 60%;">
</div>
<div
id="MyMap"
style="width: 100%; height: 100%; position: absolute; top: 0; left: 0;"
></div>
<script src="main.js"></script>
</body>
</html>
main.js
:
let terrainview = new window.ov.TerrainView("MyMap");
let weather = null;
let widgetTimeline = null;
let widgetTimelinePlayer = null;
let historylayer = null;
let weatherlayer = null;
terrainview.openTerrain({
url: "http://127.0.0.1:8080",
identifier: "範例地形圖",
callback: openCallback,
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
// 在使用其他圖層前必須要先讀入地形 其他圖層的新增都會在callback中
// 天氣API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.WeatherModule.html#addRadarReflectivityHistoryLayer
// 時間軸API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.Widget.Timeline.html
// 時間軸撥放器API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.Widget.TimelinePlayer.html
function openCallback(result) {
// 設定底圖
terrainview.setBaseLayer({
url: "BING_MAP",
identifier: "IMAGE",
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
// 設定初始位置
let initialPos = new window.GeoPoint(
121.2347878442796,
23.427553934089445,
465850.0013822634
);
let initialV = new window.Geo3DPoint(0, 0, -1);
let initialUp = new window.Geo3DPoint(0, 1, 0);
let initialCamera = new window.ov.Camera(initialPos, initialV, initialUp);
terrainview.gotoCamera(initialCamera, false);
// 新增天氣物件
weather = terrainview.getModule("weather");
weather.proxy = "https://sample.pilotgaea.com.tw/weather.ashx?"; // 設定代理伺服器位置
// weather.authorization = ""; // 填入氣象局API Key
// 新增時間軸物件
widgetTimeline = new window.ov.Widget.Timeline({
view: terrainview,
style: { left: "10%", width: "88%" },
isRepeat: true
});
// 新增時間軸撥放器物件
widgetTimelinePlayer = new window.ov.Widget.TimelinePlayer({
view: terrainview,
timeline: widgetTimeline,
playSpeed: 1500.0
});
}
// 設定開始按鈕的Click事件。
document.getElementById("Start").addEventListener("click", function () {
});
// 設定清除按鈕的Click事件。
document.getElementById("Clear").addEventListener("click", function () {
});
再來我們要把開始與清除按鈕的點擊事件加進我們撰寫好的main.js
中。
main.js
:
let terrainview = new window.ov.TerrainView("MyMap");
let weather = null;
let widgetTimeline = null;
let widgetTimelinePlayer = null;
let historylayer = null;
let weatherlayer = null;
terrainview.openTerrain({
url: "http://127.0.0.1:8080",
identifier: "範例地形圖",
callback: openCallback,
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
// 在使用其他圖層前必須要先讀入地形 其他圖層的新增都會在callback中
// 天氣API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.WeatherModule.html#addRadarReflectivityHistoryLayer
// 時間軸API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.Widget.Timeline.html
// 時間軸撥放器API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.Widget.TimelinePlayer.html
function openCallback(result) {
// 設定底圖
terrainview.setBaseLayer({
url: "BING_MAP",
identifier: "IMAGE",
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
// 設定初始位置
let initialPos = new window.GeoPoint(
121.2347878442796,
23.427553934089445,
465850.0013822634
);
let initialV = new window.Geo3DPoint(0, 0, -1);
let initialUp = new window.Geo3DPoint(0, 1, 0);
let initialCamera = new window.ov.Camera(initialPos, initialV, initialUp);
terrainview.gotoCamera(initialCamera, false);
// 新增天氣物件
weather = terrainview.getModule("weather");
weather.proxy = "https://sample.pilotgaea.com.tw/weather.ashx?"; // 設定代理伺服器位置
// weather.authorization = ""; // 填入氣象局API Key
// 新增時間軸物件
widgetTimeline = new window.ov.Widget.Timeline({
view: terrainview,
style: { left: "10%", width: "88%" },
isRepeat: true
});
// 新增時間軸撥放器物件
widgetTimelinePlayer = new window.ov.Widget.TimelinePlayer({
view: terrainview,
timeline: widgetTimeline,
playSpeed: 1500.0
});
}
document.getElementById("Start").addEventListener("click", function () {
weather.authorization = document.getElementById('apiKeyInput').value; //帶入使用者輸入的氣象局API Key
let v = document.getElementById("source").value;
document.getElementById("Start").disabled = true;
document.getElementById("loader").style.display = "block";
if (v) {
if (weatherlayer) {
weather.removeLayer(weatherlayer);
weatherlayer = null;
terrainview.updateScreen();
}
weather.addWeatherImageLayer(
{
api: v
},
function (rtn) {
if (window.IsString(rtn)) {
window.ov.UI.Alertify.Error(rtn);
} else {
window.ov.UI.Alertify.Notify("完成");
weatherlayer = rtn;
}
document.getElementById("loader").style.display = "none";
document.getElementById("Start").disabled = false;
}
);
}
});
document.getElementById("Clear").addEventListener("click", function () {
if (weatherlayer) {
weather.removeLayer(weatherlayer);
terrainview.updateScreen();
weatherlayer = null;
}
});
取得雷達回波歷史圖
透過此功能可以取得歷史雷達回波圖,並結合時間軸及特殊內插方法做出雷達回波圖的動畫呈現。
首先要先撰寫一個最基本的圖台,並在介面上新增一系列控制項用來控制參數。
index.html
:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<meta charset="utf-8" />
<script src="https://sample.pilotgaea.com.tw/demo/index/src/PGWebJS/13.0/PGWeb3D.min.js"></script>
<link
rel="stylesheet"
type="text/css"
href="https://sample.pilotgaea.com.tw/demo/index/src/PGWebJS/13.0/css/PGWeb3D.css"
/>
<link
rel="stylesheet"
type="text/css"
href="https://sample.pilotgaea.com.tw/demo/index/css/main.css"
/>
<link rel="stylesheet" type="text/css" href="./load.css" />
</head>
<body>
<div
id="MyControl"
style="
position: absolute;
z-index: 1;
color: white;
background-color: black;
"
>
<div>
雷達回波歷史圖:
<select id="limit" onchange="change()">
<option value="1">一小時</option>
<option value="2">兩小時</option>
<option value="3">三小時</option>
<option value="4">四小時</option>
<option value="5">五小時</option>
<option value="6">六小時</option>
<option value="7">七小時</option>
<option value="8">八小時</option>
<option value="9">九小時</option>
<option value="10">十小時</option>
<option value="11">十一小時</option>
<option value="12">十二小時</option>
</select>
<button id="HistoryStart">開始</button>
<button id="HistoryClear">清除</button>
</div>
<div>
API Key:<input type="text" placeholder="請至官網 https://opendata.cwa.gov.tw/申請" id="apiKeyInput" style="width: 60%;">
</div>
</div>
<div
id="MyMap"
style="width: 100%; height: 100%; position: absolute; top: 0; left: 0;"
></div>
<script src="main.js"></script>
</body>
</html>
main.js
:
let terrainview = new window.ov.TerrainView("MyMap");
let weather = null;
let widgetTimeline = null;
let widgetTimelinePlayer = null;
let historylayer = null;
let weatherlayer = null;
terrainview.openTerrain({
url: "http://127.0.0.1:8080",
identifier: "範例地形圖",
callback: openCallback,
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
// 在使用其他圖層前必須要先讀入地形 其他圖層的新增都會在callback中
// 天氣API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.WeatherModule.html#addRadarReflectivityHistoryLayer
// 時間軸API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.Widget.Timeline.html
// 時間軸撥放器API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.Widget.TimelinePlayer.html
function openCallback(result) {
// 設定底圖
terrainview.setBaseLayer({
url: "BING_MAP",
identifier: "IMAGE",
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
// 設定初始位置
let initialPos = new window.GeoPoint(
121.2347878442796,
23.427553934089445,
465850.0013822634
);
let initialV = new window.Geo3DPoint(0, 0, -1);
let initialUp = new window.Geo3DPoint(0, 1, 0);
let initialCamera = new window.ov.Camera(initialPos, initialV, initialUp);
terrainview.gotoCamera(initialCamera, false);
// 新增天氣物件
weather = terrainview.getModule("weather");
weather.proxy = "https://sample.pilotgaea.com.tw/weather.ashx?"; // 設定代理伺服器位置
// weather.authorization = ""; // 填入氣象局API Key
// 新增時間軸物件
widgetTimeline = new window.ov.Widget.Timeline({
view: terrainview,
style: { left: "10%", width: "88%" },
isRepeat: true
});
// 新增時間軸撥放器物件
widgetTimelinePlayer = new window.ov.Widget.TimelinePlayer({
view: terrainview,
timeline: widgetTimeline,
playSpeed: 1500.0
});
}
// 設定開始按鈕的Click事件。
document.getElementById("HistoryStart").addEventListener("click", function () {
});
// 設定清除按鈕的Click事件。
document.getElementById("HistoryClear").addEventListener("click", function () {
});
再來我們要把開始與清除按鈕的點擊事件加進我們撰寫好的main.js
中。
[warning] 取圖規則注意事項:
為節省網路流量資源,此功能設有"資料筆數上限"之限制。
若時間區間中取得的圖片數量大於"資料筆數上限",則以時間區間終點往前取"資料筆數上限"筆數之資料。
反之,則以時間區間中取得的圖片數量為主。
main.js
:
let terrainview = new window.ov.TerrainView("MyMap");
let weather = null;
let widgetTimeline = null;
let widgetTimelinePlayer = null;
let historylayer = null;
let weatherlayer = null;
terrainview.openTerrain({
url: "http://127.0.0.1:8080",
identifier: "範例地形圖",
callback: openCallback,
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
// 在使用其他圖層前必須要先讀入地形 其他圖層的新增都會在callback中
// 天氣API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.WeatherModule.html#addRadarReflectivityHistoryLayer
// 時間軸API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.Widget.Timeline.html
// 時間軸撥放器API:https://sample.pilotgaea.com.tw/demo/Reference/v13/js3d/ov.Widget.TimelinePlayer.html
function openCallback(result) {
// 設定底圖
terrainview.setBaseLayer({
url: "BING_MAP",
identifier: "IMAGE",
urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});
// 設定初始位置
let initialPos = new window.GeoPoint(
121.2347878442796,
23.427553934089445,
465850.0013822634
);
let initialV = new window.Geo3DPoint(0, 0, -1);
let initialUp = new window.Geo3DPoint(0, 1, 0);
let initialCamera = new window.ov.Camera(initialPos, initialV, initialUp);
terrainview.gotoCamera(initialCamera, false);
// 新增天氣物件
weather = terrainview.getModule("weather");
weather.proxy = "https://sample.pilotgaea.com.tw/weather.ashx?"; // 設定代理伺服器位置
// weather.authorization = ""; // 填入氣象局API Key
// 新增時間軸物件
widgetTimeline = new window.ov.Widget.Timeline({
view: terrainview,
style: { left: "10%", width: "88%" },
isRepeat: true
});
// 新增時間軸撥放器物件
widgetTimelinePlayer = new window.ov.Widget.TimelinePlayer({
view: terrainview,
timeline: widgetTimeline,
playSpeed: 1500.0
});
}
document.getElementById("HistoryStart").addEventListener("click", function () {
weather.authorization = document.getElementById('apiKeyInput').value; //帶入使用者輸入的氣象局API Key
let v = parseInt(document.getElementById("limit").value);
let end = new Date();
let begin = new Date(end.getTime() - v * 60 * 60 * 1000);
document.getElementById("HistoryStart").disabled = true;
document.getElementById("loader").style.display = "block";
window.ov.UI.Alertify.Notify("請稍後...");
if (historylayer) {
removeHistoryLayer(historylayer);
historylayer = null;
}
// 新增雷達回波歷史圖層
weather.addRadarReflectivityHistoryLayer(
{
layername: "weather", // 圖層名稱
timeFrom: begin, // 開始時間(包含),氣象資料開放平台只有保存十天(10246筆)的資料
timeTo: end, // 結束時間(包含)
limit: v * 6, // 限制最多回傳符合條件的最新資料筆數
offset: 0, // 指定從第幾筆開始回傳
interval: 10 // 資料間隔(分鐘),氣象資料開放平台的歷史資料間隔為10分鐘,可以設大一點來降低網路流量與系統負載
},
function (rtn) {
if (window.IsString(rtn)) {
window.ov.UI.Alertify.Error(rtn);
} else {
window.ov.UI.Alertify.Notify("完成");
historylayer = rtn;
addLayerToTimeline(historylayer, v);
}
document.getElementById("loader").style.display = "none";
document.getElementById("HistoryStart").disabled = false;
}
);
});
document.getElementById("HistoryClear").addEventListener("click", function () {
if (historylayer) {
removeHistoryLayer(historylayer);
historylayer = null;
}
});
function addLayerToTimeline(layer, v) {
let timespan = layer.playingInfo.TimeSpan;
widgetTimeline.updateParameter({
startTime: timespan[0],
stopTime: timespan[1],
playSpeed: v * 500.0
});
// 回到撥放區間最開頭
widgetTimeline.toStart();
// 撥放
widgetTimelinePlayer.play();
// weather圖層綁訂時間軸
widgetTimeline.addLink(
layer,
timespan[0].toLocaleString() + "~" + timespan[1].toLocaleString() + " 回波"
);
}
function removeHistoryLayer(layer) {
widgetTimelinePlayer.stop();
widgetTimeline.removeLink(layer);
widgetTimeline.updateParameter({
startTime: null,
stopTime: null
});
weather.removeLayer(layer);
terrainview.updateScreen();
}