/// <summary>
 /// Returns the parameter value of point.
 /// </summary>
 /// <param name="pt">The Point 2d whose get the PolylineSegment parameter at.</param>
 /// <returns>A double between 0.0 and 1.0, or -1.0 if the point does not lie on the segment.</returns>
 public double GetParameterOf(Point2d pt)
 {
     if (IsLinear)
     {
         LineSegment2d line = ToLineSegment();
         return(line.IsOn(pt) ? _startPoint.GetDistanceTo(pt) / line.Length : -1.0);
     }
     else
     {
         CircularArc2d arc = ToCircularArc();
         return(arc.IsOn(pt) ?
                arc.GetLength(arc.GetParameterOf(_startPoint), arc.GetParameterOf(pt)) /
                arc.GetLength(arc.GetParameterOf(_startPoint), arc.GetParameterOf(_endPoint)) :
                -1.0);
     }
 }
        public void exportshapefilesmethod(
            string exportDir,
            string shapeBaseName,
            string polylineSuffix,
            string blockSuffix,
            Database database = null)
        {
            DocumentCollection docCol  = Application.DocumentManager;
            Database           localDb = database ?? docCol.MdiActiveDocument.Database;
            Document           doc     = docCol.MdiActiveDocument;

            using (Transaction tx = localDb.TransactionManager.StartTransaction())
            {
                try
                {
                    Log.log($"Exporting to {exportDir}.");

                    #region Exporting (p)lines
                    HashSet <Polyline> pls = localDb.HashSetOfType <Polyline>(tx);

                    pls = pls.Where(pl => (pl.Layer.Contains("FJV-TWIN") ||
                                           pl.Layer.Contains("FJV-FREM") ||
                                           pl.Layer.Contains("FJV-RETUR")))
                          .Where(pl => GetPipeDN(pl) != 999)
                          .ToHashSet();

                    Log.log($"{pls.Count} polyline(s) found for export.");

                    #region Field def
                    DbfFieldDesc[] dbfFields = new DbfFieldDesc[3];

                    dbfFields[0].FieldName   = "DN";
                    dbfFields[0].FieldType   = DbfFieldType.Character;
                    dbfFields[0].FieldLength = 10;

                    dbfFields[1].FieldName   = "System";
                    dbfFields[1].FieldType   = DbfFieldType.Character;
                    dbfFields[1].FieldLength = 100;

                    dbfFields[2].FieldName   = "Serie";
                    dbfFields[2].FieldType   = DbfFieldType.Character;
                    dbfFields[2].FieldLength = 100;
                    #endregion

                    using (ShapeFileWriter writer = ShapeFileWriter.CreateWriter(
                               exportDir, shapeBaseName + polylineSuffix,
                               ShapeType.PolyLine, dbfFields,
                               EGIS.Projections.CoordinateReferenceSystemFactory.Default.GetCRSById(25832)
                               .GetWKT(EGIS.Projections.PJ_WKT_TYPE.PJ_WKT1_GDAL, false)))
                    {
                        foreach (Polyline pline in pls)
                        {
                            List <Point2d> points    = new List <Point2d>();
                            int            numOfVert = pline.NumberOfVertices - 1;
                            if (pline.Closed)
                            {
                                numOfVert++;
                            }
                            for (int i = 0; i < numOfVert; i++)
                            {
                                switch (pline.GetSegmentType(i))
                                {
                                case SegmentType.Line:
                                    LineSegment2d ls = pline.GetLineSegment2dAt(i);
                                    if (i == 0)
                                    {    //First iteration
                                        points.Add(ls.StartPoint);
                                    }
                                    points.Add(ls.EndPoint);
                                    break;

                                case SegmentType.Arc:
                                    CircularArc2d arc         = pline.GetArcSegment2dAt(i);
                                    double        sPar        = arc.GetParameterOf(arc.StartPoint);
                                    double        ePar        = arc.GetParameterOf(arc.EndPoint);
                                    double        length      = arc.GetLength(sPar, ePar);
                                    double        radians     = length / arc.Radius;
                                    int           nrOfSamples = (int)(radians / 0.04);
                                    if (nrOfSamples < 3)
                                    {
                                        if (i == 0)
                                        {
                                            points.Add(arc.StartPoint);
                                        }
                                        points.Add(arc.EndPoint);
                                    }
                                    else
                                    {
                                        Point2d[] samples = arc.GetSamplePoints(nrOfSamples);
                                        if (i != 0)
                                        {
                                            samples = samples.Skip(1).ToArray();
                                        }
                                        foreach (Point2d p2d in samples)
                                        {
                                            points.Add(p2d);
                                        }
                                    }
                                    break;

                                case SegmentType.Coincident:
                                case SegmentType.Point:
                                case SegmentType.Empty:
                                default:
                                    continue;
                                }
                            }

                            PointD[] shapePoints = points.Select(p => new PointD(p.X, p.Y)).ToArray();

                            string[] attributes = new string[3];
                            attributes[0] = GetPipeDN(pline).ToString();
                            attributes[1] = GetPipeType(pline).ToString();
                            attributes[2] = GetPipeSeries(pline);

                            writer.AddRecord(shapePoints, shapePoints.Length, attributes);
                        }
                    }
                    #endregion

                    #region Exporting BRs
                    System.Data.DataTable komponenter = CsvReader.ReadCsvToDataTable(
                        @"X:\AutoCAD DRI - 01 Civil 3D\FJV Dynamiske Komponenter.csv", "FjvKomponenter");

                    HashSet <BlockReference> allBrs = localDb.HashSetOfType <BlockReference>(tx);

                    HashSet <BlockReference> brs = allBrs.Where(x => UtilsDataTables.ReadStringParameterFromDataTable(
                                                                    x.RealName(), komponenter, "Navn", 0) != default).ToHashSet();

                    Log.log($"{brs.Count} br(s) found for export.");

                    //Handle legacy blocks
                    System.Data.DataTable stdBlocks = CsvReader.ReadCsvToDataTable(@"X:\AutoCAD DRI - 01 Civil 3D\FJV Komponenter.csv", "FjvKomponenter");

                    HashSet <BlockReference> legacyBrs = allBrs.Where(x => UtilsDataTables.ReadStringParameterFromDataTable(
                                                                          x.Name, stdBlocks, "Navn", 0) != default).ToHashSet();

                    if (brs.Count > 0)
                    {
                        Log.log($"Legacy blocks detected: {legacyBrs.Count}.");
                    }

                    #region Field def
                    dbfFields = new DbfFieldDesc[8];

                    dbfFields[0].FieldName   = "BlockName";
                    dbfFields[0].FieldType   = DbfFieldType.Character;
                    dbfFields[0].FieldLength = 100;

                    dbfFields[1].FieldName   = "Type";
                    dbfFields[1].FieldType   = DbfFieldType.Character;
                    dbfFields[1].FieldLength = 100;

                    dbfFields[2].FieldName   = "Rotation";
                    dbfFields[2].FieldType   = DbfFieldType.Character;
                    dbfFields[2].FieldLength = 100;

                    dbfFields[3].FieldName   = "System";
                    dbfFields[3].FieldType   = DbfFieldType.Character;
                    dbfFields[3].FieldLength = 100;

                    dbfFields[4].FieldName   = "DN1";
                    dbfFields[4].FieldType   = DbfFieldType.Character;
                    dbfFields[4].FieldLength = 100;

                    dbfFields[5].FieldName   = "DN2";
                    dbfFields[5].FieldType   = DbfFieldType.Character;
                    dbfFields[5].FieldLength = 100;

                    dbfFields[6].FieldName   = "Serie";
                    dbfFields[6].FieldType   = DbfFieldType.Character;
                    dbfFields[6].FieldLength = 100;

                    dbfFields[7].FieldName   = "Vinkel";
                    dbfFields[7].FieldType   = DbfFieldType.Character;
                    dbfFields[7].FieldLength = 100;
                    #endregion

                    using (ShapeFileWriter writer = ShapeFileWriter.CreateWriter(
                               exportDir, shapeBaseName + blockSuffix,
                               ShapeType.Point, dbfFields,
                               EGIS.Projections.CoordinateReferenceSystemFactory.Default.GetCRSById(25832)
                               .GetWKT(EGIS.Projections.PJ_WKT_TYPE.PJ_WKT1_GDAL, false)))
                    {
                        foreach (BlockReference br in brs)
                        {
                            PointD[] shapePoints = new PointD[1];
                            shapePoints[0] = new PointD(br.Position.X, br.Position.Y);

                            string[] attributes = new string[8];
                            attributes[0] = br.RealName();
                            attributes[1] = ReadComponentType(br, komponenter);
                            attributes[2] = ReadBlockRotation(br, komponenter).ToString("0.00");
                            attributes[3] = ReadComponentSystem(br, komponenter);
                            attributes[4] = ReadComponentDN1(br, komponenter);
                            attributes[5] = ReadComponentDN2(br, komponenter);
                            attributes[6] = ReadComponentSeries(br, komponenter);
                            attributes[7] = ReadComponentVinkel(br, komponenter);

                            writer.AddRecord(shapePoints, shapePoints.Length, attributes);
                        }

                        foreach (BlockReference br in legacyBrs)
                        {
                            PointD[] shapePoints = new PointD[1];
                            shapePoints[0] = new PointD(br.Position.X, br.Position.Y);

                            string[] attributes = new string[8];
                            attributes[0] = br.Name;
                            attributes[1] = ReadStringParameterFromDataTable(br.Name, stdBlocks, "Type", 0);
                            attributes[2] = (br.Rotation * (180 / Math.PI)).ToString("0.##");
                            attributes[3] = ReadStringParameterFromDataTable(br.Name, stdBlocks, "System", 0);
                            attributes[4] = ReadStringParameterFromDataTable(br.Name, stdBlocks, "DN1", 0);;
                            attributes[5] = ReadStringParameterFromDataTable(br.Name, stdBlocks, "DN2", 0);;
                            attributes[6] = "S3";
                            attributes[7] = "0";

                            writer.AddRecord(shapePoints, shapePoints.Length, attributes);
                        }
                    }
                    #endregion
                }
                catch (System.Exception ex)
                {
                    tx.Abort();
                    Log.log($"EXCEPTION!!!: {ex.ToString()}. Aborting export of current file!");
                    throw new System.Exception(ex.ToString());
                    //return;
                }
                tx.Abort();
            }
        }
        public void exportareas()
        {
            DocumentCollection docCol  = Application.DocumentManager;
            Database           localDb = docCol.MdiActiveDocument.Database;
            Document           doc     = docCol.MdiActiveDocument;

            using (Transaction tx = localDb.TransactionManager.StartTransaction())
            {
                string logFileName = @"X:\AutoCAD DRI - QGIS\EGIS\Export\export.log";
                Log.LogFileName = logFileName;

                PropertySetManager  psm        = new PropertySetManager(localDb, PSetDefs.DefinedSets.DriOmråder);
                PSetDefs.DriOmråder driOmråder = new PSetDefs.DriOmråder();

                try
                {
                    string fileName = localDb.OriginalFileName;

                    string baseDir   = @"X:\037-1178 - Gladsaxe udbygning - Dokumenter\01 Intern\04 Projektering\05 Optælling til TBL\";
                    string shapeName = "Områder";

                    Log.log($"Exporting to {baseDir}.");

                    #region Exporting (p)lines
                    HashSet <Polyline> pls = localDb.HashSetOfType <Polyline>(tx);

                    pls = pls.Where(pl => pl.Layer == "0-OMRÅDER-OK").ToHashSet();

                    Log.log($"{pls.Count} object(s) found for export.");

                    DbfFieldDesc[] dbfFields = new DbfFieldDesc[4];

                    dbfFields[0].FieldName   = "Vejnavn";
                    dbfFields[0].FieldType   = DbfFieldType.General;
                    dbfFields[0].FieldLength = 100;

                    dbfFields[1].FieldName   = "Vejklasse";
                    dbfFields[1].FieldType   = DbfFieldType.Number;
                    dbfFields[1].FieldLength = 10;

                    dbfFields[2].FieldName   = "Belaegning";
                    dbfFields[2].FieldType   = DbfFieldType.General;
                    dbfFields[2].FieldLength = 100;

                    dbfFields[3].FieldName   = "Nummer";
                    dbfFields[3].FieldType   = DbfFieldType.General;
                    dbfFields[3].FieldLength = 100;



                    using (ShapeFileWriter writer = ShapeFileWriter.CreateWriter(
                               baseDir, shapeName,
                               ShapeType.PolyLine, dbfFields,
                               EGIS.Projections.CoordinateReferenceSystemFactory.Default.GetCRSById(25832)
                               .GetWKT(EGIS.Projections.PJ_WKT_TYPE.PJ_WKT1_GDAL, false)))
                    {
                        foreach (Polyline pline in pls)
                        {
                            List <Point2d> points    = new List <Point2d>();
                            int            numOfVert = pline.NumberOfVertices - 1;
                            if (pline.Closed)
                            {
                                numOfVert++;
                            }
                            for (int i = 0; i < numOfVert; i++)
                            {
                                switch (pline.GetSegmentType(i))
                                {
                                case SegmentType.Line:
                                    LineSegment2d ls = pline.GetLineSegment2dAt(i);
                                    if (i == 0)
                                    {    //First iteration
                                        points.Add(ls.StartPoint);
                                    }
                                    points.Add(ls.EndPoint);
                                    break;

                                case SegmentType.Arc:
                                    CircularArc2d arc         = pline.GetArcSegment2dAt(i);
                                    double        sPar        = arc.GetParameterOf(arc.StartPoint);
                                    double        ePar        = arc.GetParameterOf(arc.EndPoint);
                                    double        length      = arc.GetLength(sPar, ePar);
                                    double        radians     = length / arc.Radius;
                                    int           nrOfSamples = (int)(radians / 0.04);
                                    if (nrOfSamples < 3)
                                    {
                                        if (i == 0)
                                        {
                                            points.Add(arc.StartPoint);
                                        }
                                        points.Add(arc.EndPoint);
                                    }
                                    else
                                    {
                                        Point2d[] samples = arc.GetSamplePoints(nrOfSamples);
                                        if (i != 0)
                                        {
                                            samples = samples.Skip(1).ToArray();
                                        }
                                        foreach (Point2d p2d in samples)
                                        {
                                            points.Add(p2d);
                                        }
                                    }
                                    break;

                                case SegmentType.Coincident:
                                case SegmentType.Point:
                                case SegmentType.Empty:
                                default:
                                    continue;
                                }
                            }

                            PointD[] shapePoints = points.Select(p => new PointD(p.X, p.Y)).ToArray();

                            string[] attributes = new string[4];

                            psm.GetOrAttachPropertySet(pline);

                            attributes[0] = psm.ReadPropertyString(driOmråder.Vejnavn);
                            attributes[1] = psm.ReadPropertyString(driOmråder.Vejklasse);
                            attributes[2] = psm.ReadPropertyString(driOmråder.Belægning);
                            attributes[3] = psm.ReadPropertyString(driOmråder.Nummer);

                            writer.AddRecord(shapePoints, shapePoints.Length, attributes);
                        }
                    }

                    #endregion
                }
                catch (System.Exception ex)
                {
                    tx.Abort();
                    Log.log($"EXCEPTION!!!: {ex.ToString()}. Aborting export of current file!");
                    //editor.WriteMessage("\n" + ex.Message);
                    return;
                }
                tx.Abort();
            }
        }