6 votos

Análisis cercano con tipos de rasgos mixtos en ArcObjects

Estoy intentando emular la herramienta Near (análisis) de ArcGIS en ArcObjects. http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00080000001q000000

Quiero utilizar tipos de rasgos mixtos. Tengo una clase de característica de punto, polígono y línea y quiero utilizar Near para comparar las tres entre sí. Esto se puede hacer una featureclass a la vez así (pseudocódigo lógico):

  1. Crear IFeatureIndex

  2. Almacenar mi clase de característica en IFeatureIndex.FeatureClass

  3. Utilice IIndexQuery.NearestFeature para cada IGeometry en una clase de característica para obtener la distancia a la característica más cercana

El problema con el que me encuentro es que sólo puedo almacenar una clase de característica en IFeatureIndex. Necesito almacenar tres clases de características diferentes (puntos, líneas y polígonos) para poder ejecutar correctamente mi comparación. ¿Cómo puedo hacerlo? La función de ESRI que he enlazado más arriba lo ha conseguido, pero por desgracia no hay forma de echar un vistazo al código que hay detrás de la herramienta de geoprocesamiento que yo conozca.

Editar: Ya lo he solucionado. Vea la respuesta a continuación.

4voto

saint_groceon Puntos 2696

enter image description here

Puedes considerar el uso de una caché espacial a través de ISpatialCacheManager3 . La documentación no indica si todas las clases de características de la caché deben estar en el mismo espacio de trabajo. Utilización de la caché espacial para optimizar la sección de consultas espaciales . Tendría mucha curiosidad si ese fuera el caso.

He aquí un fragmento de esa página:

// Open the feature classes used by the queries.
IFeatureClass blocksFeatureClass = featureWorkspace.OpenFeatureClass("Blocks");
IFeatureClass parcelsFeatureClass = featureWorkspace.OpenFeatureClass("Parcels");

// Fill the spatial cache.
ISpatialCacheManager spatialCacheManager = (ISpatialCacheManager)featureWorkspace;

// Check if the cache has been filled.
if (!spatialCacheManager.CacheIsFull)
{
    // If not full, fill the cache.
    spatialCacheManager.FillCache(cacheExtent);
}

// Execute spatial queries.

// Empty the cache.
spatialCacheManager.EmptyCache();

2voto

alxcpa01101 Puntos 1

Lo he resuelto hoy mismo. Aquí está el código. Una breve explicación pseudocódigo sigue.

        ESRI.ArcGIS.Geometry.IGeometryBag pGeometryBag = new GeometryBagClass();
        ESRI.ArcGIS.Geometry.IGeometryCollection pGeometryCollection = (IGeometryCollection)pGeometryBag;

        ESRI.ArcGIS.Carto.IEnumLayer pEnumLayer; //get all layers in the map
        pEnumLayer = pDoc.FocusMap.Layers;

        ESRI.ArcGIS.Carto.ILayer pLayer; //create a layer to store looped values of point combobox layers
        pLayer = pEnumLayer.Next();

        while (pLayer != null)//Get all the features and stick them into the geometry collection
        {

            ESRI.ArcGIS.Carto.IFeatureLayer pFeatureLayer = (IFeatureLayer)pLayer;
            if (pLayer == statusforselectedlayer) 
            {
                 ITable pTable = (ITable)pFeatureLayer.FeatureClass;
                 List<int> OIDList = new List<int>();
                 IQueryFilter queryFilter = new QueryFilterClass();
                 queryFilter.SubFields = pFeatureLayer.FeatureClass.OIDFieldName;
                 ICursor pCursor = pTable.Search(queryFilter, false);
                 IRow pRow = null;
                 while((pRow = pCursor.NextRow()) != null)
                 {
                     OIDList.Add(pRow.OID);
                 }

                 IFeatureCursor blocksCursor = pFeatureLayer.FeatureClass.GetFeatures(OIDList.ToArray(), false);
                 IFeature blockFeature = null;
                 while ((blockFeature = blocksCursor.NextFeature()) != null)
                 {
                     pGeometryCollection.AddGeometry(blockFeature.Shape);
                 }

            }

        ISpatialIndex spatialIndex = (ISpatialIndex)pGeometryBag;
        spatialIndex.AllowIndexing = true;
        spatialIndex.Invalidate();

        ISpatialFilter spatialFilter = new SpatialFilterClass();
        spatialFilter.Geometry = pGeometryBag;

        ESRI.ArcGIS.Geometry.IEnumGeometry pEnumGeometry = (IEnumGeometry)pGeometryBag;
        pEnumGeometry.Reset();
        ESRI.ArcGIS.Geometry.IGeometry pGeometry = pEnumGeometry.Next();

        List<double> distances = new List<double>();

        while (pGeometry != null)
        {
            IProximityOperator pProximity = (IProximityOperator)pGeometry;         

            ESRI.ArcGIS.Geometry.IEnumGeometry pEnumGeomBag = (IEnumGeometry)pGeometryBag;
            ESRI.ArcGIS.Geometry.IGeometry pGeomBagIterable = pEnumGeomBag.Next();

            while (pGeomBagIterable != null)
            {

                distances.Add(pProximity.ReturnDistance(pGeomBagIterable));
                pGeomBagIterable = pEnumGeomBag.Next();
            }
            pGeometry = pEnumGeometry.Next();

        }

El código recorre todas las capas del mapa, toma todas las características de una capa especificada si cumple un determinado criterio y las almacena en un IGeometryBag. A continuación, el código recorre cada IGeometría del IGeometryBag creado y compara cada IGeometría con todas las demás IGeometrías del IGeometryBag, obteniendo la distancia cada vez mediante IProximityOperator. Estas distancias se almacenan en una lista de tipo double llamada distancias .

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X