Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#1 Wed 27 October 2010 11:09

tnicolas
Participant actif
Date d'inscription: 18 Apr 2007
Messages: 64

[ArcGis 9.1] vba et cible d'editeur

Bonjour,

Je cherche a créer un outil me permettant de tracer une polyligne tout en utilisant le snap. Mon document de travail comporte plusieurs couches et je ne veux snaper q'une couche particulière mais je n'arrive pas à définir la cible de l'editeur en utilisant le VBA.

Voici le code que j'utilise actuellement pour ouvrir la session de mise à jour et paramétrer l'outil de traçage (c'est de la bidouille fait avec d'autres bout de code récupéré sur le net)

Code:

Sub ouvrir()
'ouvrir une session de mise à jour et activer le snap
    Dim pEditor As IEditor
    Dim pFeatureLayer As IFeatureLayer
    Dim pDataset As IDataset
    Dim pMap As IMap
    Dim pMxDoc As IMxDocument
    Dim LayerCount As Integer
    Dim pSnapEnv As ISnapEnvironment
    Dim pFeatSnap As IFeatureSnapAgent
    Dim pEditLayers As IEditLayers
    Dim pFeatureClass As IFeatureClass
    Dim pTool As ITool
    Dim pCmdItem As ICommandItem
    Dim pCommandBars As ICommandBars
    Set pEditor = Application.FindExtensionByName("ESRI Object Editor")
    Set pMxDoc = Application.Document
    Set pMap = pMxDoc.FocusMap
    'S'il n'y a pas de session d'édition ouverte
    If pEditor.EditState = esriStateNotEditing Then
    'On ouvre une session d'édition sur la couche SUG
        For LayerCount = 0 To pMap.LayerCount - 1
            If TypeOf pMap.Layer(LayerCount) Is IFeatureLayer Then
' je pense que c'est ici qu'il faut choisir la cible mais cette méthode ne fonctionne pas.
                If pMap.Layer(LayerCount).Name = "SUG" Then
                    Set pFeatureLayer = pMap.Layer(LayerCount)
                    Set pDataset = pFeatureLayer.FeatureClass
                    pEditor.StartEditing pDataset.Workspace
                    Exit For
                End If
            End If
        Next LayerCount
    End If
    'On créer un Snap Agent qui agrègue le point déplacer sur la ligne FerreFra !
    Set pEditLayers = pEditor 'QI
    Set pSnapEnv = pEditor 'QI
    pSnapEnv.ClearSnapAgents
    Set pFeatSnap = New FeatureSnap
    Set pFeatureClass = pFeatureLayer.FeatureClass
    Set pFeatSnap.FeatureClass = pFeatureClass
    'Le curseur vient se coller le long de la featureclass sélectionnée (ci dessus)
    pFeatSnap.HitType = esriGeometryPartBoundary
    pSnapEnv.AddSnapAgent pFeatSnap
    pSnapEnv.SnapToleranceUnits = esriSnapTolerancePixels
    pSnapEnv.SnapTolerance = 10
    Set pCommandBars = ThisDocument.CommandBars
    Set pCmdItem = pCommandBars.Find(ArcID.Editor_SketchTool)
    Set Application.CurrentTool = pCmdItem
    Set pTool = pCmdItem
End Sub

Si quelqu'un a une piste à me donner pour y arriver, je suis preneur  big_smile

Cordialement,

nicolas

Hors ligne

 

#2 Wed 27 October 2010 12:05

Forestis
Participant assidu
Lieu: Aniane (Hérault)
Date d'inscription: 5 Sep 2005
Messages: 168
Site web

Re: [ArcGis 9.1] vba et cible d'editeur

Voici une fonction que j'ai créée pour rechercher un feature layer par son nom
si ça peut être utile...

Code:

Public Function Recherche_FLayer(Nom_Layer As String) As esricarto.IFeatureLayer

Dim i As Integer
Dim pLayer As esricarto.ILayer

Dim MonApp As esriArcMapUI.IMxApplication
Dim MonDoc As esriArcMapUI.IMxDocument
Dim MaMap As esricarto.IMap
Dim MaVueActive As esricarto.IActiveView

Set MonApp = Application
Set MonDoc = ThisDocument
Set MaVueActive = MonDoc.ActiveView
Set MaMap = MaVueActive.FocusMap

