예제 #1
0
 public ITopology Create_Topology(IFeatureWorkspace featureWorkspace, string featuredatasetName, string featureClassName, string topologyName)
 {
     try
     {
         //1.---打开拓朴所在的要素数据集,并创建拓朴
         IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(featuredatasetName);
         if (featureDataset != null)
         {
             ITopologyContainer topologyContainer = (ITopologyContainer)featureDataset;
             ITopology          topology          = topologyContainer.CreateTopology("topo", topologyContainer.DefaultClusterTolerance, -1, ""); //在这个地方报错
             //2.---给拓朴加入要素集
             IFeatureClassContainer featureclassContainer = (IFeatureClassContainer)featureDataset;
             IFeatureClass          featureClass          = featureclassContainer.get_ClassByName(featureClassName);
             topology.AddClass(featureClass, 5, 1, 1, false);  // Parameters: AddClass(IClass, double weight, int xyrank, int zrank, Boolean EventNotificationOnValidate).
             //3.---返回拓朴
             return(topology);
         }
     }
     catch (Exception ex)
     {
         //System.Diagnostics.Debug.WriteLine(ex.ToString());
         MessageBox.Show(ex.ToString());
     }
     return(null);
 }
        /// <summary>
        /// Take a network element and return its corresponding source feature
        /// <param name="element">The return source feature corresponds to this element</param>
        /// </summary>
        private IFeature GetSourceFeature(INetworkElement element)
        {
            // To draw the network element, we will need its corresponding source feature information
            // Get the sourceID and OID from the element
            int sourceID  = element.SourceID;
            int sourceOID = element.OID;

            // Get the source feature from the network source
            INetworkSource         netSource       = m_context.NetworkDataset.get_SourceByID(sourceID);
            IFeatureClassContainer fClassContainer = m_context.NetworkDataset as IFeatureClassContainer;
            IFeatureClass          sourceFClass    = fClassContainer.get_ClassByName(netSource.Name);

            return(sourceFClass.GetFeature(sourceOID));
        }
예제 #3
0
        // Join the data.
        private static void JoinTheTableToFeatureClass(string dataToJoin)
        {
            string featureClassName          = "";
            string featureClassJoinFieldName = "";
            string tableNameJoinFieldName    = "";

            // table name.
            if (dataToJoin == "AddrPoints")
            {
                featureClassName          = "AddrPnts" + "_SGID";
                featureClassJoinFieldName = ".UTAddPtID";
                tableNameJoinFieldName    = ".ADDR_UID";
            }
            else if (dataToJoin == "Roads")
            {
                featureClassName          = "Roads" + "_SGID";
                featureClassJoinFieldName = ".UNIQUE_ID";
                tableNameJoinFieldName    = ".ROAD_UID";
            }

            string tableName           = "tbl_" + countyName + "Report";
            string queryDefTables      = tableName + "," + featureClassName;
            string queryDefWhereClause = tableName + tableNameJoinFieldName + " = " + featureClassName + featureClassJoinFieldName;

            IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspaceFGDB;
            //create query definition
            IQueryDef queryDef = featureWorkspace.CreateQueryDef();

            //provide list of tables to join
            //queryDef.Tables = "ROCKVILLE_Report, AddrPntsROCKVILLE_SGID";
            queryDef.Tables = queryDefTables;
            //retrieve the fields from all tables
            //queryDef.SubFields = "sde.datesjoin.dt_field, sde.dudates.dt_field";
            //set up join
            //queryDef.WhereClause = "ROCKVILLE_Report.ADDR_UID = AddrPntsROCKVILLE_SGID.UTAddPtID";
            queryDef.WhereClause = queryDefWhereClause;


            //Create FeatureDataset. Note the use of .OpenFeatureQuery.
            //The name "MyJoin" is the name of the restult of the query def and
            //is used in place of a feature class name.
            IFeatureDataset featureDataset = featureWorkspace.OpenFeatureQuery("MyJoin", queryDef);
            //open layer to test against
            IFeatureClassContainer featureClassContainer = (IFeatureClassContainer)featureDataset;
            IFeatureClass          featureClass          = featureClassContainer.get_ClassByName("MyJoin");

            // Export the joined feature class to the file geodatabase (at this point, it's just in memory)
            ExportTheJoinedFeatureClass(featureClass, dataToJoin);
        }
