Exemplo n.º 1
0
        //分块清理,提高效率
        public static OSGeo.OGR.Layer cleanLayer_Cut(OSGeo.OGR.Layer pdLayer, double minArea, double maxArea, double maxCha = 1)
        {
            List <CutBox> Tree = buildTree(pdLayer);


            shpDataSet.deleteLayerByName("pdClear");
            OSGeo.OGR.Layer    outLayer = shpDataSet.CreateLayer("pdClear", pdLayer.GetSpatialRef(), pdLayer.GetGeomType(), null);
            OSGeo.OGR.Envelope oriEnve  = new OSGeo.OGR.Envelope();
            OSGeo.OGR.Envelope nextEnve = new OSGeo.OGR.Envelope();
            StaticTools.msgLine("clean SlopeLine...");
            for (int c = 0; c < Tree.Count; c++)
            {
                CutBox cb        = Tree[c];
                int    featCount = cb.pdxIDs.Count;

                for (int i = 0; i < featCount - 1; i++)
                {
                    bool isOnly               = true;
                    OSGeo.OGR.Feature ori     = pdLayer.GetFeature(cb.pdxIDs[i]);
                    double            oriArea = ori.GetGeometryRef().GetArea();

                    if (oriArea < minArea || oriArea > maxArea)
                    {
                        //判断当前要素的面积,过小或过大时,认为其有相同的图形,不加入新的Layer
                        isOnly = false;
                    }
                    else
                    {
                        //判断当前要素与其它要素的包围盒的对应边,差值都小于阈值时,认为是相同的图形,需要跳过
                        //没有相同的图型时,isOnly为true ,塞到新的layer里
                        ori.GetGeometryRef().GetEnvelope(oriEnve);
                        for (int j = i + 1; j < featCount; j++)
                        {
                            pdLayer.GetFeature(cb.pdxIDs[j]).GetGeometryRef().GetEnvelope(nextEnve);
                            if (Math.Abs(oriEnve.MaxX - nextEnve.MaxX) < maxCha &&
                                Math.Abs(oriEnve.MaxY - nextEnve.MaxY) < maxCha &&
                                Math.Abs(oriEnve.MinX - nextEnve.MinX) < maxCha &&
                                Math.Abs(oriEnve.MinY - nextEnve.MinY) < maxCha)
                            {
                                isOnly = false;
                                break;
                            }
                        }
                    }
                    if (isOnly)
                    {
                        outLayer.CreateFeature(ori);
                    }
                    StaticTools.progress((i + 2) * 100 / featCount, $"{i + 1} / {featCount}");
                }
            }

            if (IsDelete)
            {
                shpDataSet.deleteLayerByName(pdLayer.GetName());
            }

            return(outLayer);
        }
Exemplo n.º 2
0
        public static ESRI.ArcGIS.Geometry.IEnvelope get_extent(OSGeo.OGR.Envelope ogr_envelope, ISpatialReference sr)
        {
            IEnvelope env = new EnvelopeClass();

            env.PutCoords(ogr_envelope.MinX, ogr_envelope.MinY, ogr_envelope.MaxX, ogr_envelope.MaxY);
            env.SpatialReference = sr;

            return(env);
        }
Exemplo n.º 3
0
        public IExtent GetExtent()
        {
            IExtent extent = null;

            if (OgrGeometry != null)
            {
                OSGeo.OGR.Envelope envelope = new OSGeo.OGR.Envelope();
                OgrGeometry.GetEnvelope(envelope);
                extent = envelope.ToExtent();
            }
            return(extent);
        }
