public void CurvesAreSimilar_NurbsCurve()
        {
            var a1 = Point.ByCoordinates(0, 0);
            var a2 = Point.ByCoordinates(1, 1);
            var a3 = Point.ByCoordinates(2, -1);
            var a4 = Point.ByCoordinates(3, 0);

            var b1 = Point.ByCoordinates(0, 0);
            var b2 = Point.ByCoordinates(1, -1);
            var b3 = Point.ByCoordinates(2, 1);
            var b4 = Point.ByCoordinates(3, 0);

            var c1 = Point.ByCoordinates(3, 0);
            var c2 = Point.ByCoordinates(2, 1);
            var c3 = Point.ByCoordinates(1, -1);
            var c4 = Point.ByCoordinates(0, 0);

            var nurbs1 = NurbsCurve.ByPoints(new[] { a1, a2, a3, a4 });
            var nurbs2 = NurbsCurve.ByPoints(new[] { b1, b2, b3, b4 });
            var nurbs3 = NurbsCurve.ByPoints(new[] { c1, c2, c3, c4 });

            var revitNurbs1 = nurbs1.ToRevitType();
            var revitNurbs2 = nurbs2.ToRevitType();
            var revitNurbs3 = nurbs3.ToRevitType();

            Assert.True(CurveUtils.CurvesAreSimilar(revitNurbs1, revitNurbs1));
            Assert.False(CurveUtils.CurvesAreSimilar(revitNurbs1, revitNurbs2));
            Assert.False(CurveUtils.CurvesAreSimilar(revitNurbs2, revitNurbs3));
        }
Example #2
0
        public void NurbsCurve_ProvidesGoodApproximationForDegree2Curve()
        {
            var pts = new[]
            {
                Point.ByCoordinates(0, 0, 0)
                , Point.ByCoordinates(0, 1, 1)
                , Point.ByCoordinates(0, 1, 0)
            };

            var bspline    = NurbsCurve.ByPoints(pts, 2);
            var revitCurve = bspline.ToRevitType(false);

            Assert.IsAssignableFrom <Autodesk.Revit.DB.NurbSpline>(revitCurve);

            var revitSpline = (Autodesk.Revit.DB.NurbSpline)revitCurve;

            Assert.AreEqual(3, revitSpline.Degree);
            var tessPts = revitSpline.Tessellate().Select(x => x.ToPoint(false));

            //assert the tesselation is very close to original curve
            foreach (var pt in tessPts)
            {
                var closestPt = bspline.ClosestPointTo(pt);
                Assert.Less(closestPt.DistanceTo(pt), 1e-6);
            }

            revitCurve.GetEndPoint(0).ShouldBeApproximately(bspline.StartPoint);
            revitCurve.GetEndPoint(1).ShouldBeApproximately(bspline.EndPoint);
        }
        /// <summary>
        /// Given some size parameters, returns a lofted surface with random bumps.
        /// </summary>
        public static Surface WobblySurface(
            double baseX, double baseY, double baseZ,
            double width, double length, double maxHeight,
            int uCount, int vCount)
        {
            double dx = width / (uCount - 1);
            double dy = length / (vCount - 1);

            Random       rnd    = new Random();
            List <Curve> curves = new List <Curve>();
            List <Point> pts    = null;

            for (double y = baseY; y <= baseY + length; y += dy)
            {
                pts = new List <Point>();
                for (double x = baseX; x <= baseX + width; x += dx)
                {
                    pts.Add(Point.ByCoordinates(x, y, baseZ + maxHeight * rnd.NextDouble()));
                }
                curves.Add(NurbsCurve.ByPoints(pts));
            }

            Surface surface = Surface.ByLoft(curves);

            return(surface);
        }
