Programatically copy certain features to new database - .NET

1753
6
02-13-2012 07:49 AM
ColleenDixon
New Contributor
I'm so new at ArcObjects it's a little sad, please point me in the right direction if this has been answered before or if I'm in the wrong place.

We have a customer who wants to use an ArcMap tool to expose certain parts of their map service outside the firewall so mobile users can hit it.  They want to pick a work order polygon and only include certain features within that polygon.  They would then create a new map service containing these features and expose that map service.

My first (and only, so far) approach was to have the user select the polygon(s) he would like to use, and then select one or more features from a list of features to include in the map service if they were in the polygon.  The user then previews the map, at which point I use map.ClipGeometry to cut off everything that's not in the polygons, and then set the other features the user didn't select to invisible, so the map looks like what they want.  This works well enough.

After this, the user clicks a Publish button, and I thought what that button would do is copy the map as-is to a new map service.  What's happening though is we're getting a new map service, and we're getting all of the feature definitions, but none of the data is in there.  It's just a blank map.

        private void publishBtn_Click(object sender, EventArgs e)
        {
            IServerObjectConfiguration2 serverObjectConfiguration = null;
            bool bFound = false;

            //If the selected text is set, then we're trying to overwrite an existing one.  Prompt the user if this is ok.
            ...

            //Save the MXD
            SaveFileDialog saveFileDlg = new SaveFileDialog();
            saveFileDlg.Filter = "ArcMap Document|*.mxd";
            saveFileDlg.FileName = mapServerCbx.Text;
            saveFileDlg.DefaultExt = "*.mxd";
            saveFileDlg.Title = "Save As";
            saveFileDlg.ShowDialog();

            //Create the mxd
            if (saveFileDlg.FileName != "")
            {
                //Open up the connection to see if the map service already exists.  If it does, this will blow up on AddConfiguration.
                IGISServerConnection agsServerConnection = new GISServerConnection();
                agsServerConnection.Connect(agsServerTxt.Text); //Selected server name.

                //Create the configuration if it doesn't already exist.
                if (serverObjectConfiguration == null)
                {
                    serverObjectConfiguration = agsServerConnection.ServerObjectAdmin.CreateConfiguration() as IServerObjectConfiguration2;
                }

                if (serverObjectConfiguration != null)
                {
                    //Stop the map service or overwriting this will crash.
                    if (bFound)
                    {
                        agsServerConnection.ServerObjectAdmin.StopConfiguration(mapServerCbx.Text, "MapServer");
                    }

                    //Save the mxd
                    String uncPath = Pathing.GetUNCPath(saveFileDlg.FileName);
                    GlobalsClass.ArcMapApplication.SaveAsDocument(uncPath);

                    // Set up the standard properties as defined in our property set
                    serverObjectConfiguration.Description = descriptionTxt.Text;
                    serverObjectConfiguration.IsPooled = true;
                    serverObjectConfiguration.MaxInstances = 20;//Convert.ToInt32(propertySet.GetProperty("MaxInstances"));
                    serverObjectConfiguration.MinInstances = 1;//Convert.ToInt32(propertySet.GetProperty("MinInstances"));
                    serverObjectConfiguration.Name = mapServerCbx.Text;//propertySet.GetProperty("Name").ToString();
                    serverObjectConfiguration.StartupType = esriStartupType.esriSTAutomatic;
                    serverObjectConfiguration.TypeName = "MapServer";

                    // Map Server objects have an additional property to point to the Mxd location
                    IPropertySet configPropertySet = serverObjectConfiguration.Properties;
                    configPropertySet.SetProperty("FilePath", saveFileDlg.FileName);//propertySet.GetProperty("MxdPath").ToString());
                    configPropertySet.SetProperties("OutputDir", "c:\\arcgisserver\arcgisoutput");
                    string virtualOutputDir = " http://" + agsServerTxt.Text + "/arcgisoutput";

                    configPropertySet.SetProperties("VirtualOutputDir", virtualOutputDir);
                    configPropertySet.SetProperties("MaxImageHeight", "2048");
                    configPropertySet.SetProperties("MaxRecordCount", "500");
                    configPropertySet.SetProperties("MaxBufferCount", "100");
                    configPropertySet.SetProperties("MaxImageWidth", "2048");
                    serverObjectConfiguration.Properties = configPropertySet;
                    
                    // We also need to enable basic web access
                    IPropertySet infoPropertySet = serverObjectConfiguration.Info;
                    infoPropertySet.SetProperty("WebEnabled", "true");
                    infoPropertySet.SetProperty("WebCapabilities", "Map,Query,Data");
                    serverObjectConfiguration.Info = infoPropertySet;

                    // Set recycle properties of the map service
                    IPropertySet recycleProperty = serverObjectConfiguration.RecycleProperties;
                    recycleProperty.SetProperties("StartTime", "12:00 AM");
                    recycleProperty.SetProperties("Interval", "86400");  // every 24 hours
                    serverObjectConfiguration.RecycleProperties = recycleProperty;

                    if (!bFound)
                    {
                        // Add the configuration to the ArcGIS Server instance
                        agsServerConnection.ServerObjectAdmin.AddConfiguration(serverObjectConfiguration);
                    }
                    else
                    {
                        // Update the existing configuration in the ArcGIS Server instance
                        agsServerConnection.ServerObjectAdmin.UpdateConfiguration(serverObjectConfiguration);
                    }

                    //Restart the map service.
                    agsServerConnection.ServerObjectAdmin.StartConfiguration(mapServerCbx.Text, "MapServer");
                }
            }
        }

