編集モードでフィーチャ間をズームしますか?


8

数百ポイントのシェープファイルを手動で編集する必要があります。

属性の意味と視覚/空間の意味の両方で、あるポイントから次のポイントにすばやくジャンプする方法を教えてください。つまり、編集モードで、属性テーブルを開かずにオブジェクトID 1からオブジェクトID 2にジャンプしたいと思います。 、次のポイントの選択、選択範囲へのズームなど

手動プロセスを迅速化する一種の「次へ」ボタン。


ArcObjectsの機能はありますか?私はこの欠陥に気づき、そのためのツールを書きました。あなたがそれを使うことができるなら、私はコードを共有してうれしいです。
Michael Stimson

残念ながら、私は学ぶことを嬉しく思いますが、しません...
user32882

ArcGisインストールメディアからSDKをインストールする必要がありますが、最初にVisual Studio(Express)を入手する必要があります。前提条件については、私の回答gis.stackexchange.com/questions/62720/…ご覧ください。シェープファイルには、保存時にFIDが変更されるという問題があるので、シェープファイルでこのツールを使用するには、最後まで保存しないようにする必要があることに言及する必要があります。
Michael Stimson

@ MichaelMiles-Stimson、ユーザーがSDKとVSをインストールする必要がないように共有できるこのツールのアドインはありますか?
アートワーク21 2015

アドインはとてもいいです...
user32882 '27 / 07/27

回答:


6

最初の部分はAddInで、実際の作業はフォームで行われます。

Inherits ESRI.ArcGIS.Desktop.AddIns.Button
Private pForm As fFeatureInspector
Public Shared IsFormLoaded As Boolean = False

Public Sub New()

End Sub

Protected Overrides Sub OnClick()
    'My.ArcMap.Application.CurrentTool = Nothing
    If Not IsFormLoaded Then
        pForm = New fFeatureInspector
        pForm.pApp = CType(My.ArcMap.Application, ESRI.ArcGIS.ArcMapUI.IMxApplication)
        pForm.Show()
    Else
        pForm.sResetList()
    End If

End Sub

Protected Overrides Sub OnUpdate()
    Enabled = My.ArcMap.Application IsNot Nothing
End Sub

新しいアドインを作成するとき、これのほとんどはすでに存在しています。次に、プロジェクトにフォームを追加します(fFeatureInspectorという名前を付けるか、コードで数回変更する必要があります)。

ここに画像の説明を入力してください

名前を正しく取得することが重要です。そうしないと、フォームコードで検索と置換を行う必要があります。フォームのツールボックスには、ボタンチェックボックスリストボックスコンボボックスのすべての共通コントロールがあります

これがどのように機能するかは、ツールがすべての選択された編集可能な機能を取得し、それらの名前とOID / FIDをリストボックスにコピーし、1つが強調表示されるとそれを選択して(最初に選択をクリアした後)、それにズームします。検査を保存するための保存と読み込みボタンがあり、1つ前と1つ前に進むと、自動保存チェックとリセットボタンがあります。ツールは読み込まれると更新されますが、その後はいつでも更新できます。FIDは静的ではなく、保存時に圧縮されるため、自動保存はシェープファイルの編集と互換性がありません

ポイントの幅の範囲は0であるため、最小スケールを現実的なものに設定することが重要です。ズーム%は、ポリゴン/ラインの周りに表示したい大きさです。

ここにフォームコードがあります(コメントがないので申し訳ありません):

Imports ESRI.ArcGIS.Framework
Imports ESRI.ArcGIS.ArcMapUI
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Editor
Imports ESRI.ArcGIS.Display