Example #4
0
        public void NurbsCurve_AcceptsStraightReplicatedDegree3NurbsCurve()
        {
            var points =
                Enumerable.Range(0, 10)
                .Select(x => Autodesk.DesignScript.Geometry.Point.ByCoordinates(x, 0, 0));

            var nurbsCurve = NurbsCurve.ByPoints(points, 3);
            var revitCurve = nurbsCurve.ToRevitType(false);

            Assert.IsAssignableFrom <Autodesk.Revit.DB.NurbSpline>(revitCurve);

            var revitSpline = (Autodesk.Revit.DB.NurbSpline)revitCurve;

            Assert.AreEqual(3, revitSpline.Degree);
            var tessPts = revitSpline.Tessellate().Select(x => x.ToPoint(false));

            //assert the tesselation is very close to original curve
            foreach (var pt in tessPts)
            {
                var closestPt = nurbsCurve.ClosestPointTo(pt);
                Assert.Less(closestPt.DistanceTo(pt), 1e-6);
            }

            revitCurve.GetEndPoint(0).ShouldBeApproximately(nurbsCurve.StartPoint);
            revitCurve.GetEndPoint(1).ShouldBeApproximately(nurbsCurve.EndPoint);
        }
Example #5
0
    /// <summary>
    ///     The logarithmic spiral can be distinguished from the Archimedean spiral by the fact that
    ///     the distances between the turnings of a logarithmic spiral increase in geometric progression,
    ///      while in an Archimedean spiral these distances are constant.
    /// </summary>
    /// <param name="angle">360 completes 1 circulation</param>
    /// <param name="scale">Determines the scale of the spiral</param>
    /// <param name="growth">This determines the factor of increase along the spiral. WARNING: Values beyond 0.3 may not give any meaningful visualization</param>
    /// <search>log,equiangular,growth,marvelous</search>
    public static NurbsCurve Logarithmic(double angle = 1800, double scale = 0.5, double growth = 0.1)
    {
        if (angle == 0.0)
        {
            throw new ArgumentException("The angle value can't be 0.", "angle");
        }

        if (angle < 0.0)
        {
            angle = angle * -1;
        }

        int numPts = 1000;

        angle = degToRad(angle);

        var pts = new List <Point>();

        for (int i = 0; i < numPts; ++i)
        {
            double currAngle = (double)i / 1000.0 * angle;
            double radius    = scale * Math.Pow(eulerConstant(), (growth * currAngle));

            double xVal = radius * Math.Cos(currAngle);
            double yVal = radius * Math.Sin(currAngle);

            pts.Add(Point.ByCoordinates(xVal, yVal, 0));
        }

        return(NurbsCurve.ByPoints(pts));
    }
Example #6
0
    /// <summary>
    ///     The Archimedean spiral is formed by locus of points corresponding to the locations over time of a point moving away from a
    ///     fixed point with a constant speed along a line which rotates with constant angular velocity.
    /// </summary>
    /// <param name="angle">360 completes 1 circulation</param>
    /// <param name="innerRadius">Changing this will change the starting place of the spiral</param>
    /// <param name="turnDistance">This controls the distance between successive turnings.</param>
    /// <search>archimedes,arithmetic</search>
    public static NurbsCurve Archimedean(double angle = 3600, double innerRadius = 0.2, double turnDistance = 0.2)
    {
        if (angle == 0.0)
        {
            throw new ArgumentException("The angle value can't be 0.", "angle");
        }

        if (angle < 0.0)
        {
            angle = angle * -1;
        }

        int numPts = 1000;

        angle = degToRad(angle);

        var pts = new List <Point>();

        for (int i = 0; i < numPts; ++i)
        {
            double currAngle = (double)i / 1000.0 * angle;
            double radius    = innerRadius + turnDistance * currAngle;

            double xVal = radius * Math.Cos(currAngle);
            double yVal = radius * Math.Sin(currAngle);

            pts.Add(Point.ByCoordinates(xVal, yVal, 0));
        }

        return(NurbsCurve.ByPoints(pts));
    }
        public void IsLineLike_Curve_CorrectlyIdentifiesStraightNurbsCurve()
        {
            var points =
                Enumerable.Range(0, 10)
                .Select(x => Autodesk.DesignScript.Geometry.Point.ByCoordinates(x, 0));

            var nurbsCurve = NurbsCurve.ByPoints(points, 3);
            var revitCurve = nurbsCurve.ToRevitType(false);

            Assert.True(CurveUtils.IsLineLike(revitCurve));
        }
        public void IsLineLike_Curve_CorrectlyIdentifiesNonStraightNurbsCurve()
        {
            var points = new[]
            {
                Point.ByCoordinates(5, 5, 0),
                Point.ByCoordinates(0, 0, 0),
                Point.ByCoordinates(-5, 5, 0),
                Point.ByCoordinates(-10, 5, 0)
            };

            var nurbsCurve = NurbsCurve.ByPoints(points, 3);

            Assert.False(CurveUtils.IsLineLike(nurbsCurve.ToRevitType(false)));
        }
        public void NurbsCurve_AcceptsStraightReplicatedDegree3NurbsCurve()
        {
            var points =
                Enumerable.Range(0, 10)
                .Select(x => Autodesk.DesignScript.Geometry.Point.ByCoordinates(x, 0, 0));

            var nurbsCurve = NurbsCurve.ByPoints(points, 3);
            var revitCurve = nurbsCurve.ToRevitType(false);

            Assert.IsAssignableFrom <Autodesk.Revit.DB.Line>(revitCurve);

            revitCurve.GetEndPoint(0).ShouldBeApproximately(nurbsCurve.StartPoint);
            revitCurve.GetEndPoint(1).ShouldBeApproximately(nurbsCurve.EndPoint);
        }
