6 votos

¿Cómo puedo actualizar un archivo MXD mediante programación?

Estoy usando ArcGIS 9.3.1. la línea de productos y MXD archivos.

A nuestros clientes que tenemos varias ambiente (DEV, QAS, PROD), que debe ser más o menos idénticos, excepto que el uso de diferentes datbases y algunos otros ajustes menores. Que alo compartir el mismo archivo MXD publicados como Servicios de Mapas. Estos MXD debe ser la misma, salvo por el hecho de su capa punto a otro origen de datos (base de datos), pero con el mismo nombre y los campos.

Ahora, a la actualización de los servicios de mapas que básicamente editar manualmente cada MXD en todas las plataformas de forma manual. Este proceso manual es propensa a errores y ha causado problemas en el pasado. Me gustaría editar el MXD documento una vez y basta con copiarlos en otra plataforma. Pero, a continuación, voy a tener que pasar a través de algún hecho en casa de encargo hecho de la herramienta para modificar la fuente de datos.

Me hizo escribir esta herramienta, lea el MXD documento, encontrar el utilizado SDF archivo (archivo de conexión) y la actualización de la MXD del connetcion propiedades con el valor de la versión local de la SDE archivos.

Funciona bien , pero para el 1 de problema. Cuando me cambie de una capa de origen de datos, sus campos de perder sus alias y la visibilidad de las banderas, en el cual se restablecen los valores predeterminados.

Me gustaría leer el valor original antes de la actualización, la actualización y, a continuación, establecer los nuevos valores (el valor anterior)(para el campo alias y visibilidad)

Yo trato de echar mis capas para ITableField, pero tengo FieldCount = 0!!! Así que no puedo actualizar nada!!!

A continuación es mi código actual (UpdateSDEWorkspaces es el método de interés) ¿Cómo puedo configurar la capa de alias y la visibilidad?

public static class MxdUtils
{
    public static IEnumerable<IMap> GetMaps(this IMapDocument pMapDocument)
    {
        int N = pMapDocument.MapCount;
        for (int i = 0; i < N; i++)
            yield return pMapDocument.get_Map(i);
    }
    public static IEnumerable<ILayer> GetLayers(this IMap pMap, UID uid, bool recursive)
    {
        IEnumLayer pEnumLayer = pMap.get_Layers(uid, recursive);
        pEnumLayer.Reset();
        for (ILayer pLayer = pEnumLayer.Next(); pLayer != null; pLayer = pEnumLayer.Next())
            yield return pLayer;
    }
    public static IEnumerable<ILayer> GetLayers(this IMapDocument pMapDocument, UID uid, bool recursive)
    {
        return
            from m in pMapDocument.GetMaps()
            from l in m.GetLayers(uid, recursive)
            select l;
    }

    /// <summary>
    /// Will update each SDE feature layer to the local sde connection.
    /// It will will loop through all layer, find a layer's sde connection, if the local find can be found, 
    /// connection properties will be updated from it.
    /// </summary>
    public static void UpdateSDEWorkspaces(string mxdPath) { UpdateSDEWorkspaces(mxdPath, null); }
    public static void UpdateSDEWorkspaces(string mxdPath, Dictionary<string, IPropertySet> memory)
    {
        if (memory == null)
            memory = new Dictionary<string, IPropertySet>();

        IMapDocument pMapDocument = new MapDocumentClass();
        pMapDocument.Open(mxdPath, "");

        foreach (var pMap in pMapDocument.GetMaps())
        {
            var sdelayers =
                from pLayer in pMap.GetLayers(new UID { Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}" }, true)
                let pFeatureLayer = pLayer as IFeatureLayer
                where pFeatureLayer != null
                let pDataLayer = pFeatureLayer as IDataLayer2
                let pDatasetName = pDataLayer.DataSourceName as IDatasetName
                where pDatasetName != null
                let pWorkspaceName = pDatasetName.WorkspaceName
                let pNewProp = GetConnectionProperties(memory, pWorkspaceName.PathName, mxdPath)
                where pNewProp != null
                select new
                {
                    Layer = pLayer,
                    DataLayer = pDataLayer,
                    DSName = pDatasetName,
                    WorkspaceName = pWorkspaceName,
                    UpdatedProperties = pNewProp,
                };

            foreach (var item in sdelayers)
            {
                var tf = (ITableFields)item.Layer;
                int N = tf.FieldCount;
                // damn, why is N always 0?

                item.WorkspaceName.ConnectionProperties = item.UpdatedProperties;
            }

            pMapDocument.ReplaceContents(pMap as IMxdContents);
        }
        pMapDocument.Save(true, false);
        pMapDocument.Close();
    }

    public static IPropertySet GetConnectionProperties(Dictionary<string, IPropertySet> memory, string sdeConnPath, string mxdPath)
    {
        var path = sdeConnPath;
        if (!File.Exists(path))
            path = Path.Combine(Path.GetDirectoryName(mxdPath), Path.GetFileName(sdeConnPath));
        if (!File.Exists(path))
            path = Path.Combine(Environment.CurrentDirectory, Path.GetFileName(sdeConnPath));
        if (!File.Exists(path))
            return null;

        IPropertySet set;
        if (memory.TryGetValue(sdeConnPath, out set))
            return set;

        Console.WriteLine("Reading " + path);
        set = GetSDEFactory().ReadConnectionPropertiesFromFile(path);
        if (set == null)
            return null;

        memory[sdeConnPath] = set;
        memory[path] = set;
        return set;
    }

    static SdeWorkspaceFactoryClass GetSDEFactory()
    {
        if(SDEDataSourceFactory == null)
            SDEDataSourceFactory = new SdeWorkspaceFactoryClass();
        return SDEDataSourceFactory;
    }
    static SdeWorkspaceFactoryClass SDEDataSourceFactory;
}

3voto

tgmdbm Puntos 1115

Mi conjetura es que al abrir el mxd documento no logran conectarse al origen de datos.

Yo hice algo parecido hace un par de años. Supongo que nunca se preocuparon acerca de los alias, aunque. Acabo de probar y los alias disponibles en ITableFields.FieldInfo, pero nunca he copiado a la nueva ubicación.

Otra cosa que también podría perder al cambiar de fuente de las tablas combinadas. Yo sabía que tenía que escribir algo de especial para que.

¿Usted realmente necesita MXD servicios basados? He cambiado de MSD y el origen de datos de reemplazo mucho más fácil. Sólo hay que descomprimir el MSD (un montón de archivos xml comprimidos) y hacer algunos cadena de reemplazo. Hay un IMSDHelper clase para hacer algunas cosas, pero no todo para mí. Las contraseñas se guardan encriptadas en la MSD como encryped_password etiqueta. He sustituido la etiqueta con una contraseña etiqueta y almacena como texto sin formato. Supuesto, esto no es apoyado por ESRI, pero a mí me funciona.

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