#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
Cordialement,
nicolas
Hors ligne
#2 Wed 27 October 2010 12:05
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
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
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
Merci pour ce dernier bout de code, ne t'en fait pas malgrés l'heure tu as été clair
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