예제 #4
0
        public void Refresh()
        {
            // This method is called internally during a solve operation immediately prior to performing the actual solve
            // This gives us an opportunity to update our evaluator's internal state based on changes to the current source feature selection set within ArcMap

            if (m_mxDocument != null)
            {
                // Clear the hashtable of any previous selections
                m_sourceHashTable.Clear();

                // Loop through every layer in the map, find the appropriate network source feature layer, and add its selection set to the source hashtable
                IMap map = m_mxDocument.FocusMap;
                IFeatureClassContainer fcContainer = m_networkDataset as IFeatureClassContainer;
                IFeatureClass          sourceFC    = fcContainer.get_ClassByName(m_networkSource.Name);

                ILayer        layer;
                IFeatureClass layerFC;
                IEnumLayer    enumLayer = map.get_Layers(null, true);
                while ((layer = enumLayer.Next()) != null)
                {
                    if (layer.Visible && layer is IFeatureLayer)
                    {
                        layerFC = ((IFeatureLayer)layer).FeatureClass;
                        if (layerFC == sourceFC)
                        {
                            IFeatureSelection featureSelection = layer as IFeatureSelection;
                            ISelectionSet     selectionSet     = featureSelection.SelectionSet;
                            IEnumIDs          idEnumerator     = selectionSet.IDs;
                            idEnumerator.Reset();
                            int oid;
                            while ((oid = idEnumerator.Next()) != -1)
                            {
                                m_sourceHashTable.Add(oid, oid);
                            }
                            break;
                        }
                    }
                }
            }
        }