Example #10
0
        /// <summary>
        /// 沿Surface生成指定数量的Curve
        /// </summary>
        /// <param name="surface">基面</param>
        /// <param name="number">线数量</param>
        /// <param name="accuracy">精度</param>
        /// <param name="direction">方向,0为U方向,1为V方向</param>
        /// <returns></returns>
        public static List <Curve> ByAlongSurface(Surface surface, int number, int accuracy = 3, int direction = 0)
        {
            double[] parameters = new double[accuracy];
            for (int i = 0; i < accuracy; i++)
            {
                if (i == accuracy)
                {
                    parameters[i] = 1;
                }
                else
                {
                    parameters[i] = i * (1.0 / (accuracy - 1));
                }
            }
            List <Curve> baseCurves = new List <Curve>();

            foreach (var i in parameters)
            {
                var tmp = surface.GetIsoline(1 - direction, i);
                baseCurves.Add(tmp);
                tmp.Dispose();
            }
            // 线数量
            double[] ts = new double[number];
            for (int i = 0; i < number; i++)
            {
                if (i == number - 1)
                {
                    ts[i] = 1;
                }
                else
                {
                    ts[i] = i * (1.0 / (number - 1));
                }
            }
            List <Curve> outCurves = new List <Curve>();

            foreach (var t in ts)
            {
                List <Point> pts = new List <Point>();
                foreach (var crv in baseCurves)
                {
                    pts.Add(crv.PointAtParameter(t));
                }
                var tmp = NurbsCurve.ByPoints(pts);
                outCurves.Add(tmp);
                tmp.Dispose();
            }
            return(outCurves);
        }
Example #11
0
        public void ByCurve_Curve_AcceptsStraightDegree3NurbsCurve()
        {
            var points =
                Enumerable.Range(0, 10)
                .Select(x => Autodesk.DesignScript.Geometry.Point.ByCoordinates(x, 0));

            var nurbsCurve = NurbsCurve.ByPoints(points, 3);

            var modelCurve = ModelCurve.ByCurve(nurbsCurve);

            Assert.NotNull(nurbsCurve);

            modelCurve.Curve.Length.ShouldBeApproximately(9);
            modelCurve.Curve.StartPoint.ShouldBeApproximately(Point.Origin());
            modelCurve.Curve.EndPoint.ShouldBeApproximately(Point.ByCoordinates(9, 0, 0));
        }
