2

I am trying to use the dimensions in ArcMap but after I dimension a map then close and reopen the map the dimensions are gone and I get a COM error, cannot initialize COM component when I try to edit the properties of the dimension feature class in ArcCatalog. Is there a way to save the dimensions so they do not disappear?
enter image description here

I created a button to recreate the dim style with arcobjects, now I don't get COM initialize error but when I close and reopen arcmap, instead of dimension there are red polygons.

enter image description here

enter image description here

Here is the code I use to create the dimension feature class,

                IFeatureLayer pFeatureLayer = (IFeatureLayer)pBoundaryLayer;
                IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
                string strCatalogPath = GetCatalogPath(pFeatureClass);
                IWorkspace pWorkspace = FileGDBWorkspaceFromPropertySet(strCatalogPath);
                IObjectClassDescription ocDescription = new DimensionClassDescription();
                IFields pRequiredFields = ocDescription.RequiredFields;
                int intShapeFieldPosition = pRequiredFields.FindField("Shape");
                IField pShapeField = pRequiredFields.get_Field(intShapeFieldPosition);
                IGeometryDef pGeomDef = pShapeField.GeometryDef;
                IGeometryDefEdit pGeomDefEdit = (IGeometryDefEdit)pGeomDef;
                ISpatialReferenceFactory3 pSpatRefFac = new SpatialReferenceEnvironmentClass();
                ISpatialReference pSpatRef = pSpatRefFac.CreateSpatialReference(6578);
                IProjectedCoordinateSystem pProSpatRef = (IProjectedCoordinateSystem)pSpatRef;
                ILinearUnit linUnit = pProSpatRef.CoordinateUnit;
                pGeomDefEdit.SpatialReference_2 = pSpatRef;
                IFeatureWorkspace pFeatWorkspace = (IFeatureWorkspace)pWorkspace;
                string pName = "DIM";
                IFeatureClass pNewFeatureClass = pFeatWorkspace.CreateFeatureClass(pName.ToString(), pRequiredFields, ocDescription.InstanceCLSID, ocDescription.ClassExtensionCLSID, esriFeatureType.esriFTDimension, "Shape", "");
                ISchemaLock schemaLock = (ISchemaLock)pNewFeatureClass;
                try
                {
                    schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);

                    IDimensionClassExtension dimExtension = (IDimensionClassExtension)pNewFeatureClass.Extension;

                    dimExtension.ReferenceScale = 12000;

                    dimExtension.ReferenceScaleUnits = esriUnits.esriFeet;

                    IDimensionStyle dimensionStyle = new DimensionStyleClass();
                    dimensionStyle.Name = "BEARING_DISTANCE";
                    IDimensionStyleText dimText = (IDimensionStyleText)dimensionStyle;
                    string expression =  "def FindLabel ( [DIMLENGTH], [BEGINX] , [BEGINY] , [ENDX] , [ENDY]  ):" + Environment.NewLine +
                                         "  import math" + Environment.NewLine +
                                         "  dY = float([ENDY]) -float( [BEGINY])" + Environment.NewLine +
                                         "  dX = float( [ENDX])-float( [BEGINX])" + Environment.NewLine +
                                         "  azimuth = math.atan2(dX, dY) * 180 / math.pi" + Environment.NewLine +
                                         "  if azimuth < 0:" + Environment.NewLine +
                                         "    azimuth = azimuth + 360" + Environment.NewLine +
                                         "    if azimuth > 270 and azimuth<= 360:" + Environment.NewLine +
                                         "      bearing = 360 - azimuth" + Environment.NewLine +
                                         "      minutes,seconds = divmod(bearing * 3600, 60)" + Environment.NewLine +
                                         "      degrees,minutes = divmod(minutes, 60)" + Environment.NewLine +
                                         "      dmsBearing = \"N \" + str(int(degrees)) + \"°\" + str(int(minutes)) + \"'\" + str(round(seconds, 2)) + \" W\"" + Environment.NewLine +
                                         "      return dmsBearing + \" \" + str(round(float( [DIMLENGTH]), 2))+\"'\"" + Environment.NewLine +
                                         "    if azimuth > 180 and azimuth<= 270:" + Environment.NewLine +
                                         "      bearing = azimuth - 180" + Environment.NewLine +
                                         "      minutes,seconds = divmod(bearing * 3600, 60)"+ Environment.NewLine +
                                         "      degrees,minutes = divmod(minutes, 60)"+ Environment.NewLine +
                                         "      dmsBearing = \"S \" + str(int(degrees)) + \"°\" + str(int(minutes)) + \"'\" + str(round(seconds, 2)) + \" W\"" + Environment.NewLine +
                                         "      return dmsBearing + \" \" + str(round(float( [DIMLENGTH]), 2))+\"'\"" + Environment.NewLine +
                                         "    if azimuth > 90 and azimuth<= 180:" + Environment.NewLine +
                                         "      bearing = 180 - azimuth" + Environment.NewLine +
                                         "      minutes,seconds = divmod(bearing * 3600, 60)" + Environment.NewLine +
                                         "      degrees,minutes = divmod(minutes, 60)" + Environment.NewLine +
                                         "      dmsBearing = \"S \" + str(int(degrees)) + \"°\" + str(int(minutes)) + \"'\" + str(round(seconds, 2)) + \" E\"" + Environment.NewLine +
                                         "      return dmsBearing + \" \" + str(round(float( [DIMLENGTH]), 2))+\"'\"" + Environment.NewLine +
                                         "    if azimuth >= 0 and azimuth<= 90:" + Environment.NewLine +
                                         "      minutes,seconds = divmod(azimuth * 3600, 60)" + Environment.NewLine +
                                         "      degrees,minutes = divmod(minutes, 60)" + Environment.NewLine +
                                         "      dmsBearing = \"N \" + str(int(degrees)) + \"°\" + str(int(minutes)) + \"'\" + str(round(seconds, 2)) + \" E\"" + Environment.NewLine +
                                         "      return dmsBearing + \" \" + str(round(float( [DIMLENGTH]), 2))+\"'\"" + Environment.NewLine +
                                         "  else:" + Environment.NewLine +
                                         "    if azimuth > 270 and azimuth<= 360:" + Environment.NewLine +
                                         "      bearing = 360 - azimuth" + Environment.NewLine +
                                         "      minutes,seconds = divmod(bearing * 3600, 60)" + Environment.NewLine +
                                         "      degrees,minutes = divmod(minutes, 60)" + Environment.NewLine +
                                         "      dmsBearing = \"N \" + str(int(degrees)) + \"°\" + str(int(minutes)) + \"'\" + str(round(seconds, 2)) + \" W\"" + Environment.NewLine +
                                         "      return dmsBearing + \" \" + str(round(float( [DIMLENGTH]), 2))+\"'\"" + Environment.NewLine +
                                         "    if azimuth > 180 and azimuth<= 270:" + Environment.NewLine +
                                         "      bearing = azimuth - 180" + Environment.NewLine +
                                         "      minutes,seconds = divmod(bearing * 3600, 60)" + Environment.NewLine +
                                         "      degrees,minutes = divmod(minutes, 60)" + Environment.NewLine +
                                         "      dmsBearing = \"S \" + str(int(degrees)) + \"°\" + str(int(minutes)) + \"'\" + str(round(seconds, 2)) + \" W\"" + Environment.NewLine +
                                         "      return dmsBearing + \" \" + str(round(float( [DIMLENGTH]), 2))+\"'\"" + Environment.NewLine +
                                         "    if azimuth > 90 and azimuth<= 180:" + Environment.NewLine +
                                         "      bearing = 180 - azimuth" + Environment.NewLine +
                                         "      minutes,seconds = divmod(bearing * 3600, 60)" + Environment.NewLine +
                                         "      degrees,minutes = divmod(minutes, 60)" + Environment.NewLine +
                                         "      dmsBearing = \"S \" + str(int(degrees)) + \"°\" + str(int(minutes)) + \"'\" + str(round(seconds, 2)) + \" E\"" + Environment.NewLine +
                                         "      return dmsBearing + \" \" + str(round(float( [DIMLENGTH]), 2))+\"'\"" + Environment.NewLine +
                                         "    if azimuth >= 0 and azimuth<= 90:" + Environment.NewLine +
                                         "      minutes,seconds = divmod(azimuth * 3600, 60)" + Environment.NewLine +
                                         "      degrees,minutes = divmod(minutes, 60)" + Environment.NewLine +
                                         "      dmsBearing = \"N \" + str(int(degrees)) + \"°\" + str(int(minutes)) + \"'\" + str(round(seconds, 2)) + \" E\"" + Environment.NewLine +
                                         "      return dmsBearing + \" \" + str(round(float( [DIMLENGTH]), 2))+\"'\"";

                    dimText.Expression = expression;
                    dimText.ExpressionSimple = false;
                    dimText.ExpressionParserName = "Python";
                    dimText.TextDisplay = esriDimensionTextDisplay.esriDimensionTDExpression;
                    dimText.ExtendLineOnFit = false;

                    stdole.IFontDisp iFont = new stdole.StdFontClass() as stdole.IFontDisp;
                    iFont.Name = "Arial";
                    iFont.Size = 8;
                    ITextSymbol txtSymbol = new TextSymbol();
                    txtSymbol.Font = iFont;
                    dimText.TextSymbol = txtSymbol;
                    IDimensionStyleDisplay dimDisplay = (IDimensionStyleDisplay)dimensionStyle;

                    dimDisplay.MarkerDisplay = esriDimensionDisplay.esriDimensionDisplayBoth;

                    IArrowMarkerSymbol mrkrSym = new ArrowMarkerSymbolClass();
                    mrkrSym.Size = 6;

                    IMarkerSymbol newMrkrSym = (IMarkerSymbol)mrkrSym;

                    dimDisplay.BeginMarkerSymbol = newMrkrSym;
                    dimDisplay.EndMarkerSymbol = newMrkrSym;

                    dimDisplay.MarkerFit = esriDimensionMarkerFit.esriDimensionMarkerFitText;
                    IDimensionStyles dimensionStyles = dimExtension.DimensionStyles;
                    dimensionStyles.AddStyle(dimensionStyle);



                }
                catch(COMException comExcept)
                {
                    MessageBox.Show(comExcept.StackTrace.ToString());
                }
                finally
                {

                    schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);

                }