Exemplo n.º 4
0
 public static bool isIntersect(OSGeo.OGR.Envelope oriEnve, OSGeo.OGR.Envelope nextEnve)
 {
     if (oriEnve.MaxX < nextEnve.MinX ||
         oriEnve.MinX > nextEnve.MaxX ||
         oriEnve.MaxY < nextEnve.MinY ||
         oriEnve.MinY > nextEnve.MaxY)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
Exemplo n.º 5
0
        ///// <summary>
        ///// Loads a Ogr datasource with the first layer
        ///// </summary>
        ///// <param name="datasource">datasource</param>
        ///// <param name="name">Returns the name of the loaded layer</param>
        /////<remarks>
        /////This constructor is obsolete!
        /////If you want this functionality use
        /////<example>
        /////SharpMap.Data.Providers.Ogr prov = new SharpMap.Data.Providers.Ogr(datasource);
        /////string layerName = prov.Layername;
        /////</example>
        /////</remarks>
        //[Obsolete("This constructor does not work well with VB.NET. Use LayerName property instead")]
        //public Ogr(string datasource, out string name)
        //    : this(datasource, 0, out name)
        //{
        //}

        #endregion

        #region IProvider Members

        /// <summary>
        /// Boundingbox of the dataset
        /// </summary>
        /// <returns>boundingbox</returns>
        public override BoundingBox GetExtents()
        {
            if (_bbox == null)
            {
                OgrEnvelope ogrEnvelope = new OgrEnvelope();
                if (_ogrLayer != null)
                {
                    _ogrLayer.GetExtent(ogrEnvelope, 1);
                }

                _bbox = new BoundingBox(ogrEnvelope.MinX, ogrEnvelope.MaxX,
                                        ogrEnvelope.MinY, ogrEnvelope.MaxY);
            }

            return(_bbox);
        }
Exemplo n.º 6
0
        /// <summary>
        /// 清理Layer中重复的,面积过小的featuer,返回一个新的Layer
        /// </summary>
        /// <param name="inLayer">源layer</param>
        /// <param name="andArea">是否判断最小面积</param>
        /// <param name="minArea">最小面积</param>
        /// <returns></returns>
        public static OSGeo.OGR.Layer cleanLayer_FF(OSGeo.OGR.Layer inLayer)
        {
            string oldLayerName = inLayer.GetName();
            string newLayerName = oldLayerName + "Clear";

            shpDataSet.deleteLayerByName(newLayerName);
            OSGeo.OGR.Layer outLayer = shpDataSet.CreateLayer(newLayerName, srs, inLayer.GetGeomType(), null);

            int featCount = inLayer.GetFeatureCount(0);

            StaticTools.msgLine($"clean resLine... before {featCount}");
            for (int i = 0; i < featCount - 1; i++)
            {
                bool isOnly                = true;
                OSGeo.OGR.Feature  ori     = inLayer.GetFeature(i);
                OSGeo.OGR.Envelope oriEnve = new OSGeo.OGR.Envelope();
                ori.GetGeometryRef().GetEnvelope(oriEnve);
                double maxCha = 1;
                for (int j = i + 1; j < featCount; j++)
                {
                    OSGeo.OGR.Feature  next     = inLayer.GetFeature(j);
                    OSGeo.OGR.Envelope nextEnve = new OSGeo.OGR.Envelope();
                    next.GetGeometryRef().GetEnvelope(nextEnve);
                    if (Math.Abs(oriEnve.MaxX - nextEnve.MaxX) < maxCha &&
                        Math.Abs(oriEnve.MaxY - nextEnve.MaxY) < maxCha &&
                        Math.Abs(oriEnve.MinX - nextEnve.MinX) < maxCha &&
                        Math.Abs(oriEnve.MinY - nextEnve.MinY) < maxCha)
                    {
                        isOnly = false;
                        break;
                    }
                }
                if (isOnly)
                {
                    outLayer.CreateFeature(ori);
                }
                ori.Dispose();
                StaticTools.progress((i + 2) * 100 / featCount, $"{i + 1} / {featCount}");
            }
            if (IsDelete)
            {
                shpDataSet.deleteLayerByName(inLayer.GetName());
            }
            StaticTools.msgLine($"clean resLine... after {outLayer.GetFeatureCount(0)}");
            return(outLayer);
        }
Exemplo n.º 7
0
        ///// <summary>
        ///// Loads a Ogr datasource with the first layer
        ///// </summary>
        ///// <param name="datasource">datasource</param>
        ///// <param name="name">Returns the name of the loaded layer</param>
        /////<remarks>
        /////This constructor is obsolete!
        /////If you want this functionality use
        /////<example>
        /////SharpMap.Data.Providers.Ogr prov = new SharpMap.Data.Providers.Ogr(datasource);
        /////string layerName = prov.Layername;
        /////</example>
        /////</remarks>
        //[Obsolete("This constructor does not work well with VB.NET. Use LayerName property instead")]
        //public Ogr(string datasource, out string name)
        //    : this(datasource, 0, out name)
        //{
        //}

        #endregion

        #region IProvider Members

        /// <summary>
        /// Boundingbox of the dataset
        /// </summary>
        /// <returns>boundingbox</returns>
        public override BoundingBox GetExtents()
        {
            if (_bbox == null)
            {
                OgrEnvelope ogrEnvelope = new OgrEnvelope();
                using (var ogrLayer = GetLayer(LayerIndex))
                {
                    if (ogrLayer != null)
                    {
                        ogrLayer.GetExtent(ogrEnvelope, 1);
                    }
                }

                _bbox = new BoundingBox(ogrEnvelope.MinX, ogrEnvelope.MaxX,
                                        ogrEnvelope.MinY, ogrEnvelope.MaxY);
            }

            return(_bbox);
        }
Exemplo n.º 8
0
        /// <summary>
        /// 判断两个Featuer是否重复,两外接矩形相同位置的边差小于1时为true
        /// </summary>
        /// <param name="ori"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public static bool isSame(OSGeo.OGR.Feature ori, OSGeo.OGR.Feature next, double maxCha = 1)
        {
            OSGeo.OGR.Envelope oriEnve = new OSGeo.OGR.Envelope();
            ori.GetGeometryRef().GetEnvelope(oriEnve);
            OSGeo.OGR.Envelope nextEnve = new OSGeo.OGR.Envelope();
            next.GetGeometryRef().GetEnvelope(nextEnve);

            if (Math.Abs(oriEnve.MaxX - nextEnve.MaxX) < maxCha && //外接矩形差
                Math.Abs(oriEnve.MaxY - nextEnve.MaxY) < maxCha &&
                Math.Abs(oriEnve.MinX - nextEnve.MinX) < maxCha &&
                Math.Abs(oriEnve.MinY - nextEnve.MinY) < maxCha)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// 获取与一个Feature有关的Raster参数,[0]offX,[1]offY,[2]sizeX,[3]sizeY
        /// </summary>
        /// <param name="Trans"></param>
        /// <param name="aFeat"></param>
        /// <returns></returns>
        private static int[] subRasterInfo(double[] Trans, int xSize, int ySize, OSGeo.OGR.Feature aFeat)
        {
            //拿到Buffer Featuer的壳
            OSGeo.OGR.Geometry bufGeom = aFeat.GetGeometryRef();
            OSGeo.OGR.Envelope bufEnve = new OSGeo.OGR.Envelope();
            bufGeom.GetEnvelope(bufEnve);
            //判断壳是否超出全局范围,是则赋边界值
            double maxX, minY;

            StaticTools.imageToGeoSpace(Trans, xSize, ySize, out maxX, out minY);
            if (bufEnve.MinX < Trans[0])
            {
                bufEnve.MinX = Trans[0];
            }
            if (bufEnve.MaxY > Trans[3])
            {
                bufEnve.MaxY = Trans[3];
            }
            if (bufEnve.MaxX > maxX)
            {
                bufEnve.MaxX = maxX;
            }
            if (bufEnve.MinY < minY)
            {
                bufEnve.MinY = minY;
            }

            //通过壳坐标拿到SubRaster的起点及行列数
            var a = new int[4];
            int leftUpX, leftUpY, rightDownX, rightDownY;

            StaticTools.geoToImageSpace(Trans, bufEnve.MinX, bufEnve.MaxY, out leftUpX, out leftUpY);
            StaticTools.geoToImageSpace(Trans, bufEnve.MaxX, bufEnve.MinY, out rightDownX, out rightDownY);

            a[0] = leftUpX;
            a[1] = leftUpY;
            a[2] = Math.Abs(rightDownX - leftUpX);
            a[3] = Math.Abs(leftUpY - rightDownY);
            bufGeom.Dispose();
            bufEnve.Dispose();
            return(a);
        }
Exemplo n.º 10
0
        public FeatureClass(Dataset dataset, OSGeo.OGR.Layer layer)
        {
            _dataset  = dataset;
            _ogrLayer = layer;

            OSGeo.OGR.FeatureDefn defn = layer.GetLayerDefn();
            _name = defn.GetName();
            if (dataset.ConnectionString.ToLower().EndsWith(".dxf"))
            {
                try
                {
                    System.IO.FileInfo fi = new System.IO.FileInfo(dataset.ConnectionString);
                    _name = fi.Name;
                }
                catch { }
            }
            _fields = new Fields();
            for (int i = 0; i < defn.GetFieldCount(); i++)
            {
                OSGeo.OGR.FieldDefn fdefn = defn.GetFieldDefn(i);
                Field field = new Field(fdefn.GetName());

                switch (fdefn.GetFieldTypeName(fdefn.GetFieldType()).ToLower())
                {
                case "integer":
                    if (_idFieldName == String.Empty)
                    {
                        _idFieldName = field.name;
                    }
                    field.type = FieldType.integer;
                    break;

                case "real":
                    field.type = FieldType.Double;
                    break;

                case "string":
                    field.type = FieldType.String;
                    field.size = fdefn.GetWidth();
                    break;
                }
                _fields.Add(field);
            }

            _countFeatures = layer.GetFeatureCount(1);
            OSGeo.OGR.Envelope env = new OSGeo.OGR.Envelope();
            layer.GetExtent(env, 1);
            _envelope = new Envelope(env.MinX, env.MinY, env.MaxX, env.MaxY);

            switch (defn.GetGeomType())
            {
            case OSGeo.OGR.wkbGeometryType.wkbPoint:
                _geomType = geometryType.Point;
                break;

            case OSGeo.OGR.wkbGeometryType.wkbLineString:
            case OSGeo.OGR.wkbGeometryType.wkbMultiLineString:
                _geomType = geometryType.Polyline;
                break;

            case OSGeo.OGR.wkbGeometryType.wkbPolygon:
            case OSGeo.OGR.wkbGeometryType.wkbMultiPolygon:
                _geomType = geometryType.Polygon;
                break;
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Boundingbox of the dataset
        /// </summary>
        /// <returns>boundingbox</returns>
        public override BoundingBox GetExtents()
        {
            if (_bbox == null)
            {
                OgrEnvelope ogrEnvelope = new OgrEnvelope();
                if (_ogrLayer != null) _ogrLayer.GetExtent(ogrEnvelope, 1);

                _bbox = new BoundingBox(ogrEnvelope.MinX, ogrEnvelope.MaxX,
                                        ogrEnvelope.MinY, ogrEnvelope.MaxY);
            }

            return _bbox;
        }
Exemplo n.º 12
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            ///Gather GHA inputs
            List <Curve> boundary = new List <Curve>();

            DA.GetDataList <Curve>("Boundary", boundary);

            string shpFileLoc = "";

            DA.GetData <string>("Vector Data Location", ref shpFileLoc);


            bool cropIt = true;

            DA.GetData <Boolean>("Crop file", ref cropIt);

            string userSRStext = "WGS84";

            DA.GetData <string>(2, ref userSRStext);


            ///GDAL setup
            ///Some preliminary testing has been done to read SHP, GeoJSON, OSM, KML, MVT, GML and GDB
            ///It can be spotty with KML, MVT and GML and doesn't throw informative errors.  Likely has to do with getting a valid CRS and
            ///TODO: resolve errors with reading KML, MVT, GML.

            RESTful.GdalConfiguration.ConfigureOgr();
            OSGeo.OGR.Ogr.RegisterAll();
            OSGeo.OGR.Driver     drv = OSGeo.OGR.Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource ds  = OSGeo.OGR.Ogr.Open(shpFileLoc, 0);

            if (ds == 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.");
                return;
            }

            List <OSGeo.OGR.Layer> layerset = new List <OSGeo.OGR.Layer>();
            List <int>             fc       = new List <int>();

            for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++)
            {
                OSGeo.OGR.Layer layer = ds.GetLayerByIndex(iLayer);

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

            ///Declare trees
            GH_Structure <GH_String>    layname = new GH_Structure <GH_String>();
            GH_Structure <GH_Integer>   fcs     = new GH_Structure <GH_Integer>();
            GH_Structure <GH_Rectangle> recs    = new GH_Structure <GH_Rectangle>();
            GH_Structure <GH_String>    sRefs   = new GH_Structure <GH_String>();
            GH_Structure <GH_String>    fnames  = new GH_Structure <GH_String>();
            GH_Structure <GH_String>    fset    = new GH_Structure <GH_String>();
            GH_Structure <GH_Point>     gset    = new GH_Structure <GH_Point>();

            GH_Structure <GH_Point>     gsetUser = new GH_Structure <GH_Point>();
            GH_Structure <GH_Rectangle> recsUser = new GH_Structure <GH_Rectangle>();


            ///Loop through each layer. Layers usually occur in Geodatabase GDB format. SHP usually has only one layer.
            for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++)
            {
                OSGeo.OGR.Layer layer = ds.GetLayerByIndex(iLayer);

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

                long count        = layer.GetFeatureCount(1);
                int  featureCount = System.Convert.ToInt32(count);
                fcs.Append(new GH_Integer(featureCount), new GH_Path(iLayer));

                layname.Append(new GH_String(layer.GetName()), new GH_Path(iLayer));


                ///Get the spatial reference of the input vector file and set to WGS84 if not known
                OSGeo.OSR.SpatialReference sourceSRS = new SpatialReference(Osr.SRS_WKT_WGS84);
                string sRef = "";

                if (layer.GetSpatialRef() == null)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is missing.  CRS set automatically set to WGS84. Mapbox to 3857");
                    //sr.ImportFromXML(shpFileLoc);
                    //sr.ImportFromEPSG(3857);
                    //sr.SetWellKnownGeogCS("EPSG:3857");
                    sourceSRS.SetFromUserInput("WGS84"); ///this seems to work where SetWellKnownGeogCS doesn't

                    string pretty = "";
                    sourceSRS.ExportToPrettyWkt(out pretty, 0);
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, pretty);
                    //sr.SetWellKnownGeogCS("WGS84");
                    //sr.SetWellKnownGeogCS("EPSG:3857");
                    sRef = "Coordinate Reference System (CRS) is missing.  CRS set automatically set to WGS84.";
                }
                else
                {
                    if (layer.GetSpatialRef().Validate() != 0)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is unknown or unsupported.  CRS set automatically set to WGS84.");
                        sourceSRS.SetWellKnownGeogCS("WGS84");
                        sRef = "Coordinate Reference System (CRS) is unknown or unsupported.  SRS set automatically set to WGS84.";
                    }
                    else
                    {
                        sourceSRS = layer.GetSpatialRef();
                        sourceSRS.ExportToWkt(out sRef);
                        try
                        {
                            int sourceSRSInt = Int16.Parse(sourceSRS.GetAuthorityCode(null));
                            AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Source Coordinate Reference System (CRS) from layer " + layer.GetName() + " is EPSG:" + sourceSRSInt + ".");
                        }
                        catch
                        {
                            AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Failed to get Source Coordinate Reference System (CRS) from layer " + layer.GetName() + ".");
                        }
                    }
                }

                sRefs.Append(new GH_String(sRef), new GH_Path(iLayer));


                ///Set transform from input spatial reference to Rhino spatial reference
                ///TODO: look into adding a step for transforming to CRS set in SetCRS
                OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference("");
                rhinoSRS.SetWellKnownGeogCS("WGS84");

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

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

                OSGeo.OSR.CoordinateTransformation coordTransformSourceToRhino = new OSGeo.OSR.CoordinateTransformation(sourceSRS, rhinoSRS);
                OSGeo.OSR.CoordinateTransformation coordTransformRhinoToUser   = new OSGeo.OSR.CoordinateTransformation(rhinoSRS, userSRS);
                OSGeo.OSR.CoordinateTransformation coordTransformSourceToUser  = new OSGeo.OSR.CoordinateTransformation(sourceSRS, userSRS);

                OSGeo.OSR.CoordinateTransformation revTransformUserToRhino   = new OSGeo.OSR.CoordinateTransformation(userSRS, rhinoSRS);
                OSGeo.OSR.CoordinateTransformation revTransformRhinoToSource = new OSGeo.OSR.CoordinateTransformation(rhinoSRS, sourceSRS);
                OSGeo.OSR.CoordinateTransformation revTransformUserToSource  = new OSGeo.OSR.CoordinateTransformation(userSRS, sourceSRS);

                ///Get OGR envelope of the data in the layer in the sourceSRS
                OSGeo.OGR.Envelope ext = new OSGeo.OGR.Envelope();
                layer.GetExtent(ext, 1);
                Point3d extMinSource = new Point3d();
                Point3d extMaxSource = new Point3d();
                extMinSource.X = ext.MinX;
                extMinSource.Y = ext.MinY;
                extMaxSource.X = ext.MaxX;
                extMaxSource.Y = ext.MaxY;

                ///Get bounding box of data in layer for coordinate transformation in Rhino SRS
                double[] extMinPT = new double[3] {
                    extMinSource.X, extMinSource.Y, extMinSource.Z
                };
                double[] extMaxPT = new double[3] {
                    extMaxSource.X, extMaxSource.Y, extMaxSource.Z
                };

                ///Transform corners of extents from Source to Rhino SRS
                coordTransformSourceToRhino.TransformPoint(extMinPT);
                coordTransformSourceToRhino.TransformPoint(extMaxPT);

                ///Get extents in Rhino SRS
                Point3d     extPTmin = new Point3d(extMinPT[0], extMinPT[1], extMinPT[2]);
                Point3d     extPTmax = new Point3d(extMaxPT[0], extMaxPT[1], extMaxPT[2]);
                Rectangle3d rec      = new Rectangle3d(Plane.WorldXY, Heron.Convert.WGSToXYZ(extPTmin), Heron.Convert.WGSToXYZ(extPTmax));
                recs.Append(new GH_Rectangle(rec), new GH_Path(iLayer));

                if (boundary.Count == 0 && cropIt == true)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Define a boundary or set cropIt to False");
                }

                else if (boundary.Count == 0 && cropIt == false)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Clipping boundary has not been defined. File extents will be used instead");
                    boundary.Add(rec.ToNurbsCurve());
                }

                ///Get bounding box of data in layer for coordinate transformation in User SRS
                ///TODO: currently the extents are showing odd results that don't seem to be shifting properly
                double[] extMinPTUser = new double[3] {
                    extMinSource.X, extMinSource.Y, extMinSource.Z
                };
                double[] extMaxPTUser = new double[3] {
                    extMaxSource.X, extMaxSource.Y, extMaxSource.Z
                };

                ///Transform corners of extents from Source to userSRS
                coordTransformSourceToUser.TransformPoint(extMinPTUser);
                coordTransformSourceToUser.TransformPoint(extMaxPTUser);

                ///Get extents in userSRS
                Point3d     extPTminUser = new Point3d(extMinPTUser[0], extMinPTUser[1], extMinPTUser[2]);
                Point3d     extPTmaxUser = new Point3d(extMaxPTUser[0], extMaxPTUser[1], extMaxPTUser[2]);
                Rectangle3d recUser      = new Rectangle3d(Plane.WorldXY, Heron.Convert.UserSRSToXYZ(extPTminUser, userSRSToModel), Heron.Convert.UserSRSToXYZ(extPTmaxUser, userSRSToModel));
                recsUser.Append(new GH_Rectangle(recUser), new GH_Path(iLayer));


                ///Loop through input boundaries
                for (int i = 0; i < boundary.Count; i++)
                {
                    OSGeo.OGR.FeatureDefn def = layer.GetLayerDefn();

                    ///Get the field names
                    List <string> fieldnames = new List <string>();
                    for (int iAttr = 0; iAttr < def.GetFieldCount(); iAttr++)
                    {
                        OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iAttr);
                        fnames.Append(new GH_String(fdef.GetNameRef()), new GH_Path(i, iLayer));
                    }

                    ///Check if boundary is contained in extent
                    if (!rec.IsValid || ((rec.Height == 0) && (rec.Width == 0)))
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more vector datasource bounds are not valid.");
                        OSGeo.OGR.Feature feat;
                        int m = 0;

                        while ((feat = layer.GetNextFeature()) != null)
                        {
                            ///Loop through field values
                            for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                            {
                                OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                fdef.Dispose();
                            }
                            m++;
                            feat.Dispose();
                        }
                    }


                    else if (boundary[i] == null)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Clipping boundary " + i + " not set.");
                    }

                    else if (!boundary[i].IsValid)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Clipping boundary " + i + "  is not valid.");
                    }

                    else if (rec.IsValid && Curve.PlanarClosedCurveRelationship(rec.ToNurbsCurve(), boundary[i], Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) == RegionContainment.Disjoint)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more boundaries may be outside the bounds of the vector datasource.");
                    }

                    else
                    {
                        ///Create bounding box for clipping geometry
                        Point3d  min   = Heron.Convert.XYZToWGS(boundary[i].GetBoundingBox(true).Min);
                        Point3d  max   = Heron.Convert.XYZToWGS(boundary[i].GetBoundingBox(true).Max);
                        double[] minpT = new double[3];
                        double[] maxpT = new double[3];

                        minpT[0] = min.X;
                        minpT[1] = min.Y;
                        minpT[2] = min.Z;
                        maxpT[0] = max.X;
                        maxpT[1] = max.Y;
                        maxpT[2] = max.Z;

                        revTransformRhinoToSource.TransformPoint(minpT);
                        revTransformRhinoToSource.TransformPoint(maxpT);

                        ///TODO: allow boundary to be converted to userSRS
                        //revTransformUserToRhino.TransformPoint(minpT);
                        //revTransformUserToRhino.TransformPoint(maxpT);

                        ///Convert to OGR geometry
                        ///TODO: add conversion from GH geometry to OGR to Convert class
                        OSGeo.OGR.Geometry ebbox = OSGeo.OGR.Geometry.CreateFromWkt("POLYGON((" + minpT[0] + " " + minpT[1] + ", " + minpT[0] + " " + maxpT[1] + ", " + maxpT[0] + " " + maxpT[1] + ", " + maxpT[0] + " " + minpT[1] + ", " + minpT[0] + " " + minpT[1] + "))");

                        ///Clip Shapefile
                        ///http://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html
                        ///TODO: allow for polyline/curve as clipper, not just bounding box
                        OSGeo.OGR.Layer clipped_layer = layer;

                        if (cropIt)
                        {
                            clipped_layer.SetSpatialFilter(ebbox);
                        }

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

                        int m = 0;
                        while ((feat = clipped_layer.GetNextFeature()) != null)
                        {
                            OSGeo.OGR.Geometry geom = feat.GetGeometryRef();
                            OSGeo.OGR.Geometry sub_geom;

                            OSGeo.OGR.Geometry geomUser = feat.GetGeometryRef().Clone();// geom.Clone();
                            OSGeo.OGR.Geometry sub_geomUser;

                            ///reproject geometry to WGS84
                            ///TODO: look into using the SetCRS global variable here
                            geom.Transform(coordTransformSourceToRhino);

                            geomUser.Transform(coordTransformSourceToUser);

                            if (feat.GetGeometryRef() != null)
                            {
                                ///Start get points if open polylines and points
                                for (int gpc = 0; gpc < geom.GetPointCount(); gpc++)
                                {
                                    ///Loop through geometry points for Rhino SRS
                                    double[] pT = new double[3];
                                    pT[0] = geom.GetX(gpc);
                                    pT[1] = geom.GetY(gpc);
                                    pT[2] = geom.GetZ(gpc);
                                    if (Double.IsNaN(geom.GetZ(gpc)))
                                    {
                                        pT[2] = 0;
                                    }

                                    Point3d pt3D = new Point3d();
                                    pt3D.X = pT[0];
                                    pt3D.Y = pT[1];
                                    pt3D.Z = pT[2];

                                    gset.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3D)), new GH_Path(i, iLayer, m));

                                    ///Loop through geometry points for User SRS
                                    double[] pTUser = new double[3];
                                    pTUser[0] = geomUser.GetX(gpc);
                                    pTUser[1] = geomUser.GetY(gpc);
                                    pTUser[2] = geomUser.GetZ(gpc);
                                    if (Double.IsNaN(geomUser.GetZ(gpc)))
                                    {
                                        pTUser[2] = 0;
                                    }

                                    Point3d pt3DUser = new Point3d();
                                    pt3DUser.X = pTUser[0];
                                    pt3DUser.Y = pTUser[1];
                                    pt3DUser.Z = pTUser[2];

                                    if ((userSRS.IsProjected() == 0) && (userSRS.IsLocal() == 0))
                                    {
                                        gsetUser.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3DUser)), new GH_Path(i, iLayer, m));
                                    }
                                    else
                                    {
                                        gsetUser.Append(new GH_Point(userSRSToModel * 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 < geom.GetGeometryCount(); gi++)
                                {
                                    sub_geom = geom.GetGeometryRef(gi);
                                    OSGeo.OGR.Geometry subsub_geom;
                                    //List<Point3d> geom_list = new List<Point3d>();

                                    sub_geomUser = geomUser.GetGeometryRef(gi);
                                    OSGeo.OGR.Geometry subsub_geomUser;

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

                                            for (int ptnum = 0; ptnum < subsub_geom.GetPointCount(); ptnum++)
                                            {
                                                ///Loop through geometry points
                                                double[] pT = new double[3];
                                                pT[0] = subsub_geom.GetX(ptnum);
                                                pT[1] = subsub_geom.GetY(ptnum);
                                                pT[2] = subsub_geom.GetZ(ptnum);

                                                Point3d pt3D = new Point3d();
                                                pt3D.X = pT[0];
                                                pt3D.Y = pT[1];
                                                pt3D.Z = pT[2];

                                                gset.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3D)), new GH_Path(i, iLayer, m, gi, n));


                                                double[] pTUser = new double[3];
                                                pTUser[0] = subsub_geomUser.GetX(ptnum);
                                                pTUser[1] = subsub_geomUser.GetY(ptnum);
                                                pTUser[2] = subsub_geomUser.GetZ(ptnum);

                                                Point3d pt3DUser = new Point3d();
                                                pt3DUser.X = pTUser[0];
                                                pt3DUser.Y = pTUser[1];
                                                pt3DUser.Z = pTUser[2];

                                                if ((userSRS.IsProjected() == 0) && (userSRS.IsLocal() == 0))
                                                {
                                                    gsetUser.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3DUser)), new GH_Path(i, iLayer, m, gi, n));
                                                }
                                                else
                                                {
                                                    gsetUser.Append(new GH_Point(userSRSToModel * pt3DUser), new GH_Path(i, iLayer, m, gi, n));
                                                }

                                                ///End loop through geometry points
                                            }
                                            subsub_geom.Dispose();
                                            subsub_geomUser.Dispose();
                                        }
                                    }

                                    else
                                    {
                                        for (int ptnum = 0; ptnum < sub_geom.GetPointCount(); ptnum++)
                                        {
                                            ///Loop through geometry points
                                            double[] pT = new double[3];
                                            pT[0] = sub_geom.GetX(ptnum);
                                            pT[1] = sub_geom.GetY(ptnum);
                                            pT[2] = sub_geom.GetZ(ptnum);

                                            Point3d pt3D = new Point3d();
                                            pt3D.X = pT[0];
                                            pt3D.Y = pT[1];
                                            pt3D.Z = pT[2];

                                            gset.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3D)), new GH_Path(i, iLayer, m, gi));


                                            double[] pTUser = new double[3];
                                            pTUser[0] = sub_geomUser.GetX(ptnum);
                                            pTUser[1] = sub_geomUser.GetY(ptnum);
                                            pTUser[2] = sub_geomUser.GetZ(ptnum);

                                            Point3d pt3DUser = new Point3d();
                                            pt3DUser.X = pTUser[0];
                                            pt3DUser.Y = pTUser[1];
                                            pt3DUser.Z = pTUser[2];

                                            if ((userSRS.IsProjected() == 0) && (userSRS.IsLocal() == 0))
                                            {
                                                gsetUser.Append(new GH_Point(Heron.Convert.WGSToXYZ(pt3DUser)), new GH_Path(i, iLayer, m, gi));
                                            }
                                            else
                                            {
                                                gsetUser.Append(new GH_Point(userSRSToModel * pt3DUser), new GH_Path(i, iLayer, m, gi));
                                            }
                                            ///End loop through geometry points
                                        }
                                    }

                                    sub_geom.Dispose();
                                    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
                                }
                                //m++;
                            }
                            m++;
                            geom.Dispose();
                            geomUser.Dispose();
                            feat.Dispose();
                        } ///end while loop through features
                    }
                }         //end loop through boundaries

                layer.Dispose();
            }///end loop through layers

            ds.Dispose();

            DA.SetDataTree(0, layname);
            DA.SetDataTree(1, fcs);
            DA.SetDataTree(2, recs);
            DA.SetDataTree(3, sRefs);
            DA.SetDataTree(4, fnames);
            DA.SetDataTree(5, fset);
            DA.SetDataTree(6, gset);

            DA.SetDataTree(7, gsetUser);
            DA.SetDataTree(8, recsUser);
        }