Example #12
0
        public void ByCurve_Curve_AcceptsStraightDegree3NurbsCurve()
        {
            var points =
                Enumerable.Range(0, 10)
                .Select(x => Autodesk.DesignScript.Geometry.Point.ByCoordinates(x, 0));

            var nurbsCurve = NurbsCurve.ByPoints(points, 3);

            Assert.NotNull(nurbsCurve);

            var detailCurve = DetailCurve.ByCurve(Revit.Application.Document.Current.ActiveView, nurbsCurve);

            Assert.NotNull(detailCurve);

            detailCurve.Curve.Length.ShouldBeApproximately(9);
            detailCurve.Curve.StartPoint.ShouldBeApproximately(Point.Origin());
            detailCurve.Curve.EndPoint.ShouldBeApproximately(Point.ByCoordinates(9, 0, 0));
        }
Example #13
0
    /// <summary>
    ///     A lituus is a spiral in which the angle is inversely proportional to the square of the radius.
    /// </summary>
    /// <param name="angle">360 completes 1 circulation</param>
    /// <param name="scale">Determines the scale of the spiral</param>
    /// <search>lituus,cotes</search>
    public static NurbsCurve Lituus(double angle = 3600, double scale = 5)
    {
        if (angle == 0.0)
        {
            throw new ArgumentException("The angle value can't be 0.", "angle");
        }

        if (scale == 0.0)
        {
            throw new ArgumentException("The scale value can't be 0.", "scale");
        }

        if (angle < 0.0)
        {
            angle = angle * -1;
        }

        int numPts = 1000;

        angle = degToRad(angle);

        var pts = new List <Point>();

        for (int i = 1; i <= numPts; ++i)
        {
            double currAngle = (double)i / 1000.0 * angle;
            double radius    = Math.Sqrt(1 / currAngle);

            double xVal = scale * radius * Math.Cos(currAngle);
            double yVal = scale * radius * Math.Sin(currAngle);

            pts.Add(Point.ByCoordinates(xVal, yVal, 0));
        }

        return(NurbsCurve.ByPoints(pts));
    }
Example #14
0
        public static Dictionary <string, object> CreateTopo(string filePath, LINE.Geometry.Interval2d location = null)
        {
            // Get the file information
            List <string> fileInfo = Elk.Common.ElkLib.TopoFileInfo(filePath);

            // output parameters
            List <List <Point> > topoPoints = null;
            List <NurbsCurve>    curves     = null;
            NurbsSurface         ns         = null;

            // try to get the scale
            double scale = 1.0;

            try
            {
                scale = Elk.DynamoCommon.GetRevitUnitScale();
            }
            catch { }



            if (filePath != null && System.IO.File.Exists(filePath) && location != null)
            {
                List <List <LINE.Geometry.Point3d> > pts = ElkLib.ProcessTopoFile(filePath, scale, location);

                Point[][] surfPoints = new Point[pts.Count][];
                topoPoints = new List <List <Point> >();
                curves     = new List <NurbsCurve>();
                for (int i = 0; i < pts.Count; i++)
                {
                    List <LINE.Geometry.Point3d> rowPoints = pts[i];
                    List <Point> crvPts = new List <Point>();

                    for (int j = 0; j < rowPoints.Count; j++)
                    {
                        Point dynPoint = Point.ByCoordinates(rowPoints[j].X, rowPoints[j].Y, rowPoints[j].Z);
                        crvPts.Add(dynPoint);
                    }
                    surfPoints[i] = crvPts.ToArray();
                    topoPoints.Add(crvPts);
                    NurbsCurve nc = NurbsCurve.ByPoints(crvPts, 3);

                    //PolyCurve pc = PolyCurve.ByPoints(crvPts, false);
                    curves.Add(nc);
                }
                try
                {
                    ns = NurbsSurface.ByPoints(surfPoints, 3, 3);
                }
                catch
                {
                    ns = null;
                }
                return(new Dictionary <string, object>
                {
                    { "Info", fileInfo },
                    { "Points", topoPoints },
                    { "Curves", curves },
                    { "Surface", ns }
                });
            }
            else
            {
                return(new Dictionary <string, object>
                {
                    { "Info", fileInfo },
                    { "Points", null },
                    { "Curves", null },
                    { "Surface", null }
                });
            }
        }
