Ejemplo n.º 1
0
        //将任意坐标系统转换为自定义Albers大地坐标(米)
        public static IPoint GeoToGra(IPoint point)
        {
            IPoint pt = new PointClass();
            pt.PutCoords(point.X, point.Y);

            ISpatialReferenceFactory2 pFact = new SpatialReferenceEnvironmentClass();

            //定义地理坐标,由输入的对象决定,也可以自己定义,参考: esriSRGeoCSType
            IGeographicCoordinateSystem pGCS = new GeographicCoordinateSystemClass();
            pGCS = pFact.CreateGeographicCoordinateSystem(point.SpatialReference.FactoryCode);

            //自定义投影方式
            IProjectedCoordinateSystem pProjectedCS = new ProjectedCoordinateSystemClass();
            IProjectedCoordinateSystemEdit pProjectedCSEdit = pProjectedCS as IProjectedCoordinateSystemEdit;

            //定义投影方式,参考: esriSRProjectionType
            IProjection pProjection = new ProjectionClass();
            pProjection = pFact.CreateProjection((int)esriSRProjectionType.esriSRProjection_Albers);

            //定义投影单位,参考:esriSRUnitType
            ILinearUnit pUnit = new LinearUnitClass();
            pUnit = pFact.CreateUnit((int)esriSRUnitType.esriSRUnit_Meter) as ILinearUnit;

            //定义其他参数,参考:esriSRParameterType
            IParameter[] pParm = new IParameter[6];
            pParm[0] = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_FalseEasting);
            pParm[0].Value = 0;

            pParm[1] = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_FalseNorthing);
            pParm[1].Value = 0;

            pParm[2] = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_CentralMeridian);
            pParm[2].Value = 110;

            pParm[3] = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_StandardParallel1);
            pParm[3].Value = 25;

            pParm[4] = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_StandardParallel2);
            pParm[4].Value = 47;

            pParm[5] = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_LatitudeOfOrigin);
            pParm[5].Value = 0;

            //设置投影相关信息
            object name = "User_Defined_Albers";
            object alias = "Albers";
            object abbreviation = "Albers";
            object remarks = "User_Defined_Albers is the projection";
            object usage = "";
            object gcs = pGCS;
            object projectedUnit = pUnit;
            object projection = pProjection;
            object parameters = pParm;
            pProjectedCSEdit.Define(ref name, ref alias, ref abbreviation, ref remarks, ref usage, ref gcs, ref projectedUnit, ref projection, ref parameters);

            //获取自定义空间参考
            ISpatialReference pSpatialRef = pProjectedCS as ISpatialReference;

            IGeometry pGeometry = (IGeometry)pt;
            pGeometry.SpatialReference = pGCS as ISpatialReference;

            //重投影处理
            pGeometry.Project(pSpatialRef);

            return pt;
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            //ESRI License Initializer generated code.
            m_AOLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeAdvanced },
                                                         new esriLicenseExtensionCode[] { });

            Dictionary <string, Vertex> nodeDict = new Dictionary <string, Vertex>();
            Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
            IWorkspace        workspace        = workspaceFactory.OpenFromFile(@"C:\Users\hellocomrade\NHDPlusV21_GL_04.gdb", 0);
            IFeatureWorkspace iFtrWs           = workspace as IFeatureWorkspace;

            if (null != iFtrWs)
            {
                IFeatureClass fcLine  = iFtrWs.OpenFeatureClass("NHD_Flowline");
                IFeatureClass fcPoint = iFtrWs.OpenFeatureClass("Hydro_Net_Junctions");
                System.Diagnostics.Debug.Assert(null != fcLine && null != fcPoint);

                var fldLst = new List <string> {
                    "OBJECTID", "FlowDir", "FTYPE", "V0001E_MA", "V0001E_MM", "V0001E_01", "V0001E_02", "V0001E_03", "V0001E_04", "V0001E_05", "V0001E_06", "V0001E_07", "V0001E_08", "V0001E_09", "V0001E_10", "V0001E_11", "V0001E_12"
                };
                Dictionary <string, int> fldDict = new Dictionary <string, int>();
                fldLst.ForEach(fldName => fldDict.Add(fldName, fcLine.FindField(fldName)));

                int lineFtrId = -1;
                //Find field index for oid in Hydro_Net_Junctions feature class
                int    pntFtrIdIdx = fcPoint.FindField("OBJECTID");
                string pntFtrId    = null;

                /*
                 * It has been observed that the most time consuming part of this script is on spatial query.
                 * We could take the same approach we had on Arcpy through fcLine.Search() with a spatial filter.
                 * However, it will make us have the same granularity as using arcpy.
                 * Instead, we took a different route here by using IFeatureIndex and IIndexQuery2
                 */
                IGeoDataset       geoLineDS = (IGeoDataset)fcLine;
                ISpatialReference srLine    = geoLineDS.SpatialReference;
                IFeatureIndex     lineIdx   = new FeatureIndexClass();
                lineIdx.FeatureClass = fcLine;
                lineIdx.Index(null, geoLineDS.Extent);
                IIndexQuery2 queryLineByIdx = lineIdx as IIndexQuery2;

                IFeatureIndex pointIdx = new FeatureIndexClass();
                pointIdx.FeatureClass = fcPoint;
                pointIdx.Index(null, ((IGeoDataset)fcPoint).Extent);
                IIndexQuery2 queryPointByIdx = pointIdx as IIndexQuery2;

                //Get a cursor on Hydro_Net_Junctions as the iterator
                IFeatureCursor pntCur        = fcPoint.Search(null, false);
                IFeature       pnt           = pntCur.NextFeature();
                IFeature       line          = null;
                IFeature       otherPnt      = null;
                List <string>  requiredTypes = new List <string> {
                    "StreamRiver", "ArtificialPath"
                };

                /*
                 * ITopologicalOpeartor is good for two geometries comparing with each other. It doesn't fit
                 * very well for our situation, which check the geometric relationships between a geometry
                 * against a feature class that may have more than 100K geometries.
                 */
                //ITopologicalOperator optor = null;

                /*
                 * It's a shame that we have to reference to a Server API in order to calcuate Geodesic
                 * distances for a polyline with lon/lat as coordinates.
                 *
                 * We could do Haversine ourselves, but we have to believe ESRI could definitely does a
                 * better job there, well, hard to figure out how to get this simple task done in an intutive
                 * way though...
                 */
                IGeometryServer2 geoOperator = new GeometryServerClass();

                IPolyline             polyLine = null;
                List <DownstreamNode> dsLst    = null;
                int[]         lineIds          = null;
                int[]         pntIds           = null;
                object        idobjs;
                object        idobjs1;
                PolylineArray tmpArr   = null;
                IDoubleArray  lengths  = null;
                double        lineLen  = 0.0;
                double        v        = 0.0;
                ILinearUnit   unit     = new LinearUnitClass();
                var           range    = Enumerable.Range(3, 14);
                int           count    = 0;
                int           incoming = 0;
                while (null != pnt)
                {
                    //get ftr id of the current vertex
                    pntFtrId = pnt.get_Value(pntFtrIdIdx).ToString();
                    //optor = pnt.Shape as ITopologicalOperator;

                    /*
                     * This should return feature ids that interects with the given geometry in the feature
                     * class having the index built.
                     */
                    queryLineByIdx.IntersectedFeatures(pnt.Shape, out idobjs);
                    lineIds = idobjs as int[];
                    if (null != lineIds && lineIds.Length > 0)
                    {
                        foreach (int id in lineIds)
                        {
                            line      = fcLine.GetFeature(id);
                            lineFtrId = int.Parse(line.get_Value(fldDict["OBJECTID"]).ToString());
                            if ("1" == line.get_Value(fldDict["FlowDir"]).ToString() && true == requiredTypes.Contains(line.get_Value(fldDict["FTYPE"]).ToString()))
                            {
                                polyLine = line.Shape as IPolyline;
                                if (isSamePoint(polyLine.FromPoint, pnt.Shape as IPoint))
                                {
                                    queryPointByIdx.IntersectedFeatures(line.Shape, out idobjs1);
                                    pntIds = idobjs1 as int[];
                                    if (null != pntIds && 2 == pntIds.Length)
                                    {
                                        foreach (int pid in pntIds)
                                        {
                                            otherPnt = fcPoint.GetFeature(pid);
                                            if (false == isSamePoint(otherPnt.Shape as IPoint, pnt.Shape as IPoint))
                                            {
                                                tmpArr = new PolylineArrayClass();
                                                tmpArr.Add(polyLine);
                                                lengths = geoOperator.GetLengthsGeodesic(srLine, tmpArr as IPolylineArray, unit);
                                                if (0 == lengths.Count)
                                                {
                                                    continue;
                                                }
                                                lineLen = lengths.get_Element(0) * 3.28084;
                                                //var velos = from idx in range select double.Parse(line.get_Value(fldDict[fldLst[idx]]).ToString());
                                                List <double> velos = new List <double>();
                                                foreach (int idx in range)
                                                {
                                                    v = double.Parse(line.get_Value(fldDict[fldLst[idx]]).ToString());
                                                    velos.Add(v == 0 ? 0 : lineLen / v);
                                                }
                                                if (null == dsLst)
                                                {
                                                    dsLst = new List <DownstreamNode>();
                                                }
                                                dsLst.Add(new DownstreamNode(pid, id, velos));
                                            }
                                        }
                                    }
                                }
                                else // pnt at the end of the polyline
                                {
                                    ++incoming;
                                }
                            }
                        }
                    }
                    if (null != dsLst || incoming > 0)
                    {
                        nodeDict.Add(pntFtrId, new Vertex(int.Parse(pntFtrId), incoming, dsLst));
                    }
                    pnt = pntCur.NextFeature();
                    if (++count % 1000 == 0)
                    {
                        Console.WriteLine("Processing Count: " + count);
                    }
                    incoming = 0;
                    dsLst    = null;
                }//end of while(null != pnt)
                ReleaseCOMObj(pntCur);
            }
            ReleaseCOMObj(workspaceFactory);
            //ESRI License Initializer generated code.
            //Do not make any call to ArcObjects after ShutDownApplication()
            m_AOLicenseInitializer.ShutdownApplication();
        }
        private void CalculateMetersKPHAndLanguageFields(string outputFileGdbPath)
        {
            // Open the Streets feature class and find the Meters and Language fields

            Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            var gdbWSF = Activator.CreateInstance(factoryType) as IWorkspaceFactory;
            var gdbFWS = gdbWSF.OpenFromFile(outputFileGdbPath, 0) as IFeatureWorkspace;
            IFeatureClass fc = gdbFWS.OpenFeatureClass(StreetsFCName);
            int metersField = fc.FindField("Meters");
            int contrAccField = fc.FindField("CONTRACC");
            int speedCatField = fc.FindField("SPEED_CAT");
            int kphField = fc.FindField("KPH");
            int suppliedLangField = fc.FindField("ST_LANGCD");
            int suppliedLangAltField = fc.FindField("ST_LANGCD_Alt");
            int languageField = fc.FindField("Language");
            int languageAltField = fc.FindField("Language_Alt");

            // Define a LinearUnit for meters

            ILinearUnit metersUnit = new LinearUnitClass();
            double metersPerUnit = 1.0;
            ((ILinearUnitEdit)metersUnit).DefineEx("Meter", "Meter", "M", "Meter is the linear unit", ref metersPerUnit);

            // Get the language lookup hash

            System.Collections.Hashtable langLookup = CreateLanguageLookup();

            // Use an UpdateCursor to populate the Meters field and Language fields

            IFeatureCursor cur = fc.Update(null, true);
            IFeature feat = null;
            while ((feat = cur.NextFeature()) != null)
            {
                var pg = feat.Shape as IPolycurveGeodetic;
                double geodLength = pg.get_LengthGeodetic(esriGeodeticType.esriGeodeticTypeGeodesic, metersUnit);
                feat.set_Value(metersField, geodLength);
                double kph = LookupKPH((string)(feat.get_Value(contrAccField)), (string)(feat.get_Value(speedCatField)));
                feat.set_Value(kphField, kph);
                string lang = SignpostUtilities.GetLanguageValue((string)(feat.get_Value(suppliedLangField)), langLookup);
                feat.set_Value(languageField, lang);

                // Alternate name language may be null -- we need to check for this condition before setting the value
                var getValueResult = feat.get_Value(suppliedLangAltField) as string;
                if (getValueResult != null)
                {
                    string langAlt = SignpostUtilities.GetLanguageValue(getValueResult, langLookup);
                    feat.set_Value(languageAltField, langAlt);
                }

                cur.UpdateFeature(feat);
            }
        }
