首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 整合 Google Earth COM API 開發實戰 (四):滑鼠滾輪縮放、地標圖層樹狀顯示與切換

     編輯:關於C#

承接前三篇,本文實作三項關鍵互動功能:滑鼠滾輪控制縮放、讀取並顯示地標 (PlaceMarks) 與圖層 (Layers) 於樹狀檢視、支援勾選切換可見度。完整程式碼展示如何透過 COM 介面與 Windows 訊息鉤子實現豐富的 Google Earth 嵌入應用體驗。

功能 1:滑鼠滾輪縮放

利用全域滑鼠鉤子 (HookAPI.dll) 攔截 WM_MOUSEWHEEL,判斷滑鼠是否在 Google Earth 渲染視窗內,送出自訂縮放訊息。


// 滾輪縮放常數 (WPARAM 值)
private const long ZoomIn = 0x00780000;   // 向前滾動
private const long ZoomOut = 0xFF880000;  // 向後滾動

// 鉤子事件註冊
mouseHook.MouseWheel += mouseHook_MouseWheel;

void mouseHook_MouseWheel(object sender, MouseEventArgs e)
{
    IntPtr hWnd = NativeMethods.WindowFromPoint(e.Location);
    if (hWnd == this.GeRenderHWnd) // 滑鼠在 GE 渲染視窗上
    {
        Point clientPt = this.Control.PointToClient(e.Location);
        if (this.Control.ClientRectangle.Contains(clientPt))
        {
            // 送出 WM_MOUSEWHEEL 給 GE 視窗
            NativeMethods.PostMessage(GeRenderHWnd, 
                (int)WM_MOUSE.WM_MOUSEWHEEL, 
                e.Delta > 0 ? ZoomIn : ZoomOut, 0);
        }
    }
}

功能 2:讀取並顯示 PlaceMarks (地標)

GE COM API 提供兩個根節點:GetMyPlaces() (我的位置) 與 GetTemporaryPlaces() (暫存位置)。遞迴走訪 FeatureGE.GetChildren() 建立樹狀結構,Visibility 屬性對應勾選狀態。


protected void ShowPlaces()
{
    Thread.Sleep(500); // 等待 GE 就緒
    var myPlaces = GeApp.GetMyPlaces();
    var tempPlaces = GeApp.GetTemporaryPlaces();

    var places = new List { myPlaces, tempPlaces };
    var toolPad = GetToolPad();
    toolPad.ShowPlaces(places); // 傳給工具面板 UI
}

// 工具面板顯示邏輯 (跨執行緒安全)
public void ShowPlaces(List places)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new Action(() => InternalShowPlaces(places)));
    }
    else InternalShowPlaces(places);
}

protected void InternalShowPlaces(List places)
{
    tvPlaces.Nodes.Clear();
    foreach (var place in places)
    {
        var node = new TreeNode(place.Name) 
        { 
            Checked = place.Visibility > 0, 
            Tag = place 
        };
        ShowChildrenPlaces(place, node);
        node.Expand();
        tvPlaces.Nodes.Add(node);
    }
}

protected void ShowChildrenPlaces(FeatureGE place, TreeNode parentNode)
{
    foreach (FeatureGE child in place.GetChildren())
    {
        var node = new TreeNode(child.Name) 
        { 
            Checked = child.Visibility > 0, 
            Tag = child 
        };
        ShowChildrenPlaces(child, node);
        parentNode.Nodes.Add(node);
    }
}

功能 3:讀取並顯示圖層

GeApp.GetLayersDatabases() 取得內建圖層資料庫集合,結構與 PlaceMarks 相同,同樣遞迴建樹並綁定 Visibility。


protected void ShowLayers()
{
    Thread.Sleep(500);
    var layers = GeApp.GetLayersDatabases();
    var toolPad = GetToolPad();
    toolPad.ShowLayers(layers);
}

public void ShowLayers(FeatureCollectionGE layers)
{
    if (this.InvokeRequired)
        this.Invoke(new Action(() => InternalShowLayers(layers)));
    else
        InternalShowLayers(layers);
}

protected void InternalShowLayers(FeatureCollectionGE layers)
{
    tvLayers.Nodes.Clear();
    foreach (FeatureGE layer in layers)
    {
        var node = new TreeNode(layer.Name) 
        { 
            Checked = layer.Visibility > 0, 
            Tag = layer 
        };
        ShowChildrenLayers(layer, node);
        node.Expand();
        tvLayers.Nodes.Add(node);
    }
}

protected void ShowChildrenLayers(FeatureGE layer, TreeNode parentNode)
{
    foreach (FeatureGE child in layer.GetChildren())
    {
        var node = new TreeNode(child.Name) 
        { 
            Checked = child.Visibility > 0, 
            Tag = child 
        };
        ShowChildrenLayers(child, node);
        parentNode.Nodes.Add(node);
    }
}

TreeView 節點勾選事件處理

使用者勾選/取消勾選節點時,更新對應 FeatureGE.Visibility 屬性即可即時控制 GE 顯示:


private void tvPlaces_AfterCheck(object sender, TreeViewEventArgs e)
{
    if (e.Action != TreeViewAction.Unknown) // 僅使用者操作觸發
    {
        var feature = e.Node.Tag as FeatureGE;
        if (feature != null)
            feature.Visibility = e.Node.Checked ? 1 : 0;
    }
}

關鍵技術點總結

技術用途關鍵 API
全域滑鼠鉤子攔截滾輪訊息並轉發給 GEHookAPI.dll, PostMessage, WM_MOUSEWHEEL
FeatureGE 型別代表地標、圖層、資料夾等節點GetChildren(), Visibility, Name
跨執行緒 UI 更新GE 事件回呼非 UI 執行緒Control.InvokeRequired, Invoke
TreeView Tag 屬性綁定 FeatureGE 物件實現雙向同步node.Tag = feature

執行畫面

Google Earth 嵌入應用畫面:左側地標與圖層樹狀清單,右側 3D 地球視圖

原始碼下載

完整專案包含前四篇所有功能:GEDemo_2009-05-22.rar

系列文章回顧

  1. (一) Hello World:啟動 GE、截圖、基本 COM 呼叫
  2. (二) 視窗嵌入:隱藏 GE 視窗、將渲染畫面重定向至自訂 Form
  3. (三) 互動增強:視窗自適應、滑鼠點擊/雙擊取得經緯度、彩色截圖
  4. (四) 本文:滾輪縮放、地標圖層樹狀管理

總結

透過 COM API 與 Windows 訊息機制,我們成功將 Google Earth 轉化為可程式化控制的 3D 地球元件。滾輪縮放提供直觀導航,樹狀地標/圖層面板賦予專業 GIS 應用的資料管理能力。後續可擴充:KML 動態載入、GPS 軌跡回放、空間查詢分析等企業級地理資訊功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved