//行列号的三维坐标 public bool GetGeoXYZ(IRaster pRaster, double[,] dbData, Pt2i ptLeftTop, int nH, int nW, ref Pt3d ptXYZ) { ptXYZ = null; if (pRaster == null) { return(false); } IRasterProps pProps = pRaster as IRasterProps; IRaster2 pRaster2 = pRaster as IRaster2; //if( ( m_pGdalData == NULL )||( m_pGdalData->m_bIsGeoFile != true) ) //{ // return false; //} //CmlGeoRaster* pGeoRaster = (CmlGeoRaster*)m_pGdalData; ptXYZ = new Pt3d(); ptXYZ.X = pRaster2.ToMapX(nW); //m_nXOffSet + nW)*pGeoRaster->m_dXResolution + pGeoRaster->m_PtOrigin.X ; ptXYZ.Y = pRaster2.ToMapY(nH); // + nH)*pGeoRaster->m_dYResolution + pGeoRaster->m_PtOrigin.Y ; //pProps.NoDataValue.GetType(); double dbNoDataValue = getNoDataValue(pProps.NoDataValue);//Convert.ToDouble(((object[])pProps.NoDataValue)[0]); if ((true == GetDoubleVal(pRaster, dbData, ptLeftTop, nH, nW, ref ptXYZ.Z)) && (Math.Abs(ptXYZ.Z - dbNoDataValue) != 0)) { return(true); } else { return(false); } }
private Pt2d getProjectBackwardPoint(IPoint pGeoCoords, IRaster pDemRaster, ClsGetCameraView pGetCameraView, Matrix pRotateMatrix, ClsCameraPara cameraPara) { Pt3d ptFeaturePoint = new Pt3d(); ptFeaturePoint.X = pGeoCoords.X; ptFeaturePoint.Y = pGeoCoords.Y; //从DEM上得到相应高程 IRasterProps pDemRasterProps = pDemRaster as IRasterProps; double nGeoRange = pDemRasterProps.MeanCellSize().X * 10; Pt2i ptLeftTop = new Pt2i(); double[,] dbSubData = pGetCameraView.getSubDem(pDemRaster, ptFeaturePoint, nGeoRange, ref ptLeftTop); if (dbSubData == null) { return(null); } if (pGetCameraView.GetGeoZ(pDemRaster, dbSubData, ptLeftTop, ptFeaturePoint.X, ptFeaturePoint.Y, ref ptFeaturePoint.Z)) { Pt2d pt2d = new Pt2d(); double dbX, dbY, dbZ; Pt3d ptCurrentFeaturePoint = ptFeaturePoint; //判断是否在视场前方 if (!IsInCameraFrontArea(ptCurrentFeaturePoint, pRotateMatrix, cameraPara)) { return(null); } dbX = pRotateMatrix.getNum(0, 0) * (ptCurrentFeaturePoint.X - cameraPara.dX) + pRotateMatrix.getNum(1, 0) * (ptCurrentFeaturePoint.Y - cameraPara.dY) + pRotateMatrix.getNum(2, 0) * (ptCurrentFeaturePoint.Z - cameraPara.dZ); dbY = pRotateMatrix.getNum(0, 1) * (ptCurrentFeaturePoint.X - cameraPara.dX) + pRotateMatrix.getNum(1, 1) * (ptCurrentFeaturePoint.Y - cameraPara.dY) + pRotateMatrix.getNum(2, 1) * (ptCurrentFeaturePoint.Z - cameraPara.dZ); dbZ = pRotateMatrix.getNum(0, 2) * (ptCurrentFeaturePoint.X - cameraPara.dX) + pRotateMatrix.getNum(1, 2) * (ptCurrentFeaturePoint.Y - cameraPara.dY) + pRotateMatrix.getNum(2, 2) * (ptCurrentFeaturePoint.Z - cameraPara.dZ); Pt2d ptImageTmp = new Pt2d(); ptImageTmp.X = (int)Math.Round(-cameraPara.dFocus * dbX / dbZ); ptImageTmp.Y = (int)Math.Round(-cameraPara.dFocus * dbY / dbZ); //ptImageTmp.Y *= -1; //像主点坐标系===>笛卡尔坐标系(以东为X,以北为Y) ptImageTmp.X += cameraPara.dPx; ptImageTmp.Y += (-1 * cameraPara.dPy); //ptImageTmp.Y *= -1; //arcgis显示时把左上角放于原点 //ptImageTmp.Y -= cameraPara.nH; return(ptImageTmp); } return(null); }
//当前地理位置的高程 public bool GetGeoZ(IRaster pRaster, double[,] dbData, Pt2i ptLeftTop, double dX, double dY, ref double dZ) { dZ = double.NaN; if (pRaster == null) { return(false); } IRaster2 pRaster2 = pRaster as IRaster2; double dXCoord = pRaster2.ToPixelColumn(dX); // dX - pGeoRaster->m_PtOrigin.X ) / pGeoRaster->m_dXResolution ; double dYCoord = pRaster2.ToPixelRow(dY); // dY - pGeoRaster->m_PtOrigin.Y ) / pGeoRaster->m_dYResolution ; IRasterProps pProps = pRaster as IRasterProps; int nWidth = pProps.Width; int nHeight = pProps.Height; if ((dXCoord < 0) || (dXCoord > (nWidth - 1)) || (dYCoord < 0) || (dYCoord > (nHeight - 1))) { return(false); } Pt2i ptLT = new Pt2i(); Pt2i ptRT = new Pt2i(); Pt2i ptLB = new Pt2i(); Pt2i ptRB = new Pt2i(); ptLT.X = (int)Math.Floor(dXCoord); ptLT.Y = (int)Math.Floor(dYCoord); ptRT.X = ptLT.X + 1; ptRT.Y = ptLT.Y; ptLB.X = ptLT.X; ptLB.Y = ptLT.Y + 1; ptRB.X = ptRT.X; ptRB.Y = ptLB.Y; Pt3d ptZLT = new Pt3d(); Pt3d ptZRT = new Pt3d(); Pt3d ptZLB = new Pt3d(); Pt3d ptZRB = new Pt3d(); if (GetGeoXYZ(pRaster, dbData, ptLeftTop, ptLT.Y, ptLT.X, ref ptZLT) && GetGeoXYZ(pRaster, dbData, ptLeftTop, ptRT.Y, ptRT.X, ref ptZRT) && GetGeoXYZ(pRaster, dbData, ptLeftTop, ptLB.Y, ptLB.X, ref ptZLB) && GetGeoXYZ(pRaster, dbData, ptLeftTop, ptRB.Y, ptRB.X, ref ptZRB)) { dZ = (ptRB.X - dXCoord) * (ptRB.Y - dYCoord) * ptZLT.Z + (dXCoord - ptLT.X) * (ptRB.Y - dYCoord) * ptZRT.Z + (ptRB.X - dXCoord) * (dYCoord - ptLT.Y) * ptZLB.Z + (dXCoord - ptLT.X) * (dYCoord - ptLT.Y) * ptZRB.Z; return(true); } else { return(false); } }
// private void CopyFeatureField(IFeature pFt, IFeatureBuffer pFtNew) // { // object o = Type.Missing; // IFields pFlds = pFt.Fields; // IFields pFldsNew = pFtNew.Fields; // int nCount = pFlds.FieldCount; // for (int i = 0; i < nCount; i++) // { // if (pFlds.get_Field(i).Type != esriFieldType.esriFieldTypeGeometry && // pFlds.get_Field(i).Type != esriFieldType.esriFieldTypeOID) // { // object ob = pFt.get_Value(i); // if(!pFlds.get_Field(i).Editable) // continue; // // string szOb = ob as string; // if (szOb == null || string.IsNullOrEmpty(szOb)) // { // if (pFldsNew.get_Field(i).IsNullable) // { // pFtNew.set_Value(i, ob); // } // else // pFtNew.set_Value(i, o); // } // else // { // //if (pFldsNew.get_Field(i).IsNullable) // //{ // // pFtNew.set_Value(i, ob); // //} // // pFtNew.set_Value(i, ob); // } // } // } // } //public bool projectBackward(string szInputShpFilename, string szDemFilename, string szXmlFilename, string szOutShpFilename) //{ // if (string.IsNullOrEmpty(szInputShpFilename) || string.IsNullOrEmpty(szDemFilename) || string.IsNullOrEmpty(szXmlFilename) || string.IsNullOrEmpty(szOutShpFilename)) // return false; // ClsGDBDataCommon processDataCommon = new ClsGDBDataCommon(); // string strInputPath = System.IO.Path.GetDirectoryName(szInputShpFilename); // string strInputName = System.IO.Path.GetFileName(szInputShpFilename); // #region 读取SHP文件 // IWorkspace pWorkspace = processDataCommon.OpenFromShapefile(strInputPath); // IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace; // IFeatureClass pInputFC = pFeatureWorkspace.OpenFeatureClass(strInputName); // #endregion // #region 读取DEM文件 // IRasterLayer pRasterLayer = new RasterLayerClass(); // pRasterLayer.CreateFromFilePath(szDemFilename); // IRaster pDemRaster = pRasterLayer.Raster; // IRasterProps pDemRasterProps=pDemRaster as IRasterProps; // #endregion // #region 得到节点信息 // List<List<Pt3d>> ptFeaturePoints = new List<List<Pt3d>>(); // List<IFeature> pFeatureList=new List<IFeature>(); // IFeatureCursor pFCursor = pInputFC.Search(null, false); // IFeature pFeature = null;// pFCursor.NextFeature(); // while ((pFeature = pFCursor.NextFeature()) != null) // { // IPolyline pPolyline = pFeature.Shape as IPolyline; // if (pPolyline == null) // { // //pFeature = pFCursor.NextFeature(); // continue; // } // IPointCollection pPtCol = pPolyline as IPointCollection; // List<Pt3d> ptSingleFeaturePoints = new List<Pt3d>(); // int nGeoRange = Convert.ToInt32(pDemRasterProps.MeanCellSize().X * 10); // Pt2i ptLeftTop=new Pt2i(); // ClsGetCameraView getCameraView = new ClsGetCameraView(); // for (int i = 0; i < pPtCol.PointCount; i++) // { // IPoint pPt = pPtCol.get_Point(i); // Pt3d ptFeaturePoint = new Pt3d(); // ptFeaturePoint.X = pPt.X; // ptFeaturePoint.Y = pPt.Y; // //从DEM上得到相应高程 // double[,] dbSubData=getCameraView.getSubDem(pDemRaster, ptFeaturePoint, nGeoRange, ref ptLeftTop); // if (dbSubData == null) // continue; // if (getCameraView.GetGeoZ(pDemRaster, dbSubData, ptLeftTop, pPt.X, pPt.Y, ref ptFeaturePoint.Z)) // { // ptSingleFeaturePoints.Add(ptFeaturePoint); // } // } // IFeature pTmpFeature=pFeature; // pFeatureList.Add(pTmpFeature); // ptFeaturePoints.Add(ptSingleFeaturePoints); // //pFeature = pFCursor.NextFeature(); // } // #endregion // #region 读取相机姿态参数 // ClsCameraPara cameraPara = ParseXmlFileToGetPara(szXmlFilename); // if (cameraPara == null) // return false; // //根据姿态参数获得旋转矩阵 // OriAngle oriAngle = new OriAngle(); // Matrix pRotateMatrix = new Matrix(3, 3); // oriAngle.kap = cameraPara.dKappa; // oriAngle.omg = cameraPara.dOmg; // oriAngle.phi = cameraPara.dPhi; // if (!ClsGetCameraView.OPK2RMat(oriAngle, ref pRotateMatrix)) // return false; // #endregion // #region 创建输出SHP文件 // string strOutputPath = System.IO.Path.GetDirectoryName(szOutShpFilename); // string strOutputName = System.IO.Path.GetFileName(szOutShpFilename); // IFields pFields = pInputFC.Fields; // //设置空间参考 // ISpatialReference pSpatialRef = new UnknownCoordinateSystemClass();//没有这一句就报错,说尝试读取或写入受保护的内存。 // pSpatialRef.SetDomain(-8000000, 8000000, -8000000, 8000000);//没有这句就抛异常来自HRESULT:0x8004120E。 // pSpatialRef.SetZDomain(-8000000, 8000000); // IFeatureClass pOutputFC = processDataCommon.CreateShapefile(strOutputPath, strOutputName, pFields, pSpatialRef); // if (pOutputFC == null) // { // return false; // } // #endregion // #region 节点位置反投影 // List<List<Pt2d>> ptImageFeaturePoints = new List<List<Pt2d>>(); // for (int i = 0; i < ptFeaturePoints.Count; i++) // { // int nCount = ptFeaturePoints[i].Count; // List<Pt2d> ptSingleImageFeaturePoints = new List<Pt2d>(); // for (int j = 0; j < nCount; j++) // { // Pt3d ptCurrentFeaturePoint = ptFeaturePoints[i][j]; // double dbX, dbY, dbZ; // dbX = pRotateMatrix.getNum(0, 0) * (ptCurrentFeaturePoint.X - cameraPara.dX) + pRotateMatrix.getNum(1, 0) * (ptCurrentFeaturePoint.Y - cameraPara.dY) // + pRotateMatrix.getNum(2, 0) * (ptCurrentFeaturePoint.Z - cameraPara.dZ); // dbY = pRotateMatrix.getNum(0, 1) * (ptCurrentFeaturePoint.X - cameraPara.dX) + pRotateMatrix.getNum(1, 1) * (ptCurrentFeaturePoint.Y - cameraPara.dY) // + pRotateMatrix.getNum(2, 1) * (ptCurrentFeaturePoint.Z - cameraPara.dZ); // dbZ = pRotateMatrix.getNum(0, 2) * (ptCurrentFeaturePoint.X - cameraPara.dX) + pRotateMatrix.getNum(1, 2) * (ptCurrentFeaturePoint.Y - cameraPara.dY) // + pRotateMatrix.getNum(2, 2) * (ptCurrentFeaturePoint.Z - cameraPara.dZ); // Pt2d ptImageTmp = new Pt2d(); // ptImageTmp.X = (int)Math.Round(-cameraPara.dFocus * dbX / dbZ); // ptImageTmp.Y = (int)Math.Round(-cameraPara.dFocus * dbY / dbZ); // //ptImageTmp.Y *= -1; // ptImageTmp.X += 512; // ptImageTmp.Y += 512; // ptImageTmp.Y -= 1024; // ptSingleImageFeaturePoints.Add(ptImageTmp); // } // ptImageFeaturePoints.Add(ptSingleImageFeaturePoints); // } // #endregion // #region 写入节点信息 // IDataset dataset = (IDataset)pOutputFC; // IWorkspace workspace = dataset.Workspace; // //Cast for an IWorkspaceEdit // IWorkspaceEdit workspaceEdit = workspace as IWorkspaceEdit; // workspaceEdit.StartEditing(true); // workspaceEdit.StartEditOperation(); // IFeatureCursor pOutFCursor = null; // ////////////////////////////////////////////////////////////////////////// // for (int i = 0; i < ptImageFeaturePoints.Count; i++) // { // int nPtsCount = ptImageFeaturePoints[i].Count; // IFeatureBuffer pFeatureBuffer = pOutputFC.CreateFeatureBuffer(); // pOutFCursor = pOutputFC.Insert(true); // IPolyline pPolyline = new PolylineClass(); // IPointCollection pPointCollection = pPolyline as IPointCollection; // for (int j = 0; j < nPtsCount; j++) // { // IPoint pt = new PointClass(); // pt.PutCoords(ptImageFeaturePoints[i][j].X, ptImageFeaturePoints[i][j].Y); // pPointCollection.AddPoint(pt); // } // CopyFeatureField(pFeatureList[i],pFeatureBuffer); // pFeatureBuffer.Shape = pPolyline as IGeometry; // object featureOID = pOutFCursor.InsertFeature(pFeatureBuffer); // } // pOutFCursor.Flush(); // //featureCursor.Flush(); // workspaceEdit.StopEditOperation(); // workspaceEdit.StopEditing(true); // #endregion // return true; //} private bool IsInCameraFrontArea(Pt3d ptObj, Matrix pRotateMatrix, ClsCameraPara cameraPara) { ////判断当前路径点是否在相机的可视范围内 视场角范围(-90, 90),即在相平面的前方 double dbCameraX = cameraPara.dX; double dbCameraY = cameraPara.dY; double dbCameraZ = cameraPara.dZ; double dbDeltaY = ptObj.Y - dbCameraY; double dbDeltaX = ptObj.X - dbCameraX; double dbDeltaZ = ptObj.Z - dbCameraZ; //物方向量 Matrix matrixObjectToCamera = new Matrix(3, 1); matrixObjectToCamera.SetNum(0, 0, dbDeltaX); matrixObjectToCamera.SetNum(1, 0, dbDeltaY); matrixObjectToCamera.SetNum(2, 0, dbDeltaZ); //主点向量转到物方 Matrix matrixFocus = new Matrix(3, 1); matrixFocus.SetNum(0, 0, 0); matrixFocus.SetNum(1, 0, 0); matrixFocus.SetNum(2, 0, -1.0 * cameraPara.dFocus); Matrix matrixFocusToObject = pRotateMatrix.Mutiply(pRotateMatrix, matrixFocus); //点乘 double dbValue = matrixObjectToCamera.getNum(0, 0) * matrixFocusToObject.getNum(0, 0) + matrixObjectToCamera.getNum(1, 0) * matrixFocusToObject.getNum(1, 0) + matrixObjectToCamera.getNum(2, 0) * matrixFocusToObject.getNum(2, 0); return(dbValue > 0); //try //{ // //计算以东朝向为准的方位角 [0, 2*PI] // // 返回结果: // // 角度 θ,以弧度为单位,满足 -π≤θ≤π,且 tan(θ) = y / x,其中 (x, y) 是笛卡尔平面中的一个点。请看下面:如果 (x, // // y) 在第 1 象限,则 0 < θ < π/2。如果 (x, y) 在第 2 象限,则 π/2 < θ≤π。如果 (x, y) 在第 3 象限,则 // // -π < θ < -π/2。如果 (x, y) 在第 4 象限,则 -π/2 < θ < 0。如果点在象限的边界上,则返回值如下:如果 y 为 0 // // 并且 x 不为负值,则 θ = 0。如果 y 为 0 并且 x 为负值,则 θ = π。如果 y 为正值并且 x 为 0,则 θ = π/2。如果 // // y 负值并且 x 为 0,则 θ = -π/2。 // double dbAzimuth = Math.Atan2(dbDeltaY, dbDeltaX); // if (dbDeltaY < 0) //第三第四象限 // dbAzimuth += (2 * Math.PI); // //KAPPA+PI/2的原因:相机方位以北为0度,逆时针增加;而方位角以东为0度,逆时针增加,两者恒差90 // double dbDeltaAngle = Math.Abs(dbAzimuth - (cameraPara.dKappa + Math.PI / 2)); // if (dbDeltaAngle > (Math.PI / 2)) // return null; //} //catch (System.Exception ex) //{ // return null; //} }
public OriAngle ori; //!<外方位角元素 public ExOriPara() { pos = new Pt3d(); ori = new OriAngle(); }
public double[,] getSubDem(IRaster pSrcRaster, Pt3d ptCenter, double nGeoRange, ref Pt2i ptImageTopLeft) { //IRaster pDstRaster = null; if (pSrcRaster == null) { return(null); } IRasterProps pProps = pSrcRaster as IRasterProps; IEnvelope pEnvelop = pProps.Extent; Pt2d[] ptRange = new Pt2d[4]; for (int i = 0; i < 4; i++) { ptRange[i] = new Pt2d(); } ptRange[0].X = ptCenter.X - nGeoRange; //lefttop ptRange[0].X = Math.Max(ptRange[0].X, pEnvelop.UpperLeft.X); ptRange[0].Y = ptCenter.Y + nGeoRange; ptRange[0].Y = Math.Min(ptRange[0].Y, pEnvelop.UpperLeft.Y); ptRange[1].X = ptCenter.X + nGeoRange; //righttop ptRange[1].Y = ptCenter.Y + nGeoRange; ptRange[1].X = Math.Min(ptRange[1].X, pEnvelop.UpperRight.X); ptRange[1].Y = Math.Min(ptRange[1].Y, pEnvelop.UpperRight.Y); ptRange[2].X = ptCenter.X - nGeoRange; //leftbottom ptRange[2].Y = ptCenter.Y - nGeoRange; ptRange[2].X = Math.Max(ptRange[2].X, pEnvelop.LowerLeft.X); ptRange[2].Y = Math.Max(ptRange[2].Y, pEnvelop.LowerLeft.Y); ptRange[3].X = ptCenter.X + nGeoRange; //rightbottom ptRange[3].Y = ptCenter.Y - nGeoRange; ptRange[3].X = Math.Min(ptRange[3].X, pEnvelop.LowerRight.X); ptRange[3].Y = Math.Max(ptRange[3].Y, pEnvelop.LowerRight.Y); Pt2i[] ptImageRange = new Pt2i[4]; for (int i = 0; i < 4; i++) { ptImageRange[i] = new Pt2i(); } IRaster2 pRaster2 = pSrcRaster as IRaster2; ptImageRange[0].X = pRaster2.ToPixelColumn(ptRange[0].X); ptImageRange[0].Y = pRaster2.ToPixelRow(ptRange[0].Y); ptImageRange[1].X = pRaster2.ToPixelColumn(ptRange[1].X); ptImageRange[1].Y = pRaster2.ToPixelRow(ptRange[1].Y); ptImageRange[2].X = pRaster2.ToPixelColumn(ptRange[2].X); ptImageRange[2].Y = pRaster2.ToPixelRow(ptRange[2].Y); ptImageRange[3].X = pRaster2.ToPixelColumn(ptRange[3].X); ptImageRange[3].Y = pRaster2.ToPixelRow(ptRange[3].Y); ptImageTopLeft.X = Math.Min(Math.Min(Math.Min(ptImageRange[0].X, ptImageRange[1].X), ptImageRange[2].X), ptImageRange[3].X); ptImageTopLeft.Y = Math.Min(Math.Min(Math.Min(ptImageRange[0].Y, ptImageRange[1].Y), ptImageRange[2].Y), ptImageRange[3].Y); int[] nSize = new int[2]; nSize[0] = Math.Max(Math.Max(Math.Max(ptImageRange[0].X, ptImageRange[1].X), ptImageRange[2].X), ptImageRange[3].X) - ptImageTopLeft.X; nSize[1] = Math.Max(Math.Max(Math.Max(ptImageRange[0].Y, ptImageRange[1].Y), ptImageRange[2].Y), ptImageRange[3].Y) - ptImageTopLeft.Y; double[,] dbData = new double[nSize[0], nSize[1]]; Point2D ptLeftTop = new Point2D(); ptLeftTop.X = ptImageTopLeft.X; ptLeftTop.Y = ptImageTopLeft.Y; //double[,] dbData = new double[pProps.Width,pProps.Height]; //Point2D ptLeftTop = new Point2D(); //ptImageTopLeft.X = pRaster2.ToPixelColumn(pEnvelop.UpperLeft.X); //(int)pEnvelop.UpperLeft.X; //ptImageTopLeft.Y = pRaster2.ToPixelRow(pEnvelop.UpperLeft.Y); //(int)pEnvelop.UpperLeft.X;//(int)pEnvelop.UpperLeft.Y; //ptLeftTop.X = ptImageTopLeft.X;// pEnvelop.UpperLeft.X; //ptLeftTop.Y = ptImageTopLeft.Y;// pEnvelop.UpperLeft.Y; readBlockDataToFile(ptLeftTop, ref dbData, pSrcRaster); return(dbData); }