Example #15
0
        /// <summary>
        /// Returns the list of Dynamo curves that defines the Alignment.
        /// </summary>
        /// <param name="tessellation">The length of the tessellation for spirals, by default is 1 unit.</param>
        /// <returns>A list of curves that represent the Alignment.</returns>
        /// <remarks>The tool returns only lines and arcs.</remarks>
        public IList <Curve> GetCurves(double tessellation = 1)
        {
            Utils.Log(string.Format("Alignment.GetCurves {0} Started...", this.Name));

            IList <Curve> output = new List <Curve>();

            if (this._entities == null)
            {
                Utils.Log(string.Format("ERROR: Alignment Entities are null", ""));

                var stations = this.GeometryStations.ToList();
                stations.AddRange(this.PIStations.ToList());
                stations.AddRange(this.SuperTransStations.ToList());

                stations.Sort();

                var pts = new List <Point>();

                foreach (var s in stations)
                {
                    pts.Add(this.PointByStationOffsetElevation(s));
                }

                pts = Point.PruneDuplicates(pts).ToList();

                output.Add(PolyCurve.ByPoints(pts));

                return(output);
            }

            Utils.Log(string.Format("Total Entities: {0}", this._entities.Count));

            try
            {
                var entities = new List <AeccAlignmentEntity>();

                for (int c = 0; c < this._entities.Count; ++c)
                {
                    try
                    {
                        var ce = this._entities.Item(c);

                        Utils.Log(string.Format("Entity: {0}", ce.Type));

                        if (ce.Type != AeccAlignmentEntityType.aeccArc && ce.Type != AeccAlignmentEntityType.aeccTangent)
                        {
                            int count = ce.SubEntityCount;

                            if (count > 0)
                            {
                                for (int i = 0; i < ce.SubEntityCount; ++i)
                                {
                                    try
                                    {
                                        var se = ce.SubEntity(i);

                                        Utils.Log(string.Format("SubEntity: {0}", se.Type));

                                        entities.Add(se);
                                    }
                                    catch (Exception ex)
                                    {
                                        Utils.Log(string.Format("ERROR1: {0} {1}", ex.Message, ex.StackTrace));
                                    }
                                }
                            }
                            else
                            {
                                entities.Add(ce);
                            }
                        }
                        else
                        {
                            entities.Add(ce);
                        }
                    }
                    catch (Exception ex)
                    {
                        Utils.Log(string.Format("ERROR2: {0} {1}", ex.Message, ex.StackTrace));
                    }
                }

                Utils.Log(string.Format("Missing Entities: {0}", this._entities.Count - entities.Count));

                foreach (AeccAlignmentEntity e in entities)
                {
                    try
                    {
                        switch (e.Type)
                        {
                        case AeccAlignmentEntityType.aeccTangent:
                        {
                            //Utils.Log(string.Format("Tangent..", ""));

                            AeccAlignmentTangent a = e as AeccAlignmentTangent;

                            var start = Point.ByCoordinates(a.StartEasting, a.StartNorthing);
                            var end   = Point.ByCoordinates(a.EndEasting, a.EndNorthing);

                            output.Add(Line.ByStartPointEndPoint(start, end));

                            start.Dispose();
                            end.Dispose();

                            //Utils.Log(string.Format("OK", ""));

                            break;
                        }

                        case AeccAlignmentEntityType.aeccArc:
                        {
                            //Utils.Log(string.Format("Arc..", ""));

                            AeccAlignmentArc a = e as AeccAlignmentArc;

                            Point center = Point.ByCoordinates(a.CenterEasting, a.CenterNorthing);
                            Point start  = Point.ByCoordinates(a.StartEasting, a.StartNorthing);
                            Point end    = Point.ByCoordinates(a.EndEasting, a.EndNorthing);

                            Arc arc = null;
                            if (!a.Clockwise)
                            {
                                arc = Arc.ByCenterPointStartPointEndPoint(center, start, end);
                            }
                            else
                            {
                                arc = Arc.ByCenterPointStartPointEndPoint(center, end, start);
                            }

                            output.Add(arc);

                            center.Dispose();
                            start.Dispose();
                            end.Dispose();

                            //Utils.Log(string.Format("OK", ""));

                            break;
                        }

                        default:
                        {
                            //Utils.Log(string.Format("Curve...", ""));
                            try
                            {
                                AeccAlignmentCurve a = e as AeccAlignmentCurve;

                                var pts = new List <Point>();

                                double start = this.Start;

                                try
                                {
                                    start = a.StartingStation;
                                }
                                catch (Exception ex)
                                {
                                    Utils.Log(string.Format("ERROR11: {0} {1}", ex.Message, ex.StackTrace));

                                    break;
                                }

                                //Utils.Log(string.Format("start: {0}", start));

                                double length = a.Length;

                                //Utils.Log(string.Format("length: {0}", length));

                                int subs = Convert.ToInt32(Math.Ceiling(length / tessellation));

                                if (subs < 10)
                                {
                                    subs = 10;
                                }

                                double delta = length / subs;

                                for (int i = 0; i < subs + 1; ++i)
                                {
                                    try
                                    {
                                        double x = 0;
                                        double y = 0;

                                        this._alignment.PointLocation(start + i * delta, 0, out x, out y);

                                        pts.Add(Point.ByCoordinates(x, y));
                                    }
                                    catch (Exception ex)
                                    {
                                        Utils.Log(string.Format("ERROR21: {2} {0} {1}", ex.Message, ex.StackTrace, start + i * delta));
                                    }
                                }

                                //Utils.Log(string.Format("Points: {0}", pts.Count));

                                if (pts.Count < 2)
                                {
                                    Utils.Log(string.Format("ERROR211: not enough points to create a spiral", ""));
                                    break;
                                }

                                NurbsCurve spiral = NurbsCurve.ByPoints(pts);          // Degree by default is 3

                                output.Add(spiral);

                                foreach (var pt in pts)
                                {
                                    if (pts != null)
                                    {
                                        pt.Dispose();
                                    }
                                }

                                pts.Clear();

                                //Utils.Log(string.Format("OK", ""));

                                //prevStation += length;
                            }
                            catch (Exception ex)
                            {
                                Utils.Log(string.Format("ERROR22: {0} {1}", ex.Message, ex.StackTrace));
                            }

                            break;
                        }
                        }
                    }
                    catch (Exception ex)
                    {
                        Utils.Log(string.Format("ERROR3: {0} {1}", ex.Message, ex.StackTrace));
                    }
                }
            }
            catch (Exception ex)
            {
                Utils.Log(string.Format("ERROR4: {0} {1}", ex.Message, ex.StackTrace));
            }

            output = SortCurves(output);

            Utils.Log("Alignment.GetCurves Completed.");

            return(output);
        }
