FAQ
ArcObjects での Snapping クラスを使用したスナップ

ナレッジ番号:2769 | 登録日:2023/05/29 | 更新日:2023/12/28

概要

ArcGIS10 から、新しいスナップ機能(Snapping、SnappingFeedback)が追加されました。このスナップは従来までのバージョンで提供されていたフィーチャ編集時のみ使用できるスナップ(FeatureSnap)とは異なり、フィーチャ編集時以外にもさまざまな場面で使用することができます。

スナップを開始するための手順

  1. グローバル変数として IPointSnapper を宣言します。
  2. IExtensionManager::FindExtension メソッドにより Snapping オブジェクトを取得します。
  3. ISnappingEnvironment で必要なスナップ設定を行います。
  4. スナッピングのフィードバックが必要な場合は、SnappingFeedback オブジェクトを作成し、Initialize メソッドを実行します。
  5. マウス移動時などのタイミングで IPointSnapper::Snap メソッドを実行し、引数に現在のマップ座標をセットします。
  6. スナップされた場合は、戻り値として ISnappingResult 型のオブジェクトが返されるので、ISnappingResult::Location でスナップされた Point オブジェクトを取得します。
  7. スナッピングのフィールドバックが使用されている場合、スナップされるとマップ上にスナップ地点が表示されます。

サンプル コード

このサンプル コードはアドインのツールです。ツールを有効すると、マウス カーソル上のマップ座標をステータス バーに示します。フィーチャ ジオメトリの頂点、もしくはエッジに近接するとスナップを実行して座標値を更新します。スナップした際はフィードバックを表示します。

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using System.Windows.Forms;

namespace FAQ5230
{
    public class Tool_5230 : ESRI.ArcGIS.Desktop.AddIns.Tool
    {
        //参考
        //Working with the ArcGIS snapping environment
        //http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#/d/0001000001s1000000.htm

        //モジュールレベル変数
        private IPoint m_pPoint;
        private IPointSnapper m_pPointSnapper;
        private ISnappingFeedback m_pSnappingFeedback;

        public Tool_5230()
        {
            //スナップ環境の初期化
            IExtensionManager pExtensionManager = (IExtensionManager)ArcMap.Application;
            UID pUID = new UIDClass();
            pUID.Value = "{E07B4C52-C894-4558-B8D4-D4050018D1DA}";
            //Snapping extension.
            ISnappingEnvironment pSnappingEnvironment = pExtensionManager.FindExtension(pUID) as ISnappingEnvironment;

            //スナップ タイプの設定
            pSnappingEnvironment.SnappingType = (esriSnappingType)4 + 8;
            //esriSnappingTypeNone           :  0 スナップなし 
            //esriSnappingTypePoint          :  1 ポイントへスナップ 
            //esriSnappingTypeEndpoint       :  2 端点にスナップ
            //esriSnappingTypeVertex         :  4 頂点にスナップ 
            //esriSnappingTypeEdge           :  8 エッジにスナップ
            //esriSnappingTypeMidpoint       : 16 中間点にスナップ 
            //esriSnappingTypeIntersection   : 32 交点にスナップ 
            //esriSnappingTypeTangent        : 64 タンジェント スナップ(IPointSnapper::TangentInputPoint設定が必要) 

            //スナップ許容値
            pSnappingEnvironment.Tolerance = 10;

            //スナッピング フィードバックの初期化
            m_pPointSnapper = pSnappingEnvironment.PointSnapper;
            m_pSnappingFeedback = new SnappingFeedbackClass();
            m_pSnappingFeedback.Initialize(ArcMap.Application, pSnappingEnvironment, true);
        }

        protected override void OnMouseDown(ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs arg)
        {
            //クリック座標の表示
            MessageBox.Show("X:" + m_pPoint.X.ToString() + ", Y:" + m_pPoint.Y.ToString());
        }

