This document is archived and information here might be outdated.  Recommended version.


Create A Schematic Diagram Class Entirely Based On Custom Queries From Scratch Snippet (ArcObjects .NET 10.4 SDK)
ArcObjects Library Reference

Create A Schematic Diagram Class Entirely Based On Custom Queries From Scratch Snippet

This class behaves as a template to create a schematic diagram template class based on the standard builder for which the diagrams are entirely built from custom queries. It uses a set of predefined object tables (which names can be changed according to your cases) which contain records that are queried to build the set of schematic features contained in schematic diagrams.

[C#]
    public class QueryDiagramClass
    {
        //This class behaves as a template to create a schematic diagram template based on the standard builder for which the diagrams are entirely built from custom queries.
        //It uses 3 object tables: Document, Nodes and Link which names can be changed according to your needs in the constant TABLE_NAME.
        //The structure of the 3 tables is predefined and the queries used to generate the diagrams based on the diagram template built by this code are linked to the tables' structure.

        //The Document table lists all the diagrams which can be generated from this template.
        //The Document table fields are:
        //OBJECTID          AutoNumber      Primary Key    
        //DOCID             Long            Unique Index
        //DOCNAME           Text(255)       Diagram name

        //The Nodes table gives the list of the nodes expected to be contained in the different diagrams.
        //The Nodes table fields are:
        //OBJECTID          AutoNumber      Primary Key    
        //DOCID             Long            Related DOCID value - Linked to the Document Table DOCID field
        //ObjectType        Text(50)        Type of object node (Container, Junction, NodeOnLink)
        //XGeo              Double          X Postion of the node - Only used for a Junction node
        //YGeo              Double          Y Postion of the node - Only used for a Junction node
        //ParentLink        Long            OBJECTID of the reference link - Only used for a NodeOnLink node
        //PositionOnLink    Double          Relative position on the reference link (ParentLink) - Only used for a NodeOnLink node
        //RelatedFCName     Text(50)        Type of the related container - Only used for a child node which is related to a Container node
        //RelatedFOID       Long            OBJECTID of the related container - Only used for a child node which is related to a Container node
        //Rotation          Double          Rotation of the node - Not used for a Container node

        //The Links table gives the list of the links expected to be contained in the different diagrams.
        //The Links table fields are:
        //OBJECTID          AutoNumber      Primary Key    
        //DOCID             Long            Related DOCID value - Linked to the Document Table DOCID field
        //ObjectType        Text(50)        Type of object link (Link, SubLink)
        //FromOID           Long            OBJECTID Of the origin node
        //ToOID             Long            OBJECTID of extremity node
        //FromPort          Short           Number of the origin port
        //ToPort            Short           Number of the extremity port
        //ListPoint         Memo            List of vertices along le link (Syntax: NumberOfPoint;X1;Y1;X2;Y2...)
        //ParentLink        Long            OBJECTID of the reference link - Only used for a SubLink link
        //RelatedFCName     Text(50)        Type of the related container - Only used for a child link which is related to a Container node
        //RelatedFOID       Long            OBJECTID of the related container - Only used for a child link which is related to a Container node

        const string DATASET_NAME="MyQueryDatasetCS";
        const string DIAGRAM_TEMPLATE_NAME="MyDiagramClass";
        const string DOCUMENT_TABLE_NAME="Document";
        const string NODE_TABLE_NAME="Nodes";
        const string LINK_TABLE_NAME="Links";
        const string NODEONLINK_TABLE_NAME="Nodes";
        const string SUBLINK_TABLE_NAME="Links";
        const string CONTAINER_TABLE_NAME="Nodes";

        /// <summary>
        ///  Type of attributes used in this class
        /// </summary>
        public enum EnumAtttributeType
        {
            AttributeConstant,
            AttributeField,
            AttributeFormatted
        }

        /// <summary>
        /// This sample shows how to create a schematic diagram template entirely configured with custom queries by code from scratch based on the object tables described above
        /// </summary>
        /// <param name="esriWorkspace">The ESRI.ArcGIS.Geodatabase.IWorkspace where the diagram template is going to be created</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicDataset</returns>
        /// <remarks>The esriWorkspace must be opened</remarks>
        public ESRI.ArcGIS.Schematic.ISchematicDataset CreateQuerySchematicDataset(ESRI.ArcGIS.Geodatabase.IWorkspace esriWorkspace)
        {
            // if the input IWorkspace is null, exit
            if (esriWorkspace == null) return null;

            ESRI.ArcGIS.Schematic.ISchematicWorkspace schWorkspace=null;
            ESRI.ArcGIS.Schematic.ISchematicDiagramClass schDiagClass;
            ESRI.ArcGIS.Schematic.ISchematicDataset schData=null;

            // -- STEP#1 -- Opening the ISchematicWorkspace related to the input IWorkspace
            Type objectType=Type.GetTypeFromProgID("esriSchematic.SchematicWorkspaceFactory");

            ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory schWorkspaceFct;
            schWorkspaceFct=Activator.CreateInstance(objectType) as ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory;

            schWorkspace=schWorkspaceFct.Open(esriWorkspace);

            // -- STEP#2 -- Creating the new ISchematicDataset
            schData=schWorkspace.get_SchematicDatasetByName(DATASET_NAME);
            // if it already exists, exit
            if (schData != null) return schData;

            // create the new ISchematicDataset in the input IWorkspace
            try
            {
                schData=schWorkspace.CreateSchematicDataset(DATASET_NAME, "");
                schData.DesignMode=true;
            }
            catch
            {
                // if the ISchematicDataset cannot be created, the process stops
                return null;
            }

            // -- STEP#3 -- Creating the ISchematicStandardBuilder that will be assigned afterwards to the schematic diagram template
            objectType=Type.GetTypeFromProgID("esriSchematic.SchematicStandardBuilder");
            ESRI.ArcGIS.Schematic.ISchematicStandardBuilder pSchStandardBuilder;
            if (objectType == null) return null;

            pSchStandardBuilder=Activator.CreateInstance(objectType) as ESRI.ArcGIS.Schematic.ISchematicStandardBuilder;
            // if the ISchematicStandardBuilder is Nothing, exit
            if (pSchStandardBuilder == null) return null;

            pSchStandardBuilder.AddConnectedNodes=true;
            pSchStandardBuilder.InitializeLinksVertices=true;
            ESRI.ArcGIS.Schematic.ISchematicBuilder pSchBuilder=(ESRI.ArcGIS.Schematic.ISchematicBuilder)pSchStandardBuilder;

            // -- STEP#4 -- Creating the ISchematicDiagramClass
            schDiagClass=CreateDiagramClass(schData, DIAGRAM_TEMPLATE_NAME, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, schData.DefaultSchematicDataSource, "SELECT * FROM " + DOCUMENT_TABLE_NAME, new string[] { "DOCNAME" });
            schDiagClass.SchematicBuilder=pSchBuilder;

            // -- STEP#5 -- Creating the attributes for the diagram class
            ESRI.ArcGIS.Schematic.ISchematicAttributeField schAttribField=CreateAttribute(schDiagClass, "DOCID", EnumAtttributeType.AttributeField, ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode.esriSchematicAttributeBuildEvaluation, ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage) as ESRI.ArcGIS.Schematic.ISchematicAttributeField;
            schAttribField.FieldNames=new string[] { "DOCID" }; // This Attribute is used for link with Element

            ESRI.ArcGIS.Schematic.EnumSchematicQueryParameterClass enumQueryParameters=new ESRI.ArcGIS.Schematic.EnumSchematicQueryParameterClass();
            ESRI.ArcGIS.Schematic.ISchematicQueryParameter schQueryParameter=new ESRI.ArcGIS.Schematic.SchematicQueryParameter();

            // -- STEP#6 -- Configuring the query for the diagram class
            schQueryParameter.Name="DOCID";
            schQueryParameter.Textual=false;
            enumQueryParameters.Add(schQueryParameter);
            schQueryParameter=null;

            ESRI.ArcGIS.Schematic.ISchematicElementClass schEltClass;

            // -- STEP#7 -- Creating the schematic feature classes
            // creating the SchematicLinks schematic feature class
            CreateLinks(schData, schDiagClass, "SchematicLinks", LINK_TABLE_NAME, "Links", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline, true);

            // creating the SchematicSubLinks schematic feature class
            CreateSubLinks(schData, schDiagClass, "SchematicSubLinks", SUBLINK_TABLE_NAME, "SubLinks", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline, true);

            // creating the SchematicNodeOnLinks schematic feature class
            CreateNodeOnLink(schData, schDiagClass, "SchematicNodeOnLinks", NODEONLINK_TABLE_NAME, "SubNodes", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint, true);

            // creating the SchematicNodes schematic feature class
            schEltClass=CreateNode(schData, schDiagClass, "SchematicNodes", NODE_TABLE_NAME, "Nodes", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint, false);

            // creating the Containers schematic feature class
            CreateChildNode(schData, schDiagClass, schEltClass, "SchematicJunctions", NODE_TABLE_NAME, "Junctions", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint, true);

            // creating the Links schematic feature class
            ESRI.ArcGIS.Schematic.ISchematicElementClass schContClass=CreateChildNode(schData, schDiagClass, schEltClass, "Containers", NODE_TABLE_NAME, "Container 1", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon, true);
            AddAttributeConst(schContClass, "ContainerMargin", "0.5");

            // -- STEP#8 -- Saving the schematic dataset and exit the design mode
            schData.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersionCurrent, false);
            schData.DesignMode=false;

            return schData;
        }

        /// <summary>
        /// Return the classID for the type of attributes used in this sample
        /// </summary>
        /// <param name="Value">EnumAtttributeType</param>
        /// <returns>string</returns>
        private string GetAttributeType(EnumAtttributeType Value)
        {
            switch (Value)
            {
                case EnumAtttributeType.AttributeConstant:
                    return "{3AD9D8B8-0A1D-4F32-ABB5-54B848A46F85}";
                case EnumAtttributeType.AttributeField:
                    return "{E1902BB0-6070-4EE2-995A-DB86FAC5EEB0}";
                case EnumAtttributeType.AttributeFormatted:
                    return "{1DE95A2A-B750-446A-8D3A-3C67660E8B59}";
                default:
                    return "";
            }
        }

        #region Create Elements
        /// <summary>
        /// <param name="schDataset">The ISchematicDataset where the schematic diagram template must be created</param>
        /// <param name="DiagramClassName">The name of the schematic diagram template to create</param>
        /// <param name="QueryMode">The evaluation mode for the query that must be configured on the diagram template</param>
        /// <param name="schDataSource">The ISchematicDataSource related to the query</param>
        /// <param name="QueryString">The query string</param>
        /// <param name="FieldNames">The field names used to build each diagram identifier</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicDiagramClass</returns>
        /// <remarks></remarks>
        private ESRI.ArcGIS.Schematic.ISchematicDiagramClass CreateDiagramClass(ESRI.ArcGIS.Schematic.ISchematicDataset schDataset, string DiagramClassName, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode QueryMode, ESRI.ArcGIS.Schematic.ISchematicDataSource schDataSource, string QueryString, object FieldNames)
        {
            ESRI.ArcGIS.Schematic.ISchematicDiagramClass schDiagClass=null;
            try
            {
                schDiagClass=schDataset.CreateSchematicDiagramClass(DiagramClassName);
            }
            catch { }

            schDiagClass.SchematicDataSource=schDataSource;
            schDiagClass.ExternalQueryEvaluationMode=QueryMode;

            schDiagClass.QueryString=QueryString;
            schDiagClass.IdentifierFieldNames=FieldNames;

            return schDiagClass;
        }

        /// <summary>
        /// Create a schematic feature class - basic creation
        /// </summary>
        /// <param name="schDataset">The ISchematicDataset where the schematic feature class must be created</param>
        /// <param name="schDiagClass">The ISchematicDiagramClass the new schematic feature class must be associated with</param>
        /// <param name="ElementName">The name of the schematic feature class to create</param>
        /// <param name="ClassType">The type of schematic element managed by this schematic feature class</param>
        /// <param name="schDataSource">The ISchematicDataSource related to the query that must return the schematic features based on this class</param>
        /// <param name="QueryString">The query string</param>
        /// <param name="FieldNames">The field names used to build each schematic feature identifier</param>
        /// <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
        /// <param name="Geometry">The type of geometry for the schematic features based on this class</param>
        /// <param name="QueryEvaluation">The evaluation mode for the query</param>
        /// <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass</returns>
        /// <remarks></remarks>
        private ESRI.ArcGIS.Schematic.ISchematicElementClass CreateElementClass(ESRI.ArcGIS.Schematic.ISchematicDataset schDataset, ESRI.ArcGIS.Schematic.ISchematicDiagramClass schDiagClass, string ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType ClassType, ESRI.ArcGIS.Schematic.ISchematicDataSource schDataSource, string QueryString, object FieldNames, ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter QueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType Geometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode QueryEvaluation, bool WithAssociation)
        {
            // schematic feature class creation
            ESRI.ArcGIS.Schematic.ISchematicElementClass schElement=null;
            try
            {
                schElement=schDataset.CreateSchematicElementClass(ElementName, ClassType);
            }
            catch { }

            schElement.ShapeField=BuildShapeField(Geometry, schDataset.SchematicWorkspace.Workspace);

            schElement.GeometryType=Geometry;
            schElement.SchematicDataSource=schDataSource;
            schElement.ExternalQueryEvaluationMode=QueryEvaluation;
            schElement.QueryString=QueryString;
            schElement.IdentifierFieldNames=FieldNames;
            schElement.SchematicQueryParameters=QueryParameters;

            // if WithAssociation is True, the schematic feature class is associated with the specified input diagram class
            if (WithAssociation) schDiagClass.AssociateSchematicElementClass(schElement);

            return schElement;
        }

        /// <summary>
        /// Create a schematic feature class which inherits from another schematic feature class
        /// </summary>
        /// <param name="ParentClass">The parent ISchematicElementClass</param>
        /// <param name="schDataset">The ISchematicDataset where the schematic feature class must be created</param>
        /// <param name="schDiagClass">The ISchematicDiagramClass the new schematic feature class must be associated with</param>
        /// <param name="ElementName">The name of the schematic feature class to create</param>
        /// <param name="ClassType">The type of schematic element managed by this schematic feature class</param>
        /// <param name="schDataSource">The ISchematicDataSource related to the query that must return the schematic features based on this class</param>
        /// <param name="QueryString">The query string</param>
        /// <param name="FieldNames">The field names used to build each schematic feature identifier</param>
        /// <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
        /// <param name="Geometry">The type of geometry for the schematic features based on this class</param>
        /// <param name="QueryEvaluation">The evaluation mode for the query</param>
        /// <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass</returns>
        /// <remarks></remarks>
        private ESRI.ArcGIS.Schematic.ISchematicElementClass CreateSubElementClass(ESRI.ArcGIS.Schematic.ISchematicElementClass ParentClass, ESRI.ArcGIS.Schematic.ISchematicDataset schDataset, ESRI.ArcGIS.Schematic.ISchematicDiagramClass schDiagClass, string ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType ClassType, ESRI.ArcGIS.Schematic.ISchematicDataSource schDataSource, string QueryString, object FieldNames, ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter QueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType Geometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode QueryEvaluation, bool WithAssociation)
        {

            ESRI.ArcGIS.Schematic.ISchematicElementClass schElement=null;
            try
            {
                // schematic feature class creation
                schElement=CreateElementClass(schDataset, schDiagClass, ElementName, ClassType, schDataSource, QueryString, FieldNames, QueryParameters, Geometry, QueryEvaluation, WithAssociation);
                // specifying the parent schematic feature class for the new schematic feature class
                schElement.Parent=ParentClass;
            }
            catch { }
            return schElement;
        }


        /// <summary>
        /// Create a node schematic feature class
        /// </summary>
        /// <param name="schDataset">The ISchematicDataset where the node schematic feature class must be created</param>
        /// <param name="schDiagClass">The ISchematicDiagramClass the new node schematic feature class must be associated with</param>
        /// <param name="ElementName">The name of the node schematic feature class to create</param>
        /// <param name="TableName">The name of the table where the records related to the node schematic features must be queried</param>
        /// <param name="FilterElementInTable">The filter that must be used to filter out the records</param>
        /// <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
        /// <param name="TypeGeometry">The type of geometry for the schematic features based on this class</param>
        /// <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass node schematic feature class</returns>
        /// <remarks></remarks>
        private ESRI.ArcGIS.Schematic.ISchematicElementClass CreateNode(ESRI.ArcGIS.Schematic.ISchematicDataset schDataset, ESRI.ArcGIS.Schematic.ISchematicDiagramClass schDiagClass, string ElementName, string TableName, string FilterElementInTable, ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter QueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType TypeGeometry, bool WithAssociation)
        {
            // node schematic feature class creation
            ESRI.ArcGIS.Schematic.ISchematicElementClass schEltClass=CreateElementClass(schDataset, schDiagClass, ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicNodeType, schDataset.DefaultSchematicDataSource, "SELECT * FROM " + TableName + " WHERE DOCID=?", new string[] { "DOCID", "IDOBJECT", "Node" }, QueryParameters, TypeGeometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, WithAssociation);

            // creation of the set of attributes expected for node schematic features
            AddAttributeField(schEltClass, "DOCID", new string[] { "DOCID" });
            AddAttributeField(schEltClass, "ObjectId", new string[] { "IDOBJECT" });
            AddAttributeFormat(schEltClass, "Name", "%s-%s-Node", new string[] { "DOCID", "ObjectId" });
            AddAttributeField(schEltClass, "InitialXPosition", new string[] { "XGeo" });
            AddAttributeField(schEltClass, "InitialYPosition", new string[] { "YGeo" });
            AddAttributeField(schEltClass, "ParentId", new string[] { "RelatedFOID" });
            AddAttributeField(schEltClass, "InitialRotation", new string[] { "Rotation" });
            
            // creation of the attributes used to manage container if the nodes based on this schematic feature class have relations with container schematic features
            AddAttributeField(schEltClass, "PTN", new string[] { "RelatedFCName" });
            AddAttributeFormat(schEltClass, "PEN", "%s-%s-Node", new string[] { "DOCID", "ParentId" });

            return schEltClass;
        }

        /// <summary>
        /// Create a node schematic feature class which inherits from another node schematic feature class
        /// </summary>
        /// <param name="schDataset">The ISchematicDataset where the node schematic feature class must be created</param>
        /// <param name="schDiagClass">The ISchematicDiagramClass the new node schematic feature class must be associated with</param>
        /// <param name="schParentClass">The parent ISchematicElementClass</param>
        /// <param name="ElementName">The name of the node schematic feature class to create</param>
        /// <param name="TableName">The name of the table where the records related to the node schematic features must be queried</param>
        /// <param name="FilterElementInTable">The filter that must be used to filter out the records</param>
        /// <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
        /// <param name="TypeGeometry">The type of geometry for the schematic features based on this class</param>
        /// <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass node schematic feature class</returns>        /// <remarks></remarks>
        private ESRI.ArcGIS.Schematic.ISchematicElementClass CreateChildNode(ESRI.ArcGIS.Schematic.ISchematicDataset schDataset, ESRI.ArcGIS.Schematic.ISchematicDiagramClass schDiagClass, ESRI.ArcGIS.Schematic.ISchematicElementClass schParentClass, string ElementName, string TableName, string FilterElementInTable, ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter QueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType TypeGeometry, bool WithAssociation)
        {
            // schematic feature class creation with a parent node schematic feature class
            ESRI.ArcGIS.Schematic.ISchematicElementClass schEltClass=CreateSubElementClass(schParentClass, schDataset, schDiagClass, ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicNodeType, schDataset.DefaultSchematicDataSource, "SELECT * FROM " + TableName + " WHERE OBJECTTYPE='" + FilterElementInTable + "' AND DOCID=?", new string[] { "DOCID", "IDOBJECT", "Node" }, QueryParameters, TypeGeometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, WithAssociation);

            return schEltClass;
        }

        /// <summary>
        /// Create a link schematic feature class
        /// </summary>
        /// <param name="schDataset">The ISchematicDataset where the link schematic feature class must be created</param>
        /// <param name="schDiagClass">The ISchematicDiagramClass the new link schematic feature class must be associated with</param>
        /// <param name="ElementName">The name of the link schematic feature class to create</param>
        /// <param name="TableName">The name of the table where the records related to the link schematic features must be queried</param>
        /// <param name="FilterElementInTable">The filter that must be used to filter out the records</param>
        /// <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
        /// <param name="TypeGeometry">The type of geometry for the schematic features based on this class</param>
        /// <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass link schematic feature class</returns>
        /// <remarks></remarks>
        private ESRI.ArcGIS.Schematic.ISchematicElementClass CreateLinks(ESRI.ArcGIS.Schematic.ISchematicDataset schDataset, ESRI.ArcGIS.Schematic.ISchematicDiagramClass schDiagClass, string ElementName, string TableName, string FilterElementInTable, ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter QueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType TypeGeometry, bool WithAssociation)
        {
            // link schematic feature class creation
            ESRI.ArcGIS.Schematic.ISchematicElementClass schEltClass=CreateElementClass(schDataset, schDiagClass, ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicLinkType, schDataset.DefaultSchematicDataSource, "SELECT * FROM " + TableName + " WHERE OBJECTTYPE='" + FilterElementInTable + "' AND DOCID=?", new string[] { "DOCID", "IDOBJECT", "Link" }, QueryParameters, TypeGeometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, WithAssociation);

            // creation of the set of attributes expected for link schematic features
            AddAttributeField(schEltClass, "ExtremityNode",  new string[] { "DOCID", "ToOID", "Node" });
            AddAttributeField(schEltClass, "OriginNode", new string[] { "DOCID", "FromOID", "Node" });
            AddAttributeField(schEltClass, "InitialListPoints",  new string[] { "ListPoints" });
            AddAttributeField(schEltClass, "DOCID",new string[] { "DOCID" });
            AddAttributeField(schEltClass, "ObjectId",  new string[] { "IDOBJECT" });
            AddAttributeFormat(schEltClass, "Name",  "%s-%s-Link", new string[] { "DOCID", "ObjectId" });

            return schEltClass;
        }

        /// <summary>
        /// Create a sublink schematic feature class
        /// </summary>
        /// <param name="schDataset">The ISchematicDataset where the sublink schematic feature class must be created</param>
        /// <param name="schDiagClass">The ISchematicDiagramClass the new sublink schematic feature class must be associated with</param>
        /// <param name="ElementName">The name of the sublink schematic feature class to create</param>
        /// <param name="TableName">The name of the table where the records related to the sublink schematic features must be queried</param>
        /// <param name="FilterElementInTable">The filter that must be used to filter out the records</param>
        /// <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
        /// <param name="TypeGeometry">The type of geometry for the schematic features based on this class</param>
        /// <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass sublink schematic feature class</returns>
        /// <remarks></remarks>
        private ESRI.ArcGIS.Schematic.ISchematicElementClass CreateSubLinks(ESRI.ArcGIS.Schematic.ISchematicDataset schDataset, ESRI.ArcGIS.Schematic.ISchematicDiagramClass schDiagClass, string ElementName, string TableName, string FilterElementInTable, ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter QueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType TypeGeometry, bool WithAssociation)
        {
            // sublink schematic feature class creation
            ESRI.ArcGIS.Schematic.ISchematicElementClass schEltClass=CreateElementClass(schDataset, schDiagClass, ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicSubLinkType, schDataset.DefaultSchematicDataSource, "SELECT * FROM " + TableName + " WHERE OBJECTTYPE='" + FilterElementInTable + "' AND DOCID=?", new string[] { "DOCID", "IDOBJECT", "SubLink" }, QueryParameters, TypeGeometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, WithAssociation);

            // creation of the set of attributes expected for sublink schematic features
            AddAttributeField(schEltClass, "ExtremityNode", new string[] { "DOCID", "ToOID", "Node" });
            AddAttributeField(schEltClass, "OriginNode", new string[] { "DOCID", "FromOID", "Node" });
            AddAttributeField(schEltClass, "ReferenceLink", new string[] { "DOCID", "ParentLink", "Link" });
            AddAttributeField(schEltClass, "DOCID", new string[] { "DOCID" });
            AddAttributeField(schEltClass, "ObjectId", new string[] { "IDOBJECT" });
            AddAttributeFormat(schEltClass, "Name", "%s-%s-SubLink", new string[] { "DOCID", "ObjectId" });

            return schEltClass;
        }

        /// <summary>
        /// Create a node-on-link schematic feature class 
        /// </summary>
        /// <param name="schDataset">The ISchematicDataset where the node-on-link schematic feature class must be created</param>
        /// <param name="schDiagClass">The ISchematicDiagramClass the new node-on-link schematic feature class must be associated with</param>
        /// <param name="ElementName">The name of the node-on-link schematic feature class to create</param>
        /// <param name="TableName">The name of the table where the records related to the node-on-link schematic features must be queried</param>
        /// <param name="FilterElementInTable">The filter that must be used to filter out the records</param>
        /// <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
        /// <param name="TypeGeometry">The type of geometry for the schematic features based on this class</param>
        /// <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass node-on-link schematic feature class</returns>
        /// <remarks></remarks>
        private ESRI.ArcGIS.Schematic.ISchematicElementClass CreateNodeOnLink(ESRI.ArcGIS.Schematic.ISchematicDataset schDataset, ESRI.ArcGIS.Schematic.ISchematicDiagramClass schDiagClass, string ElementName, string TableName, string FilterElementInTable, ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter QueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType TypeGeometry, bool WithAssociation)
        {
            // node-on-link schematic feature class creation
            ESRI.ArcGIS.Schematic.ISchematicElementClass schEltClass=CreateElementClass(schDataset, schDiagClass, ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicNodeOnLinkType, schDataset.DefaultSchematicDataSource, "SELECT * FROM " + TableName + " WHERE OBJECTTYPE='" + FilterElementInTable + "' AND DOCID=?", new string[] { "DOCID", "IDOBJECT", "Node" }, QueryParameters, TypeGeometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, WithAssociation);

            // creation of the set of attributes expected for node-on-link schematic features
            AddAttributeField(schEltClass, "DOCID", new string[] { "DOCID" });
            AddAttributeField(schEltClass, "InitialRotation", new string[] { "Rotation" });
            AddAttributeField(schEltClass, "ObjectId", new string[] { "IDOBJECT" });
            AddAttributeField(schEltClass, "RelativePosition", new string[] { "PositionOnLink" });
            AddAttributeField(schEltClass, "ReferenceLink", new string[] { "DOCID", "ParentLink", "Link" });
            AddAttributeFormat(schEltClass, "Name", "%s-%s-Node", new string[] { "DOCID", "ObjectId" });

            return schEltClass;
        }

        #endregion

        #region Attributes
        /// <summary>
        /// Create an attribute on a schematic diagram class
        /// </summary>
        /// <param name="schDiagClass">The ISchematicDiagramClass where the attribute must be created</param>
        /// <param name="AttributeName">The name of the new attribute</param>
        /// <param name="AttribType">The type of attribute</param>
        /// <param name="EvalMode">The evaluation mode for the attribute</param>
        /// <param name="StorageMode">The storage mode for the attribute</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicAttribute</returns>
        /// <remarks></remarks>
        private ESRI.ArcGIS.Schematic.ISchematicAttribute CreateAttribute(ESRI.ArcGIS.Schematic.ISchematicDiagramClass schDiagClass, string AttributeName, EnumAtttributeType AttribType, ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode EvalMode, ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode StorageMode)
        {
            ESRI.ArcGIS.Schematic.ISchematicAttribute schAttribute=null;
            try
            {
                ESRI.ArcGIS.esriSystem.UID pUid=new ESRI.ArcGIS.esriSystem.UID();
                pUid.Value=GetAttributeType(AttribType);
                schAttribute=schDiagClass.CreateSchematicAttribute(AttributeName, pUid);
            }
            catch
            {
                return null;
            }
            ESRI.ArcGIS.Schematic.ISchematicAttributeManagement schAttributeMngt=(ESRI.ArcGIS.Schematic.ISchematicAttributeManagement)schAttribute;
            try
            {
                // the StorageMode must be set before the EvaluationMode 
                // consistenty is checked when the EvaluationMode is set 
                schAttributeMngt.StorageMode=StorageMode;
                schAttributeMngt.EvaluationMode=EvalMode;
            }
            catch { } // an error is returned if the StorageMode and EvaluationMode are not consistent

            return schAttribute;
        }

        /// <summary>
        /// Create an attribute on a schematic feature class
        /// </summary>
        /// <param name="schElementClass">The ISchematicElementClass where the attribute must be created</param>
        /// <param name="AttributeName">The name of the new attribute</param>
        /// <param name="AttribType">The type of attribute</param>
        /// <param name="EvalMode">The evaluation mode for the attribute</param>
        /// <param name="StorageMode">The storage mode for the attribute</param>
        /// <returns>The created ESRI.ArcGIS.Schematic.ISchematicAttribute</returns>
        /// <remarks></remarks>
        private ESRI.ArcGIS.Schematic.ISchematicAttribute CreateAttribute(ESRI.ArcGIS.Schematic.ISchematicElementClass schElementClass, string AttributeName, EnumAtttributeType AttribType, ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode EvalMode, ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode StorageMode)
        {
            ESRI.ArcGIS.Schematic.ISchematicAttribute schAttribute=null;
            try
            {
                ESRI.ArcGIS.esriSystem.UID pUid=new ESRI.ArcGIS.esriSystem.UID();
                pUid.Value=GetAttributeType(AttribType);
                schAttribute=schElementClass.CreateSchematicAttribute(AttributeName, pUid);
            }
            catch
            {
                return null;
            }
            ESRI.ArcGIS.Schematic.ISchematicAttributeManagement schAttributeMngt=(ESRI.ArcGIS.Schematic.ISchematicAttributeManagement)schAttribute;
            try
            {
                // the StorageMode must be set before the EvaluationMode 
                // consistenty is checked when the EvaluationMode is set 
                schAttributeMngt.StorageMode=StorageMode;
                schAttributeMngt.EvaluationMode=EvalMode;
            }
            catch { } // an error is returned if the StorageMode and EvaluationMode are not consistent

            return schAttribute;
        }

        /// <summary>
        /// Add a constant schematic attribute on a schematic feature class
        /// </summary>
        /// <param name="schElementClass">The schematic feature class where the constant attribute must be created</param>
        /// <param name="AttributeName">The name of the constant schematic attribute</param>
        /// <param name="value">The constant value for the created schematic attribute</param>
        /// <remarks></remarks>
        private void AddAttributeConst(ESRI.ArcGIS.Schematic.ISchematicElementClass schElementClass, string AttributeName, string value)
        {
            ESRI.ArcGIS.Schematic.ISchematicAttributeConstant schAttConst=CreateAttribute(schElementClass, AttributeName, EnumAtttributeType.AttributeConstant, ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode.esriSchematicAttributeOnTheFlyEvaluation, ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode.esriSchematicAttributeNoStorage) as ESRI.ArcGIS.Schematic.ISchematicAttributeConstant;

            if (schAttConst != null) schAttConst.ConstantValue=value;
        }

        /// <summary>
        /// Add a field schematic attribute on a schematic feature class
        /// </summary>
        /// <param name="schElementClass">The schematic feature class where the field attribute must be created</param>
        /// <param name="AttributeName">The name of the constant schematic attribute</param>
        /// <param name="FieldNames">The FieldNames for the created schematic attribute()</param>
        /// <remarks></remarks>
        private void AddAttributeField(ESRI.ArcGIS.Schematic.ISchematicElementClass schElementClass, string AttributeName, string[] FieldNames)
        {
            ESRI.ArcGIS.Schematic.ISchematicAttributeField schAttField=CreateAttribute(schElementClass, AttributeName, EnumAtttributeType.AttributeField, ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode.esriSchematicAttributeBuildEvaluation, ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage) as ESRI.ArcGIS.Schematic.ISchematicAttributeField;

            if (schAttField != null) schAttField.FieldNames=FieldNames;
        }

        /// <summary>
        /// Add a formatted schematic attribute on a schematic feature class
        /// </summary>
        /// <param name="schElementClass">The schematic feature class where the formatted attribute must be created</param>
        /// <param name="AttributeName">The name of the formatted schematic attribute</param>
        /// <param name="sFormat">The Format for the created schematic attribute</param>
        /// <param name="ParameterNames">The ParameterNames for the created schematic attribute()</param>
        /// <remarks></remarks>
        private void AddAttributeFormat(ESRI.ArcGIS.Schematic.ISchematicElementClass schElementClass, string AttributeName, string sFormat, string[] ParameterNames)
        {
            ESRI.ArcGIS.Schematic.ISchematicAttributeFormatted schAttField=CreateAttribute(schElementClass, AttributeName, EnumAtttributeType.AttributeFormatted, ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode.esriSchematicAttributeBuildEvaluation, ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode.esriSchematicAttributeNoStorage) as ESRI.ArcGIS.Schematic.ISchematicAttributeFormatted;

            if (schAttField != null)
            {
                schAttField.Format=sFormat;
                schAttField.ParameterNames=ParameterNames;
            }
        }
        #endregion

        #region Others
        /// <summary>
        /// Building the Shape field for container schematic features
        /// </summary>
        /// <param name="geometryType">The type of geometry the Shape must manage</param>
        /// <param name="pWorkspace">The impacted IWorkspace</param>
        /// <returns>The created ESRI.ArcGIS.Geodatabase.IField Shape field</returns>
        /// <remarks></remarks>
        private static ESRI.ArcGIS.Geodatabase.IField BuildShapeField(ESRI.ArcGIS.Geometry.esriGeometryType geometryType, ESRI.ArcGIS.Geodatabase.IWorkspace pWorkspace)
        {
            ESRI.ArcGIS.Geodatabase.IField ipShapeField=null;

            try
            {
                ESRI.ArcGIS.Geometry.ISpatialReference ipSpatialReference=new ESRI.ArcGIS.Geometry.UnknownCoordinateSystem() as ESRI.ArcGIS.Geometry.ISpatialReference;

                if (ipSpatialReference == null)
                    return null;

                ESRI.ArcGIS.Geometry.ISpatialReferenceResolution ipSpatialReferenceResolution=ipSpatialReference as ESRI.ArcGIS.Geometry.ISpatialReferenceResolution;

                if (ipSpatialReferenceResolution != null)
                {
                    // initializing the resolution (and so the domain) if needed
                    double xyRes=ipSpatialReferenceResolution.get_XYResolution(false);

                    if (System.Double.IsNaN(xyRes)) ipSpatialReferenceResolution.SetDefaultXYResolution();
                }

                ESRI.ArcGIS.Geometry.ISpatialReferenceTolerance ipSpatialReferenceTolerance=ipSpatialReference as ESRI.ArcGIS.Geometry.ISpatialReferenceTolerance;

                // initializing the tolerance if needed
                if (ipSpatialReferenceTolerance != null && ipSpatialReferenceTolerance.XYToleranceValid != ESRI.ArcGIS.Geometry.esriSRToleranceEnum.esriSRToleranceOK) ipSpatialReferenceTolerance.SetDefaultXYTolerance();


                ESRI.ArcGIS.Geometry.ISpatialReference ipAdjustedSpatialReference=ConstructSpatialReference(pWorkspace, ipSpatialReference);

                if (ipAdjustedSpatialReference == null) ipAdjustedSpatialReference=ipSpatialReference;


                ipShapeField=new ESRI.ArcGIS.Geodatabase.Field();

                ESRI.ArcGIS.Geodatabase.IGeometryDefEdit ipGeometryDefEdit=new ESRI.ArcGIS.Geodatabase.GeometryDef() as ESRI.ArcGIS.Geodatabase.IGeometryDefEdit;

                if (ipShapeField == null || ipGeometryDefEdit == null) return null;

                ipGeometryDefEdit.SpatialReference_2=ipAdjustedSpatialReference;
                ipGeometryDefEdit.GeometryType_2=geometryType;
                ipGeometryDefEdit.HasZ_2=false;

                if (geometryType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline)
                {
                    ipGeometryDefEdit.HasM_2=true;

                    if (ipSpatialReferenceResolution != null)
                    {
                        // initializing the resolution (and so the domain) if needed
                        double interval=ipSpatialReferenceResolution.MResolution;
                        if (System.Double.IsNaN(interval)) ipSpatialReferenceResolution.SetDefaultMResolution();
                    }

                    // initializing the tolerance if needed
                    if (ipSpatialReferenceTolerance != null && ipSpatialReferenceTolerance.MToleranceValid != ESRI.ArcGIS.Geometry.esriSRToleranceEnum.esriSRToleranceOK) ipSpatialReferenceTolerance.SetMinimumMTolerance();
                }
                else
                    ipGeometryDefEdit.HasM_2=false;

                ESRI.ArcGIS.Geodatabase.IFieldEdit ipShapeFieldEdit=ipShapeField as ESRI.ArcGIS.Geodatabase.IFieldEdit;
                ipShapeFieldEdit.IsNullable_2=true;
                ipShapeFieldEdit.Name_2="SHAPE";
                ipShapeFieldEdit.Type_2=ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeGeometry;
                ipShapeFieldEdit.GeometryDef_2=ipGeometryDefEdit as ESRI.ArcGIS.Geodatabase.IGeometryDef;

            } // try

            catch (Exception ex)
            {
                ipShapeField=null;

                // don't use any verbose option if throwing error
                throw new SystemException(ex.Message, ex.InnerException);
            }

            return ipShapeField;
        }

        /// <summary>
        /// SpatialReference construction for the Shape field
        /// </summary>
        /// <param name="pWorkspace">ESRI.ArcGIS.Geodatabase.IWorkspace</param>
        /// <param name="pSpatialref">ESRI.ArcGIS.Geometry.ISpatialReference</param>
        /// <returns>ESRI.ArcGIS.Geometry.ISpatialReference</returns>
        /// <remarks></remarks>
        private static ESRI.ArcGIS.Geometry.ISpatialReference ConstructSpatialReference(ESRI.ArcGIS.Geodatabase.IWorkspace pWorkspace, ESRI.ArcGIS.Geometry.ISpatialReference pSpatialref)
        {
            if (pWorkspace == null || pSpatialref == null) return null;

            ESRI.ArcGIS.Geometry.ISpatialReference ipOutputSR=null;

            ESRI.ArcGIS.Geodatabase.IWorkspaceProperty ipWSProperty=((ESRI.ArcGIS.Geodatabase.IWorkspaceProperties)pWorkspace).get_Property(ESRI.ArcGIS.Geodatabase.esriWorkspacePropertyGroupType.esriWorkspacePropertyGroup, (int)ESRI.ArcGIS.Geodatabase.esriWorkspacePropertyType.esriWorkspacePropSupportsHighPrecisionStorage);

            bool highPrecisionDB=(bool)ipWSProperty.PropertyValue;
            bool highPrecisionSR=((ESRI.ArcGIS.Geometry.IControlPrecision2)(pSpatialref)).IsHighPrecision;

            if (highPrecisionSR && !highPrecisionDB)
            {
                // Need to create a low precision spatial reference

                double Xmin=0;
                double Ymin=0;
                double Xmax=0;
                double Ymax=0;
                pSpatialref.GetDomain(out Xmin, out Xmax, out Ymin, out Ymax);

                ESRI.ArcGIS.Geometry.IEnvelope ipEnv=new ESRI.ArcGIS.Geometry.Envelope() as ESRI.ArcGIS.Geometry.IEnvelope;
                ipEnv.PutCoords(Xmin, Ymin, Xmax, Ymax);

                ESRI.ArcGIS.Geometry.ISpatialReferenceFactory3 ipSpatialReferenceFactory=new ESRI.ArcGIS.Geometry.SpatialReferenceEnvironment() as ESRI.ArcGIS.Geometry.ISpatialReferenceFactory3;

                try
                {
                    ipOutputSR=ipSpatialReferenceFactory.ConstructLowPrecisionSpatialReference(true, pSpatialref, ipEnv);
                }
                catch { }    // Ignore errors

                if (ipOutputSR == null) ipOutputSR=ipSpatialReferenceFactory.ConstructLowPrecisionSpatialReference(false, pSpatialref, ipEnv);
            }

            if (!highPrecisionSR && highPrecisionDB)
            {
                // Create an equivalent high precision spatial reference

                ESRI.ArcGIS.Geometry.ISpatialReferenceTolerance ipSRTolerance=(ESRI.ArcGIS.Geometry.ISpatialReferenceTolerance)pSpatialref;

                ipSRTolerance.SetMinimumXYTolerance();
                ipSRTolerance.SetMinimumZTolerance();
                ipSRTolerance.SetMinimumMTolerance();

                ESRI.ArcGIS.Geometry.ISpatialReferenceFactory3 ipSpatialReferenceFactory=new ESRI.ArcGIS.Geometry.SpatialReferenceEnvironment() as ESRI.ArcGIS.Geometry.ISpatialReferenceFactory3;

                ipOutputSR=ipSpatialReferenceFactory.ConstructHighPrecisionSpatialReference(pSpatialref, -1, -1, -1);

                if (ipOutputSR == null) ipOutputSR=ipSpatialReferenceFactory.ConstructHighPrecisionSpatialReference(pSpatialref, -1, -1, -1);
            }

            return ipOutputSR;
        }
        #endregion


    }
