軍事模組API開發


[info] 小提示:

程式碼連結:https://doc-3dgdp.colife.org.tw/samplecode/#src/testweb/military_2525b/


初始化軍事模組

軍事模組需要額外引入PGWeb3DMilitary.min.js,並使用terrainview.getModule取得軍事模組。

下面的範例可以用來建立一個附帶參數設定面板的軍事模組圖台

index.html

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Military Demo</title>
  <meta charset="utf-8" />
  <!-- 引用 js -->
  <script src="PGWeb3D.min.js"></script> 
  <script src="PGWeb3DMilitary.min.js"></script>
  <!-- 引用 style -->
  <link rel="stylesheet" type="text/css" href="PGWeb3D.css" />
  <link rel="stylesheet" type="text/css" href="style.css" />
</head>

<body>
  <!-- 圖台初始化 -->
  <div id="MyMap">
    <!-- 數量控制面板 -->
    <div id="MyControl">
      <select id="totalnumber" onchange="insert2525b()">
        <option value="0">----</option>
        <option value="100" selected="selected">100</option>
        <option value="200">200</option>
        <option value="500">500</option>
        <option value="1000">1000</option>
        <option value="2000">2000</option>
        <option value="5000">5000</option>
      </select>
      <span id="FpsSpan"></span>
    </div>
    <!-- 自訂參數面板 -->
    <div style="position: absolute; z-index: 1; top: 30px; left: 0;">
      <details class="ov-widget-details" style="width: 270px;">
        <summary class="ov-widget-summary ov-widget-unselectable">
          <div class="ov-widget-summary-title">自訂</div>
        </summary>
        <div class="ov-widget-scrollBar">
          <table>
            <tr>
              <td>中心點位置</td>
              <td>
                <div class="degree">
                  <input type="number" id="lng" step="0.01" value="121.23" />
                </div>
                <div class="degree">
                  <input type="number" id="lat" step="0.01" value="23.42" />
                </div>
                <div class="meter">
                  <input type="number" id="height" value="3000.0" />
                </div>
              </td>
            </tr>
            <tr>
              <td>
                <div>
                  <span>編碼</span><span class="SIDCHint" onclick="toggleSIDCHint()"></span>
                </div>
              </td>
              <td>
                <div class="megahertz">
                  <input type="text" id="code" value="sfgpewrh--mt" />
                </div>
              </td>
            </tr>
            <tr>
              <td>尺寸</td>
              <td>
                <div class="dBW">
                  <input type="number" id="size" value="64.0" />
                </div>
              </td>
            </tr>
            <tr>
              <td>時間</td>
              <td>
                <div class="megahertz">
                  <input type="text" id="dtg" value="30140000ZSEP97" />
                </div>
              </td>
            </tr>
            <tr>
              <td>位置</td>
              <td>
                <div class="megahertz">
                  <input type="text" id="location" value="0900000.0E570306.0N" />
                </div>
              </td>
            </tr>
            <tr>
              <td>移動方向</td>
              <td>
                <div class="megahertz">
                  <input type="number" id="direction" value="45" />
                </div>
              </td>
            </tr>
            <tr>
              <td>種類</td>
              <td>
                <div class="megahertz">
                  <input type="text" id="type" value="MACHINE GUN" />
                </div>
              </td>
            </tr>
            <tr>
              <td>數量</td>
              <td>
                <div class="megahertz">
                  <input type="number" id="quantity" value="200" />
                </div>
              </td>
            </tr>
            <tr>
              <td>人員說明</td>
              <td>
                <div class="megahertz">
                  <input type="text" id="staffComments" value="FOR REINFORCEMENTS" />
                </div>
              </td>
            </tr>
            <tr>
              <td>追加資訊</td>
              <td>
                <div class="megahertz">
                  <input type="text" id="additionalInformation" value="ADDED SUPPORT FOR JJ" />
                </div>
              </td>
            </tr>
            <tr>
              <td colspan="2">
                <div class="megahertz">
                  <input type="button" id="cbMoveToClick" value="移動到滑鼠點擊座標" onclick="clickToMove()" />
                </div>
              </td>
            </tr>
          </table>
          <!-- 資訊提示面板 -->
          <div id="SIDC_HINT_PANEL" draggable="true">
            <table>
              <span class="panelCloseButton" onclick="toggleSIDCHint()"></span>
              <caption>
                提供 2525C-Coding Scheme:WARFIGHTING
                的基本符號表供參考,需要進一步符號定義請參閱
                <a href="https://quicksearch.dla.mil/qsDocDetails.aspx?ident_number=114934" target="_blank">MIL-STD-2525
                  Spec</a>
              </caption>
              <tr>
                <th>Coding Scheme<br />(字母1)</th>
                <th>
                  AFFILIATION / EXERCISE <br />AMPLIFYING DESCRIPTOR<br />(字母2)
                </th>
                <th>BATTLE DIMENSION<br />(字母3)</th>
                <th>STATUS<br />(字母4)</th>
              </tr>
              <tr>
                <td>S - WARFIGHTING</td>
                <td>
                  P - PENDING<br />
                  U - UNKNOWN<br />
                  A - ASSUME FRIEND<br />
                  F - FRIEND<br />
                  N - NEUTRAL<br />
                  S - SUSPECT<br />
                  H - HOSTILE
                </td>
                <td>
                  P - SPACE<br />
                  A - AIR<br />
                  G - GROUND<br />
                  S - SEA SURFACE<br />
                  U - SEA SUBSURFACE<br />
                </td>
                <td>
                  A - ANTICIPATED/PLANNED<br />
                  P - PRESENT
                </td>
              </tr>
              <tr>
                <th>FUNCTION ID<br />(字母5~10)</th>
                <th>SYMBOL MODIFIER<br />(字母11~12)</th>
                <th>COUNTRY CODE<br />(字母13~14)</th>
                <th>ORDER OF BATTLE<br />(字母15)</th>
              </tr>
              <tr>
                <td>詳請參見 2525C SPEC A-III</td>
                <td>詳請參見 2525C SPEC A-III</td>
                <td>詳請參見 FIPS Pub 10 系列</td>
                <td>
                  A - AIR OB<br />
                  E - ELECTRONIC OB<br />
                  C - CIVILIAN OB<br />
                  G - GROUND OB<br />
                  N - MARITIME OB<br />
                  S - STRATEGIC FORCE RELATED
                </td>
              </tr>
            </table>
          </div>
        </div>
      </details>
    </div>
  </div>

  <!-- 引用主要 js,邏輯會寫在這個檔案 -->
  <script src="main.js"></script>