        protected override void OnMouseMove(ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs arg)
        {
            //マップ座標の取得
            m_pPoint = ArcMap.Document.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(arg.X, arg.Y);

            //スナップのテスト
            ISnappingResult snapResult = m_pPointSnapper.Snap(m_pPoint);

            //スナップ フィードバックの更新
            m_pSnappingFeedback.Update(snapResult, 0);

            //スナップされた場合、ポイント座標を更新
            if ((snapResult != null))
            {
                m_pPoint = snapResult.Location;
            }

            //スナップ座標の表示
            ArcMap.Application.StatusBar.set_Message(0, "X:" + m_pPoint.X.ToString() + ", Y:" + m_pPoint.Y.ToString());
        }
    }

}
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports ESRI.ArcGIS.Controls
Imports System.Windows.Forms
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Display
Imports ESRI.ArcGIS.Carto

Public Class Tool_5230
    Inherits ESRI.ArcGIS.Desktop.AddIns.Tool

    '参考
    'Working with the ArcGIS snapping environment
    'http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#/d/0001000001s1000000.htm

    'モジュールレベル変数
    Private m_pPoint As IPoint
    Private m_pPointSnapper As IPointSnapper
    Private m_pSnappingFeedback As ISnappingFeedback


    Public Sub New()
        'スナップ環境の初期化
        Dim pExtensionManager As IExtensionManager = CType(My.ArcMap.Application, IExtensionManager)
        Dim pUID As UID = New UIDClass()
        pUID.Value = "{E07B4C52-C894-4558-B8D4-D4050018D1DA}" 'Snapping extension.
        Dim pSnappingEnvironment As ISnappingEnvironment = TryCast(pExtensionManager.FindExtension(pUID), ISnappingEnvironment)

        'スナップ タイプの設定
        pSnappingEnvironment.SnappingType = DirectCast(4 + 8, esriSnappingType)
        'esriSnappingTypeNone           :  0 スナップなし 
        'esriSnappingTypePoint          :  1 ポイントへスナップ 
        'esriSnappingTypeEndpoint       :  2 終点にスナップ
        'esriSnappingTypeVertex         :  4 頂点にスナップ 
        'esriSnappingTypeEdge           :  8 エッジにスナップ
        'esriSnappingTypeMidpoint       : 16 中間点にスナップ 
        'esriSnappingTypeIntersection   : 32 交点にスナップ 
        'esriSnappingTypeTangent        : 64 タンジェント スナップ(IPointSnapper::TangentInputPoint設定が必要) 

        'スナップ許容値
        pSnappingEnvironment.Tolerance = 10

        'スナッピング フィードバックの初期化
        m_pPointSnapper = pSnappingEnvironment.PointSnapper
        m_pSnappingFeedback = New SnappingFeedbackClass()
        m_pSnappingFeedback.Initialize(My.ArcMap.Application, pSnappingEnvironment, True)
    End Sub

    Protected Overrides Sub OnMouseDown(arg As ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs)
        'クリック座標の表示
        MessageBox.Show("X:" + m_pPoint.X.ToString() + ", Y:" + m_pPoint.Y.ToString())
    End Sub

    Protected Overrides Sub OnMouseMove(arg As ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs)
        'マップ座標の取得
        m_pPoint = My.ArcMap.Document.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(arg.X, arg.Y)

        'スナップのテスト
        Dim snapResult As ISnappingResult = m_pPointSnapper.Snap(m_pPoint)

        'スナップ フィードバックの更新
        m_pSnappingFeedback.Update(snapResult, 0)

        'スナップされた場合、ポイント座標を更新
        If Not snapResult Is Nothing Then
            m_pPoint = snapResult.Location
        End If

        'スナップ座標の表示
        My.ArcMap.Application.StatusBar.Message(0) = "X:" + m_pPoint.X.ToString() + ", Y:" + m_pPoint.Y.ToString()
    End Sub

End Class

参考情報

メタデータ

種類

製品