Exemple #1
0
        public static Brep DrawCore(Core hhp)
        {
            double   height = hhp.Stories == 0 ? Consts.PilotiHeight : Consts.FloorHeight;
            Vector3d x      = hhp.XDirection;
            Vector3d y      = hhp.YDirection;
            double   width  = hhp.Width;
            double   depth  = hhp.Depth;

            PolylineCurve plc = new PolylineCurve(new Point3d[] { hhp.Origin, hhp.Origin + x * width, hhp.Origin + x * width + y * depth, hhp.Origin + y * depth, hhp.Origin });

            if (plc.ClosedCurveOrientation(Plane.WorldXY) == CurveOrientation.CounterClockwise)
            {
                plc.Reverse();
            }
            return(Extrusion.Create(plc, height, true).ToBrep());
        }
Exemple #2
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            ///Gather GHA inputs
            Curve boundary = null;

            DA.GetData <Curve>(0, ref boundary);

            string osmFilePath = string.Empty;

            DA.GetData <string>("OSM Data Location", ref osmFilePath);

            //string userSRStext = "WGS84";
            //DA.GetData<string>(2, ref userSRStext);

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

            DA.GetDataList <string>(2, filterWords);

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

            DA.GetDataList <string>(3, filterKeyValue);

            Transform xformToMetric   = new Transform(Rhino.RhinoMath.UnitScale(RhinoDoc.ActiveDoc.ModelUnitSystem, Rhino.UnitSystem.Meters));
            Transform xformFromMetric = new Transform(Rhino.RhinoMath.UnitScale(Rhino.UnitSystem.Meters, RhinoDoc.ActiveDoc.ModelUnitSystem));

            ///Declare trees
            Rectangle3d recs = new Rectangle3d();
            GH_Structure <GH_String>        fieldNames  = new GH_Structure <GH_String>();
            GH_Structure <GH_String>        fieldValues = new GH_Structure <GH_String>();
            GH_Structure <IGH_GeometricGoo> geometryGoo = new GH_Structure <IGH_GeometricGoo>();
            GH_Structure <IGH_GeometricGoo> buildingGoo = new GH_Structure <IGH_GeometricGoo>();


            Point3d max = new Point3d();
            Point3d min = new Point3d();

            if (boundary != null)
            {
                Point3d maxM = boundary.GetBoundingBox(true).Corner(true, false, true);
                max = Heron.Convert.XYZToWGS(maxM);

                Point3d minM = boundary.GetBoundingBox(true).Corner(false, true, true);
                min = Heron.Convert.XYZToWGS(minM);
            }

            /// get extents (why is this not part of OsmSharp?)
            System.Xml.Linq.XDocument xdoc = System.Xml.Linq.XDocument.Load(osmFilePath);
            if (xdoc.Root.Element("bounds") != null)
            {
                double  minlat    = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("minlat").Value);
                double  minlon    = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("minlon").Value);
                double  maxlat    = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("maxlat").Value);
                double  maxlon    = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("maxlon").Value);
                Point3d boundsMin = Heron.Convert.WGSToXYZ(new Point3d(minlon, minlat, 0));
                Point3d boundsMax = Heron.Convert.WGSToXYZ(new Point3d(maxlon, maxlat, 0));

                recs = new Rectangle3d(Plane.WorldXY, boundsMin, boundsMax);
            }
            else
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Cannot determine the extents of the OSM file. A 'bounds' element may not be present in the file.");
            }


            using (var fileStreamSource = File.OpenRead(osmFilePath))
            {
                /// create a source.
                OsmSharp.Streams.XmlOsmStreamSource source = new OsmSharp.Streams.XmlOsmStreamSource(fileStreamSource);

                /// filter by bounding box
                OsmSharp.Streams.OsmStreamSource sourceClipped = source;
                if (clipped)
                {
                    sourceClipped = source.FilterBox((float)max.X, (float)max.Y, (float)min.X, (float)min.Y, true);
                }

                /// create a dictionary of elements
                OsmSharp.Db.Impl.MemorySnapshotDb sourceMem = new OsmSharp.Db.Impl.MemorySnapshotDb(sourceClipped);

                /// filter the source
                var filtered = from osmGeos in sourceClipped
                               where osmGeos.Tags != null
                               select osmGeos;

                if (filterWords.Any())
                {
                    filtered = from osmGeos in filtered
                               where osmGeos.Tags.ContainsAnyKey(filterWords)
                               select osmGeos;
                }

                if (filterKeyValue.Any())
                {
                    List <Tag> tags = new List <Tag>();
                    foreach (string term in filterKeyValue)
                    {
                        string[] kv  = term.Split(',');
                        Tag      tag = new Tag(kv[0], kv[1]);
                        tags.Add(tag);
                    }
                    filtered = from osmGeos in filtered
                               where osmGeos.Tags.Intersect(tags).Any()
                               select osmGeos;
                }

                source.Dispose();

                /// loop over all objects and count them.
                int nodes = 0, ways = 0, relations = 0;

                foreach (OsmSharp.OsmGeo osmGeo in filtered)
                {
                    //NODES
                    if (osmGeo.Type == OsmGeoType.Node)
                    {
                        OsmSharp.Node n         = (OsmSharp.Node)osmGeo;
                        GH_Path       nodesPath = new GH_Path(0, nodes);

                        //populate Fields and Values for each node
                        fieldNames.AppendRange(GetKeys(osmGeo), nodesPath);
                        fieldValues.AppendRange(GetValues(osmGeo), nodesPath);

                        //get geometry for node
                        Point3d nPoint = Heron.Convert.WGSToXYZ(new Point3d((double)n.Longitude, (double)n.Latitude, 0));
                        geometryGoo.Append(new GH_Point(nPoint), nodesPath);

                        //increment nodes
                        nodes++;
                    }

                    ////////////////////////////////////////////////////////////
                    //WAYS
                    if (osmGeo.Type == OsmGeoType.Way)
                    {
                        OsmSharp.Way w        = (OsmSharp.Way)osmGeo;
                        GH_Path      waysPath = new GH_Path(1, ways);

                        //populate Fields and Values for each way
                        fieldNames.AppendRange(GetKeys(osmGeo), waysPath);
                        fieldValues.AppendRange(GetValues(osmGeo), waysPath);

                        //get polyline geometry for way
                        List <Point3d> wayNodes = new List <Point3d>();
                        foreach (long j in w.Nodes)
                        {
                            OsmSharp.Node n = (OsmSharp.Node)sourceMem.Get(OsmGeoType.Node, j);
                            wayNodes.Add(Heron.Convert.WGSToXYZ(new Point3d((double)n.Longitude, (double)n.Latitude, 0)));
                        }

                        PolylineCurve pL = new PolylineCurve(wayNodes);
                        if (pL.IsClosed)
                        {
                            //create base surface
                            Brep[] breps = Brep.CreatePlanarBreps(pL, DocumentTolerance());
                            geometryGoo.Append(new GH_Brep(breps[0]), waysPath);
                        }
                        else
                        {
                            geometryGoo.Append(new GH_Curve(pL), waysPath);
                        }

                        //building massing
                        if (w.Tags.ContainsKey("building") || w.Tags.ContainsKey("building:part"))
                        {
                            if (pL.IsClosed)
                            {
                                CurveOrientation orient = pL.ClosedCurveOrientation(Plane.WorldXY);
                                if (orient != CurveOrientation.CounterClockwise)
                                {
                                    pL.Reverse();
                                }

                                Vector3d hVec = new Vector3d(0, 0, GetBldgHeight(osmGeo));
                                hVec.Transform(xformFromMetric);

                                Extrusion        ex      = Extrusion.Create(pL, hVec.Z, true);
                                IGH_GeometricGoo bldgGoo = GH_Convert.ToGeometricGoo(ex);
                                buildingGoo.Append(bldgGoo, waysPath);
                            }
                        }

                        //increment ways
                        ways++;
                    }
                    ///////////////////////////////////////////////////////////

                    //RELATIONS
                    if (osmGeo.Type == OsmGeoType.Relation)
                    {
                        OsmSharp.Relation r            = (OsmSharp.Relation)osmGeo;
                        GH_Path           relationPath = new GH_Path(2, relations);

                        //populate Fields and Values for each relation
                        fieldNames.AppendRange(GetKeys(osmGeo), relationPath);
                        fieldValues.AppendRange(GetValues(osmGeo), relationPath);

                        List <Curve> pLines = new List <Curve>();

                        // start members loop
                        for (int mem = 0; mem < r.Members.Length; mem++)
                        {
                            GH_Path memberPath = new GH_Path(2, relations, mem);

                            OsmSharp.RelationMember rMem    = r.Members[mem];
                            OsmSharp.OsmGeo         rMemGeo = sourceMem.Get(rMem.Type, rMem.Id);

                            if (rMemGeo != null)
                            {
                                //get geometry for node
                                if (rMemGeo.Type == OsmGeoType.Node)
                                {
                                    long          memNodeId = rMem.Id;
                                    OsmSharp.Node memN      = (OsmSharp.Node)sourceMem.Get(rMem.Type, rMem.Id);
                                    Point3d       memPoint  = Heron.Convert.WGSToXYZ(new Point3d((double)memN.Longitude, (double)memN.Latitude, 0));
                                    geometryGoo.Append(new GH_Point(memPoint), memberPath);
                                }

                                //get geometry for way
                                if (rMem.Type == OsmGeoType.Way)
                                {
                                    long memWayId = rMem.Id;

                                    OsmSharp.Way memWay = (OsmSharp.Way)rMemGeo;

                                    //get polyline geometry for way
                                    List <Point3d> memNodes = new List <Point3d>();
                                    foreach (long memNodeId in memWay.Nodes)
                                    {
                                        OsmSharp.Node memNode = (OsmSharp.Node)sourceMem.Get(OsmGeoType.Node, memNodeId);
                                        memNodes.Add(Heron.Convert.WGSToXYZ(new Point3d((double)memNode.Longitude, (double)memNode.Latitude, 0)));
                                    }

                                    PolylineCurve memPolyline = new PolylineCurve(memNodes);

                                    geometryGoo.Append(new GH_Curve(memPolyline.ToNurbsCurve()), memberPath);

                                    CurveOrientation orient = memPolyline.ClosedCurveOrientation(Plane.WorldXY);
                                    if (orient != CurveOrientation.CounterClockwise)
                                    {
                                        memPolyline.Reverse();
                                    }

                                    pLines.Add(memPolyline.ToNurbsCurve());
                                }

                                //get nested relations
                                if (rMem.Type == OsmGeoType.Relation)
                                {
                                    ///not sure if this is needed
                                }
                            }
                        }
                        //end members loop

                        bool allClosed = true;
                        foreach (Curve pc in pLines)
                        {
                            if (!pc.IsClosed)
                            {
                                allClosed = false;
                            }
                        }

                        if (pLines.Count > 0 && allClosed)
                        {
                            //create base surface
                            Brep[] breps = Brep.CreatePlanarBreps(pLines, DocumentTolerance());
                            geometryGoo.RemovePath(relationPath);

                            foreach (Brep b in breps)
                            {
                                geometryGoo.Append(new GH_Brep(b), relationPath);

                                //building massing
                                if (r.Tags.ContainsKey("building") || r.Tags.ContainsKey("building:part"))
                                {
                                    Vector3d hVec = new Vector3d(0, 0, GetBldgHeight(osmGeo));
                                    hVec.Transform(xformFromMetric);

                                    //create extrusion from base surface
                                    buildingGoo.Append(new GH_Brep(Brep.CreateFromOffsetFace(b.Faces[0], hVec.Z, DocumentTolerance(), false, true)), relationPath);
                                }
                            }
                        }

                        //increment relations
                        relations++;
                    } ///end relation loop
                }     ///end filtered loop
            }         ///end osm source loop

            if (recs.IsValid)
            {
                DA.SetData(0, recs);
            }
            DA.SetDataTree(1, fieldNames);
            DA.SetDataTree(2, fieldValues);
            DA.SetDataTree(3, geometryGoo);
            DA.SetDataTree(4, buildingGoo);
        } ///end SolveInstance
        private bool GetInnerBoundary()
        {
            //plot 의 boundary 와 roads 를 사용.
            var segments = boundary.DuplicateSegments();

            double offsetDistance = UnderGroundParkingConsts.Clearance;

            for (int i = 0; i < segments.Length; i++)
            {
                Curve temp = segments[i];
                var   v    = temp.TangentAtStart;
                v.Rotate(-Math.PI / 2, Vector3d.ZAxis);
                temp.Translate(v * offsetDistance);
                segments[i] = temp;
            }

            List <Point3d> topoly = new List <Point3d>();

            for (int k = 0; k < segments.Length; k++)
            {
                int  j  = (k + 1) % segments.Length;
                Line li = new Line(segments[k].PointAtStart, segments[k].PointAtEnd);
                Line lj = new Line(segments[j].PointAtStart, segments[j].PointAtEnd);

                double paramA;
                double paramB;
                var    intersect = Rhino.Geometry.Intersect.Intersection.LineLine(li, lj, out paramA, out paramB, 0, false);

                // 교점이 A 선 위에 있음
                bool isparamAonA = paramA >= 0 && paramA <= 1 ? true : false;
                // 교점이 B 선 위에 있음
                bool isparamBonB = paramB >= 0 && paramB <= 1 ? true : false;

                bool isRightSided = paramA > 1 && paramB > 1 ? true : false;
                bool isLeftSided  = paramA < 0 && paramB < 0 ? true : false;
                // A 나 B 둘중 한 선의 위에.
                if (isparamAonA && !isparamBonB || !isparamAonA && isparamBonB)
                {
                    topoly.Add(li.PointAt(paramA));
                    //topoly.Add(segments[k].PointAtEnd);
                    //topoly.Add(segments[j].PointAtStart);
                    //k의 endpoint 에서 j의 startpoint로 선 긋는다.
                }
                // 두 선 위의 교점에.
                else if (isparamAonA && isparamBonB)
                {
                    //교점을 더함
                    topoly.Add(li.PointAt(paramA));
                }
                //외부에
                else
                {
                    //오른쪽 치우침
                    if (isRightSided)
                    {
                        topoly.Add(segments[k].PointAtEnd);
                        topoly.Add(segments[j].PointAtStart);
                    }
                    //왼쪽 치우침
                    else if (isLeftSided)
                    {
                        topoly.Add(segments[k].PointAtEnd);
                        topoly.Add(segments[j].PointAtStart);
                    }
                    //일반
                    else
                    {
                        topoly.Add(li.PointAt(paramA));
                    }
                }
            }
            topoly.Add(topoly[0]);
            var tempcurve        = new PolylineCurve(topoly);
            var rotation         = tempcurve.ClosedCurveOrientation(Vector3d.ZAxis);
            var selfintersection = Rhino.Geometry.Intersect.Intersection.CurveSelf(tempcurve, 0);
            var parameters       = selfintersection.Select(n => n.ParameterA).ToList();

            parameters.AddRange(selfintersection.Select(n => n.ParameterB));
            var spl    = tempcurve.Split(parameters);
            var f      = CommonFunc.NewJoin(spl);
            var merged = f.Where(n => n.ClosedCurveOrientation(Vector3d.ZAxis) == rotation).ToList();

            if (merged.Count == 0)
            {
                return(false);
            }

            merged        = merged.OrderByDescending(n => n.GetArea()).ToList();
            innerBoundary = merged[0];
            return(true);
        }