</body>

</html>

main.js

// 初始化圖台
var terrainview = new ov.TerrainView("MyMap");

// 載入軍事模組,需要PGWeb3DMilitary.min.js
var militaryModule = terrainview.getModule("military");

// 軍事符號單元集合
var military2525BEntitys = [];

// 自訂符號單元
var customEntity = null;

// 記錄上次更新時間, 用來計算移動距離模擬符號移動
var lastTime = 0;

// 2525B符號代碼集合 (此範例提供 50 個不同的符號代碼, 需要更多符號代碼請參考MIL-STD-2525B)
var Code2525BCollection = [
  "SFAPM-----*****",  "SHAPM-----*****",  "SFAPMFF---*****",  "SHAPMFF---*****",  "SFAPMFFI--*****",  "SUAP------*****",  "SFAPMF----*****",  "IFAPSCO-----***",  "IHAPSCO-----***",  "IFAPSRE-----***",
  "IHAPSRE-----***",  "IUSPSCP-----***",  "IUSPSRU-----***",  "IFGPSCP-----***",  "IHGPSCP-----***",  "IFGPSRE-----***",  "IHGPSRE-----***",  "SUSP------*****",  "SUSPCLBB--*****",  "SUSPXM----*****",
  "SHSPXM----*****",  "SFSPXM----*****",  "SNSPXM----*****",  "SUSPXF----*****",  "SHSPXF----*****",  "SHSPXF----*****",  "SFSPXF----*****",  "SFSPXF----*****",  "SFSPXF----*****",  "SFSPXF----*****",
  "SFSPXF----*****",  "SFSPXF----*****",  "SUUP------*****",  "SHUP------*****",  "SFUP------*****",  "SNUP------*****",  "SUAPMFF---*****",  "SNAPMFF---*****",  "SUAPC-----*****",  "SHAPC-----*****",
  "SFAPC-----*****",  "SNAPC-----*****",  "IFSPSCP-----***",  "IHSPSCP-----***",  "IFSPSRE-----***",  "IHSPSRE-----***",  "SFSPG-------***",  "SHSPG-------***",  "SHAPMF----*****",  "SFUPWT------***"
];