Ejemplo n.º 4
0
        static void Main(string[] args)
        {
            //ESRI License Initializer generated code.
            m_AOLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeAdvanced },
            new esriLicenseExtensionCode[] { });

            Dictionary<string, Vertex> nodeDict = new Dictionary<string, Vertex>();
            Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
            IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
            IWorkspace workspace = workspaceFactory.OpenFromFile(@"C:\Users\hellocomrade\NHDPlusV21_GL_04.gdb", 0);
            IFeatureWorkspace iFtrWs = workspace as IFeatureWorkspace;
            if(null != iFtrWs)
            {
                IFeatureClass fcLine = iFtrWs.OpenFeatureClass("NHD_Flowline");
                IFeatureClass fcPoint = iFtrWs.OpenFeatureClass("Hydro_Net_Junctions");
                System.Diagnostics.Debug.Assert(null != fcLine && null != fcPoint);

                var fldLst = new List<string>{"OBJECTID","FlowDir","FTYPE","V0001E_MA","V0001E_MM","V0001E_01","V0001E_02","V0001E_03","V0001E_04","V0001E_05","V0001E_06","V0001E_07","V0001E_08","V0001E_09","V0001E_10","V0001E_11","V0001E_12"};
                Dictionary<string,int> fldDict = new Dictionary<string,int>();
                fldLst.ForEach(fldName => fldDict.Add(fldName, fcLine.FindField(fldName)));

                int lineFtrId = -1;
                //Find field index for oid in Hydro_Net_Junctions feature class
                int pntFtrIdIdx = fcPoint.FindField("OBJECTID");
                string pntFtrId = null;

                /*
                 * It has been observed that the most time consuming part of this script is on spatial query.
                 * We could take the same approach we had on Arcpy through fcLine.Search() with a spatial filter.
                 * However, it will make us have the same granularity as using arcpy. 
                 * Instead, we took a different route here by using IFeatureIndex and IIndexQuery2
                 */ 
                IGeoDataset geoLineDS = (IGeoDataset)fcLine;
                ISpatialReference srLine = geoLineDS.SpatialReference;
                IFeatureIndex lineIdx = new FeatureIndexClass();
                lineIdx.FeatureClass = fcLine;
                lineIdx.Index(null, geoLineDS.Extent);
                IIndexQuery2 queryLineByIdx = lineIdx as IIndexQuery2;

                IFeatureIndex pointIdx = new FeatureIndexClass();
                pointIdx.FeatureClass = fcPoint;
                pointIdx.Index(null, ((IGeoDataset)fcPoint).Extent);
                IIndexQuery2 queryPointByIdx = pointIdx as IIndexQuery2;

                //Get a cursor on Hydro_Net_Junctions as the iterator
                IFeatureCursor pntCur = fcPoint.Search(null, false);
                IFeature pnt = pntCur.NextFeature();
                IFeature line = null;
                IFeature otherPnt = null;
                List<string> requiredTypes = new List<string>{"StreamRiver","ArtificialPath"};
                /*
                 * ITopologicalOpeartor is good for two geometries comparing with each other. It doesn't fit
                 * very well for our situation, which check the geometric relationships between a geometry
                 * against a feature class that may have more than 100K geometries.
                */ 
                //ITopologicalOperator optor = null;

                /*
                 * It's a shame that we have to reference to a Server API in order to calcuate Geodesic
                 * distances for a polyline with lon/lat as coordinates.
                 * 
                 * We could do Haversine ourselves, but we have to believe ESRI could definitely does a 
                 * better job there, well, hard to figure out how to get this simple task done in an intutive
                 * way though...
                 */ 
                IGeometryServer2 geoOperator = new GeometryServerClass();
                
                IPolyline polyLine = null;
                List<DownstreamNode> dsLst = null;
                int[] lineIds = null;
                int[] pntIds = null;
                object idobjs;
                object idobjs1;
                PolylineArray tmpArr = null;
                IDoubleArray lengths = null;
                double lineLen = 0.0;
                double v = 0.0;
                ILinearUnit unit = new LinearUnitClass();
                var range = Enumerable.Range(3, 14);
                int count = 0;
                int incoming = 0;
                while(null != pnt)
                {
                    //get ftr id of the current vertex
                    pntFtrId = pnt.get_Value(pntFtrIdIdx).ToString();
                    //optor = pnt.Shape as ITopologicalOperator;
                    /*
                     * This should return feature ids that interects with the given geometry in the feature
                     * class having the index built.
                     */ 
                    queryLineByIdx.IntersectedFeatures(pnt.Shape, out idobjs);
                    lineIds = idobjs as int[];
                    if(null != lineIds && lineIds.Length > 0)
                    {
                        foreach(int id in lineIds)
                        {
                            line = fcLine.GetFeature(id);
                            lineFtrId = int.Parse(line.get_Value(fldDict["OBJECTID"]).ToString());
                            if ("1" == line.get_Value(fldDict["FlowDir"]).ToString() && true == requiredTypes.Contains(line.get_Value(fldDict["FTYPE"]).ToString()))
                            {
                                polyLine = line.Shape as IPolyline;
                                if(isSamePoint(polyLine.FromPoint, pnt.Shape as IPoint))
                                {
                                    queryPointByIdx.IntersectedFeatures(line.Shape, out idobjs1);
                                    pntIds = idobjs1 as int[];
                                    if(null != pntIds && 2 == pntIds.Length)
                                    {
                                        foreach(int pid in pntIds)
                                        {
                                            otherPnt = fcPoint.GetFeature(pid);
                                            if(false == isSamePoint(otherPnt.Shape as IPoint, pnt.Shape as IPoint))
                                            {
                                                tmpArr = new PolylineArrayClass();
                                                tmpArr.Add(polyLine);
                                                lengths = geoOperator.GetLengthsGeodesic(srLine, tmpArr as IPolylineArray, unit);
                                                if (0 == lengths.Count)
                                                    continue;
                                                lineLen = lengths.get_Element(0) * 3.28084;
                                                //var velos = from idx in range select double.Parse(line.get_Value(fldDict[fldLst[idx]]).ToString());
                                                List<double> velos = new List<double>();
                                                foreach(int idx in range)
                                                {
                                                    v = double.Parse(line.get_Value(fldDict[fldLst[idx]]).ToString());
                                                    velos.Add(v == 0 ? 0 : lineLen / v);
                                                }
                                                if (null == dsLst)
                                                    dsLst = new List<DownstreamNode>();
                                                dsLst.Add(new DownstreamNode(pid, id, velos));
                                             }
                                        }
                                    }
                                }
                                else // pnt at the end of the polyline
                                    ++incoming;
                            }
                        }
                    }
                    if(null != dsLst || incoming > 0)
                        nodeDict.Add(pntFtrId, new Vertex(int.Parse(pntFtrId), incoming, dsLst));
                    pnt = pntCur.NextFeature();
                    if (++count % 1000 == 0)
                        Console.WriteLine("Processing Count: " + count);
                    incoming = 0;
                    dsLst = null;
                }//end of while(null != pnt)
                ReleaseCOMObj(pntCur);
            }
            ReleaseCOMObj(workspaceFactory);
            //ESRI License Initializer generated code.
            //Do not make any call to ArcObjects after ShutDownApplication()
            m_AOLicenseInitializer.ShutdownApplication();
        }