Update: I am still trying to persist the dimensions in arcmap I am now using the PersistenceHelper I am having some success persisting the shape but the text expression and line style are not persisting, to persist the DimensionStyleText and DimensionStyleDisplay do I add them to the struct and how do I do that since they are interfaces?

namespace CreateDimensions
{
    public class PersistExtension: ESRI.ArcGIS.Desktop.AddIns.Extension
    {

        private DimStyleStruct dimStyleClass;
        [Serializable()]
        public struct DimStyleStruct
        {
            public DimensionStyleClass dimStyle;

        }


        public PersistExtension()
        {

        }

        protected override void OnSave(Stream outStrm)
        {
            dimStyleClass = new DimStyleStruct();
            dimStyleClass.dimStyle = PersistDimClass.DimStyleClass;
            PersistenceHelper.Save<DimStyleStruct>(outStrm, dimStyleClass);
        }

        protected override void OnLoad(Stream inStrm)
        {
            dimStyleClass.dimStyle = new DimensionStyleClass();
            PersistenceHelper.Load<DimStyleStruct>(inStrm, ref dimStyleClass);
        }



    }
}

I have made a little more progress and I have rewritten my add-in as arcobjects extension, I use the load and save methods to write to the document stream and I am getting the style I want back in the map but the only thing missing is the custom expression to display bearing and distance.

    public void Save(IVariantStream Stream)
    {
        //TODO: Save extension related data to document stream
        if (DimStyleModel.Name != "")
        {
            Stream.Write(DimStyleModel.Name.ToString());
            MessageBox.Show(DimStyleModel.Name.ToString());
            Stream.Write(DimStyleModel.RefScale);
            Stream.Write(DimStyleModel.Expression);
            Stream.Write(DimStyleModel.TextSymbol);
            Stream.Write(DimStyleModel.LineSymbol);
            Stream.Write(DimStyleModel.MrkrSymbol);
        }
        Marshal.ReleaseComObject(Stream);
    }


    public void Load(IVariantStream Stream)
    {
        //TODO: Load persisted data from document stream
        if(Stream!=null)
        {
            string sName = "";
            int iRefScale = 0;
            string sExpression = "";
            ITextSymbol pTextSymbol = null;
            ILineSymbol pLineSymbol = null;
            IMarkerSymbol pMrkrSymbol = null;

            sName = (string)Stream.Read();
            iRefScale = (int)Stream.Read();
            sExpression = (string)Stream.Read();
            pTextSymbol = (ITextSymbol)Stream.Read();
            pLineSymbol = (ILineSymbol)Stream.Read();
            pMrkrSymbol = (IMarkerSymbol)Stream.Read();

            ILayer pLayer = ReturnLayerByName("DIM");
            IFeatureLayer pFeatureLayer = (IFeatureLayer)pLayer;
            IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
            ISchemaLock pSchemaLock = (ISchemaLock)pFeatureClass;
            try
            {
                pSchemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
                IDimensionClassExtension pDimExt = (IDimensionClassExtension)pFeatureClass.Extension;
                pDimExt.ReferenceScale = iRefScale;
                pDimExt.ReferenceScaleUnits = esriUnits.esriFeet;
                IDimensionStyle pDimStyle = new DimensionStyleClass
                {
                    Name = sName
                };
                IDimensionStyleDisplay pNewDimDisplay = (IDimensionStyleDisplay)pDimStyle;
                pNewDimDisplay.MarkerDisplay = esriDimensionDisplay.esriDimensionDisplayBoth;
                pNewDimDisplay.DimensionLineSymbol = pLineSymbol;
                pNewDimDisplay.BeginMarkerSymbol = pMrkrSymbol;
                pNewDimDisplay.EndMarkerSymbol = pMrkrSymbol;
                pNewDimDisplay.MarkerFit = esriDimensionMarkerFit.esriDimensionMarkerFitText;
                pNewDimDisplay.MarkerDisplay = esriDimensionDisplay.esriDimensionDisplayBoth;
                pNewDimDisplay.DrawLineOnFit = false;
                IDimensionStyleText pNewDimText = (IDimensionStyleText)pDimStyle;
                pNewDimText.Expression = sExpression;
                pNewDimText.ExpressionParserName = "Python";
                pNewDimText.TextDisplay = esriDimensionTextDisplay.esriDimensionTDExpression;
                pNewDimText.TextSymbol = pTextSymbol;

                pDimExt.UpdateProperties();

                IDimensionStyles pDimStyles = pDimExt.DimensionStyles;
                pDimStyles.AddStyle(pDimStyle);
            }
            catch (COMException comExcept)
            {
                MessageBox.Show(comExcept.StackTrace.ToString());
            }
            finally
            {
                pSchemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
            }


        }
        Marshal.ReleaseComObject(Stream);



    }

Next step I am going to tyr and add the expression in the load method,

0

1 Answer 1

0
+50

What's happening is that you're updating the class extension but you're missing the call to update what's persisted in the feature class. So, after you've updated the DimensionStyles, call UpdateProperties on IDimensionClassExtension

4
  • I think I found another problem I am getting this error after I save and reopen a map w dimensions in it here is the error: at ESRI.Carto.IDimensionStyles.AddStyle() as DimToolbar.ApplicationExtension1.Load() in ...\DimToolbar ApplicationExtension1.cs: line 254 when Load() adds the style to the DIMextension Jun 23, 2019 at 10:44
  • You're getting the persistence load error? Jun 26, 2019 at 16:25
  • Yes I am. I am going to go through and persist each object individually to see what exactly is having trouble loading. I am trying to persist a dimension with a text expression. Jun 26, 2019 at 16:54
  • I found the issue I had for got pNewDimText.ExpressionSimple = false; Jun 30, 2019 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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