void _ReadBoreholes(
            DGObjects objs,
            string tableNameSQL,
            string conditionSQL,
            string orderSQL)
        {
            ReadRawData(objs, tableNameSQL, orderSQL, conditionSQL);
            DataTable table = objs.rawDataSet.Tables[0];
            foreach (DataRow row in table.Rows)
            {
                if (IsDbNull(row, "ID"))
                    continue;

                Borehole bh = new Borehole(row);
                bh.id = ReadInt(row, "ID").Value;
                bh.name = ReadString(row, "Name");
                bh.fullName = ReadString(row, "FullName");
                bh.description = ReadString(row, "Description");
                bh.shape = ReadShape(row);

                bh.Type = ReadString(row, "BoreholeType");
                bh.Top = ReadDouble(row, "TopElevation").Value;
                bh.Base = bh.Top - ReadDouble(row, "BoreholeLength").Value;
                bh.Mileage = ReadDouble(row, "Mileage");

                objs[bh.key] = bh;
            }
        }
        static List<STGraphic> LinkBorehole(Borehole bh1, Borehole bh2,
            double x1, double x2, double zScale)
        {
            List<BoreholeGeology> bhGeos1 = new List<BoreholeGeology>();
            List<BoreholeGeology> bhGeos2 = new List<BoreholeGeology>();
            bhGeos1.AddRange(bh1.Geologies);
            bhGeos2.AddRange(bh2.Geologies);

            int firstStratum = bhGeos1[0].StratumID;
            if (firstStratum > bhGeos2[0].StratumID)
                firstStratum = bhGeos2[0].StratumID;
            int lastStratum = bhGeos1[bhGeos1.Count - 1].StratumID;
            if (lastStratum < bhGeos2[bhGeos2.Count - 1].StratumID)
                lastStratum = bhGeos2[bhGeos2.Count - 1].StratumID;

            List<int> containers1 = new List<int>();
            List<int> containers2 = new List<int>();
            bool simple1 = FillBoreholeGeology(bhGeos1, firstStratum, lastStratum, containers1);
            bool simple2 = FillBoreholeGeology(bhGeos2, firstStratum, lastStratum, containers2);

            List<STGraphic> stGraphics = new List<STGraphic>();
            if (simple1 && simple2 || !simple1 && !simple2)
            {
                List<STGraphic> results = LinkSimpleBoreholeGeology(
                    bhGeos1, bhGeos2, x1, x2, zScale);
                stGraphics.AddRange(results);
            }
            else if (simple1 && !simple2)
            {
                List<STGraphic> results = LinkBoreholeGeologyWithLens(
                    bhGeos1, bhGeos2, x1, x2, containers2, true, zScale);
                stGraphics.AddRange(results);
            }
            else
            {
                List<STGraphic> results = LinkBoreholeGeologyWithLens(
                    bhGeos1, bhGeos2, x1, x2, containers1, false, zScale);
                stGraphics.AddRange(results);
            }

            return stGraphics;
        }
        static IGraphicCollection ProjectBorehole(Borehole bh,
            double distance, double zScale)
        {
            double d = distance;
            IGraphicCollection graphics = NewGraphicCollection();

            double top = bh.Geologies[0].Top * zScale;
            double bottom;
            double width = 0.5;
            IMapPoint p1 = NewMapPoint(d - width, top);
            IMapPoint p2 = NewMapPoint(d + width, top);
            for (int i = 0; i < bh.Geologies.Count; ++i)
            {
                bottom = bh.Geologies[i].Base * zScale;
                IMapPoint p3 = NewMapPoint(d - width, bottom);
                IMapPoint p4 = NewMapPoint(d + width, bottom);
                IGraphic g = NewQuadrilateral(p1, p2, p4, p3);
                p1 = p3;
                p2 = p4;
                g.Symbol = GetDefaultFillSymbols(bh.Geologies[i].StratumID);
                graphics.Add(g);
            }

            return graphics;
        }
        static void ExtendBorehole(Borehole bh, Borehole bhMax)
        {
            List<BoreholeGeology> bhGeos = bh.Geologies;
            List<BoreholeGeology> bhMaxGeos = bhMax.Geologies;

            double bhBase = bh.Base;
            double bhMaxBase = bhMax.Base;
            if (bhGeos.Count == 0 || bhBase <= bhMaxBase)
                return;
            int index;
            for (index = 0; index < bhMaxGeos.Count; ++index)
            {
                if (bhMaxGeos[index].Base <= bhBase)
                    break;
            }
            if (index == bhMaxGeos.Count)
                index--;
            if (bhGeos[bhGeos.Count - 1].StratumID == bhMaxGeos[index].StratumID)
                bhGeos[bhGeos.Count - 1].Base = bhMaxGeos[index].Base;
            else if (bhGeos[bhGeos.Count - 1].StratumID < bhMaxGeos[index].StratumID)
            {
                BoreholeGeology geo = new BoreholeGeology();
                geo.StratumID = bhMaxGeos[index].StratumID;
                geo.Top = bh.Base;
                geo.Base = bhMaxGeos[index].Base;
                bhGeos.Add(geo);
            }
            else
            {
                while (bhGeos[bhGeos.Count - 1].StratumID > bhMaxGeos[index].StratumID
                    && index < bhMaxGeos.Count - 1)
                    index++;
                bhGeos[bhGeos.Count - 1].Base = bhMaxGeos[index].Base;
            }

            for (int i = index + 1; i < bhMaxGeos.Count; ++i)
            {
                bhGeos.Add(bhMaxGeos[i]);
            }
            bh.Base = bhMaxBase;
        }