For i = 0 To MaMap.LayerCount - 1
    If TypeOf MaMap.Layer(i) Is esricarto.ICompositeLayer = True Then
        Dim MaCoucheCompose As esricarto.ICompositeLayer
        Set MaCoucheCompose = MaMap.Layer(i)
        Dim A As Integer
        For A = 0 To MaCoucheCompose.Count - 1
            If MaCoucheCompose.Layer(A).Name = Nom_Layer Then
                Set Recherche_FLayer = MaCoucheCompose.Layer(A)
                Exit For
            End If
        Next A
    Else
        Set pLayer = MaMap.Layer(i)
        If pLayer.Name = Nom_Layer Then
            Set Recherche_FLayer = pLayer
            Exit For
        End If
    End If
Next i
End Function

EDIT:correction

Dernière modification par Forestis (Wed 27 October 2010 12:07)


[Matthieu Pette - Ad Terram] (@Ad_Terram sur le PiouPiou bleu)

~Géomaticien Indépendant~

Hors ligne

 

#3 Wed 27 October 2010 12:29

tnicolas
Participant actif
Date d'inscription: 18 Apr 2007
Messages: 64

Re: [ArcGis 9.1] vba et cible d'editeur

Merci pour ta fonction mais le problème persiste.
En fait je crois que j'ai pris le problème à l'envers car sans macro on change la cible aprés avoir ouvert la session, pourquoi on ne ferait pas de même dans une macro ... je creuse.

Hors ligne

 

#4 Wed 27 October 2010 12:49

Forestis
Participant assidu
Lieu: Aniane (Hérault)
Date d'inscription: 5 Sep 2005
Messages: 168
Site web

Re: [ArcGis 9.1] vba et cible d'editeur

l'outil de saisie est un outil assez difficile à recreer donc si ta polyligne tu veux la creer "a la main" sans utiliser de données ça me parrait penible et je ne vois pas pourquoi ne pas utiliser les outils existants.
Il faudrait que tu précise un peu plus ton but pour que je puisse mieux t'orienter.
par exemple l'ouverture de session n'est obligatoire sauf si tu implémente le ctrl-z il me semble
C'est un peu vieux mais j'avais utiliser cette fonction quand j'ai eu besoin du snap.

Code:

Private Function ISnapAgent_Snap(ByVal MaCouche As String, ByVal MonPoint As esriGeometry.IPoint, ByVal tolerance As Double) As esriGeometry.IPoint

  Dim minDist As Double
  Dim pFLayer As esricarto.IFeatureLayer
  Dim pSnapPt As esriGeometry.IPoint
  Dim pOutPoly As esriGeometry.IPolygon
  Dim pProximity As esriGeometry.IProximityOperator
  Dim pTopo As esriGeometry.ITopologicalOperator
  Dim X As Double, Y As Double

  Set pProximity = MonPoint
  minDist = 10
  Set pFLayer = ThisDocument.Recherche_FLayer(MaCouche)

  Set pTopo = MonPoint
  Set pOutPoly = pTopo.Buffer(minDist) 'Set the buffer distance to 10 map units

Dim MaRequete As esriGeoDatabase.IQueryFilter
Set MaRequete = New esriGeoDatabase.QueryFilter
MaRequete.WhereClause = ""

Dim pFilter As esriGeoDatabase.ISpatialFilter
Set pFilter = New esriGeoDatabase.SpatialFilter

With pFilter
    Set .Geometry = pOutPoly
    .GeometryField = "Shape"
    .SpatialRel = esriSpatialRelIntersects
End With

Dim pFeatureSelection As esricarto.IFeatureSelection
Set pFeatureSelection = pFLayer
pFeatureSelection.SelectFeatures pFilter, esriSelectionResultNew, True
Dim MonCurseur As esriGeoDatabase.ICursor
pFeatureSelection.SelectionSet.Search MaRequete, False, MonCurseur
Dim MaLigne As esriGeoDatabase.IRow
Set MaLigne = MonCurseur.NextRow
pFeatureSelection.Clear

Dim MaFeature As esriGeoDatabase.IFeature
Set MaFeature = MaLigne
If MaFeature Is Nothing Then
    Set ISnapAgent_Snap = MonPoint
    Exit Function
Else

    Dim MaCollection As esriGeometry.IPointCollection
    Dim MaCollection2 As esriGeometry.IPointCollection
    Set MaCollection = MaFeature.Shape
    Set MaCollection2 = New esriGeometry.Multipoint
    MaCollection2.InsertPointCollection 0, MaCollection
    Dim MonMultipoint As esriGeometry.IMultipoint
    Set MonMultipoint = MaCollection2
    Set pProximity = MonMultipoint
    Set pSnapPt = pProximity.ReturnNearestPoint(MonPoint, esriNoExtension)
    If pSnapPt Is Nothing Then
        Set ISnapAgent_Snap = MonPoint
    Else
        Dim MonTrace As esriGeometry.ILine
        Set MonTrace = New esriGeometry.Line
        MonTrace.PutCoords MonPoint, pSnapPt
        If MonTrace.Length < tolerance Then
            Set ISnapAgent_Snap = pSnapPt
        Else
            Set ISnapAgent_Snap = MonPoint
        End If
    End If
