Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

Let's say you have a map with three or four data frames. In each data frame there is the same road layer. Is there a way to ensure that all the symbology/labeling/annotation is the same for that layer across all data frames. So let's say I modify the symbology of the road layer in data frame 1, is it possible to automate that change across all data frames?

share|improve this question

4 Answers 4

up vote 2 down vote accepted

Update:
The little bit of the code that I mentioned was just snippets. But I think the functionality that you want was the part that I (sort of) got through. I dropped it into an ArcGIS 10 Addin to test out: http://dl.dropbox.com/u/1156285/SynchLayers.avi

As you can see, this code doesn't handle group/composite layers (need to recursively search composite layers). And it's an ArcGIS 10 addin button and you are on 9.3. I'm putting code in this answer--it shouldn't hard to wire up to 9.3 (don't think I used anything new to 10):

namespace SynchronizeLayer
{
    using System;
    using System.IO;
    using ESRI.ArcGIS.Carto;
    using ESRI.ArcGIS.Catalog;

    public class SynchronizeLayerByLayerName : ESRI.ArcGIS.Desktop.AddIns.Button
    {
        private const string LayerFileName = "u{0}.lyr";

        public SynchronizeLayerByLayerName()
        {
        }

        protected override void OnClick()
        {
            ArcMap.Application.CurrentTool = null;

            try
            {
                string temporaryLayerFilePath = Path.Combine(
                    Path.GetTempPath(),
                    String.Format(LayerFileName, System.Guid.NewGuid().ToString("N")));

                ILayer selectedLayer = ArcMap.Document.SelectedLayer;

                if (selectedLayer != null && selectedLayer.Valid)
                {
                    ILayerFile layerFile = new LayerFileClass();
                    layerFile.New(temporaryLayerFilePath);
                    layerFile.ReplaceContents(selectedLayer);
                    layerFile.SaveAs(temporaryLayerFilePath);

                    for (int i = 0; i < ArcMap.Document.Maps.Count; i++)
                    {
                        IMap map = ArcMap.Document.Maps.get_Item(i);

                        if (map != null)
                        {
                            IEnumLayer mapLayers = map.get_Layers(null, false);

                            ILayer maplayer = null;
                            int layerindex = 0;

                            while ((maplayer = mapLayers.Next()) != null)
                            {
                                if (maplayer.Name.Equals(selectedLayer.Name)
                                    && selectedLayer != maplayer)
                                {
                                    IGxLayer gxlayer = new GxLayer();
                                    IGxFile gxfile = gxlayer as GxFile;

                                    gxfile.Path = temporaryLayerFilePath;

                                    map.AddLayer(gxlayer.Layer);
                                    map.MoveLayer(gxlayer.Layer, layerindex);
                                    map.DeleteLayer(maplayer);
                                }

                                layerindex++;
                            }
                        }            
                    }
                            if (File.Exists(temporaryLayerFilePath))
                            {
                                File.Delete(temporaryLayerFilePath);
                            }
                    ArcMap.Document.UpdateContents();
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.StackTrace);
                throw;
            }
        }
        protected override void OnUpdate()
        {
            Enabled = ArcMap.Application != null;
        }
    }
}

Maybe a year ago, I was working on an ArcMap button that would keep layers in sync and along the same idea's as dmsnell's manual copy except that I was working to automate the process by updating layers with layers stored in a subversion repository.

In my case, I had layer files in a subversion repository and I was looking to replace any layer in an MXD that was older than the layer file in my subversion repository.

I think @dassouki question is the same except that instead of a layer in a subversion repository, his layer is the one he just modified. And he's only wanting to modify the MXD that he is in, rather than any MXD (although that is probably useful too). I think that it's just remove a layer and add a new layer (that is a copy) at the same location. This was work that was low priority for me and I stopped before it was completed, but I think I have some code for the layer operations(swap) buried somewhere. I'll look around and update this answer.

The challenge for my solution was to uniquely identify layers (that would persist with the layer)--which I accomplished by using a guid in the layer extension properties. Given the number of end-users I support, using the layer name would be risky since the chance of a layer with different renderers having the same layer name is high. The amount of our layer modifications decreased and with the promise of web map services, this all seemed like overkill, so I stopped the work.

The only thing I completed was an ArcMap button to modify the layer extension properties.

Update: It just occurred to me that rambled on without actually answering the question of whether it is possible to automate layer changes across data frames.

Yes, but not with out some custom code.

share|improve this answer
    
Sounds really great. Actually, for my purposes, the layers in my maps, should NOT be updated, as we produce mostly as built, or temporal historical data. –  dassouki Jan 6 '11 at 14:35
    
@dassouki: wasn't your question how to automate the change of layers in other data frames when another is changed? If the layers should NOT be updated, then don't use a tool that automates the updating of layers! –  Jay Cummins Jan 6 '11 at 14:40
    
In the same MXD, if roads is in GroupLayers1, it should be updated in GroupLayers2. But in different MXDs, they should still remain separate, which happens anyway, as I differentiate my shps from project to project –  dassouki Jan 6 '11 at 14:52
    
Great script, I've been looking for this for a very long time after running into hundreds of errors with my own and others. The only change I require in your script is that all layers, regardless of name, need to match eachother in symbology. Furthermore, what if the ranges between the layers are different? Is it possible to quickly locate the highest and lowest values across the entire set of layers and create a symbology that can incorporate this where all the layers use it? Many thanks for your expertise! Bo –  Tetra Jul 11 '11 at 18:10

You have to update each data frame manually, as far as I know. You can right-click on a layer and save it as a "Layer" file (.lyr), then right click on the other data frames and use the "Add Data" tool to find that saved layer file. If you make changes, just re-save that layer to the same .lyr file and delete and re-add it to each data frame.

I've been looking for some kind of text-file based rules (such as XML) for describing the symbology and layering and be able to apply that to a map, where the map would reload that file at least at every program load, so I could just change the file but so far I haven't been able to find anything like that.

share|improve this answer

I agree with the aproach that dmsnell describes, but you can simply copy the layer from one Dataframe to another by a rightclick on the layer -> select copy -> rightclick the other Dataframe name -> select Paste Layer(s).

I have not found any automation script or add-in to take care of this task.

share|improve this answer
    
That's what I currently due, and it really is a pain in the ... . I was hoping for an automated way –  dassouki Jan 5 '11 at 16:10
    
damn keyboard fingers - s/due/use –  dassouki Jan 5 '11 at 16:17
    
I agree. and in one doc it's not that bad but when you want to maintain them in many docs it can turn your (my) hair grey. –  Brad Nesom Jan 6 '11 at 7:17

There are a few automatic options you can use

1) Cartographic Representation

Cartographic Representations add new fields to your geodatabase so that the symbology is stored in the data. This would allow you to make a change to the representation (using editing) so that any change you make will be reflected in all locations the representation is being used

2) Views and Visual Specifications

Views are available with Production Mapping (Previously PLTS) and are stored Dataframe Properties and allow you to specify which components of a dataframe are being used from the stored database version of the Dataframe. Where As Visual Specifications are SQL Select Queries which are used in Production Mapping to assign Cartographic Representations based on attribute fields

These are just some ideas, I will edit this and add more as I think of them, but based on you use case I would say carto Reps are the go, will need to be in either File Geodatabase or SDE.

Have Fun, CDB

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.