예제 #5
0
 private void ReadFileGDBWorkspaceFactory(string path)
 {
     Wsf                  = new FileGDBWorkspaceFactoryClass();
     Directory            = path.Substring(0, path.IndexOf(".gdb") + 4);
     FeatDsName           = System.IO.Path.GetDirectoryName(path.Substring(path.IndexOf(".gdb") + 5, path.Length - path.IndexOf(".gdb") - 5));
     NameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(path.Substring(path.IndexOf(".gdb") + 5, path.Length - path.IndexOf(".gdb") - 5));
     Extension            = System.IO.Path.GetExtension(path.Substring(path.IndexOf(".gdb") + 5, path.Length - path.IndexOf(".gdb") - 5));
     Ws     = Wsf.OpenFromFile(Directory, 0);
     FeatWs = Ws as IFeatureWorkspace;
     if (FeatDsName.Equals(string.Empty))
     {
         IFeatureClassContainer featClsCtn = FeatWs.OpenFeatureDataset(FeatDsName) as IFeatureClassContainer;
         FeatCls = featClsCtn.get_ClassByName(NameWithoutExtension);
         EnumDs  = Ws.get_Datasets(esriDatasetType.esriDTFeatureClass);
     }
     else
     {
         FeatCls = FeatWs.OpenFeatureClass(NameWithoutExtension);
         IFeatureDataset FeatDs = FeatWs.OpenFeatureDataset(FeatDsName);
         EnumDs = FeatDs.Subsets;
     }
 }
        public static IFeatureClass GetFeatureClassWithQueryDef(IDataset arcDataSet, IFeatureWorkspace arcFeatureWS, string strDispatchEtlName, string strWhereClause)
        {
            try
            {
                // make idataset from the reverse geocode sde feature class
                IDataset arcSDEDataSet_RevGeocoder;
                arcSDEDataSet_RevGeocoder = (IDataset)arcDataSet;

                //IFeatureClass arcETL_HwyRevGeocodeFC = arcFeatWorkspaceETL.OpenFeatureClass(strDispatchEtlName);
                //IFeatureLayerDefinition arcFeatLayerDef = arcETL_HwyRevGeocodeFC;

                IQueryDef queryDef = arcFeatureWS.CreateQueryDef();
                //provide list of tables to join
                queryDef.Tables = strDispatchEtlName;
                //retrieve the fields from all tables
                queryDef.SubFields = "*";
                //set up join
                queryDef.WhereClause = strWhereClause;

                //Create FeatureDataset. Note the use of .OpenFeatureQuery.
                //The name "MyJoin" is the name of the restult of the query def and
                //is used in place of a feature class name.
                IFeatureDataset featureDataset = arcFeatureWS.OpenFeatureQuery("FeatClassWithQueryDef", queryDef);
                //open layer to test against
                IFeatureClassContainer featureClassContainer = (IFeatureClassContainer)featureDataset;
                IFeatureClass          featureClass          = featureClassContainer.get_ClassByName("FeatClassWithQueryDef");

                return(featureClass);
            }
            catch (Exception ex)
            {
                return(null);

                MessageBox.Show("Error Message: " + Environment.NewLine + ex.Message + Environment.NewLine + Environment.NewLine +
                                "Error Source: " + Environment.NewLine + ex.Source + Environment.NewLine + Environment.NewLine +
                                "Error Location:" + Environment.NewLine + ex.StackTrace,
                                "UTRANS Editor tool error!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }
예제 #7
0
        public void Beat()
        {
            IWorkspace      workspace      = ArcClass.GetmdbWorkspace(mdbFilePath);
            IFeatureDataset featureDataset = ArcClass.GetFeatureDataset(workspace, "WJL");

            if (featureDataset != null)
            {
                ITopologyContainer     topologyContainer     = featureDataset as ITopologyContainer;
                ITopology              topology              = topologyContainer.CreateTopology("result", topologyContainer.DefaultClusterTolerance, -1, "");
                IFeatureClassContainer featureClassContainer = featureDataset as IFeatureClassContainer;
                IFeatureClass          featureClass          = featureClassContainer.get_ClassByName("Roads");
                topology.AddClass(featureClass, 5, 1, 1, false);
                ITopologyRuleContainer topologyRuleContainer = topology as ITopologyRuleContainer;
                ITopologyRule          topologyRule          = new TopologyRuleClass();
                topologyRule.TopologyRuleType = esriTopologyRuleType.esriTRTLineNoOverlap;
                topologyRule.OriginClassID    = featureClass.ObjectClassID;
                topologyRule.Name             = "Roads No Overlap";

                if (topologyRuleContainer.get_CanAddRule(topologyRule))
                {
                    topologyRuleContainer.AddRule(topologyRule);
                }

                topologyRule = new TopologyRuleClass();
                topologyRule.TopologyRuleType  = esriTopologyRuleType.esriTRTLineNoDangles;
                topologyRule.OriginClassID     = featureClass.ObjectClassID;
                topologyRule.AllOriginSubtypes = true;
                topologyRule.Name = "Roads No Dangles";

                // Add the rule to the Topology
                if (topologyRuleContainer.get_CanAddRule(topologyRule))
                {
                    topologyRuleContainer.AddRule(topologyRule);
                }
            }
        }
예제 #8
0
        public void Execute(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager envMgr, ESRI.ArcGIS.Geodatabase.IGPMessages message)
        {
            try
            {
                IGPUtilities3 execute_Utilities = new GPUtilitiesClass();

                if (TrackCancel == null)
                {
                    TrackCancel = new CancelTrackerClass();
                }

                IGPParameter inputFeatureDatasetParameter = paramvalues.get_Element(in_featureDatasetParameterNumber) as IGPParameter;
                IGPValue inputFeatureDatasetGPValue = execute_Utilities.UnpackGPValue(inputFeatureDatasetParameter);
                IGPValue outputOSMFileGPValue = execute_Utilities.UnpackGPValue(paramvalues.get_Element(out_osmFileLocationParameterNumber));

                // get the name of the feature dataset
                int fdDemlimiterPosition = inputFeatureDatasetGPValue.GetAsText().LastIndexOf("\\");

                string nameOfFeatureDataset = inputFeatureDatasetGPValue.GetAsText().Substring(fdDemlimiterPosition + 1);


                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;

                System.Xml.XmlWriter xmlWriter = null;

                try
                {
                    xmlWriter = XmlWriter.Create(outputOSMFileGPValue.GetAsText(), settings);
                }
                catch (Exception ex)
                {
                    message.AddError(120021, ex.Message);
                    return;
                }

                xmlWriter.WriteStartDocument();
                xmlWriter.WriteStartElement("osm"); // start the osm root node
                xmlWriter.WriteAttributeString("version", "0.6"); // add the version attribute
                xmlWriter.WriteAttributeString("generator", "ArcGIS Editor for OpenStreetMap"); // add the generator attribute

                // write all the nodes
                // use a feature search cursor to loop through all the known points and write them out as osm node

                IFeatureClassContainer osmFeatureClasses = execute_Utilities.OpenDataset(inputFeatureDatasetGPValue) as IFeatureClassContainer;

                if (osmFeatureClasses == null)
                {
                    message.AddError(120022, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), inputFeatureDatasetParameter.Name));
                    return;
                }

                IFeatureClass osmPointFeatureClass = osmFeatureClasses.get_ClassByName(nameOfFeatureDataset + "_osm_pt");

                if (osmPointFeatureClass == null)
                {
                    message.AddError(120023, string.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_no_pointfeatureclass"), nameOfFeatureDataset + "_osm_pt"));
                    return;
                }

                // check the extension of the point feature class to determine its version
                int internalOSMExtensionVersion = osmPointFeatureClass.OSMExtensionVersion();

                IFeatureCursor searchCursor = null;

                System.Xml.Serialization.XmlSerializerNamespaces xmlnsEmpty = new System.Xml.Serialization.XmlSerializerNamespaces();
                xmlnsEmpty.Add("", "");

                message.AddMessage(resourceManager.GetString("GPTools_OSMGPExport2OSM_exporting_pts_msg"));
                int pointCounter = 0;

                string nodesExportedMessage = String.Empty;

                // collect the indices for the point feature class once
                int pointOSMIDFieldIndex = osmPointFeatureClass.Fields.FindField("OSMID");
                int pointChangesetFieldIndex = osmPointFeatureClass.Fields.FindField("osmchangeset");
                int pointVersionFieldIndex = osmPointFeatureClass.Fields.FindField("osmversion");
                int pointUIDFieldIndex = osmPointFeatureClass.Fields.FindField("osmuid");
                int pointUserFieldIndex = osmPointFeatureClass.Fields.FindField("osmuser");
                int pointTimeStampFieldIndex = osmPointFeatureClass.Fields.FindField("osmtimestamp");
                int pointVisibleFieldIndex = osmPointFeatureClass.Fields.FindField("osmvisible");
                int pointTagsFieldIndex = osmPointFeatureClass.Fields.FindField("osmTags");

                using (ComReleaser comReleaser = new ComReleaser())
                {
                    searchCursor = osmPointFeatureClass.Search(null, false);
                    comReleaser.ManageLifetime(searchCursor);

                    System.Xml.Serialization.XmlSerializer pointSerializer = new System.Xml.Serialization.XmlSerializer(typeof(node));

                    IFeature currentFeature = searchCursor.NextFeature();

                    IWorkspace pointWorkspace = ((IDataset)osmPointFeatureClass).Workspace;

                    while (currentFeature != null)
                    {
                        if (TrackCancel.Continue() == true)
                        {
                            // convert the found point feature into a osm node representation to store into the OSM XML file
                            node osmNode = ConvertPointFeatureToOSMNode(currentFeature, pointWorkspace, pointTagsFieldIndex, pointOSMIDFieldIndex, pointChangesetFieldIndex, pointVersionFieldIndex, pointUIDFieldIndex, pointUserFieldIndex, pointTimeStampFieldIndex, pointVisibleFieldIndex, internalOSMExtensionVersion);

                            pointSerializer.Serialize(xmlWriter, osmNode, xmlnsEmpty);

                            // increase the point counter to later status report
                            pointCounter++;

                            currentFeature = searchCursor.NextFeature();
                        }
                        else
                        {
                            // properly close the document
                            xmlWriter.WriteEndElement(); // closing the osm root element
                            xmlWriter.WriteEndDocument(); // finishing the document

                            xmlWriter.Close(); // closing the document

                            // report the number of elements loader so far
                            nodesExportedMessage = String.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_pts_exported_msg"), pointCounter);
                            message.AddMessage(nodesExportedMessage);

                            return;
                        }
                    }
                }

                nodesExportedMessage = String.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_pts_exported_msg"), pointCounter);
                message.AddMessage(nodesExportedMessage);

                // next loop through the line and polygon feature classes to export those features as ways
                // in case we encounter a multi-part geometry, store it in a relation collection that will be serialized when exporting the relations table
                IFeatureClass osmLineFeatureClass = osmFeatureClasses.get_ClassByName(nameOfFeatureDataset + "_osm_ln");

                if (osmLineFeatureClass == null)
                {
                    message.AddError(120023, string.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_no_linefeatureclass"), nameOfFeatureDataset + "_osm_ln"));
                    return;
                }

                message.AddMessage(resourceManager.GetString("GPTools_OSMGPExport2OSM_exporting_ways_msg"));

                // as we are looping through the line and polygon feature classes let's collect the multi-part features separately 
                // as they are considered relations in the OSM world
                List<relation> multiPartElements = new List<relation>();

                System.Xml.Serialization.XmlSerializer waySerializer = new System.Xml.Serialization.XmlSerializer(typeof(way));
                int lineCounter = 0;
                int relationCounter = 0;
                string waysExportedMessage = String.Empty;

                using (ComReleaser comReleaser = new ComReleaser())
                {
                    searchCursor = osmLineFeatureClass.Search(null, false);
                    comReleaser.ManageLifetime(searchCursor);

                    IFeature currentFeature = searchCursor.NextFeature();

                    // collect the indices for the point feature class once
                    int lineOSMIDFieldIndex = osmLineFeatureClass.Fields.FindField("OSMID");
                    int lineChangesetFieldIndex = osmLineFeatureClass.Fields.FindField("osmchangeset");
                    int lineVersionFieldIndex = osmLineFeatureClass.Fields.FindField("osmversion");
                    int lineUIDFieldIndex = osmLineFeatureClass.Fields.FindField("osmuid");
                    int lineUserFieldIndex = osmLineFeatureClass.Fields.FindField("osmuser");
                    int lineTimeStampFieldIndex = osmLineFeatureClass.Fields.FindField("osmtimestamp");
                    int lineVisibleFieldIndex = osmLineFeatureClass.Fields.FindField("osmvisible");
                    int lineTagsFieldIndex = osmLineFeatureClass.Fields.FindField("osmTags");
                    int lineMembersFieldIndex = osmLineFeatureClass.Fields.FindField("osmMembers");

                    IWorkspace lineWorkspace = ((IDataset)osmLineFeatureClass).Workspace;

                    while (currentFeature != null)
                    {
                        if (TrackCancel.Continue() == false)
                        {
                            // properly close the document
                            xmlWriter.WriteEndElement(); // closing the osm root element
                            xmlWriter.WriteEndDocument(); // finishing the document

                            xmlWriter.Close(); // closing the document

                            // report the number of elements loaded so far
                            waysExportedMessage = String.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_ways_exported_msg"), lineCounter);
                            message.AddMessage(waysExportedMessage);

                            return;
                        }

                        //test if the feature geometry has multiple parts
                        IGeometryCollection geometryCollection = currentFeature.Shape as IGeometryCollection;

                        if (geometryCollection != null)
                        {
                            if (geometryCollection.GeometryCount == 1)
                            {
                                // convert the found polyline feature into a osm way representation to store into the OSM XML file
                                way osmWay = ConvertFeatureToOSMWay(currentFeature, lineWorkspace, osmPointFeatureClass, pointOSMIDFieldIndex, lineTagsFieldIndex, lineOSMIDFieldIndex, lineChangesetFieldIndex, lineVersionFieldIndex, lineUIDFieldIndex, lineUserFieldIndex, lineTimeStampFieldIndex, lineVisibleFieldIndex, internalOSMExtensionVersion);
                                waySerializer.Serialize(xmlWriter, osmWay, xmlnsEmpty);

                                // increase the line counter for later status report
                                lineCounter++;
                            }
                            else
                            {
                                relation osmRelation = ConvertRowToOSMRelation((IRow)currentFeature, lineWorkspace, lineTagsFieldIndex, lineOSMIDFieldIndex, lineChangesetFieldIndex, lineVersionFieldIndex, lineUIDFieldIndex, lineUserFieldIndex, lineTimeStampFieldIndex, lineVisibleFieldIndex, lineMembersFieldIndex, internalOSMExtensionVersion);
                                multiPartElements.Add(osmRelation);

                                // increase the line counter for later status report
                                relationCounter++;
                            }
                        }

                        currentFeature = searchCursor.NextFeature();
                    }
                }


                IFeatureClass osmPolygonFeatureClass = osmFeatureClasses.get_ClassByName(nameOfFeatureDataset + "_osm_ply");
                IFeatureWorkspace commonWorkspace = ((IDataset)osmPolygonFeatureClass).Workspace as IFeatureWorkspace;

                if (osmPolygonFeatureClass == null)
                {
                    message.AddError(120024, string.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_no_polygonfeatureclass"), nameOfFeatureDataset + "_osm_ply"));
                    return;
                }

                using (ComReleaser comReleaser = new ComReleaser())
                {
                    searchCursor = osmPolygonFeatureClass.Search(null, false);
                    comReleaser.ManageLifetime(searchCursor);

                    IFeature currentFeature = searchCursor.NextFeature();

                    // collect the indices for the point feature class once
                    int polygonOSMIDFieldIndex = osmPolygonFeatureClass.Fields.FindField("OSMID");
                    int polygonChangesetFieldIndex = osmPolygonFeatureClass.Fields.FindField("osmchangeset");
                    int polygonVersionFieldIndex = osmPolygonFeatureClass.Fields.FindField("osmversion");
                    int polygonUIDFieldIndex = osmPolygonFeatureClass.Fields.FindField("osmuid");
                    int polygonUserFieldIndex = osmPolygonFeatureClass.Fields.FindField("osmuser");
                    int polygonTimeStampFieldIndex = osmPolygonFeatureClass.Fields.FindField("osmtimestamp");
                    int polygonVisibleFieldIndex = osmPolygonFeatureClass.Fields.FindField("osmvisible");
                    int polygonTagsFieldIndex = osmPolygonFeatureClass.Fields.FindField("osmTags");
                    int polygonMembersFieldIndex = osmPolygonFeatureClass.Fields.FindField("osmMembers");

                    IWorkspace polygonWorkspace = ((IDataset)osmPolygonFeatureClass).Workspace;

                    while (currentFeature != null)
                    {
                        if (TrackCancel.Continue() == false)
                        {
                            // properly close the document
                            xmlWriter.WriteEndElement(); // closing the osm root element
                            xmlWriter.WriteEndDocument(); // finishing the document

                            xmlWriter.Close(); // closing the document

                            // report the number of elements loaded so far
                            waysExportedMessage = String.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_ways_exported_msg"), lineCounter);
                            message.AddMessage(waysExportedMessage);

                            message.AddAbort(resourceManager.GetString("GPTools_toolabort"));
                            return;
                        }

                        //test if the feature geometry has multiple parts
                        IGeometryCollection geometryCollection = currentFeature.Shape as IGeometryCollection;

                        if (geometryCollection != null)
                        {
                            if (geometryCollection.GeometryCount == 1)
                            {
                                // convert the found polyline feature into a osm way representation to store into the OSM XML file
                                way osmWay = ConvertFeatureToOSMWay(currentFeature, polygonWorkspace, osmPointFeatureClass, pointOSMIDFieldIndex, polygonTagsFieldIndex, polygonOSMIDFieldIndex, polygonChangesetFieldIndex, polygonVersionFieldIndex, polygonUIDFieldIndex, polygonUserFieldIndex, polygonTimeStampFieldIndex, polygonVisibleFieldIndex, internalOSMExtensionVersion);
                                waySerializer.Serialize(xmlWriter, osmWay, xmlnsEmpty);

                                // increase the line counter for later status report
                                lineCounter++;
                            }
                            else
                            {
                                relation osmRelation = ConvertRowToOSMRelation((IRow)currentFeature, polygonWorkspace, polygonTagsFieldIndex, polygonOSMIDFieldIndex, polygonChangesetFieldIndex, polygonVersionFieldIndex, polygonUIDFieldIndex, polygonUserFieldIndex, polygonTimeStampFieldIndex, polygonVisibleFieldIndex, polygonMembersFieldIndex, internalOSMExtensionVersion);
                                multiPartElements.Add(osmRelation);

                                // increase the line counter for later status report
                                relationCounter++;
                            }
                        }

                        currentFeature = searchCursor.NextFeature();
                    }
                }

                waysExportedMessage = String.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_ways_exported_msg"), lineCounter);
                message.AddMessage(waysExportedMessage);


                // now let's go through the relation table 
                message.AddMessage(resourceManager.GetString("GPTools_OSMGPExport2OSM_exporting_relations_msg"));
                ITable relationTable = commonWorkspace.OpenTable(nameOfFeatureDataset + "_osm_relation");

                if (relationTable == null)
                {
                    message.AddError(120025, String.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_no_relationTable"), nameOfFeatureDataset + "_osm_relation"));
                    return;
                }


                System.Xml.Serialization.XmlSerializer relationSerializer = new System.Xml.Serialization.XmlSerializer(typeof(relation));
                string relationsExportedMessage = String.Empty;

                using (ComReleaser comReleaser = new ComReleaser())
                {
                    ICursor rowCursor = relationTable.Search(null, false);
                    comReleaser.ManageLifetime(rowCursor);

                    IRow currentRow = rowCursor.NextRow();

                    // collect the indices for the relation table once
                    int relationOSMIDFieldIndex = relationTable.Fields.FindField("OSMID");
                    int relationChangesetFieldIndex = relationTable.Fields.FindField("osmchangeset");
                    int relationVersionFieldIndex = relationTable.Fields.FindField("osmversion");
                    int relationUIDFieldIndex = relationTable.Fields.FindField("osmuid");
                    int relationUserFieldIndex = relationTable.Fields.FindField("osmuser");
                    int relationTimeStampFieldIndex = relationTable.Fields.FindField("osmtimestamp");
                    int relationVisibleFieldIndex = relationTable.Fields.FindField("osmvisible");
                    int relationTagsFieldIndex = relationTable.Fields.FindField("osmTags");
                    int relationMembersFieldIndex = relationTable.Fields.FindField("osmMembers");

                    IWorkspace polygonWorkspace = ((IDataset)osmPolygonFeatureClass).Workspace;


                    while (currentRow != null)
                    {
                        if (TrackCancel.Continue() == false)
                        {
                            // properly close the document
                            xmlWriter.WriteEndElement(); // closing the osm root element
                            xmlWriter.WriteEndDocument(); // finishing the document

                            xmlWriter.Close(); // closing the document

                            // report the number of elements loaded so far
                            relationsExportedMessage = String.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_relations_exported_msg"), relationCounter);
                            message.AddMessage(relationsExportedMessage);

                            message.AddAbort(resourceManager.GetString("GPTools_toolabort"));
                            return;
                        }

                        relation osmRelation = ConvertRowToOSMRelation(currentRow, (IWorkspace)commonWorkspace, relationTagsFieldIndex, relationOSMIDFieldIndex, relationChangesetFieldIndex, relationVersionFieldIndex, relationUIDFieldIndex, relationUserFieldIndex, relationTimeStampFieldIndex, relationVisibleFieldIndex, relationMembersFieldIndex, internalOSMExtensionVersion);
                        relationSerializer.Serialize(xmlWriter, osmRelation, xmlnsEmpty);

                        // increase the line counter for later status report
                        relationCounter++;

                        currentRow = rowCursor.NextRow();
                    }
                }

                // lastly let's serialize the collected multipart-geometries back into relation elements
                foreach (relation currentRelation in multiPartElements)
                {
                    if (TrackCancel.Continue() == false)
                    {
                        // properly close the document
                        xmlWriter.WriteEndElement(); // closing the osm root element
                        xmlWriter.WriteEndDocument(); // finishing the document

                        xmlWriter.Close(); // closing the document

                        // report the number of elements loaded so far
                        relationsExportedMessage = String.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_relations_exported_msg"), relationCounter);
                        message.AddMessage(relationsExportedMessage);

                        return;
                    }

                    relationSerializer.Serialize(xmlWriter, currentRelation, xmlnsEmpty);
                    relationCounter++;
                }

                relationsExportedMessage = String.Format(resourceManager.GetString("GPTools_OSMGPExport2OSM_relations_exported_msg"), relationCounter);
                message.AddMessage(relationsExportedMessage);


                xmlWriter.WriteEndElement(); // closing the osm root element
                xmlWriter.WriteEndDocument(); // finishing the document

                xmlWriter.Close(); // closing the document
            }
            catch (Exception ex)
            {
                message.AddError(11111, ex.StackTrace);
                message.AddError(120026, ex.Message);
            }
        }