Public Class fFeatureInspector
    Const FormCaption As String = "Feature Inspector (22 Feb 10)"
    Const FormName As String = "fFeatureClass"
    Public pApp As IApplication
    Private pDoc As IMxDocument
    Private pMap As IMap

    Dim pEd As IEditor2
    Dim pID As UID = New UID
    Dim pFeatFrom() As String
    Dim pFeatWS As IFeatureWorkspace
    Dim pWS As IWorkspace
    Dim pFeatOID() As Long
    Dim pFeatCnt As Long
    Dim pInRefresh As Boolean
    Dim pPointExtent As IEnvelope
    Dim pSaveEdits As ICommandItem
    Dim pLoadTime As Long
    Dim pNow As Date
    Dim pStartIndex As Long

    Dim vStartTime As DateTime
    Dim vCurrentTime As DateTime

    Private Sub fFeatureInspector_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
        StartFeatureInspector.IsFormLoaded = False
    End Sub
    Private Sub fFeatureInspector_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        pEd = pApp.FindExtensionByName("Esri Object Editor")
    End Sub
    Private Sub form1_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move
        Dim pOutFile As Integer
        Dim pTempDir As String = Environ("Temp")

        If Me.Visible Then
            pOutFile = FreeFile()
            FileOpen(pOutFile, pTempDir & "\" & FormName & ".xy", OpenMode.Output)
            WriteLine(pOutFile, Me.Left & "," & Me.Top)
            FileClose(pOutFile)
        End If
    End Sub
    Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        StartFeatureInspector.IsFormLoaded = True
        Me.Text = FormCaption
        pDoc = CType(pApp.Document, IMxDocument)

        Dim pTempDir As String = Environ("temp")
        Dim pInFile As Integer
        Dim pReadString As String = ""
        Dim pResyk As String = ""
        Dim pXpos As Integer = 0
        Dim pYpos As Integer = 0

        fZoomPercent.Items.Add(110)
        fZoomPercent.Items.Add(150)
        fZoomPercent.Items.Add(200)
        fZoomPercent.Text = "110"

        fPointScale.Items.Add(200)
        fPointScale.Items.Add(500)
        fPointScale.Items.Add(1000)
        fPointScale.Items.Add(2500)
        fPointScale.Items.Add(10000)
        fPointScale.Text = "1000"

        If My.Computer.FileSystem.FileExists(Environ("Temp" & "\" & FormName & ".xy")) Then
            pApp.StatusBar.Message(0) = "Loading position"
            pInFile = FreeFile()
            FileOpen(pInFile, pTempDir & "\" & FormName & ".xy", OpenMode.Input)
            pReadString = LineInput(pInFile)
            pReadString = Mid(pReadString, 2, Len(pReadString) - 2)
            pApp.StatusBar.Message(0) = pReadString

            pResyk = Microsoft.VisualBasic.Left(pReadString, InStr(pReadString, ",") - 1)
            pApp.StatusBar.Message(0) = pResyk
            pXpos = CInt(pResyk)

            pApp.StatusBar.Message(0) = "Xposition " & pXpos
            pResyk = Microsoft.VisualBasic.Right(pReadString, Len(pReadString) - InStr(pReadString, ","))
            pApp.StatusBar.Message(0) = pResyk
            pYpos = CInt(pResyk)
            pApp.StatusBar.Message(0) = "Yposition " & pYpos
            FileClose(pInFile)
            Me.Left = pXpos
            Me.Top = pYpos
        End If
        sResetList()
        pID.Value = "{59D2AFD2-9EA2-11D1-9165-0080C718DF97}"
        Dim pComBars As ICommandBars = pApp.Document.CommandBars
        pSaveEdits = pComBars.Find(pID, False, False)

    End Sub
    Private Sub fSaveButton_Click()
        Dim pOutfile As Integer
        Dim cnt As Long

        pOutfile = FreeFile()
        FileOpen(pOutfile, (Environ("Temp") & "\" & "FeatInspect"), OpenMode.Output, OpenAccess.Write)

        Print(pOutfile, pFeatCnt & vbNewLine)
        For cnt = 0 To pFeatCnt - 1
            Print(pOutfile, pFeatFrom(cnt) & "|" & pFeatOID(cnt) & vbNewLine)
        Next cnt
        Print(pOutfile, fFeatureList.SelectedIndex & vbNewLine)
        Print(pOutfile, fZoomPercent.Text & vbNewLine)
        Print(pOutfile, fPointScale.Text & vbNewLine)
        FileClose(pOutfile)
    End Sub
    Private Sub fSaveButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fSaveButton.Click
        fSaveButton_Click()
    End Sub
    Private Sub fLoadButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fLoadButton.Click
        Dim cnt As Long
        Dim pInFile As Integer
        Dim pReadString As String
        Dim pSplitString() As String

        pInRefresh = True
        fFeatureList.Items.Clear()
        pInFile = FreeFile()
        FileOpen(pInFile, (Environ("Temp") & "\" & "FeatInspect"), OpenMode.Input, OpenAccess.Read)
        pReadString = LineInput(pInFile)
        pFeatCnt = pReadString
        ReDim pFeatFrom(pFeatCnt)
        ReDim pFeatOID(pFeatCnt)

        fFeatureList.Items.Clear()

        For cnt = 0 To pFeatCnt - 1
            pReadString = LineInput(pInFile)
            pSplitString = Split(pReadString, "|")

            pFeatFrom(cnt) = pSplitString(0)
            pFeatOID(cnt) = pSplitString(1)
            fFeatureList.Items.Add(pFeatFrom(cnt) & " - " & pFeatOID(cnt))
        Next cnt
        pInRefresh = False
        pReadString = LineInput(pInFile)
        fFeatureList.SelectedIndex = pReadString
        pReadString = LineInput(pInFile)
        fZoomPercent.Text = pReadString
        pReadString = LineInput(pInFile)
        fPointScale.Text = pReadString
        FileClose()
        pStartIndex = fFeatureList.SelectedIndex
        pNow = Now()
        pLoadTime = (Hour(pNow) * 3600) + (Minute(pNow) * 60) + Second(pNow)

    End Sub

    Private Sub fBackButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fBackButton.Click
        If fFeatureList.SelectedIndex = 0 Then
            MsgBox("But you're already at the start!")
            Exit Sub
        End If
        fFeatureList.SelectedIndex = fFeatureList.SelectedIndex - 1
    End Sub
    Private Sub fGoDown_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fGoDown.Click
        If fFeatureList.SelectedIndex = fFeatureList.Items.Count - 1 Then
            MsgBox("That's all there is, there isn't anymore.")
            Exit Sub
        End If
        fFeatureList.SelectedIndex = fFeatureList.SelectedIndex + 1
    End Sub
    Private Sub bReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bReset.Click
        pInRefresh = True
        sResetList()
        pInRefresh = False
        fFeatureList_Change()
        pLoadTime = (Hour(pNow) * 3600) + (Minute(pNow) * 60) + Second(pNow)
    End Sub
    Public Sub sResetList()
        Dim pEnumFeat As IEnumFeature
        Dim pFeature As IFeature
        Dim pFeatClass As IFeatureClass

        If pEd.EditState = esriEditState.esriStateNotEditing Then Exit Sub
        pEnumFeat = pEd.EditSelection

        pFeature = pEnumFeat.Next
        If pFeature Is Nothing Then
            MsgBox("Nothing selected", vbCritical)
            Exit Sub
        End If
        pFeatCnt = pEd.SelectionCount - 1

        ReDim pFeatFrom(pFeatCnt)
        ReDim pFeatOID(pFeatCnt)

        pFeatCnt = 0

        fFeatureList.Items.Clear()

        Do Until pFeature Is Nothing
            pFeatClass = pFeature.Class
            pFeatFrom(pFeatCnt) = pFeatClass.AliasName
            pFeatOID(pFeatCnt) = pFeature.OID
            fFeatureList.Items.Add(pFeatFrom(pFeatCnt) & " - " & pFeatOID(pFeatCnt))
            pFeatCnt = pFeatCnt + 1
            pFeature = pEnumFeat.Next
        Loop

        pEd.Map.ClearSelection()
        fFeatureList.SelectedIndex = 0
        pNow = Now()
        pLoadTime = (Hour(pNow) * 3600) + (Minute(pNow) * 60) + Second(pNow)

    End Sub

    Private Sub fFeatureList_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fFeatureList.SelectedIndexChanged
        fFeatureList_Change()
    End Sub
    Private Sub fFeatureList_Change()
        Dim pFeatClass As IFeatureClass
        Dim pFeature As IFeature
        Dim pSelection As ISelection
        Dim pLayer As ILayer
        Dim pEnumLayer As IEnumLayer
        Dim pEditLayers As IEditLayers
        Dim pFeatLayer As IFeatureLayer
        Dim pEnv As IEnvelope2
        Dim pDispTran As IDisplayTransformation
        Dim pThisTime As Long
        Dim pAvVis As Single
        Dim pTotTime As Long
        Dim pDeltaVis As Long
        Dim pLeft As Long
        Dim pTPF As Long
        Dim pAvVisStr As String
        Dim pETAstr As String
        Dim pPoint As ESRI.ArcGIS.Geometry.IPoint
        Dim cnt As Long

        If pInRefresh Then Exit Sub
        If fFeatureList.SelectedIndex < 0 Then Exit Sub

        If pEd.EditState = esriEditState.esriStateNotEditing Then
            MsgBox("This tool only works on EDIT features" & vbNewLine & "Please start editing", vbCritical)
            Exit Sub
        End If
        pFeatWS = pEd.EditWorkspace
        pFeatClass = pFeatWS.OpenFeatureClass(pFeatFrom(fFeatureList.SelectedIndex))
        On Error Resume Next
        pFeature = pFeatClass.GetFeature(pFeatOID(fFeatureList.SelectedIndex))
        If pFeature Is Nothing Then
            MsgBox("Feature not found", vbCritical) ' comment this out if you don't want to see errors
        End If
        pEd.Map.ClearSelection()
        pID.Value = "{6CA416B1-E160-11D2-9F4E-00C04F6BC78E} "
        pEnumLayer = pEd.Map.Layers(pID, True)
        pEditLayers = pEd

        pLayer = pEnumLayer.Next
        Do Until pLayer Is Nothing
            If TypeOf pLayer Is IFeatureLayer Then
                If pEditLayers.IsEditable(pLayer) And pLayer.Visible = True Then
                    pFeatLayer = pLayer
                    If pFeatLayer.Selectable Then
                        If pFeatLayer.FeatureClass.AliasName = pFeatFrom(fFeatureList.SelectedIndex) Then
                            pEd.Map.SelectFeature(pLayer, pFeature)
                            If pFeatLayer.FeatureClass.ShapeType = esriGeometryType.esriGeometryPoint Then
                                pEnv = New Envelope
                                pEnv.PutCoords(pDoc.ActiveView.Extent.XMin, pDoc.ActiveView.Extent.YMin, pDoc.ActiveView.Extent.XMax, pDoc.ActiveView.Extent.YMax)
                                pEnv.SpatialReference = pFeature.Shape.SpatialReference
                                If pEnv.SpatialReference.FactoryCode <> pDoc.FocusMap.SpatialReference.FactoryCode Then pEnv.Project(pDoc.FocusMap.SpatialReference)
                                pPoint = New ESRI.ArcGIS.Geometry.PointClass
                                pPoint = pFeature.ShapeCopy
                                pEnv.CenterAt(pPoint)
                                pDoc.ActiveView.Extent = pEnv
                                pDispTran = pDoc.ActiveView.ScreenDisplay.DisplayTransformation
                                If Len(fPointScale.Text) > 0 Then
                                    pDispTran.ScaleRatio = Int(fPointScale.Text)
                                Else
                                    pDispTran.ScaleRatio = 1000
                                End If
                                If fSaveOnNext.Checked Then
                                    pSaveEdits.Execute()
                                    fSaveButton_Click()
                                End If 'If fSaveOnNext.Checked Then
                                pDoc.ActiveView.Refresh()
                            Else

                                If Not pFeature.Shape.Envelope.IsEmpty Then
                                    pEnv = New Envelope
                                    pEnv.PutCoords(pFeature.Extent.XMin, pFeature.Extent.YMin, pFeature.Extent.XMax, pFeature.Extent.YMax)
                                    pEnv.SpatialReference = pFeature.Shape.SpatialReference
                                    If pEnv.SpatialReference.FactoryCode <> pDoc.FocusMap.SpatialReference.FactoryCode Then pEnv.Project(pDoc.FocusMap.SpatialReference)
                                    If Len(fZoomPercent.Text) > 0 Then
                                        pEnv.Expand(Int(fZoomPercent.Text) / 100, Int(fZoomPercent.Text) / 100, True)
                                    End If
                                    pDoc.ActiveView.Extent = pEnv
                                    If fPointScale.Text.Length > 0 Then
                                        If pDoc.ActiveView.ScreenDisplay.DisplayTransformation.ScaleRatio < Int(fPointScale.Text) Then pDoc.ActiveView.ScreenDisplay.DisplayTransformation.ScaleRatio = Int(fPointScale.Text)
                                    End If
                                    If fSaveOnNext.Checked Then
                                        pSaveEdits.Execute()
                                        fSaveButton_Click()
                                    End If 'If fSaveOnNext.Checked Then
                                    pDoc.ActiveView.Refresh()
                                End If 'Not pFeature.Shape.Envelope.IsEmpty
                            End If 'pFeatLayer.FeatureClass.ShapeType = esriGeometryType.esriGeometryPoint Then
                        End If 'pFeatLayer.FeatureClass.AliasName = pFeatFrom(fFeatureList.SelectedIndex) Then
                    End If 'pFeatLayer.Selectable Then
                End If 'pEditLayers.IsEditable(pLayer) And pLayer.Visible = True Then
            End If
            pLayer = pEnumLayer.Next
        Loop 'Until pLayer Is Nothing

        pNow = Now()
        pThisTime = (Hour(pNow) * 3600) + (Minute(pNow) * 60) + Second(pNow)
        pTotTime = pThisTime - pLoadTime
        pDeltaVis = fFeatureList.SelectedIndex - pStartIndex
        If pDeltaVis <= 0 Then
            fProgressLabel.Text = "Unable to Calculate"
            Exit Sub
        Else
            pAvVis = pTotTime / pDeltaVis
            pLeft = fFeatureList.Items.Count - fFeatureList.SelectedIndex + 1
            pETAstr = fLongTime_to_TimeString(pLeft * pAvVis)

            fProgressLabel.Text = pDeltaVis & " Inspected of " & fFeatureList.Items.Count & ". ETA " & pETAstr
            Me.Update()

        End If
    End Sub

    Private Function fLongTime_to_TimeString(ByVal pLongTime As Long) As String
        Dim pRemainder As Long
        Dim pHour As Integer
        Dim pMin As Integer
        Dim pSec As Integer

        pRemainder = pLongTime Mod 3600
        pHour = pLongTime - pRemainder
        If pHour > 0 Then pLongTime = pLongTime - pHour
        pRemainder = pLongTime Mod 60
        pMin = pLongTime - pRemainder
        If pMin > 0 Then pLongTime = pLongTime - pMin
        pSec = pLongTime

        pHour = pHour / 3600
        pMin = pMin / 60

        fLongTime_to_TimeString = pHour & ":" & pMin & ":" & pSec
    End Function


End Class

コンパイルされたコードを共有したくないので、ここにリンクがあります。Esriのドキュメント「アドインの共有と追加」をお読みください。


寛大にありがとうございました。これは非常に有益になると私の時間の全体の多くを保存します
user32882

7

次の機能へのズームのアークピーバージョンです。これは、ArcMapのpythonウィンドウで実行できます。

mxd = arcpy.mapping.MapDocument("CURRENT") # currently opened map doc
df = arcpy.mapping.ListDataFrames(mxd, "Layers") [0]

# define layer you want to iterate and zoom on
for lyr in arcpy.mapping.ListLayers(mxd):
    if lyr.name == 'myTOCLayerNameHere':
        fc = lyr

# get total record count of fc
with arcpy.da.SearchCursor(fc, ["FID"]) as cursor:
    for row in cursor:
        totalCount+=1

def selectZoomNext(fc, field, record):
    if record > totalCount:
        record = 0 # reset to first feature
    expression = '{} = {}'.format(field, record)
    arcpy.SelectLayerByAttribute_management (fc, "NEW_SELECTION", expression)
    df.zoomToSelectedFeatures()
    nextRecord = record + 1
    return nextRecord

record = 0
record = selectZoomNext(fc, 'FID', record) # second argument is the field name, this could be OBJECTID too

record = selectZoomNext(fc, 'FID', record)ステートメントを引き続き実行して、テーブル内の次の機能を選択し、ズームすることができます。このスニペットをpythonアドインまたはpythonスクリプトツールに含めることもできます。さらに、編集中に物事を簡単にするために、(レイヤープロパティの)不要なフィールドをオフにして、属性パネルを開いてすばやく属性にアクセスすることもできます。


それも機能します。コードの長さと複雑さにおけるArcObjectsとPythonの違いを示す良い例だと思います。これはシェープファイルでも同じ問題が発生し、ファイル/パーソナル/ SDEジオデータベースフィーチャクラスでは機能しないことに注意してください。これは、OID / FID値が連続的で0ベースであることが保証されていないためです。これはシェープファイル形式の癖です。
Michael Stimson、2015

@ MichaelMiles-Stimson、はいAddFieldDelimitersメソッドを使用して、ファイル、.mdb、および.gdbソース間の正しいフィールド式を作成することをお勧めしますhelp.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//…
アートワーク21 2015

1
ジオデータベースフィーチャクラスでは、OID値は0から開始する必要はなく、次の値が1である必要もありません。カウントするときに、OBJECTIDをリストまたはディクショナリに取得する必要があります。ジオデータベースにはFIDではなくOBJECTIDがあるため、カーソルを上に向けて、arcpy.Describe(fc).OIDFieldNameをフィールドとして使用する必要もあります。
Michael Stimson、2015

3

あなたが持っていますか、データレビューの拡張子が?Data Reviewerでは、「次へ」ボタンをクリックするだけで、すべての機能を「参照」できます(空間位置と属性テーブルレコードの両方にズームします)。これ以外に、Data Reviewerには多くの機能があります(「修正済み」、「マーク付き」などのエラーにフラグを付け、バッチジョブを実行するなど)。既成のツールですが、@ Michaelのツールも素晴らしいと思います。

ここに画像の説明を入力してください


私が必要としているもののように見えますが、私のライセンスレベルにはデータレビュー担当者が含まれていないようです:(
user32882

PLTS(現在はプロダクションマッピング)を聞く前に自分のツールを作成しました。要件は非常に基本的ですが必要であるため、元のインスピレーションはAMLスクリプトに書き込まれました。Esriがこのツールを使用していることに驚いていませんが、ArcMapにネイティブではないのはなぜですか?データレビュアーはその機能に非常に優れていますが、評価時に付属するほとんどのツールを既に作成していることがわかりました。
Michael Stimson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.