// 自訂符號-點擊移動模式
var isDragging;
var isMoveToClickMode = false;

// 在使用其他圖層前必須要先讀入地形 其他圖層的新增都會在callback中
terrainview.openTerrain({
  url: "http://127.0.0.1:8080",
  identifier: "範例地形圖",
  callback: openCallback,
  urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
});

// 地形讀取完成後的callback
function openCallback(result) {
  // 設定底圖
  terrainview.setBaseLayer({
    url: "BING_MAP",
    identifier: "VECTOR",
    urlTemplate: "https://sample.pilotgaea.com.tw/Oview.aspx?{URL}"
  });

  // 設定初始位置
  let initialPos = new GeoPoint(121.2347878442796, 23.427553934089445, 900000);
  let initialV = new Geo3DPoint(0, 0, -1);
  let initialUp = new Geo3DPoint(0, 1, 0);
  let initialCamera = new ov.Camera(initialPos, initialV, initialUp);
  terrainview.gotoCamera(initialCamera, false);

  // 設定滑鼠點擊事件(自訂符號-點擊移動模式)
  document.querySelector("#MyMap canvas").addEventListener("mousedown", () => {
    isMoveToClickMode && (isDragging = false);
  });
  document.querySelector("#MyMap canvas").addEventListener("mousemove", () => {
    isMoveToClickMode && (isDragging = true);
  });
  document.querySelector("#MyMap canvas").addEventListener("mouseup", () => {
    isMoveToClickMode && setCustomEntityGeo();
  });

  // 插入軍事符號
  insert2525b();
  // 更新畫面
  updateScreen();

  // 設定自訂參數面板的的input事件
  var allInput = document.getElementsByTagName("input");
  for (var i = 0; i < allInput.length; i++) {
    allInput[i].addEventListener("input", updateCustomEntity);
  }

  // 更新自訂符號
  updateCustomEntity();
}

// 更新自訂符號
function updateCustomEntity() {
  // 取得自訂符號參數
  var lat = Number(document.getElementById("lat").value);
  var lng = Number(document.getElementById("lng").value);
  var height = Number(document.getElementById("height").value);
  var code = document.getElementById("code").value;
  var size = Number(document.getElementById("size").value);
  var dtg = document.getElementById("dtg").value;
  var location = document.getElementById("location").value;
  var direction = document.getElementById("direction").value;
  var type = document.getElementById("type").value;
  var quantity = document.getElementById("quantity").value;
  var staffComments = document.getElementById("staffComments").value;
  var additionalInformation = document.getElementById("additionalInformation")
    .value;

  // 建立自訂符號參數物件
  var parameter = {
    code,
    geo: new GeoPoint(lng, lat, height),
    size,
    extra: {
      dtg,
      location,
      direction,
      type,
      quantity,
      staffComments,
      additionalInformation
    }
  };

  // 如果已經有自訂符號就更新, 沒有就新增
  if (customEntity) {
    customEntity.update(parameter);
  } else {
    customEntity = militaryModule.add2525BEntity(parameter);
  }
}

// 更新軍事符號
function update2525B(time) {
  // 檢查時間參數
  if (time === undefined) time = 0;

  // 計算時間差
  let delta = time - lastTime;

  // 更新軍事符號位置
  for (var i = 0; i < military2525BEntitys.length; i++) {
    var course = military2525BEntitys[i].course;
    var speed = military2525BEntitys[i].speed;
    var geo = military2525BEntitys[i].geo;
    var updateFlag = military2525BEntitys[i].updateFlag++;
    var code = undefined;
    geo.x += Math.sin(course * Math.PI * 2) * speed * delta * 0.001;
    geo.y += Math.cos(course * Math.PI * 2) * speed * delta * 0.001;

    if (updateFlag % 60 === 0) {
      military2525BEntitys[i].course += Math.random() - 0.5;
    }

    if (updateFlag % 20 === 0) {
      code = Code2525BCollection[Math.floor(Math.random() * 50) % 50];
    }

    military2525BEntitys[i].entity.update({ geo: geo, code: code });
  }

  // 更新上次更新時間
  lastTime = time;
}

// 自訂符號-點擊移動模式
function setCustomEntityGeo() {
  if (isDragging) return;
  const { x: lng, y: lat } = terrainview.mousePos;
  document.getElementById("lat").value = lat;
  document.getElementById("lng").value = lng;
  isMoveToClickMode = false;
  terrainview.cursor = "default";
  updateCustomEntity();
}