Example #16
0
        /// <summary>
        ///     GPS Viewer that takes a GPX file (/path/name.gpx as string) and gives a bitmap image of the plot. Use Watch Image node to view the result.
        ///     Limitations: 1. Only the first track will be plotted
        ///                  2. All the track segments will be joined as one.
        ///                  3. The track will be approximated to suit the http request requiements
        ///     WARNNG: The google maps allows only 25000 requests per day per application, please be considerate in number of requests you use.
        /// </summary>
        /// <param name="gpxFile">Use File Path node OR String /path/name.gpx</param>
        /// <param name="lineWidth">Thickness of the plotted track (1-9)</param>
        /// <param name="mapHeight">Height of the bitmap map (400 - 800)</param>
        /// <param name="mapWidth">Width of the bitmap map (400 - 800)</param>
        /// <search>GPS,view,plot,track,gpx</search>
        public static Bitmap plotTrack(string gpxFile, int mapWidth = 400, int mapHeight = 400, int lineWidth = 1)
        {
            if (mapWidth > 800)
            {
                mapWidth = 800;
            }
            else if (mapWidth < 400)
            {
                mapWidth = 400;
            }

            if (mapHeight > 800)
            {
                mapHeight = 800;
            }
            else if (mapHeight < 400)
            {
                mapHeight = 400;
            }

            if (lineWidth > 9)
            {
                lineWidth = 9;
            }
            else if (lineWidth < 1)
            {
                lineWidth = 1;
            }

            List <string> trackSegments = new List <string>();

            //open the xml doc
            XmlDocument doc = new XmlDocument();

            doc.Load(gpxFile);

            //namespace of the gps viewer
            string namespc          = "http://www.topografix.com/GPX/1/1";
            XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);

            mgr.AddNamespace("", namespc);

            //get all trks
            //only one track is going to be supported because of the limitation in url encoding
            XmlNodeList    trksList = doc.GetElementsByTagName("trk");
            List <XmlNode> trks     = new List <XmlNode>(trksList.Cast <XmlNode>());

            //foreach code for all tracks -- but we will take only the first track
            //foreach (var trk in trks)
            //{
            XmlNode        trk     = trks[0];
            List <XmlNode> trksegs = ProcessNodes(trk.ChildNodes, "trkseg");

            List <Autodesk.DesignScript.Geometry.Point> pts = new List <Autodesk.DesignScript.Geometry.Point>();

            //get aggregate of all the trkpoints and store it in pts -- note we just approximately join the tracksegments
            foreach (XmlNode trkseg in trksegs)
            {
                List <XmlNode> trkpts = ProcessNodes(trkseg.ChildNodes, "trkpt");

                foreach (XmlNode trkpt in trkpts)
                {
                    double tempLat = Double.Parse(trkpt.Attributes["lat"].Value);
                    double tempLng = Double.Parse(trkpt.Attributes["lon"].Value);
                    Autodesk.DesignScript.Geometry.Point m = Autodesk.DesignScript.Geometry.Point.ByCoordinates(tempLat, tempLng, 0);
                    pts.Add(m);
                }
            }

            bool   status         = true;
            string encodedString  = "";
            int    originalNumPts = pts.Count;
            int    currentNumPts  = originalNumPts;
            int    iterationCount = 0;
            List <Autodesk.DesignScript.Geometry.Point> simplifiedPts = pts;

            do
            {
                //first encode all the raw coordinates
                encodedString = Encode(simplifiedPts);

                //webrequests cant go beyond 2048 characters
                if (encodedString.Length > (2048 - 100))
                {
                    //need to reduce the number of points by 5%
                    currentNumPts = (int)(currentNumPts * (1 - 0.05 * ++iterationCount));

                    NurbsCurve crv = NurbsCurve.ByPoints(simplifiedPts);
                    simplifiedPts.Clear();
                    List <double> parameter = Enumerable.Range(0, currentNumPts).Select(i => 0 + (1 - 0) * ((double)i / (currentNumPts - 1))).ToList <double>();

                    foreach (double para in parameter)
                    {
                        simplifiedPts.Add(crv.PointAtParameter(para));
                    }

                    status = false;
                }
                else
                {
                    status = true;
                }
            } while (status == false);

            StringBuilder finalStr = new StringBuilder();

            finalStr.Append(String.Format("https://maps.googleapis.com/maps/api/staticmap?size={0}x{1}", mapWidth, mapHeight));
            finalStr.Append(String.Format("&path=color:0xFF0000FF%7Cweight:{0}%7Cenc:", lineWidth));
            finalStr.Append(encodedString);

            Uri uri = new Uri(finalStr.ToString(), UriKind.Absolute);

            WebRequest http = HttpWebRequest.Create(finalStr.ToString());

            http.ContentType = "text/plain";

            HttpWebResponse response = (HttpWebResponse)http.GetResponse();
            Stream          stream   = response.GetResponseStream();

            Bitmap bitmap = (Bitmap)Bitmap.FromStream(stream);

            return(bitmap);
        }