What am I doing wrong here?  One of our map gurus but non-developers thought it might be something with the active view?  Or is this just the completely wrong workflow?  Another developer suggested programatically copying the feature from one database to another, is that what I need?  And if so, is there an example of that anywhere?

Thanks so much for looking through this, I know it's a ton of information.
0 Kudos
6 Replies
MLowry
by
Occasional Contributor II
Does the service need to be replaced with the "published" data, or are new services created as many as needed?

If you just need one service to be refreshed with a new set of data, that's a whole lot easier. Just do a clip like you did, then do a replace data source on the "template" map service layer so the public just gets that small bit of published info?

If this needs to be dynamic and create tons of services with different area of interests, your workflow is a good starting point.
0 Kudos
ColleenDixon
New Contributor
Does the service need to be replaced with the "published" data, or are new services created as many as needed?

If you just need one service to be refreshed with a new set of data, that's a whole lot easier. Just do a clip like you did, then do a replace data source on the "template" map service layer so the public just gets that small bit of published info?

If this needs to be dynamic and create tons of services with different area of interests, your workflow is a good starting point.


Thanks for your response! I believe they want to keep their original data in tact.  There must be something I'm doing wrong that's keeping the data out of the new map service.  If I replace the data source, is there any chance after that to save that off to another location?  Or once I replace it, the old one is overwritten?  So sorry for the ignorance, this is my first ArcMap tool...
0 Kudos
MLowry
by
Occasional Contributor II
Thanks for your response! I believe they want to keep their original data in tact.  There must be something I'm doing wrong that's keeping the data out of the new map service.  If I replace the data source, is there any chance after that to save that off to another location?  Or once I replace it, the old one is overwritten?  So sorry for the ignorance, this is my first ArcMap tool...


If I was designing a workflow similar to your goal, I would set up an .mxd with "template" data that would replaced with the "published" clipped data. The symbology and such would already be defined using a sample set of the same dataset that the published data is coming from. Then, after the replace data source command, you can save the .mxd with a new name, such as Publish_Date_v1, etc. and then start the service as you are doing already. I am unsure how much publishing will be going on here, though (100x publish per day or 1x publish per week, etc.).

Are you clearing the ArcGIS Server REST cache after starting the new service? I'm not clear on exactly what error you're receiving with your posted code.

What exactly does the following mean:

"and we're getting all of the feature definitions, but none of the data is in there. "

None of the data is showing in the REST Services directory? No layers at all? How about exporting the new .mxd to a .msd before starting the service?
0 Kudos
ColleenDixon
New Contributor
Thanks for your response, I'll talk to the higher ups and see if that workflow will work, I'm not sure if they'll be ok with that or not.

We're not really getting an error, the rest service is returning all layers and schema but the feature data is not exposed via the rest endpoint.  Does that make sense?  When I go to the URL for the map service, I can see all the layers in there, but when I click to view it it's just a big blank screen.
0 Kudos
MLowry
by
Occasional Contributor II
Thanks for your response, I'll talk to the higher ups and see if that workflow will work, I'm not sure if they'll be ok with that or not.

We're not really getting an error, the rest service is returning all layers and schema but the feature data is not exposed via the rest endpoint.  Does that make sense?  When I go to the URL for the map service, I can see all the layers in there, but when I click to view it it's just a big blank screen.


I debugged your posted btnclick code and everything looks good. I think you should double check the dataset in that published .mxd, and also consider adding an export to .msd step as well. I don't think Server 10.1 is going to even support .mxd's anymore.
0 Kudos
ColleenDixon
New Contributor
I debugged your posted btnclick code and everything looks good. I think you should double check the dataset in that published .mxd, and also consider adding an export to .msd step as well. I don't think Server 10.1 is going to even support .mxd's anymore.


Thank you so much for trying it, it's good to know it works on SOME MXD. 🙂  One of the GIS guys here thought maybe it could be a projection issue, we're going to fiddle around with it here in a bit.  I really appreciate you looking at it, I'm glad to know we're headed in the right direction!
0 Kudos