Suite

Requête spatiale entre les entités polylignes et les entités ponctuelles dans le tampon spécifié


Je suis nouveau sur les SIG (donc je suis perdu là-dessus) et je recherche un exemple de code C# pour m'aider à faire 2 types de requêtes spatiales. J'ai 2 couches seulement. La première couche est constituée de pipelines, qui sont des formes polylignes afin que je puisse sélectionner plusieurs segments de pipeline pour constituer un pipeline entier. La deuxième couche est constituée d'installations, qui sont des formes ponctuelles.

Requête 1: sélectionnez les segments de pipeline dans la couche de pipeline (polylignes) et recherchez les installations (dans la couche d'installation) qui se trouvent à une certaine distance des segments de pipeline sélectionnés.

Requête 2: Sélectionnez une seule installation dans la couche d'installation (point) et recherchez les segments de pipeline (polylignes) qui se trouvent à une certaine distance du point d'installation.

Je peux faire ces requêtes via l'interface ArcMap. Je sélectionne les entités source dans la table attributaire, puis le menu de sélection, sélectionnez par emplacement, sélectionnez "l'autre" couche comme couche cible et pour la méthode de sélection spatiale, je sélectionne "les caractéristiques de la ou des couches cibles se trouvent à une distance de la couche source fonctionnalité". Mais maintenant, je dois le faire en code C# pour mon complément ArcMap.


En supposant que vous ayez un handle de la classe d'entités de votre requête et de l'entité sélectionnée, vous pouvez utiliser l'extrait de code suivant :

double rechercheDistance = 10 ; //il s'agit de votre distance tampon IFeatureClass fc =… ; //Requête1 : il s'agit de la classe d'entités de votre installation IFeature feat =… ;// Requête1 : il s'agit de l'entité de pipeline sélectionnée ISpatialFilter spatialFilter = new SpatialFilterClass(); if (searchDistance == 0) spatialFilter.Geometry = feat.Shape; // peut être IGeometry else { ITopologicalOperator topoOperator = (ITopologicalOperator)feat.ShapeCopy; spatialFilter.Geometry = topoOperator.Buffer(searchDistance); } spatialFilter.GeometryField = fc.ShapeFieldName; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; IFeatureCursor featureCursor = fc.Search(spatialFilter, true); //parcourir les fonctionnalités dans le curseur

C'est ce que j'ai fait pour résoudre le problème. Il faudrait peut-être expliquer certaines choses, mais je pense que c'est très clair. Merci à Brenth. /users/19213/brenth

Cela a beaucoup aidé ! Sélection d'entités par emplacement en fonction de l'entité sélectionnée à l'aide d'ArcObjects ?

public void GetClosestFeatures(IEnumerable selectedFeatures) { try { var mxDocument = ArcMap.Application.Document as IMxDocument; if (mxDocument != null) { var map = mxDocument.FocusMap; var DistanceRecherche = 1000,0 ; if(UI.LayerSelection.Equals("Pipeline")) { if (UI.txtRadiusToFacilities.Text != "") { searchDistance = Convert.ToDouble(UI.txtRadiusToFacilities.Text); } else { UI.txtRadiusToFacilities.Text = searchDistance.ToString(CultureInfo.InvariantCulture); } // Ce n'est pas précis à 100 % en raison du changement de Lattitude lorsque vous vous déplacez vers le nord/sud, donc si nous connaissons le lattite, nous pouvons utiliser // la fonction MetersToDecimalDegrees mais cela fera l'affaire ! searchDistance = Convert.ToDouble((UI.txtRadiusToFacilities.Text)) / (111.32 * 1000); } else { if (UI.txtRadiusToPipelines.Text != "") { searchDistance = Convert.ToDouble(UI.txtRadiusToPipelines.Text); } else { UI.txtRadiusToPipelines.Text = searchDistance.ToString(CultureInfo.InvariantCulture); } // Ce n'est pas précis à 100 % en raison du changement de Lattitude lorsque vous vous déplacez vers le nord/sud, donc si nous connaissons le lattite, nous pouvons utiliser // la fonction MetersToDecimalDegrees mais cela fera l'affaire ! searchDistance = Convert.ToDouble((UI.txtRadiusToPipelines.Text)) / (111.32 * 1000); } var curseur = GetSelectedFeatures(CurrentLayer); // Le tampon par défaut est Degrés décimaux var polygon = UnionShapes(cursor, searchDistance); // Peut-être utiliser le nom à la place de CurrentLayer.Name car il s'agit de trouver des installations pour les pipelines sélectionnés var featureLayer = Utilities.GetOppositeFeatureLayerByFeatureClassName(map, CurrentLayer.Name); var filter = CreateSpatialFilter(featureLayer.FeatureClass, polygon); var curseur2 = GetSelectedItemsByShape(featureLayer.FeatureClass, filter); // Itérer à travers les fonctionnalités, en les visualisant (comme dans ce cas) ou en les éditant. IFeatureClass fc = Utilities.GetOppositeFeatureLayerByFeatureClassName(carte, CurrentLayer.Name).FeatureClass; Fonctionnalité IFeature = null ; if (UI.LayerSelection.Equals("Pipeline")) { var nameFacilityNameIndex = fc.Fields.FindField(GeodatabaseFieldNames.FacilityNameFieldName); var nameFacilityTypeIndex = fc.Fields.FindField(GeodatabaseFieldNames.FacilityTypeFieldFieldName); compteur var = 0 ; UI.lvwFacilitiesSpatialResult.Items.Clear(); try { while ((feature = cursor2.NextFeature()) != null) { //Console.WriteLine("Facility Found : {0}", feature.get_Value(nameFieldIndex)); compteur++; string[] rowData = { (counter).ToString(CultureInfo.InvariantCulture), feature.get_Value(nameFacilityNameIndex).ToString(), feature.get_Value(nameFacilityTypeIndex).ToString() } ; var lvItem = new ListViewItem(rowData); UI.lvwFacilitiesSpatialResult.Items.Add(lvItem); } } catch (Exception ex) { // Gère toutes les erreurs qui pourraient se produire sur NextFeature(). MessageBox.Show(ex.Message, @"Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } else // Facility { var namePipelinenameIndex = fc.Fields.FindField(GeodatabaseFieldNames.PipelineNameFieldName); var companyNameFieldIndex = fc.Fields.FindField(GeodatabaseFieldNames.OperatorNameFieldName); compteur var = 0 ; UI.lvwPipelinesSpatialResult.Items.Clear(); try { while ((feature = cursor2.NextFeature()) != null) { //Console.WriteLine("Facility Found : {0}", feature.get_Value(nameFieldIndex)); compteur++; string[] rowData = { (compteur).ToString(CultureInfo.InvariantCulture), feature.get_Value(namePipelinenameIndex).ToString(), feature.get_Value(companyNameFieldIndex).ToString() } ; var lvItem = new ListViewItem(rowData); UI.lvwPipelinesSpatialResult.Items.Add(lvItem); } } catch (Exception ex) { // Gère toutes les erreurs qui pourraient se produire sur NextFeature(). MessageBox.Show(ex.Message, @"Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } } } catch (Exception ex) { MessageBox.Show(ex.Message, @"Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
public static IFeatureCursor GetSelectedFeatures(IFeatureLayer featureLayer) { if (featureLayer == null) return null; IFeatureSelection fSel = (IFeatureSelection)featureLayer; ISelectionSet selSet = (ISelectionSet)fSel.SelectionSet; ICursor curseur = null; selSet.Search(null, false, curseur de sortie); IFeatureCursor fCursor = curseur comme IFeatureCursor; retour fCurseur; }
public static IPolygon UnionShapes(IFeatureCursor curseur, double bufferDist) { if (cursor == null) return null; IFeature pFeat = curseur.NextFeature(); if (pFeat != null) { if (pFeat.Shape est IPoint || pFeat.Shape est IPolyline) { ITopologicalOperator ptopBuffer = (ITopologicalOperator)pFeat.Shape; IPolygon pTempPoly = (IPolygon)ptopBuffer.Buffer(bufferDist); ITopologicalOperator ptopUnion = (ITopologicalOperator)pTempPoly; pFeat = curseur.NextFeature(); while (pFeat != null) { ptopBuffer = (ITopologicalOperator)pFeat.Shape; pTempPoly = (IPolygon)ptopBuffer.Buffer(bufferDist); ptopUnion = (ITopologicalOperator)ptopUnion.Union(pTempPoly); pFeat = curseur.NextFeature(); } return (IPolygon)ptopUnion; } renvoie null ; } renvoie null ; }
public static ISpatialFilter CreateSpatialFilter (IFeatureClass fc, forme IGeometry) { if (fc == null) return null; ISpatialFilter sf = new SpatialFilterClass(); sf.GeometryField = fc.ShapeFieldName; sf.Geometry = forme; sf.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; retour sf; }
public static IFeatureCursor GetSelectedItemsByShape(IFeatureClass fc, ISpatialFilter filter) { try { if (filter == null) return null; if (fc == null) renvoie null ; IFeatureCursor fcursor = fc.Search(filter, true); retour fcursor; } catch { return null; } }
public static ISelectionSet CursorToSelectionSet (couche IFeatureLayer, curseur IFeatureCursor) { IFeatureSelection fSel = (IFeatureSelection)layer; if (cursor != null) { IFeature feat = cursor.NextFeature(); while (feat != null) { fSel.Add(feat); exploit = ​​curseur.NextFeature(); } } return fSel.SelectionSet; }

Comme je n'ai que 2 couches, je peux le faire.

public statique IFeatureLayer GetOppositeFeatureLayerByFeatureClassName (carte IMap, chaîne featureClassName) { résultat IFeatureLayer = null; pour (var i = 0; je


Voir la vidéo: 3 Découverte des entités (Octobre 2021).