[Visual Basic .NET]
Public Class QueryDiagramClass
    'This class behaves as a template to create a schematic diagram template based on the standard builder for which the diagrams are entirely built from custom queries.
    'It uses 3 object tables: Document, Nodes and Links which names can be changed according to your needs in the constant TABLE_NAME.
    'The structure of the 3 tables is predefined and the queries used to generate the diagrams based on the diagram template built by this code are linked to the tables' structure.

    'The Document table lists all the diagrams which can be generated from this template.
    'The Document table fields are:
    'OBJECTID          AutoNumber      Primary Key    
    'DOCID             Long            Unique Index
    'DOCNAME           Text(255)       Diagram name

    'The Nodes table gives the list of the nodes expected to be contained in the different diagrams.
    'The Nodes table fields are:
    'OBJECTID          AutoNumber      Primary Key    
    'DOCID             Long            Related DOCID value - Linked to the Document Table DOCID field
    'ObjectType        Text(50)        Type of object node (Container, Junction, NodeOnLink)
    'XGeo              Double          X Postion of the node - Only used for a Junction node
    'YGeo              Double          Y Postion of the node - Only used for a Junction node
    'ParentLink        Long            OBJECTID of the reference link - Only used for a NodeOnLink node
    'PositionOnLink    Double          Relative position on the reference link (ParentLink) - Only used for a NodeOnLink node
    'RelatedFCName     Text(50)        Type of the related container - Only used for a child node which is related to a Container node
    'RelatedFOID       Long            OBJECTID of the related container - Only used for a child node which is related to a Container node
    'Rotation          Double          Rotation of the node - Not used for a Container node

    'The Links table gives the list of the links expected to be contained in the different diagrams.
    'The Links table fields are:
    'OBJECTID          AutoNumber      Primary Key    
    'DOCID             Long            Related DOCID value - Linked to the Document Table DOCID field
    'ObjectType        Text(50)        Type of object link (Link, SubLink)
    'FromOID           Long            OBJECTID Of the origin node
    'ToOID             Long            OBJECTID of extremity node
    'FromPort          Short           Number of the origin port
    'ToPort            Short           Number of the extremity port
    'ListPoint         Memo            List of vertices along le link (Syntax: NumberOfPoint;X1;Y1;X2;Y2...)
    'ParentLink        Long            OBJECTID of the reference link - Only used for a SubLink link
    'RelatedFCName     Text(50)        Type of the related container - Only used for a child link which is related to a Container node
    'RelatedFOID       Long            OBJECTID of the related container - Only used for a child link which is related to a Container node

    Private Const DATASET_NAME As String="MyQueryDatasetVB"
    Private Const DIAGRAM_TEMPLATE_NAME As String="MyDiagramClass"
    Private Const DOCUMENT_TABLE_NAME As String="Document"
    Private Const NODE_TABLE_NAME As String="Nodes"
    Private Const LINK_TABLE_NAME As String="Links"
    Private Const NODEONLINK_TABLE_NAME As String="Nodes"
    Private Const SUBLINK_TABLE_NAME As String="Links"
    Private Const CONTAINER_TABLE_NAME As String="Nodes"

    ''' <summary>
    ''' Type of attributes used in this class
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum EnumAtttributeType
        AttributeConstant
        AttributeField
        AttributeFormatted
    End Enum

    ''' <summary>
    ''' This sample shows how to create a schematic diagram template entirely configured with custom queries by code from scratch based on the object tables described above
    ''' </summary>
    ''' <param name="esriWorkspace">The ESRI.ArcGIS.Geodatabase.IWorkspace where the diagram template is going to be created</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicDataset</returns>
    ''' <remarks>The esriWorkspace must be opened</remarks>
    Public Function CreateQuerySchematicDataset(ByVal esriWorkspace As ESRI.ArcGIS.Geodatabase.IWorkspace) As ESRI.ArcGIS.Schematic.ISchematicDataset

        ' if the input IWorkspace is null, exit
        If (esriWorkspace Is Nothing) Then Return Nothing

        Dim schWorkspace As ESRI.ArcGIS.Schematic.ISchematicWorkspace=Nothing
        Dim schDiagClass As ESRI.ArcGIS.Schematic.ISchematicDiagramClass
        Dim schData As ESRI.ArcGIS.Schematic.ISchematicDataset=Nothing

        ' -- STEP#1 -- Opening the ISchematicWorkspace related to the input IWorkspace
        Dim objectType As Type=Type.GetTypeFromProgID("esriSchematic.SchematicWorkspaceFactory")

        Dim schWorkspaceFct As ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory
        schWorkspaceFct=TryCast(Activator.CreateInstance(objectType), ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory)

        schWorkspace=schWorkspaceFct.Open(esriWorkspace)

        ' -- STEP#2 -- Creating the new ISchematicDataset
        ' verify that the ISchematicDataset to create doesn't already exist in the input IWorkspace
        schData=schWorkspace.SchematicDatasetByName(DATASET_NAME)
        ' if it already exists, exit
        If (schData IsNot Nothing) Then Return schData

        ' create the new ISchematicDataset in the input IWorkspace
        Try
            schData=schWorkspace.CreateSchematicDataset(DATASET_NAME, "")
            schData.DesignMode=True
        Catch
            ' if the ISchematicDataset cannot be created, the process stops
            Return Nothing
        End Try

        ' -- STEP#3 -- Creating the ISchematicStandardBuilder that will be assigned afterwards to the schematic diagram template
        objectType=Type.GetTypeFromProgID("esriSchematic.SchematicStandardBuilder")
        Dim pSchStandardBuilder As ESRI.ArcGIS.Schematic.ISchematicStandardBuilder
        If (objectType Is Nothing) Then Return Nothing

        pSchStandardBuilder=TryCast(Activator.CreateInstance(objectType), ESRI.ArcGIS.Schematic.ISchematicStandardBuilder)
        ' if the ISchematicStandardBuilder is Nothing, exit
        If (pSchStandardBuilder Is Nothing) Then Return Nothing

        pSchStandardBuilder.AddConnectedNodes=True
        pSchStandardBuilder.InitializeLinksVertices=True
        Dim pSchBuilder As ESRI.ArcGIS.Schematic.ISchematicBuilder=TryCast(pSchStandardBuilder, ESRI.ArcGIS.Schematic.ISchematicBuilder)

        ' -- STEP#4 -- Creating the ISchematicDiagramClass
        schDiagClass=CreateDiagramClass(schData, DIAGRAM_TEMPLATE_NAME, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, schData.DefaultSchematicDataSource, "SELECT * FROM " + DOCUMENT_TABLE_NAME, New String() {"DOCNAME"})
        schDiagClass.SchematicBuilder=pSchBuilder

        ' -- STEP#5 -- Creating the attributes for the diagram class 
        Dim schAttribField As ESRI.ArcGIS.Schematic.ISchematicAttributeField

        schAttribField=TryCast(CreateAttribute(schDiagClass, "DOCID", EnumAtttributeType.AttributeField, ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode.esriSchematicAttributeBuildEvaluation, ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage), ESRI.ArcGIS.Schematic.ISchematicAttributeField)
        schAttribField.FieldNames=New String() {"DOCID"} ' This Attribute is used for link with Element

        Dim enumQueryParameters As ESRI.ArcGIS.Schematic.EnumSchematicQueryParameterClass=New ESRI.ArcGIS.Schematic.EnumSchematicQueryParameterClass()
        Dim schQueryParameter As ESRI.ArcGIS.Schematic.ISchematicQueryParameter=New ESRI.ArcGIS.Schematic.SchematicQueryParameter()

        ' -- STEP#6 -- Configuring the query for the diagram class
        schQueryParameter.Name="DOCID"
        schQueryParameter.Textual=False
        enumQueryParameters.Add(schQueryParameter)
        schQueryParameter=Nothing

        Dim schEltClass As ESRI.ArcGIS.Schematic.ISchematicElementClass

        ' -- STEP#7 -- Creating the schematic feature classes
        ' creating the SchematicLinks schematic feature class
        CreateLinks(schData, schDiagClass, "SchematicLinks", LINK_TABLE_NAME, "Links", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline, True)

        ' creating the SchematicSubLinks schematic feature class
        CreateSubLinks(schData, schDiagClass, "SchematicSubLinks", SUBLINK_TABLE_NAME, "SubLinks", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline, True)

        ' creating the SchematicNodeOnLinks schematic feature class
        CreateNodeOnLink(schData, schDiagClass, "SchematicNodeOnLinks", NODEONLINK_TABLE_NAME, "SubNodes", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint, True)

        ' creating the SchematicNodes schematic feature class
        schEltClass=CreateNode(schData, schDiagClass, "SchematicNodes", NODE_TABLE_NAME, "Nodes", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint, False)

        ' creating the SchematicJunctions schematic feature class that inherits from the Nodes schematic feature class
        CreateChildNode(schData, schDiagClass, schEltClass, "SchematicJunctions", NODE_TABLE_NAME, "Junctions", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint, True)

        ' creating the Containers schematic feature class
        Dim schContClass As ESRI.ArcGIS.Schematic.ISchematicElementClass=CreateChildNode(schData, schDiagClass, schEltClass, "Containers", NODE_TABLE_NAME, "Container 1", enumQueryParameters, ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon, True)
        AddAttributeConst(schContClass, "ContainerMargin", "0.5")

        ' -- STEP#8 -- Saving the schematic dataset and exit the design mode
        schData.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersionCurrent, False)
        schData.DesignMode=False

        Return schData
    End Function

    ''' <summary>
    ''' Return the classID for the type of attributes used in this sample
    ''' </summary>
    ''' <param name="Value">EnumAtttributeType</param>
    ''' <returns>string</returns>
    ''' <remarks></remarks>
    Private Function GetAttributeType(ByVal Value As EnumAtttributeType) As String
        Select Case Value
            Case EnumAtttributeType.AttributeConstant
                Return "{3AD9D8B8-0A1D-4F32-ABB5-54B848A46F85}"
            Case EnumAtttributeType.AttributeField
                Return "{E1902BB0-6070-4EE2-995A-DB86FAC5EEB0}"
            Case EnumAtttributeType.AttributeFormatted
                Return "{1DE95A2A-B750-446A-8D3A-3C67660E8B59}"
            Case Else
                Return ""
        End Select
    End Function

#Region "Create Elements"
    ''' <summary>
    ''' Create the schematic diagram template
    ''' </summary>
    ''' <param name="schDataset">The ISchematicDataset where the schematic diagram template must be created</param>
    ''' <param name="DiagramClassName">The name of the schematic diagram template to create</param>
    ''' <param name="QueryMode">The evaluation mode for the query that must be configured on the diagram template</param>
    ''' <param name="schDataSource">The ISchematicDataSource related to the query</param>
    ''' <param name="QueryString">The query string</param>
    ''' <param name="FieldNames">The field names used to build each diagram identifier</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicDiagramClass</returns>
    ''' <remarks></remarks>
    Private Function CreateDiagramClass(ByVal schDataset As ESRI.ArcGIS.Schematic.ISchematicDataset, ByVal DiagramClassName As String, ByVal QueryMode As ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode, ByVal schDataSource As ESRI.ArcGIS.Schematic.ISchematicDataSource, ByVal QueryString As String, ByVal FieldNames As Object) As ESRI.ArcGIS.Schematic.ISchematicDiagramClass
        Dim schDiagClass As ESRI.ArcGIS.Schematic.ISchematicDiagramClass=Nothing
        Try
            schDiagClass=schDataset.CreateSchematicDiagramClass(DiagramClassName)
        Catch
            Return Nothing
        End Try

        schDiagClass.SchematicDataSource=schDataSource
        schDiagClass.ExternalQueryEvaluationMode=QueryMode

        schDiagClass.QueryString=QueryString
        schDiagClass.IdentifierFieldNames=FieldNames

        Return schDiagClass
    End Function

    ''' <summary>
    '''  Create a schematic feature class - basic creation
    ''' </summary>
    ''' <param name="schDataset">The ISchematicDataset where the schematic feature class must be created</param>
    ''' <param name="schDiagClass">The ISchematicDiagramClass the new schematic feature class must be associated with</param>
    ''' <param name="ElementName">The name of the schematic feature class to create</param>
    ''' <param name="ClassType">The type of schematic element managed by this schematic feature class</param>
    ''' <param name="schDataSource">The ISchematicDataSource related to the query that must return the schematic features based on this class</param>
    ''' <param name="QueryString">The query string</param>
    ''' <param name="FieldNames">The field names used to build each schematic feature identifier</param>
    ''' <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
    ''' <param name="Geometry">The type of geometry for the schematic features based on this class</param>
    ''' <param name="QueryEvaluation">The evaluation mode for the query</param>
    ''' <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass</returns>
    ''' <remarks></remarks>
    Private Function CreateElementClass(ByVal schDataset As ESRI.ArcGIS.Schematic.ISchematicDataset, ByVal schDiagClass As ESRI.ArcGIS.Schematic.ISchematicDiagramClass, ByVal ElementName As String, ByVal ClassType As ESRI.ArcGIS.Schematic.esriSchematicElementType, ByVal schDataSource As ESRI.ArcGIS.Schematic.ISchematicDataSource, ByVal QueryString As String, ByVal FieldNames As Object, ByVal QueryParameters As ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter, ByVal Geometry As ESRI.ArcGIS.Geometry.esriGeometryType, ByVal QueryEvaluation As ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode, ByVal WithAssociation As Boolean) As ESRI.ArcGIS.Schematic.ISchematicElementClass

        ' schematic feature class creation
        Dim schElement As ESRI.ArcGIS.Schematic.ISchematicElementClass=Nothing
        Try
            schElement=schDataset.CreateSchematicElementClass(ElementName, ClassType)
        Catch
            Return Nothing
        End Try

        schElement.ShapeField=BuildShapeField(Geometry, schDataset.SchematicWorkspace.Workspace)

        schElement.GeometryType=Geometry
        schElement.SchematicDataSource=schDataSource
        schElement.ExternalQueryEvaluationMode=QueryEvaluation
        schElement.QueryString=QueryString
        schElement.IdentifierFieldNames=FieldNames
        schElement.SchematicQueryParameters=QueryParameters

        ' if WithAssociation is True, the schematic feature class is associated with the specified input diagram class
        If (WithAssociation) Then schDiagClass.AssociateSchematicElementClass(schElement)
        Return schElement
    End Function

    ''' <summary>
    ''' Create a schematic feature class which inherits from another schematic feature class
    ''' </summary>
    ''' <param name="ParentClass">The parent ISchematicElementClass</param>
    ''' <param name="schDataset">The ISchematicDataset where the schematic feature class must be created</param>
    ''' <param name="schDiagClass">The ISchematicDiagramClass the new schematic feature class must be associated with</param>
    ''' <param name="ElementName">The name of the schematic feature class to create</param>
    ''' <param name="ClassType">The type of schematic element managed by this schematic feature class</param>
    ''' <param name="schDataSource">The ISchematicDataSource related to the query that must return the schematic features based on this class</param>
    ''' <param name="QueryString">The query string</param>
    ''' <param name="FieldNames">The field names used to build each schematic feature identifier</param>
    ''' <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
    ''' <param name="Geometry">The type of geometry for the schematic features based on this class</param>
    ''' <param name="QueryEvaluation">The evaluation mode for the query</param>
    ''' <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass</returns>
    ''' <remarks></remarks>
    Private Function CreateSubElementClass(ByVal ParentClass As ESRI.ArcGIS.Schematic.ISchematicElementClass, ByVal schDataset As ESRI.ArcGIS.Schematic.ISchematicDataset, ByVal schDiagClass As ESRI.ArcGIS.Schematic.ISchematicDiagramClass, ByVal ElementName As String, ByVal ClassType As ESRI.ArcGIS.Schematic.esriSchematicElementType, ByVal schDataSource As ESRI.ArcGIS.Schematic.ISchematicDataSource, ByVal QueryString As String, ByVal FieldNames As Object, ByVal QueryParameters As ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter, ByVal Geometry As ESRI.ArcGIS.Geometry.esriGeometryType, ByVal QueryEvaluation As ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode, ByVal WithAssociation As Boolean) As ESRI.ArcGIS.Schematic.ISchematicElementClass

        Dim schElement As ESRI.ArcGIS.Schematic.ISchematicElementClass=Nothing
        Try
            ' schematic feature class creation
            schElement=CreateElementClass(schDataset, schDiagClass, ElementName, ClassType, schDataSource, QueryString, FieldNames, QueryParameters, Geometry, QueryEvaluation, WithAssociation)

            ' specifying the parent schematic feature class for the new schematic feature class
            schElement.Parent=ParentClass
        Catch
            Return Nothing
        End Try
        Return schElement
    End Function

    ''' <summary>
    ''' Create a node schematic feature class
    ''' </summary>
    ''' <param name="schDataset">The ISchematicDataset where the node schematic feature class must be created</param>
    ''' <param name="schDiagClass">The ISchematicDiagramClass the new node schematic feature class must be associated with</param>
    ''' <param name="ElementName">The name of the node schematic feature class to create</param>
    ''' <param name="TableName">The name of the table where the records related to the node schematic features must be queried</param>
    ''' <param name="FilterElementInTable">The filter that must be used to filter out the records</param>
    ''' <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
    ''' <param name="TypeGeometry">The type of geometry for the schematic features based on this class</param>
    ''' <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass node schematic feature class</returns>
    ''' <remarks></remarks>
    Private Function CreateNode(ByVal schDataset As ESRI.ArcGIS.Schematic.ISchematicDataset, ByVal schDiagClass As ESRI.ArcGIS.Schematic.ISchematicDiagramClass, ByVal ElementName As String, ByVal TableName As String, ByVal FilterElementInTable As String, ByVal QueryParameters As ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter, ByVal TypeGeometry As ESRI.ArcGIS.Geometry.esriGeometryType, ByVal WithAssociation As Boolean) As ESRI.ArcGIS.Schematic.ISchematicElementClass

        Dim schEltClass As ESRI.ArcGIS.Schematic.ISchematicElementClass
        ' node schematic feature class creation
        schEltClass=CreateElementClass(schDataset, schDiagClass, ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicNodeType, schDataset.DefaultSchematicDataSource, "SELECT * FROM " + TableName + " WHERE DOCID=?", New String() {"DOCID", "IDOBJECT", "Node"}, QueryParameters, TypeGeometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, WithAssociation)

        ' creation of the set of attributes expected for node schematic features
        AddAttributeField(schEltClass, "DOCID", New String() {"DOCID"})
        AddAttributeField(schEltClass, "ObjectId", New String() {"IDOBJECT"})
        AddAttributeFormat(schEltClass, "Name", "%s-%s-Node", New String() {"DOCID", "ObjectId"})
        AddAttributeField(schEltClass, "InitialXPosition", New String() {"XGeo"})
        AddAttributeField(schEltClass, "InitialYPosition", New String() {"YGeo"})
        AddAttributeField(schEltClass, "ParentId", New String() {"RelatedFOID"})
        AddAttributeField(schEltClass, "InitialRotation", New String() {"Rotation"})

        ' creation of the attributes used to manage container if the nodes based on this schematic feature class have relations with container schematic features
        AddAttributeField(schEltClass, "PTN", New String() {"RelatedFCName"})
        AddAttributeFormat(schEltClass, "PEN", "%s-%s-Node", New String() {"DOCID", "ParentId"})

        Return schEltClass
    End Function

    ''' <summary>
    ''' Create a node schematic feature class which inherits from another node schematic feature class
    ''' </summary>
    ''' <param name="schDataset">The ISchematicDataset where the node schematic feature class must be created</param>
    ''' <param name="schDiagClass">The ISchematicDiagramClass the new node schematic feature class must be associated with</param>
    ''' <param name="schParentClass">The parent ISchematicElementClass</param>
    ''' <param name="ElementName">The name of the node schematic feature class to create</param>
    ''' <param name="TableName">The name of the table where the records related to the node schematic features must be queried</param>
    ''' <param name="FilterElementInTable">The filter that must be used to filter out the records</param>
    ''' <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
    ''' <param name="TypeGeometry">The type of geometry for the schematic features based on this class</param>
    ''' <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass node schematic feature class</returns>
    ''' <remarks></remarks>
    Private Function CreateChildNode(ByVal schDataset As ESRI.ArcGIS.Schematic.ISchematicDataset, ByVal schDiagClass As ESRI.ArcGIS.Schematic.ISchematicDiagramClass, ByVal schParentClass As ESRI.ArcGIS.Schematic.ISchematicElementClass, ByVal ElementName As String, ByVal TableName As String, ByVal FilterElementInTable As String, ByVal QueryParameters As ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter, ByVal TypeGeometry As ESRI.ArcGIS.Geometry.esriGeometryType, ByVal WithAssociation As Boolean) As ESRI.ArcGIS.Schematic.ISchematicElementClass

        ' schematic feature class creation with a parent node schematic feature class
        Dim schEltClass As ESRI.ArcGIS.Schematic.ISchematicElementClass
        schEltClass=CreateSubElementClass(schParentClass, schDataset, schDiagClass, ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicNodeType, schDataset.DefaultSchematicDataSource, "SELECT * FROM " + TableName + " WHERE OBJECTTYPE='" + FilterElementInTable + "' AND DOCID=?", New String() {"DOCID", "IDOBJECT", "Node"}, QueryParameters, TypeGeometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, WithAssociation)

        Return schEltClass
    End Function

    ''' <summary>
    ''' Create a link schematic feature class
    ''' </summary>
    ''' <param name="schDataset">The ISchematicDataset where the link schematic feature class must be created</param>
    ''' <param name="schDiagClass">The ISchematicDiagramClass the new link schematic feature class must be associated with</param>
    ''' <param name="ElementName">The name of the link schematic feature class to create</param>
    ''' <param name="TableName">The name of the table where the records related to the link schematic features must be queried</param>
    ''' <param name="FilterElementInTable">The filter that must be used to filter out the records</param>
    ''' <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
    ''' <param name="TypeGeometry">The type of geometry for the schematic features based on this class</param>
    ''' <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass link schematic feature class</returns>
    ''' <remarks></remarks>
    Private Function CreateLinks(ByVal schDataset As ESRI.ArcGIS.Schematic.ISchematicDataset, ByVal schDiagClass As ESRI.ArcGIS.Schematic.ISchematicDiagramClass, ByVal ElementName As String, ByVal TableName As String, ByVal FilterElementInTable As String, ByVal QueryParameters As ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter, ByVal TypeGeometry As ESRI.ArcGIS.Geometry.esriGeometryType, ByVal WithAssociation As Boolean) As ESRI.ArcGIS.Schematic.ISchematicElementClass

        ' link schematic feature class creation
        Dim schEltClass As ESRI.ArcGIS.Schematic.ISchematicElementClass
        schEltClass=CreateElementClass(schDataset, schDiagClass, ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicLinkType, schDataset.DefaultSchematicDataSource, "SELECT * FROM " + TableName + " WHERE OBJECTTYPE='" + FilterElementInTable + "' AND DOCID=?", New String() {"DOCID", "IDOBJECT", "Link"}, QueryParameters, TypeGeometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, WithAssociation)

        ' creation of the set of attributes expected for link schematic features
        AddAttributeField(schEltClass, "ExtremityNode", New String() {"DOCID", "ToOID", "Node"})
        AddAttributeField(schEltClass, "OriginNode", New String() {"DOCID", "FromOID", "Node"})
        AddAttributeField(schEltClass, "InitialListPoints", New String() {"ListPoints"})
        AddAttributeField(schEltClass, "DOCID", New String() {"DOCID"})
        AddAttributeField(schEltClass, "ObjectId", New String() {"IDOBJECT"})
        AddAttributeFormat(schEltClass, "Name", "%s-%s-Link", New String() {"DOCID", "ObjectId"})

        Return schEltClass
    End Function

    ''' <summary>
    ''' Create a sublink schematic feature class
    ''' </summary>
    ''' <param name="schDataset">The ISchematicDataset where the sublink schematic feature class must be created</param>
    ''' <param name="schDiagClass">The ISchematicDiagramClass the new sublink schematic feature class must be associated with</param>
    ''' <param name="ElementName">The name of the sublink schematic feature class to create</param>
    ''' <param name="TableName">The name of the table where the records related to the sublink schematic features must be queried</param>
    ''' <param name="FilterElementInTable">The filter that must be used to filter out the records</param>
    ''' <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
    ''' <param name="TypeGeometry">The type of geometry for the schematic features based on this class</param>
    ''' <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass sublink schematic feature class</returns>
    ''' <remarks></remarks>
    Private Function CreateSubLinks(ByVal schDataset As ESRI.ArcGIS.Schematic.ISchematicDataset, ByVal schDiagClass As ESRI.ArcGIS.Schematic.ISchematicDiagramClass, ByVal ElementName As String, ByVal TableName As String, ByVal FilterElementInTable As String, ByVal QueryParameters As ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter, ByVal TypeGeometry As ESRI.ArcGIS.Geometry.esriGeometryType, ByVal WithAssociation As Boolean) As ESRI.ArcGIS.Schematic.ISchematicElementClass

        ' sublink schematic feature class creation
        Dim schEltClass As ESRI.ArcGIS.Schematic.ISchematicElementClass
        schEltClass=CreateElementClass(schDataset, schDiagClass, ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicSubLinkType, schDataset.DefaultSchematicDataSource, "SELECT * FROM " + TableName + " WHERE OBJECTTYPE='" + FilterElementInTable + "' AND DOCID=?", New String() {"DOCID", "IDOBJECT", "SubLink"}, QueryParameters, TypeGeometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, WithAssociation)

        ' creation of the set of attributes expected for sublink schematic features
        AddAttributeField(schEltClass, "ExtremityNode", New String() {"DOCID", "ToOID", "Node"})
        AddAttributeField(schEltClass, "OriginNode", New String() {"DOCID", "FromOID", "Node"})
        AddAttributeField(schEltClass, "ReferenceLink", New String() {"DOCID", "ParentLink", "Link"})
        AddAttributeField(schEltClass, "DOCID", New String() {"DOCID"})
        AddAttributeField(schEltClass, "ObjectId", New String() {"IDOBJECT"})
        AddAttributeFormat(schEltClass, "Name", "%s-%s-SubLink", New String() {"DOCID", "ObjectId"})

        Return schEltClass
    End Function

    ''' <summary>
    ''' Create a node-on-link schematic feature class 
    ''' </summary>
    ''' <param name="schDataset">The ISchematicDataset where the node-on-link schematic feature class must be created</param>
    ''' <param name="schDiagClass">The ISchematicDiagramClass the new node-on-link schematic feature class must be associated with</param>
    ''' <param name="ElementName">The name of the node-on-link schematic feature class to create</param>
    ''' <param name="TableName">The name of the table where the records related to the node-on-link schematic features must be queried</param>
    ''' <param name="FilterElementInTable">The filter that must be used to filter out the records</param>
    ''' <param name="QueryParameters">ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter</param>
    ''' <param name="TypeGeometry">The type of geometry for the schematic features based on this class</param>
    ''' <param name="WithAssociation">If True, the schematic feature class is associated with the specified input diagram class</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicElementClass node-on-link schematic feature class</returns>
    ''' <remarks></remarks>
    Private Function CreateNodeOnLink(ByVal schDataset As ESRI.ArcGIS.Schematic.ISchematicDataset, ByVal schDiagClass As ESRI.ArcGIS.Schematic.ISchematicDiagramClass, ByVal ElementName As String, ByVal TableName As String, ByVal FilterElementInTable As String, ByVal QueryParameters As ESRI.ArcGIS.Schematic.IEnumSchematicQueryParameter, ByVal TypeGeometry As ESRI.ArcGIS.Geometry.esriGeometryType, ByVal WithAssociation As Boolean) As ESRI.ArcGIS.Schematic.ISchematicElementClass

        ' node-on-link schematic feature class creation
        Dim schEltClass As ESRI.ArcGIS.Schematic.ISchematicElementClass
        schEltClass=CreateElementClass(schDataset, schDiagClass, ElementName, ESRI.ArcGIS.Schematic.esriSchematicElementType.esriSchematicNodeOnLinkType, schDataset.DefaultSchematicDataSource, "SELECT * FROM " + TableName + " WHERE OBJECTTYPE='" + FilterElementInTable + "' AND DOCID=?", New String() {"DOCID", "IDOBJECT", "Node"}, QueryParameters, TypeGeometry, ESRI.ArcGIS.Schematic.esriSchematicExternalQueryEvaluationMode.esriSchematicQueryBuildEvaluation, WithAssociation)

        ' creation of the set of attributes expected for node-on-link schematic features
        AddAttributeField(schEltClass, "DOCID", New String() {"DOCID"})
        AddAttributeField(schEltClass, "InitialRotation", New String() {"Rotation"})
        AddAttributeField(schEltClass, "ObjectId", New String() {"IDOBJECT"})
        AddAttributeField(schEltClass, "RelativePosition", New String() {"PositionOnLink"})
        AddAttributeField(schEltClass, "ReferenceLink", New String() {"DOCID", "ParentLink", "Link"})
        AddAttributeFormat(schEltClass, "Name", "%s-%s-Node", New String() {"DOCID", "ObjectId"})

        Return schEltClass
    End Function

#End Region

#Region "Attributes"
    ''' <summary>
    ''' Create an attribute on a schematic diagram class
    ''' </summary>
    ''' <param name="schDiagClass">The ISchematicDiagramClass where the attribute must be created</param>
    ''' <param name="AttributeName">The name of the new attribute</param>
    ''' <param name="AttribType">The type of attribute</param>
    ''' <param name="EvalMode">The evaluation mode for the attribute</param>
    ''' <param name="StorageMode">The storage mode for the attribute</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicAttribute</returns>
    ''' <remarks></remarks>
    Private Function CreateAttribute(ByVal schDiagClass As ESRI.ArcGIS.Schematic.ISchematicDiagramClass, ByVal AttributeName As String, ByVal AttribType As EnumAtttributeType, ByVal EvalMode As ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode, ByVal StorageMode As ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode) As ESRI.ArcGIS.Schematic.ISchematicAttribute

        Dim schAttribute As ESRI.ArcGIS.Schematic.ISchematicAttribute=Nothing
        Try
            Dim pUid As ESRI.ArcGIS.esriSystem.UID=New ESRI.ArcGIS.esriSystem.UID()
            pUid.Value=GetAttributeType(AttribType)
            schAttribute=schDiagClass.CreateSchematicAttribute(AttributeName, pUid)
        Catch
            Return Nothing
        End Try
        Dim schAttributeMngt As ESRI.ArcGIS.Schematic.ISchematicAttributeManagement=TryCast(schAttribute, ESRI.ArcGIS.Schematic.ISchematicAttributeManagement)
        Try
            ' the StorageMode must be set before the EvaluationMode 
            ' consistenty is checked when the EvaluationMode is set 
            schAttributeMngt.StorageMode=StorageMode
            schAttributeMngt.EvaluationMode=EvalMode
        Catch
            ' an error is returned if the StorageMode and EvaluationMode are not consistent
        End Try

        Return schAttribute
    End Function

    ''' <summary>
    ''' Create an attribute on a schematic feature class
    ''' </summary>
    ''' <param name="schElementClass">The ISchematicElementClass where the attribute must be created</param>
    ''' <param name="AttributeName">The name of the new attribute</param>
    ''' <param name="AttribType">The type of attribute</param>
    ''' <param name="EvalMode">The evaluation mode for the attribute</param>
    ''' <param name="StorageMode">The storage mode for the attribute</param>
    ''' <returns>The created ESRI.ArcGIS.Schematic.ISchematicAttribute</returns>
    ''' <remarks></remarks>
    Private Function CreateAttribute(ByVal schElementClass As ESRI.ArcGIS.Schematic.ISchematicElementClass, ByVal AttributeName As String, ByVal AttribType As EnumAtttributeType, ByVal EvalMode As ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode, ByVal StorageMode As ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode) As ESRI.ArcGIS.Schematic.ISchematicAttribute

        Dim schAttribute As ESRI.ArcGIS.Schematic.ISchematicAttribute=Nothing
        Try
            Dim pUid As ESRI.ArcGIS.esriSystem.UID=New ESRI.ArcGIS.esriSystem.UID()
            pUid.Value=GetAttributeType(AttribType)
            schAttribute=schElementClass.CreateSchematicAttribute(AttributeName, pUid)
        Catch
            Return Nothing
        End Try
        Dim schAttributeMngt As ESRI.ArcGIS.Schematic.ISchematicAttributeManagement=TryCast(schAttribute, ESRI.ArcGIS.Schematic.ISchematicAttributeManagement)
        Try
            ' the StorageMode must be set before the EvaluationMode 
            ' consistenty is checked when the EvaluationMode is set 
            schAttributeMngt.StorageMode=StorageMode
            schAttributeMngt.EvaluationMode=EvalMode
        Catch
            ' an error is returned if the StorageMode and EvaluationMode are not consistent
        End Try

        Return schAttribute
    End Function

    ''' <summary>
    ''' Add a constant schematic attribute on a schematic feature class
    ''' </summary>
    ''' <param name="schElementClass">The schematic feature class where the constant attribute must be created</param>
    ''' <param name="AttributeName">The name of the constant schematic attribute</param>
    ''' <param name="value">The constant value for the created schematic attribute</param>
    ''' <remarks></remarks>
    Private Sub AddAttributeConst(ByVal schElementClass As ESRI.ArcGIS.Schematic.ISchematicElementClass, ByVal AttributeName As String, ByVal value As String)

        Dim schAttConst As ESRI.ArcGIS.Schematic.ISchematicAttributeConstant
        schAttConst=TryCast(CreateAttribute(schElementClass, AttributeName, EnumAtttributeType.AttributeConstant, ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode.esriSchematicAttributeOnTheFlyEvaluation, ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode.esriSchematicAttributeNoStorage), ESRI.ArcGIS.Schematic.ISchematicAttributeConstant)

        If (schAttConst IsNot Nothing) Then schAttConst.ConstantValue=value
    End Sub

    ''' <summary>
    ''' Add a field schematic attribute on a schematic feature class
    ''' </summary>
    ''' <param name="schElementClass">The schematic feature class where the field attribute must be created</param>
    ''' <param name="AttributeName">The name of the constant schematic attribute</param>
    ''' <param name="FieldNames">The FieldNames for the created schematic attribute()</param>
    ''' <remarks></remarks>
    Private Sub AddAttributeField(ByVal schElementClass As ESRI.ArcGIS.Schematic.ISchematicElementClass, ByVal AttributeName As String, ByVal FieldNames As String())

        Dim schAttField As ESRI.ArcGIS.Schematic.ISchematicAttributeField
        schAttField=TryCast(CreateAttribute(schElementClass, AttributeName, EnumAtttributeType.AttributeField, ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode.esriSchematicAttributeBuildEvaluation, ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode.esriSchematicAttributeNoStorage), ESRI.ArcGIS.Schematic.ISchematicAttributeField)

        If (schAttField IsNot Nothing) Then schAttField.FieldNames=FieldNames
    End Sub

    ''' <summary>
    ''' Add a formatted schematic attribute on a schematic feature class
    ''' </summary>
    ''' <param name="schElementClass">The schematic feature class where the formatted attribute must be created</param>
    ''' <param name="AttributeName">The name of the formatted schematic attribute</param>
    ''' <param name="sFormat">The Format for the created schematic attribute</param>
    ''' <param name="ParameterNames">The ParameterNames for the created schematic attribute()</param>
    ''' <remarks></remarks>
    Private Sub AddAttributeFormat(ByVal schElementClass As ESRI.ArcGIS.Schematic.ISchematicElementClass, ByVal AttributeName As String, ByVal sFormat As String, ByVal ParameterNames As String())

        Dim schAttField As ESRI.ArcGIS.Schematic.ISchematicAttributeFormatted
        schAttField=TryCast(CreateAttribute(schElementClass, AttributeName, EnumAtttributeType.AttributeFormatted, ESRI.ArcGIS.Schematic.esriSchematicAttributeEvaluationMode.esriSchematicAttributeBuildEvaluation, ESRI.ArcGIS.Schematic.esriSchematicAttributeStorageMode.esriSchematicAttributeNoStorage), ESRI.ArcGIS.Schematic.ISchematicAttributeFormatted)

        If (schAttField IsNot Nothing) Then
            schAttField.Format=sFormat
            schAttField.ParameterNames=ParameterNames
        End If
    End Sub
