Setting Spatial Reference on a Folder of MrSID Files…

So I’m getting ready to cook up a tile cache, and I want to use the ESRI ArcGIS Online tile scheme so I can use their tiles for the first 10 or so zoom levels. To do this, you need to have your map’s spatial reference set to WGS84, which was not a problem when I was setting up the “Road Map”, but I ran into a snag with the “Hybrid” (roads + parcels + orthos) – the Ortho images did not have any spatial reference defined – which means that ArcMap could not project them. Doh!

Now – I should point out that there is likely a neat-o way to do this with some Geoprocessing Python, but I’m a .NET guy, so I used my .NET hammer to solve this.

Ive done enough with images over the years to know that the spatial reference will be stored in the .aux.xml files that share the name of the raster. But for one set of images, there were no .aux.xml files. Solution: Open all the files in ArcMap and it will create these files. Sweet.

Next up, for one raster, I manually set the correct spatial reference in ArcCatalog. Easy, but there are several hundred files, so it’s not going to work as a solution. Enter System.Xml…

I then opened up the .aux.xml file (in notepad) for the raster that I manually assigned a spatial reference to, and simply copied the projection information from the <SRS> element. I then cooked up a simple loop over all the files, opened them up in an XmlDocument, injected or updated the <SRS> element, saved the file and shazam! all done. The pertinent function is below.

 

        private void UpdateSpatialRef(string folderPath, string srs)

        {

            //Loop over all the xml files, open as xml doc, inject the SRS node, save

            string[] fileNames = Directory.GetFiles(folderPath, “*.sid.aux.xml”);

            for (int i = 0; i < fileNames.Length; i++)

            {

                string fileName = fileNames[i];

                //Open the file

                XmlDocument xDoc = new XmlDocument();

                xDoc.Load(fileName);

                //find the SRS element if it’s here

                XmlNodeList srsNodes = xDoc.SelectNodes(“//SRS”);

                XmlElement srsEl = xDoc.CreateElement(“SRS”);

                srsEl.InnerText = srs;

                if (srsNodes.Count > 0)

                {

                    //Already set… replace                   

                    if (xDoc.DocumentElement.FirstChild.Name == “SRS”)

                    {

                        xDoc.DocumentElement.ReplaceChild(srsEl, xDoc.DocumentElement.FirstChild);

                        xDoc.Save(fileName);

                    }//if it’s somewhere else in your doc, it’s likely bad & you’ve got other problems!

                }

                else

                {

                    xDoc.DocumentElement.PrependChild(srsEl);

                    xDoc.Save(fileName);

                }

                Console.WriteLine(“Fixed: “ + fileName);

            }

        }

 

While more over the top than may be necessary, it was quick to write and solved my problem… now to kick off the cache creation!

Advertisement
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s