Exemple #4
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            ///Gather GHA inputs
            Curve boundary = null;

            DA.GetData <Curve>(0, ref boundary);

            string osmFilePath = string.Empty;

            DA.GetData <string>("OSM Data Location", ref osmFilePath);

            //string userSRStext = "WGS84";
            //DA.GetData<string>(2, ref userSRStext);

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

            DA.GetDataList <string>(2, filterWords);

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

            DA.GetDataList <string>(3, filterKeyValue);

            Transform xformToMetric   = new Transform(scaleToMetric);
            Transform xformFromMetric = new Transform(scaleFromMetric);

            ///Declare trees
            Rectangle3d recs = new Rectangle3d();
            GH_Structure <GH_String>        fieldNames  = new GH_Structure <GH_String>();
            GH_Structure <GH_String>        fieldValues = new GH_Structure <GH_String>();
            GH_Structure <IGH_GeometricGoo> geometryGoo = new GH_Structure <IGH_GeometricGoo>();
            GH_Structure <IGH_GeometricGoo> buildingGoo = new GH_Structure <IGH_GeometricGoo>();


            Point3d max = new Point3d();
            Point3d min = new Point3d();

            if (boundary != null)
            {
                Point3d maxM = boundary.GetBoundingBox(true).Corner(true, false, true);
                max = Heron.Convert.XYZToWGS(maxM);

                Point3d minM = boundary.GetBoundingBox(true).Corner(false, true, true);
                min = Heron.Convert.XYZToWGS(minM);
            }

            /// get extents (why is this not part of OsmSharp?)
            System.Xml.Linq.XDocument xdoc = System.Xml.Linq.XDocument.Load(osmFilePath);
            if (xdoc.Root.Element("bounds") != null)
            {
                double  minlat    = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("minlat").Value);
                double  minlon    = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("minlon").Value);
                double  maxlat    = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("maxlat").Value);
                double  maxlon    = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("maxlon").Value);
                Point3d boundsMin = Heron.Convert.WGSToXYZ(new Point3d(minlon, minlat, 0));
                Point3d boundsMax = Heron.Convert.WGSToXYZ(new Point3d(maxlon, maxlat, 0));

                recs = new Rectangle3d(Plane.WorldXY, boundsMin, boundsMax);
            }
            else
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Cannot determine the extents of the OSM file. A 'bounds' element may not be present in the file. " +
                                  "Try turning off clipping in this component's menu.");
            }


            using (var fileStreamSource = File.OpenRead(osmFilePath))
            {
                /// create a source.
                OsmSharp.Streams.XmlOsmStreamSource source = new OsmSharp.Streams.XmlOsmStreamSource(fileStreamSource);

                /// filter by bounding box
                OsmSharp.Streams.OsmStreamSource sourceClipped = source;
                if (clipped)
                {
                    sourceClipped = source.FilterBox((float)max.X, (float)max.Y, (float)min.X, (float)min.Y, true);
                }

                /// create a dictionary of elements
                OsmSharp.Db.Impl.MemorySnapshotDb sourceMem = new OsmSharp.Db.Impl.MemorySnapshotDb(sourceClipped);

                /// filter the source
                var filtered = from osmGeos in sourceClipped
                               where osmGeos.Tags != null
                               select osmGeos;

                if (filterWords.Any())
                {
                    filtered = from osmGeos in filtered
                               where osmGeos.Tags.ContainsAnyKey(filterWords)
                               select osmGeos;
                }

                if (filterKeyValue.Any())
                {
                    List <Tag> tags = new List <Tag>();
                    foreach (string term in filterKeyValue)
                    {
                        string[] kv  = term.Split(',');
                        Tag      tag = new Tag(kv[0], kv[1]);
                        tags.Add(tag);
                    }
                    filtered = from osmGeos in filtered
                               where osmGeos.Tags.Intersect(tags).Any()
                               select osmGeos;
                }

                source.Dispose();

                /// loop over all objects and count them.
                int nodes = 0, ways = 0, relations = 0;
                Dictionary <PolylineCurve, GH_Path> bldgOutlines = new Dictionary <PolylineCurve, GH_Path>();
                List <BuildingPart> buildingParts = new List <BuildingPart>();


                foreach (OsmSharp.OsmGeo osmGeo in filtered)
                {
                    //NODES
                    if (osmGeo.Type == OsmGeoType.Node)
                    {
                        OsmSharp.Node n         = (OsmSharp.Node)osmGeo;
                        GH_Path       nodesPath = new GH_Path(0, nodes);

                        //populate Fields and Values for each node
                        fieldNames.AppendRange(GetKeys(osmGeo), nodesPath);
                        fieldValues.AppendRange(GetValues(osmGeo), nodesPath);

                        //get geometry for node
                        Point3d nPoint = Heron.Convert.WGSToXYZ(new Point3d((double)n.Longitude, (double)n.Latitude, 0));
                        geometryGoo.Append(new GH_Point(nPoint), nodesPath);

                        //increment nodes
                        nodes++;
                    }

                    ////////////////////////////////////////////////////////////
                    //WAYS
                    if (osmGeo.Type == OsmGeoType.Way)
                    {
                        OsmSharp.Way w        = (OsmSharp.Way)osmGeo;
                        GH_Path      waysPath = new GH_Path(1, ways);

                        //populate Fields and Values for each way
                        fieldNames.AppendRange(GetKeys(osmGeo), waysPath);
                        fieldValues.AppendRange(GetValues(osmGeo), waysPath);

                        //get polyline geometry for way
                        List <Point3d> wayNodes = new List <Point3d>();
                        foreach (long j in w.Nodes)
                        {
                            OsmSharp.Node n = (OsmSharp.Node)sourceMem.Get(OsmGeoType.Node, j);
                            wayNodes.Add(Heron.Convert.WGSToXYZ(new Point3d((double)n.Longitude, (double)n.Latitude, 0)));
                        }

                        PolylineCurve pL = new PolylineCurve(wayNodes);
                        if (pL.IsClosed)
                        {
                            //create base surface
                            Brep[] breps = Brep.CreatePlanarBreps(pL, DocumentTolerance());
                            geometryGoo.Append(new GH_Brep(breps[0]), waysPath);
                        }
                        else
                        {
                            geometryGoo.Append(new GH_Curve(pL), waysPath);
                        }

                        //building massing
                        if ((w.Tags.ContainsKey("building") || w.Tags.ContainsKey("building:part")))// && !w.Tags.ContainsKey("construction"))
                        {
                            if (pL.IsClosed)
                            {
                                ///Populate dictionary for sorting building parts later
                                if (w.Tags.ContainsKey("building"))
                                {
                                    bldgOutlines.Add(pL, waysPath);
                                }

                                CurveOrientation orient = pL.ClosedCurveOrientation(Plane.WorldXY);
                                if (orient != CurveOrientation.CounterClockwise)
                                {
                                    pL.Reverse();
                                }

                                ///Move polylines to min height
                                double   minHeightWay = GetMinBldgHeight(osmGeo);
                                Vector3d minVec       = new Vector3d(0, 0, minHeightWay);
                                //minVec.Transform(xformFromMetric);
                                if (minHeightWay > 0.0)
                                {
                                    var minHeightTranslate = Transform.Translation(minVec);
                                    pL.Transform(minHeightTranslate);
                                }

                                Vector3d hVec = new Vector3d(0, 0, GetBldgHeight(osmGeo) - minHeightWay);
                                //hVec.Transform(xformFromMetric);

                                Extrusion        ex      = Extrusion.Create(pL, hVec.Z, true);
                                IGH_GeometricGoo bldgGoo = GH_Convert.ToGeometricGoo(ex);

                                ///Save building parts for sorting later and remove part from geometry goo tree
                                if (w.Tags.ContainsKey("building:part"))
                                {
                                    BuildingPart bldgPart = new BuildingPart(pL, bldgGoo, fieldNames[waysPath], fieldValues[waysPath], osmGeo);
                                    buildingParts.Add(bldgPart);
                                    fieldNames.RemovePath(waysPath);
                                    fieldValues.RemovePath(waysPath);
                                    geometryGoo.RemovePath(waysPath);
                                    ways = ways - 1;
                                }
                                else
                                {
                                    buildingGoo.Append(bldgGoo, waysPath);
                                }
                            }
                        }

                        //increment ways
                        ways++;
                    }
                    ///////////////////////////////////////////////////////////

                    //RELATIONS
                    if (osmGeo.Type == OsmGeoType.Relation)
                    {
                        OsmSharp.Relation r            = (OsmSharp.Relation)osmGeo;
                        GH_Path           relationPath = new GH_Path(2, relations);

                        //populate Fields and Values for each relation
                        fieldNames.AppendRange(GetKeys(osmGeo), relationPath);
                        fieldValues.AppendRange(GetValues(osmGeo), relationPath);

                        List <Curve> pLines = new List <Curve>();

                        // start members loop
                        for (int mem = 0; mem < r.Members.Length; mem++)
                        {
                            GH_Path memberPath = new GH_Path(2, relations, mem);

                            OsmSharp.RelationMember rMem    = r.Members[mem];
                            OsmSharp.OsmGeo         rMemGeo = sourceMem.Get(rMem.Type, rMem.Id);

                            if (rMemGeo != null)
                            {
                                //get geometry for node
                                if (rMemGeo.Type == OsmGeoType.Node)
                                {
                                    long          memNodeId = rMem.Id;
                                    OsmSharp.Node memN      = (OsmSharp.Node)sourceMem.Get(rMem.Type, rMem.Id);
                                    Point3d       memPoint  = Heron.Convert.WGSToXYZ(new Point3d((double)memN.Longitude, (double)memN.Latitude, 0));
                                    geometryGoo.Append(new GH_Point(memPoint), memberPath);
                                }

                                //get geometry for way
                                if (rMem.Type == OsmGeoType.Way)
                                {
                                    long memWayId = rMem.Id;

                                    OsmSharp.Way memWay = (OsmSharp.Way)rMemGeo;

                                    //get polyline geometry for way
                                    List <Point3d> memNodes = new List <Point3d>();
                                    foreach (long memNodeId in memWay.Nodes)
                                    {
                                        OsmSharp.Node memNode = (OsmSharp.Node)sourceMem.Get(OsmGeoType.Node, memNodeId);
                                        memNodes.Add(Heron.Convert.WGSToXYZ(new Point3d((double)memNode.Longitude, (double)memNode.Latitude, 0)));
                                    }

                                    PolylineCurve memPolyline = new PolylineCurve(memNodes);

                                    geometryGoo.Append(new GH_Curve(memPolyline.ToNurbsCurve()), memberPath);

                                    CurveOrientation orient = memPolyline.ClosedCurveOrientation(Plane.WorldXY);
                                    if (orient != CurveOrientation.CounterClockwise)
                                    {
                                        memPolyline.Reverse();
                                    }

                                    pLines.Add(memPolyline.ToNurbsCurve());
                                }

                                //get nested relations
                                if (rMem.Type == OsmGeoType.Relation)
                                {
                                    ///not sure if this is needed
                                }
                            }
                        }
                        //end members loop

                        bool allClosed = true;
                        foreach (Curve pc in pLines)
                        {
                            if (!pc.IsClosed)
                            {
                                allClosed = false;
                            }
                        }

                        if (pLines.Count > 0 && allClosed)
                        {
                            ///Move polylines to min height
                            double minHeight = GetMinBldgHeight(osmGeo);
                            if (minHeight > 0.0)
                            {
                                Vector3d minVec = new Vector3d(0, 0, minHeight);
                                //minVec.Transform(xformFromMetric);
                                var minHeightTranslate = Transform.Translation(minVec);
                                for (int i = 0; i < pLines.Count; i++)
                                {
                                    pLines[i].Transform(minHeightTranslate);
                                }
                            }
                            ///Create base surface
                            Brep[] breps = Brep.CreatePlanarBreps(pLines, DocumentTolerance());
                            geometryGoo.RemovePath(relationPath);

                            foreach (Brep b in breps)
                            {
                                geometryGoo.Append(new GH_Brep(b), relationPath);

                                ///Building massing
                                if (r.Tags.ContainsKey("building") || r.Tags.ContainsKey("building:part"))
                                {
                                    Vector3d hVec = new Vector3d(0, 0, GetBldgHeight(osmGeo) - minHeight);
                                    //hVec.Transform(xformFromMetric);

                                    ///Create extrusion from base surface
                                    buildingGoo.Append(new GH_Brep(Brep.CreateFromOffsetFace(b.Faces[0], hVec.Z, DocumentTolerance(), false, true)), relationPath);
                                }
                            }
                        }

                        ///Increment relations
                        relations++;
                    } ///End relation loop
                }     ///End filtered loop

                ///Add building parts to sub-branches under main building
                for (int partIndex = 0; partIndex < buildingParts.Count; partIndex++)
                {
                    BuildingPart bldgPart  = buildingParts[partIndex];
                    Point3d      partPoint = bldgPart.PartFootprint.PointAtStart;
                    partPoint.Z = 0;
                    bool          replaceBuidingMass   = false;
                    GH_Path       mainBuildingMassPath = new GH_Path();
                    PolylineCurve massOutline          = new PolylineCurve();

                    bool isRoof = bldgPart.PartOsmGeo.Tags.TryGetValue("roof:shape", out string isRoofString);
                    if (isRoof)
                    {
                        bldgPart.PartGoo = BldgPartToRoof(bldgPart);
                    }

                    foreach (KeyValuePair <PolylineCurve, GH_Path> pair in bldgOutlines)
                    {
                        PointContainment pc = pair.Key.Contains(partPoint, Plane.WorldXY, DocumentTolerance());
                        if (pc != PointContainment.Outside)
                        {
                            ///Create new sub-branch
                            int     numSubBranches = 0;
                            GH_Path partPath       = pair.Value.AppendElement(numSubBranches);
                            while (buildingGoo.PathExists(partPath))
                            {
                                numSubBranches++;
                                partPath = pair.Value.AppendElement(numSubBranches);
                            }

                            ///Add data to sub-branch
                            fieldNames.AppendRange(bldgPart.PartFieldNames, partPath);
                            fieldValues.AppendRange(bldgPart.PartFieldValues, partPath);
                            buildingGoo.Append(bldgPart.PartGoo, partPath);

                            ///Remove the main building mass
                            replaceBuidingMass   = true;
                            mainBuildingMassPath = pair.Value;
                            massOutline          = pair.Key;
                        }
                    }
                    ///Remove the main building mass
                    if (replaceBuidingMass)
                    {
                        buildingGoo.RemovePath(mainBuildingMassPath);
                        buildingGoo.Append(new GH_Curve(massOutline), mainBuildingMassPath);
                    }
                    else
                    {
                        GH_Path extrasPath = new GH_Path(3, partIndex);
                        buildingGoo.Append(bldgPart.PartGoo, extrasPath);
                        fieldNames.AppendRange(bldgPart.PartFieldNames, extrasPath);
                        fieldValues.AppendRange(bldgPart.PartFieldValues, extrasPath);
                    }
                }
            } ///end osm source loop

            if (recs.IsValid)
            {
                DA.SetData(0, recs);
            }
            DA.SetDataTree(1, fieldNames);
            DA.SetDataTree(2, fieldValues);
            DA.SetDataTree(3, geometryGoo);
            DA.SetDataTree(4, buildingGoo);
        } ///end SolveInstance