Ejemplo n.º 5
0
        //将任意坐标系统转换为自定义Albers大地坐标(米)
        public static IPoint GeoToGra(IPoint point)
        {
            IPoint pt = new PointClass();

            pt.PutCoords(point.X, point.Y);

            ISpatialReferenceFactory2 pFact = new SpatialReferenceEnvironmentClass();

            //定义地理坐标,由输入的对象决定,也可以自己定义,参考: esriSRGeoCSType
            IGeographicCoordinateSystem pGCS = new GeographicCoordinateSystemClass();

            pGCS = pFact.CreateGeographicCoordinateSystem(point.SpatialReference.FactoryCode);

            //自定义投影方式
            IProjectedCoordinateSystem     pProjectedCS     = new ProjectedCoordinateSystemClass();
            IProjectedCoordinateSystemEdit pProjectedCSEdit = pProjectedCS as IProjectedCoordinateSystemEdit;

            //定义投影方式,参考: esriSRProjectionType
            IProjection pProjection = new ProjectionClass();

            pProjection = pFact.CreateProjection((int)esriSRProjectionType.esriSRProjection_Albers);

            //定义投影单位,参考:esriSRUnitType
            ILinearUnit pUnit = new LinearUnitClass();

            pUnit = pFact.CreateUnit((int)esriSRUnitType.esriSRUnit_Meter) as ILinearUnit;

            //定义其他参数,参考:esriSRParameterType
            IParameter[] pParm = new IParameter[6];
            pParm[0]       = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_FalseEasting);
            pParm[0].Value = 0;

            pParm[1]       = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_FalseNorthing);
            pParm[1].Value = 0;

            pParm[2]       = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_CentralMeridian);
            pParm[2].Value = 110;

            pParm[3]       = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_StandardParallel1);
            pParm[3].Value = 25;

            pParm[4]       = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_StandardParallel2);
            pParm[4].Value = 47;

            pParm[5]       = pFact.CreateParameter((int)esriSRParameterType.esriSRParameter_LatitudeOfOrigin);
            pParm[5].Value = 0;

            //设置投影相关信息
            object name          = "User_Defined_Albers";
            object alias         = "Albers";
            object abbreviation  = "Albers";
            object remarks       = "User_Defined_Albers is the projection";
            object usage         = "";
            object gcs           = pGCS;
            object projectedUnit = pUnit;
            object projection    = pProjection;
            object parameters    = pParm;

            pProjectedCSEdit.Define(ref name, ref alias, ref abbreviation, ref remarks, ref usage, ref gcs, ref projectedUnit, ref projection, ref parameters);

            //获取自定义空间参考
            ISpatialReference pSpatialRef = pProjectedCS as ISpatialReference;

            IGeometry pGeometry = (IGeometry)pt;

            pGeometry.SpatialReference = pGCS as ISpatialReference;

            //重投影处理
            pGeometry.Project(pSpatialRef);

            return(pt);
        }