End If
End Function

[Matthieu Pette - Ad Terram] (@Ad_Terram sur le PiouPiou bleu)

~Géomaticien Indépendant~

Hors ligne

 

#5 Wed 27 October 2010 14:08

tnicolas
Participant actif
Date d'inscription: 18 Apr 2007
Messages: 64

Re: [ArcGis 9.1] vba et cible d'editeur

En fait je veux pouvoir créer des polylignes dont les extrémités se superposent parfaitement et pour cela la seule méthode que je connaisse c'est le snap. En faisant des recherches j'avais cru comprendre qu'il fallait forcement passer par l'éditeur pour pouvoir l'utiliser. Mais si on peut utiliser le snap sans éditeur c'est encore mieux. En plus de cela il va falloir que je remplisse des champs associés aux polylignes (à l'aide d'un formualire). Pour l'instant j'ai développé l'outil pour créer les polylignes et pour les renseigner. Il me manque juste de pouvoir snapper sur les polylignes déjà éxistantes.

Le code que j'utilise pour dessiner les polylignes est le suivant :

Code:

Sub ajouter_polyligne(ByRef couche As String)
'pour créer une polyligne
    Dim MonDoc As IMxDocument
    Dim macarte As IMap
    Dim pline As IPolyline
    Dim monelast As IRubberBand
    Dim pLayer As IFeatureLayer
    Dim pclasse As IFeatureClass
    Dim pfeature As IFeature
    Dim i As Integer
    Dim macouche As ILayer
    Dim matable As ITable
    Dim moncur As ICursor
    Dim maligne As IRow
    Dim num1 As Long
    Dim num2 As Long
    Dim masel As IFeatureSelection
    Dim monfiltre As IQueryFilter
    'dessine la polyligne
    Set MonDoc = ThisDocument
    Set macarte = MonDoc.Maps.Item(0)
    For i = 0 To macarte.LayerCount - 1
        If macarte.Layer(i).Name = couche Then
            Set pLayer = MonDoc.FocusMap.Layer(i)
            Set macouche = macarte.Layer(i)
            Exit For
        End If
    Next i
    Set pclasse = pLayer.FeatureClass
    Set pfeature = pclasse.CreateFeature
    Set monelast = New RubberLine
    Set pline = monelast.TrackNew(MonDoc.ActiveView.ScreenDisplay, Nothing)
    Set pfeature.Shape = pline
    pfeature.Store
    MonDoc.ActiveView.Refresh
    '...
 End sub

Il y a des variables déclarées qui ne semblent pas utilisé car je n'ai pas mis tout le code, le reste concerne l'enregistrement de données.

Hors ligne

 

#6 Thu 28 October 2010 00:42

Forestis
Participant assidu
Lieu: Aniane (Hérault)
Date d'inscription: 5 Sep 2005
Messages: 168
Site web

Re: [ArcGis 9.1] vba et cible d'editeur

ok je vois un peu mieux, bien que je ne comprend toujours pas pourquoi tu recreer l'outil de saisie des polylignes.
Moi quand je l'ai fais, je pensais que c'etait la seule maniere pour ouvrir un formulaire en fin de saisie mais finalement c'est se donner beaucoup de mal pour eviter le clic sur un bouton.
si tu veux absolument utiliser ce code pour la saisie il faut que tu change ta maniere de creer une polyligne.
ici ta saisie se fait grace à ta rubberline mais en fait pour pouvoir snapper tes noeuds il faut que tu gere l'acquisition point par point.
ceci est un exemple mais il ne correspond pas exactement a ce que tu veux car les points qui te sont utiles sont plutot a creer grace au curseur de ta souris, il faut recuperer les coordonnées en cours lors du clic pour creer le point.

Code:

    
            Dim C As esriGeometry.IPoint
            Set C = New esriGeometry.Point
            Dim D As esriGeometry.IPoint
            Set D = New esriGeometry.Point