#End Region

#Region "Others"
    ''' <summary>
    ''' Building the Shape field for container schematic features
    ''' </summary>
    ''' <param name="geometryType">The type of geometry the Shape must manage</param>
    ''' <param name="pWorkspace">The impacted IWorkspace</param>
    ''' <returns>The created ESRI.ArcGIS.Geodatabase.IField Shape field</returns>
    ''' <remarks></remarks>
    Private Function BuildShapeField(ByVal geometryType As ESRI.ArcGIS.Geometry.esriGeometryType, ByVal pWorkspace As ESRI.ArcGIS.Geodatabase.IWorkspace) As ESRI.ArcGIS.Geodatabase.IField

        Dim ipShapeField As ESRI.ArcGIS.Geodatabase.IField=Nothing

        Try
            Dim ipSpatialReference As ESRI.ArcGIS.Geometry.ISpatialReference=TryCast(New ESRI.ArcGIS.Geometry.UnknownCoordinateSystem(), ESRI.ArcGIS.Geometry.ISpatialReference)

            If (ipSpatialReference Is Nothing) Then Return Nothing

            Dim ipSpatialReferenceResolution As ESRI.ArcGIS.Geometry.ISpatialReferenceResolution=TryCast(ipSpatialReference, ESRI.ArcGIS.Geometry.ISpatialReferenceResolution)

            If (ipSpatialReferenceResolution IsNot Nothing) Then

                ' initializing the resolution (and so the domain) if needed
                Dim xyRes As Double=ipSpatialReferenceResolution.XYResolution(False)

                If (System.Double.IsNaN(xyRes)) Then ipSpatialReferenceResolution.SetDefaultXYResolution()
            End If

            Dim ipSpatialReferenceTolerance As ESRI.ArcGIS.Geometry.ISpatialReferenceTolerance=TryCast(ipSpatialReference, ESRI.ArcGIS.Geometry.ISpatialReferenceTolerance)

            ' initializing the tolerance if needed
            If (ipSpatialReferenceTolerance IsNot Nothing AndAlso ipSpatialReferenceTolerance.XYToleranceValid <> ESRI.ArcGIS.Geometry.esriSRToleranceEnum.esriSRToleranceOK) Then ipSpatialReferenceTolerance.SetDefaultXYTolerance()

            Dim ipAdjustedSpatialReference As ESRI.ArcGIS.Geometry.ISpatialReference=ConstructSpatialReference(pWorkspace, ipSpatialReference)

            If (ipAdjustedSpatialReference Is Nothing) Then ipAdjustedSpatialReference=ipSpatialReference

            ipShapeField=New ESRI.ArcGIS.Geodatabase.Field()

            Dim ipGeometryDefEdit As ESRI.ArcGIS.Geodatabase.IGeometryDefEdit=TryCast(New ESRI.ArcGIS.Geodatabase.GeometryDef(), ESRI.ArcGIS.Geodatabase.IGeometryDefEdit)

            If (ipShapeField Is Nothing OrElse ipGeometryDefEdit Is Nothing) Then Return Nothing

            ipGeometryDefEdit.SpatialReference_2=ipAdjustedSpatialReference
            ipGeometryDefEdit.GeometryType_2=geometryType
            ipGeometryDefEdit.HasZ_2=False

            If (geometryType=ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline) Then
                ipGeometryDefEdit.HasM_2=True

                If (ipSpatialReferenceResolution IsNot Nothing) Then

                    ' initializing the resolution (and so domain) if needed
                    Dim interval As Double=ipSpatialReferenceResolution.MResolution
                    If (System.Double.IsNaN(interval)) Then ipSpatialReferenceResolution.SetDefaultMResolution()
                End If

                ' initializing the tolerance if needed
                If (ipSpatialReferenceTolerance IsNot Nothing AndAlso ipSpatialReferenceTolerance.MToleranceValid <> ESRI.ArcGIS.Geometry.esriSRToleranceEnum.esriSRToleranceOK) Then
                    ipSpatialReferenceTolerance.SetMinimumMTolerance()
                End If
            Else
                ipGeometryDefEdit.HasM_2=False
            End If

            Dim ipShapeFieldEdit As ESRI.ArcGIS.Geodatabase.IFieldEdit=TryCast(ipShapeField, ESRI.ArcGIS.Geodatabase.IFieldEdit)
            ipShapeFieldEdit.IsNullable_2=True
            ipShapeFieldEdit.Name_2="SHAPE"
            ipShapeFieldEdit.Type_2=ESRI.ArcGIS.Geodatabase.esriFieldType.esriFieldTypeGeometry
            ipShapeFieldEdit.GeometryDef_2=TryCast(ipGeometryDefEdit, ESRI.ArcGIS.Geodatabase.IGeometryDef)


        Catch ex As Exception
            ipShapeField=Nothing

            ' don't use any verbose option if throwing error
            Throw New SystemException(ex.Message, ex.InnerException)
        End Try

        Return ipShapeField
    End Function

    ''' <summary>
    ''' SpatialReference construction for the Shape field
    ''' </summary>
    ''' <param name="pWorkspace">ESRI.ArcGIS.Geodatabase.IWorkspace</param>
    ''' <param name="pSpatialref">ESRI.ArcGIS.Geometry.ISpatialReference</param>
    ''' <returns>ESRI.ArcGIS.Geometry.ISpatialReference</returns>
    ''' <remarks></remarks>
    Private Function ConstructSpatialReference(ByVal pWorkspace As ESRI.ArcGIS.Geodatabase.IWorkspace, ByVal pSpatialref As ESRI.ArcGIS.Geometry.ISpatialReference) As ESRI.ArcGIS.Geometry.ISpatialReference

        If (pWorkspace Is Nothing OrElse pSpatialref Is Nothing) Then Return Nothing

        Dim ipOutputSR As ESRI.ArcGIS.Geometry.ISpatialReference=Nothing

        Dim ipWSProperty As ESRI.ArcGIS.Geodatabase.IWorkspaceProperty=TryCast(pWorkspace, ESRI.ArcGIS.Geodatabase.IWorkspaceProperties).Property(ESRI.ArcGIS.Geodatabase.esriWorkspacePropertyGroupType.esriWorkspacePropertyGroup, CInt(ESRI.ArcGIS.Geodatabase.esriWorkspacePropertyType.esriWorkspacePropSupportsHighPrecisionStorage))

        Dim highPrecisionDB As Boolean=CBool(ipWSProperty.PropertyValue)
        Dim highPrecisionSR As Boolean=(TryCast(pSpatialref, ESRI.ArcGIS.Geometry.IControlPrecision2)).IsHighPrecision

        If (highPrecisionSR AndAlso Not highPrecisionDB) Then
            ' Need to create a low precision spatial reference

            Dim Xmin As Double=0
            Dim Ymin As Double=0
            Dim Xmax As Double=0
            Dim Ymax As Double=0
            pSpatialref.GetDomain(Xmin, Xmax, Ymin, Ymax)

            Dim ipEnv As ESRI.ArcGIS.Geometry.IEnvelope=TryCast(New ESRI.ArcGIS.Geometry.Envelope(), ESRI.ArcGIS.Geometry.IEnvelope)
            ipEnv.PutCoords(Xmin, Ymin, Xmax, Ymax)

            Dim ipSpatialReferenceFactory As ESRI.ArcGIS.Geometry.ISpatialReferenceFactory3=TryCast(New ESRI.ArcGIS.Geometry.SpatialReferenceEnvironment(), ESRI.ArcGIS.Geometry.ISpatialReferenceFactory3)

            Try
                ipOutputSR=ipSpatialReferenceFactory.ConstructLowPrecisionSpatialReference(True, pSpatialref, ipEnv)

            Catch    ' Ignore(errors)
            End Try

            If (ipOutputSR Is Nothing) Then ipOutputSR=ipSpatialReferenceFactory.ConstructLowPrecisionSpatialReference(False, pSpatialref, ipEnv)
        End If

        If (Not highPrecisionSR AndAlso highPrecisionDB) Then
            ' Create an equivalent high precision spatial reference

            Dim ipSRTolerance As ESRI.ArcGIS.Geometry.ISpatialReferenceTolerance=TryCast(pSpatialref, ESRI.ArcGIS.Geometry.ISpatialReferenceTolerance)

            ipSRTolerance.SetMinimumXYTolerance()
            ipSRTolerance.SetMinimumZTolerance()
            ipSRTolerance.SetMinimumMTolerance()

            Dim ipSpatialReferenceFactory As ESRI.ArcGIS.Geometry.ISpatialReferenceFactory3=TryCast(New ESRI.ArcGIS.Geometry.SpatialReferenceEnvironment(), ESRI.ArcGIS.Geometry.ISpatialReferenceFactory3)

            ipOutputSR=ipSpatialReferenceFactory.ConstructHighPrecisionSpatialReference(pSpatialref, -1, -1, -1)

            If (ipOutputSR Is Nothing) Then ipOutputSR=ipSpatialReferenceFactory.ConstructHighPrecisionSpatialReference(pSpatialref, -1, -1, -1)
        End If

        Return ipOutputSR
    End Function

#End Region
End Class

Additional Requirements
  • The code in this document requires the following References added to the Visual Studio project:
  • ESRI.ArcGIS.Geodatabase
  • ESRI.ArcGIS.Geometry
  • ESRI.ArcGIS.Schematic
  • System