Exemple #5
0
        //채광방향
        public static List <Curve> Lighting(Curve roadCenter, Plot plot, double aptAngle)
        {
            double d = 0;

            if (plot.PlotType != PlotTypes.상업지역)
            {
                if (plot.LegalMaxF <= 7)
                {
                    d = 0.25;
                }
                else
                {
                    d = 0.5;
                }
            }
            else
            {
                d = 0.25;
            }

            Curve basecurve = null;
            var   cp        = AreaMassProperties.Compute(plot.Boundary).Centroid;
            var   basev     = Vector3d.XAxis;

            basev.Rotate(aptAngle, Vector3d.ZAxis);
            var bounding = plot.Boundary.GetBoundingBox(false);

            basecurve = new LineCurve(cp - basev * bounding.Diagonal.Length / 2, cp + basev * bounding.Diagonal.Length / 2);

            List <Curve> result  = new List <Curve>();
            Curve        last    = roadCenter.DuplicateCurve();
            double       pheight = 3.3;
            double       fheight = 2.8;
            int          floor   = plot.LegalMaxF;

            List <Curve> debug = new List <Curve>();

            for (int i = 0; i < floor; i++)
            {
                var height   = pheight + fheight * i;
                var distance = d * (height - pheight);

                var segments = roadCenter.DuplicateSegments();
                for (int j = 0; j < segments.Length; j++)
                {
                    var ps = segments[j].PointAtStart;
                    var pe = segments[j].PointAtEnd;

                    double ds = 0;
                    double de = 0;


                    basecurve.ClosestPoint(ps, out ds);
                    basecurve.ClosestPoint(pe, out de);

                    Vector3d vs = basecurve.PointAt(ds) - ps;
                    Vector3d ve = basecurve.PointAt(de) - pe;
                    vs.Unitize();
                    ve.Unitize();

                    var mp = segments[j].PointAtNormalizedLength(0.5);
                    var ts = mp + vs;
                    var te = mp + ve;

                    if (roadCenter.Contains(ts) == PointContainment.Inside)
                    {
                        segments[j].Translate(vs * distance);
                    }
                    else if (roadCenter.Contains(te) == PointContainment.Inside)
                    {
                        segments[j].Translate(ve * distance);
                    }

                    segments[j].Translate(Vector3d.ZAxis * height);
                }

                List <Point3d> topoly = new List <Point3d>();
                for (int k = 0; k < segments.Length; k++)
                {
                    int    j  = (k + 1) % segments.Length;
                    Line   li = new Line(segments[k].PointAtStart, segments[k].PointAtEnd);
                    Line   lj = new Line(segments[j].PointAtStart, segments[j].PointAtEnd);
                    double paramA;
                    double paramB;
                    var    intersect = Rhino.Geometry.Intersect.Intersection.LineLine(li, lj, out paramA, out paramB, 0, false);

                    topoly.Add(li.PointAt(paramA));
                }

                topoly.Add(topoly[0]);
                var tempcurve        = new PolylineCurve(topoly);
                var rotation         = tempcurve.ClosedCurveOrientation(Vector3d.ZAxis);
                var selfintersection = Rhino.Geometry.Intersect.Intersection.CurveSelf(tempcurve, 0);

                var parameters = selfintersection.Select(n => n.ParameterA).ToList();

                parameters.AddRange(selfintersection.Select(n => n.ParameterB));

                var spl = tempcurve.Split(parameters);

                var f = NewJoin(spl);


                var merged = f.Where(n => n.ClosedCurveOrientation(Vector3d.ZAxis) == rotation).ToList();
                debug.AddRange(merged);


                for (int j = merged.Count - 1; j >= 0; j--)
                {
                    var tc = merged[j].DuplicateCurve();
                    tc.Translate(Vector3d.ZAxis * -tc.PointAtStart.Z);

                    if (Curve.CreateBooleanDifference(tc, last).Length == 0)
                    {
                        last = tc;
                        result.Add(merged[j]);
                    }
                }
            }

            return(result);
        }