'la il faudrait un bout de code suplémentaire pour creer tes points. Si tu trouve pas je devrais pouvoir te trouver ça
       
            Dim MaligneCD As esriGeometry.ILine
            Set MaligneCD = New esriGeometry.Line
            MaligneCD.PutCoords C, D
    
            Dim MonSegment As ISegment
            Set MonSegment = MaligneCD
    
            Dim MonSegmentCollection As esriGeometry.ISegmentCollection
            Set MonSegmentCollection = New esriGeometry.Polyline
            MonSegmentCollection.AddSegment MonSegment
    
            Dim CD As esriGeometry.IPolyline
            Set CD = MonSegmentCollection

a partir du moment ou tu gère ton acquisition point par point tu peux utiliser le code que je t'ai indiqué plus haut.
Je pense pas etre très clair la mais je suis un peu fatigué alors je reprendrais cette conversation plutot vendredi car demain pleins de rdv.
bon courage

Dernière modification par Forestis (Thu 28 October 2010 00:44)


[Matthieu Pette - Ad Terram] (@Ad_Terram sur le PiouPiou bleu)

~Géomaticien Indépendant~

Hors ligne

 

#7 Thu 28 October 2010 12:34

tnicolas
Participant actif
Date d'inscription: 18 Apr 2007
Messages: 64

Re: [ArcGis 9.1] vba et cible d'editeur

Je veux recreer l'outil de saisie des polylignes car l'application  pourra être uiliser sur un portable sans souris par des personnes pas spécialement trés à l'aise avec la partie editeur d'arcview, donc moins il y a de manip à faire et mieux ça vaut smile

Merci pour ce dernier bout de code, ne t'en fait pas malgrés l'heure tu as été clair  wink
Avec les fonction ISnapAgent_Snap et Recherche_FLayer j'ai pu faire ce que je voulais en bidouillant le tout à ma sauce, c'est pas du grand art mais ça fonctionne.

Tout est dans thisdocument

Dans l'entête

Code:

Private cpt As Integer
Private C As esriGeometry.IPoint
Private D As esriGeometry.IPoint
Private temp As esriGeometry.IPoint
Private MonSegmentCollection As esriGeometry.ISegmentCollection
Private CD As esriGeometry.IPolyline

Au double clic de l'outil, je finalise la construction

Code:

Dim pCommandBars As ICommandBars
    Dim pCmdItem As ICommandItem
    Dim pTool As ITool
    Set pCommandBars = ThisDocument.CommandBars
    Set pCmdItem = pCommandBars.Find(arcid.PageLayout_SelectTool)
    Set Application.CurrentTool = pCmdItem
    Set pTool = pCmdItem
    ajouter_polyligne2 CD

Au clic sur la carte, je créé la polyligne

Code:

'créer une sug
    Dim MonDoc As IMxDocument
    Dim macarte As IMap
    Dim MaligneCD As esriGeometry.ILine
    Dim MonSegment As ISegment
    Set MonDoc = ThisDocument
    Set macarte = MonDoc.Maps.Item(0)
    If cpt = 1 Then
        Set D = New esriGeometry.Point
        Set temp = MonDoc.CurrentLocation
        Set temp = ISnapAgent_Snap("nomdelacouhe", temp, 10)
        D.PutCoords temp.X, temp.Y
        Set MaligneCD = New esriGeometry.Line
        MaligneCD.PutCoords C, D
        Set MonSegment = MaligneCD
        MonSegmentCollection.AddSegment MonSegment
        Set CD = MonSegmentCollection
        cpt = 0
    End If
    If cpt = 0 Then
        Set C = New esriGeometry.Point
        Set temp = MonDoc.CurrentLocation
        Set temp = ISnapAgent_Snap("nomdelacouhe", temp, 10)
        C.PutCoords temp.X, temp.Y
        cpt = 1
    End If

A la sélection de l'outil, j'initialise les valeurs

Code:

cpt = 0
Set MonSegmentCollection = New esriGeometry.Polyline

C'est sans doute améliorable mais j'ai pas trop le temps pour l'instant.
Si ça peut servir à quelqu'un d'autre.

Merci Forestis pour ton aide

Dernière modification par tnicolas (Thu 28 October 2010 12:35)

Hors ligne

 

#8 Thu 28 October 2010 18:36

Forestis
Participant assidu
Lieu: Aniane (Hérault)
Date d'inscription: 5 Sep 2005
Messages: 168
Site web

Re: [ArcGis 9.1] vba et cible d'editeur

de rien wink j'aime bien quand j'arrive à aider ^^


[Matthieu Pette - Ad Terram] (@Ad_Terram sur le PiouPiou bleu)

~Géomaticien Indépendant~

Hors ligne

 

Pied de page des forums

Powered by FluxBB