// 切換軍事符號提示面板顯示
function toggleSIDCHint() {
  var SIDC_HINT_PANEL = document.getElementById("SIDC_HINT_PANEL");
  var currentDisplay = SIDC_HINT_PANEL.style.display;

  SIDC_HINT_PANEL.style.display =
    currentDisplay == "none" || currentDisplay == "" ? "block" : "none";
}

// 開始點擊移動模式
function clickToMove() {
  terrainview.cursor = "alias"; // 設定滑鼠游標
  isMoveToClickMode = true;
}

// 更新畫面
function updateScreen(time) {
  terrainview.updateScreen(); // 更新圖台畫面
  update2525B(time); // 更新軍事符號位置
  updateFPS(); // 更新FPS
  requestAnimationFrame(updateScreen); // 設定下一次更新畫面
}

// 設定FPS顯示
function updateFPS() {
  document.getElementById("FpsSpan").innerHTML =
    "Fps: " + terrainview.getFPS().toFixed(0);
}

// 插入軍事符號
function insert2525b() {
  // 取得軍事符號數量
  let iconcount = document.getElementById("totalnumber").value;

  // 檢查軍事模組是否存在, 如果存在就移除所有軍事符號重新插入
  if (militaryModule !== null) {
    militaryModule.removeAllEntity(); // 移除所有軍事符號
    military2525BEntitys = []; // 重置軍事符號集合

    // 按照軍事符號數量插入軍事符號
    for (var i = 0; i < iconcount; i++) {
      // 隨機取得軍事符號代碼
      var codeString = Code2525BCollection[i % 50];
      // 隨機取得軍事符號位置
      var geo = new GeoPoint(
        119 + Math.random() * 10,
        21 + Math.random() * 10,
        Math.random() * 5000 + 8000
      );
      // 插入軍事符號
      var entity = militaryModule.add2525BEntity({
        code: codeString,
        geo: geo,
        size: 32
      });

      // 將軍事符號加入軍事符號集合
      military2525BEntitys.push({
        geo: geo,
        entity: entity,
        course: Math.random(),
        speed: Math.random(),
        updateFlag: i
      });
    }

    // 重置自訂符號
    customEntity = null;
    // 更新自訂符號
    updateCustomEntity();
  }
}

style.css

#MyMap {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

#MyControl {
  position: absolute;
  z-index: 1;
  color: white;
  background-color: black;
}

#SIDC_HINT_PANEL {
  position: absolute;
  top: 0px;
  left: 270px;
  padding: 2px;
  width: 700px;
  background-color: snow;
  color: #333;
  z-index: 10;
  font-size: 8px;
  margin: auto;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
  padding: 16px;
  display: none;
}

#SIDC_HINT_PANEL table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 16px;
}

#SIDC_HINT_PANEL th,
#SIDC_HINT_PANEL td {
  border: 1px solid #ddd;
  text-align: left;
  padding: 8px;
}

#SIDC_HINT_PANEL th {
  background-color: #207523;
  color: white;
}

#SIDC_HINT_PANEL caption {
  font-size: 14px;
  margin-bottom: 2px;
}

#SIDC_HINT_PANEL caption a {
  text-decoration: underline;
  color: royalblue;
}

.SIDCHint {
  background-color: silver;
  border-radius: 50%;
  margin-right: 5px;
  font-size: 8px;
  padding: 2px;
  position: relative;
  cursor: pointer;
  margin-left: 5px;
  top: -2px;
}

.SIDCHint:hover::after {
  content: "點擊顯示編碼提示";
  position: absolute;
  width: 100px;
  background-color: white;
  border: 1px solid black;
  color: black;
  font-size: 12px;
  top: 25px;
  transform: translateX(-50%);
  cursor: pointer;
}

.panelCloseButton {
  position: absolute;
  top: 5px;
  right: 5px;
  color: gray;
  z-index: 10;
  border-radius: 4px;
  cursor: pointer;
}

DEMO 簡介

military_demo_3

操作說明

  1. 藍色箭頭處下拉式選單可設定畫面上要生成的符號數量
  2. 紅色箭頭處點擊後可顯示符號提示面板
  3. 綠色箭頭處點擊後再點擊地圖上任意位置可移動自訂符號
Copyright © NCHC 2022 Version:13.0 all right reserved,powered by Gitbook修訂時間: 2024-11-20 13:52:09