Exemple #1
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Curve> boundary = new List <Curve>();

            DA.GetDataList <Curve>(0, boundary);

            string URL = string.Empty;

            DA.GetData <string>("REST URL", ref URL);
            if (!URL.EndsWith("/"))
            {
                URL = URL + "/";
            }

            string userSRStext = string.Empty;

            DA.GetData <string>("User Spatial Reference System", ref userSRStext);

            bool run = false;

            DA.GetData <bool>("run", ref run);

            ///GDAL setup
            RESTful.GdalConfiguration.ConfigureOgr();

            ///TODO: implement SetCRS here.
            ///Option to set CRS here to user-defined.  Needs a SetCRS global variable.

            OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference("");
            userSRS.SetFromUserInput(userSRStext);
            int userSRSInt = Int16.Parse(userSRS.GetAuthorityCode(null));

            ///Set transform from input spatial reference to Rhino spatial reference
            OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference("");
            rhinoSRS.SetWellKnownGeogCS("WGS84");

            ///This transform moves and scales the points required in going from userSRS to XYZ and vice versa
            Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS);
            Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS);

            GH_Structure <GH_String> mapquery = new GH_Structure <GH_String>();

            GH_Structure <GH_Point>         gsetUser   = new GH_Structure <GH_Point>();
            GH_Structure <IGH_GeometricGoo> gGoo       = new GH_Structure <IGH_GeometricGoo>();
            GH_Structure <GH_String>        fset       = new GH_Structure <GH_String>();
            GH_Structure <GH_String>        fieldnames = new GH_Structure <GH_String>();


            for (int i = 0; i < boundary.Count; i++)
            {
                GH_Path     cpath = new GH_Path(i);
                BoundingBox bbox  = boundary[i].GetBoundingBox(false);
                bbox.Transform(modelToUserSRSTransform);

                string restquery = URL +
                                   "query?where=&text=&objectIds=&time=&geometry=" + bbox.Min.X + "%2C" + bbox.Min.Y + "%2C" + bbox.Max.X + "%2C" + bbox.Max.Y +
                                   "&geometryType=esriGeometryEnvelope&inSR=" + userSRSInt +
                                   "&spatialRel=esriSpatialRelIntersects" +
                                   "&relationParam=&outFields=*" +
                                   "&returnGeometry=true" +
                                   "&maxAllowableOffset=" +
                                   "&geometryPrecision=" +
                                   "&outSR=" + userSRSInt +
                                   "&returnIdsOnly=false" +
                                   "&returnCountOnly=false" +
                                   "&orderByFields=" +
                                   "&groupByFieldsForStatistics=&outStatistics=" +
                                   "&returnZ=true" +
                                   "&returnM=false" +
                                   "&gdbVersion=" +
                                   "&returnDistinctValues=false" +
                                   "&f=json";

                mapquery.Append(new GH_String(restquery), cpath);

                if (run)
                {
                    //string result = Heron.Convert.HttpToJson(restquery);

                    OSGeo.OGR.DataSource dataSource = OSGeo.OGR.Ogr.Open("ESRIJSON:" + restquery, 0);

                    if (dataSource == null)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The vector datasource was unreadable by this component. It may not a valid file type for this component or otherwise null/empty.");
                    }


                    ///Loop through each layer. Likely not any layers in a REST service
                    for (int iLayer = 0; iLayer < dataSource.GetLayerCount(); iLayer++)
                    {
                        OSGeo.OGR.Layer ogrLayer = dataSource.GetLayerByIndex(iLayer);

                        if (ogrLayer == null)
                        {
                            Console.WriteLine($"Couldn't fetch advertised layer {iLayer}");
                            System.Environment.Exit(-1);
                        }

                        long count        = ogrLayer.GetFeatureCount(1);
                        int  featureCount = System.Convert.ToInt32(count);
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Layer #{iLayer} {ogrLayer.GetName()} has {featureCount} features");

                        OSGeo.OGR.FeatureDefn def = ogrLayer.GetLayerDefn();

                        ///Get the field names
                        for (int iAttr = 0; iAttr < def.GetFieldCount(); iAttr++)
                        {
                            ///TODO: Look into GetAlternativeNameRef() for field aliases (more readable) available in GDAL 3.2
                            OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iAttr);
                            fieldnames.Append(new GH_String(fdef.GetNameRef()), new GH_Path(i, iLayer));
                        }

                        ///Loop through geometry
                        OSGeo.OGR.Feature feat;
                        def = ogrLayer.GetLayerDefn();

                        int m = 0;
                        while ((feat = ogrLayer.GetNextFeature()) != null)
                        {
                            OSGeo.OGR.Geometry geomUser = feat.GetGeometryRef().Clone();
                            OSGeo.OGR.Geometry sub_geomUser;

                            ///reproject geometry to WGS84 and userSRS
                            ///TODO: look into using the SetCRS global variable here
                            if (geomUser.GetSpatialReference() == null)
                            {
                                geomUser.AssignSpatialReference(userSRS);
                            }

                            geomUser.TransformTo(userSRS);

                            if (feat.GetGeometryRef() != null)
                            {
                                if (!pointsOnly)
                                {
                                    ///Convert GDAL geometries to IGH_GeometricGoo
                                    gGoo.AppendRange(Heron.Convert.OgrGeomToGHGoo(geomUser, userSRSToModelTransform), new GH_Path(i, iLayer, m));

                                    /// Get Feature Values
                                    if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                    {
                                        fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                    }
                                    for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                    {
                                        OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                        if (feat.IsFieldSet(iField))
                                        {
                                            fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                        }
                                        else
                                        {
                                            fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                        }
                                    }
                                    ///End get Feature Values
                                }

                                else
                                {
                                    ///Start get points if open polylines and points
                                    for (int gpc = 0; gpc < geomUser.GetPointCount(); gpc++)
                                    {
                                        ///Loop through geometry points for User SRS
                                        double[] ogrPtUser = new double[3];
                                        geomUser.GetPoint(gpc, ogrPtUser);
                                        Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]);
                                        pt3DUser.Transform(userSRSToModelTransform);

                                        gGoo.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m));
                                        ///End loop through geometry points


                                        /// Get Feature Values
                                        if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                        {
                                            fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                        }
                                        for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                        {
                                            OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                            if (feat.IsFieldSet(iField))
                                            {
                                                fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                            }
                                            else
                                            {
                                                fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                            }
                                        }
                                        ///End Get Feature Values
                                    }
                                    ///End getting points if open polylines or points


                                    ///Start getting points if closed polylines and multipolygons
                                    for (int gi = 0; gi < geomUser.GetGeometryCount(); gi++)
                                    {
                                        sub_geomUser = geomUser.GetGeometryRef(gi);
                                        OSGeo.OGR.Geometry subsub_geomUser;

                                        if (sub_geomUser.GetGeometryCount() > 0)
                                        {
                                            for (int n = 0; n < sub_geomUser.GetGeometryCount(); n++)
                                            {
                                                subsub_geomUser = sub_geomUser.GetGeometryRef(n);

                                                for (int ptnum = 0; ptnum < subsub_geomUser.GetPointCount(); ptnum++)
                                                {
                                                    ///Loop through geometry points for User SRS
                                                    double[] ogrPtUser = new double[3];
                                                    subsub_geomUser.GetPoint(ptnum, ogrPtUser);
                                                    Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]);
                                                    pt3DUser.Transform(userSRSToModelTransform);

                                                    gGoo.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m, gi, n));
                                                    ///End loop through geometry points
                                                }
                                                subsub_geomUser.Dispose();
                                            }
                                        }

                                        else
                                        {
                                            for (int ptnum = 0; ptnum < sub_geomUser.GetPointCount(); ptnum++)
                                            {
                                                ///Loop through geometry points for User SRS
                                                double[] ogrPtUser = new double[3];
                                                sub_geomUser.GetPoint(ptnum, ogrPtUser);
                                                Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]);
                                                pt3DUser.Transform(userSRSToModelTransform);

                                                gGoo.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m, gi));

                                                ///End loop through geometry points
                                            }
                                        }

                                        sub_geomUser.Dispose();

                                        /// Get Feature Values
                                        if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                        {
                                            fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                        }
                                        for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                        {
                                            OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                            if (feat.IsFieldSet(iField))
                                            {
                                                fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                            }
                                            else
                                            {
                                                fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                            }
                                        }
                                        ///End Get Feature Values
                                    } ///End closed polygons and multipolygons
                                }     ///End points only
                            }
                            m++;
                            geomUser.Dispose();
                            feat.Dispose();
                        }///end while loop through features
                    }
                    dataSource.Dispose();
                }
            }

            ///Not the most elegant way of setting outputs only on run
            if (run)
            {
                DA.SetDataList(0, fieldnames.get_Branch(0));
                DA.SetDataTree(1, fset);
                DA.SetDataTree(2, gGoo);
            }
            DA.SetDataTree(3, mapquery);
        }
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)
        {
            ///Setup location
            Point3d location = new Point3d();

            DA.GetData(0, ref location);
            double lat = Heron.Convert.XYZToWGS(location).Y;
            double lon = Heron.Convert.XYZToWGS(location).X;

            ///Setup contour style and unit type
            List <double> contourNums = new List <double>();

            DA.GetDataList <double>(1, contourNums);
            string contourType    = String.Empty;
            double unitConversion = Rhino.RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, Rhino.UnitSystem.Meters);

            contourNums.Sort();
            for (int i = 0; i < contourNums.Count; i++)
            {
                double contourNum = contourNums[i];
                if (contourNum < 0.0)
                {
                    contourNum = 0.0;
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Minimum countour must be greater than 0.");
                }

                if (MinutesOrMeters == "Distance")
                {
                    contourType = "contours_meters=";
                    contourNum  = Math.Round(contourNum * unitConversion, 0);
                    if (contourNum < 1)
                    {
                        contourNum = 1;
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Minimum distance contour must be greater than the Rhino unit equivalent of 1 meter.");
                    }
                    if (contourNum > 100000)
                    {
                        contourNum = 100000;
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Maximum distance contour must be less than the Rhino unit equivalent of 1,000km.");
                    }
                }
                else
                {
                    contourType = "contours_minutes=";
                    if (contourNum > 60)
                    {
                        contourNum = 60;
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Maximum minute contour is 60.  Contour value reduced to 60.");
                    }
                }

                contourNums[i] = contourNum;
            }

            ///Setup denoise and make sure Denoise is between 0..1
            double?denoiseNum = null;

            DA.GetData(2, ref denoiseNum);
            if (denoiseNum < 0.0)
            {
                denoiseNum = 0.0;
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Denoise must be greater than 0.");
            }
            if (denoiseNum > 1.0)
            {
                denoiseNum = 1.0;
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Denoise must be less than 1.0");
            }

            ///Setup generalize and make sure it's greater than 0
            double?generalize = null;

            DA.GetData(3, ref generalize);
            double?generalizeNum = generalize * unitConversion;

            if (generalizeNum < 0.0)
            {
                generalizeNum = 0.0;
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Generalize must be greater than 0");
            }

            ///Setup Mapbox token
            string apiKey = string.Empty;

            DA.GetData(4, ref apiKey);
            string mbToken = apiKey;

            if (mbToken == "")
            {
                string hmbToken = System.Environment.GetEnvironmentVariable("HERONMAPBOXTOKEN");
                if (hmbToken != null)
                {
                    mbToken = hmbToken;
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Using Mapbox token stored in Environment Variable HERONMAPBOXTOKEN.");
                }
                else
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No Mapbox token is specified.  Please get a valid token from mapbox.com");
                    return;
                }
            }

            ///Setup run
            bool run = false;

            DA.GetData(5, ref run);


            ///Outputs
            List <IGH_GeometricGoo> isochrones = new List <IGH_GeometricGoo>();
            List <string>           urls       = new List <string>();

            ///GDAL setup
            RESTful.GdalConfiguration.ConfigureOgr();
            OSGeo.OGR.Ogr.RegisterAll();

            ///Set transform from input spatial reference to Rhino spatial reference
            OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference("");
            rhinoSRS.SetWellKnownGeogCS("WGS84");

            ///TODO: use this as override of global SetSRS
            OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference("");
            //userSRS.SetFromUserInput(userSRStext);
            userSRS.SetFromUserInput("WGS84");

            ///These transforms move and scale in order to go from userSRS to XYZ and vice versa
            Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS);


            ///Construct URL query string
            int increment = 0;

            while (increment < contourNums.Count)
            {
                string contourString = contourNums[increment].ToString();

                if (increment + 1 < contourNums.Count)
                {
                    contourString = contourString + "%2C" + contourNums[increment + 1];
                }
                if (increment + 2 < contourNums.Count)
                {
                    contourString = contourString + "%2C" + contourNums[increment + 2];
                }
                if (increment + 3 < contourNums.Count)
                {
                    contourString = contourString + "%2C" + contourNums[increment + 3];
                }

                string url = @"https://api.mapbox.com/isochrone/v1/mapbox/";
                if (!String.IsNullOrEmpty(Profile))
                {
                    url = url + Profile.ToLower() + "/";
                }
                if (lon > -180.0 && lon <= 180.0)
                {
                    url = url + lon + "%2C";
                }
                if (lat > -90.0 && lat <= 90.0)
                {
                    url = url + lat + "?";
                }
                if (!String.IsNullOrEmpty(contourType))
                {
                    url = url + contourType.ToLower();
                }
                if (contourString != null)
                {
                    url = url + contourString;
                }
                if (polygons == "Meshes")
                {
                    url = url + "&polygons=true";
                }
                else
                {
                    url = url + "&polygons=false";
                }
                if (denoiseNum != null)
                {
                    url = url + "&denoise=" + denoiseNum;
                }
                if (generalizeNum != null)
                {
                    url = url + "&generalize=" + generalizeNum;
                }
                if (mbToken != "")
                {
                    url = url + "&access_token=" + mbToken;
                }

                urls.Add(url);
                increment = increment + 4;
            }


            if (run)
            {
                foreach (string u in urls)
                {
                    List <IGH_GeometricGoo> gGoo       = new List <IGH_GeometricGoo>();
                    OSGeo.OGR.DataSource    dataSource = OSGeo.OGR.Ogr.Open(u, 0);

                    if (dataSource == null)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mapbox returned an invalid response.");
                        return;
                    }

                    ///Only interested in geometry, not fields or values
                    OSGeo.OGR.Layer   ogrLayer = dataSource.GetLayerByIndex(0);
                    OSGeo.OGR.Feature feat;

                    while ((feat = ogrLayer.GetNextFeature()) != null)
                    {
                        if (feat.GetGeometryRef() == null)
                        {
                            AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Isochrone may be too small or otherwise degenerate.");
                            continue;
                        }
                        OSGeo.OGR.Geometry geomUser = feat.GetGeometryRef().Clone();
                        ///reproject geometry to WGS84 and userSRS
                        ///TODO: look into using the SetCRS global variable here
                        if (geomUser.GetSpatialReference() == null)
                        {
                            geomUser.AssignSpatialReference(userSRS);
                        }

                        geomUser.TransformTo(userSRS);
                        if (feat.GetGeometryRef() != null)
                        {
                            isochrones.AddRange(Heron.Convert.OgrGeomToGHGoo(geomUser, userSRSToModelTransform));
                        }
                    }
                    ///Garbage cleanup
                    ogrLayer.Dispose();
                    dataSource.Dispose();
                }
            }

            List <string> mbAtts = new List <string> {
                "© Mapbox, © OpenStreetMap", "https://www.mapbox.com/about/maps/", "http://www.openstreetmap.org/copyright"
            };

            DA.SetDataList(0, isochrones);
            DA.SetDataList(1, urls);
            DA.SetDataList(2, mbAtts);
        }