#include "stdafx.h" #include "GeoInfoCalculate.h" // 加载 地理信息计算dll #include "MapPrj.h" #pragma comment( lib, "MapPrj.lib" ) // 系统级几何校正文件夹 #include "SysGeoCorrect.h" //功能:计算(几何校正后)图像中两点间的距离和方位 //输入: 1. img 图像数据结构体指针 // 2. pt1 起点(像素坐标) // 3. pt2 终点(像素坐标) //输出: 1. distance 距离 // 2. azAngle 方位,起点点到终点 // 3. 返回值:计算有效返回true,否则返回false bool ImgStruCalTwoPtsDistanceAzimuth(double &distance, double &azAngle, const ImgStru* img, cv::Point pt1, cv::Point pt2) { try { // 基本条件验证 if (img == NULL || img->ImgWidth <= 0 || img->ImgHeight <= 0 || img->buff == NULL) { return false; } if (img->bitcount != 8 || img->bitcount != 24) { return false; } // 经纬度边界盒子 有效性验证 if(img->BoundingBox.WestLon < -180.0 || img->BoundingBox.EastLon > 180.0 || img->BoundingBox.EastLon - img->BoundingBox.WestLon < 0.0 || img->BoundingBox.NorthLat > 90.0 || img->BoundingBox.SouthLat < -90.0 || img->BoundingBox.NorthLat - img->BoundingBox.SouthLat < 0.0) { return false; } // pt1有效性验证 if (pt1.x < 0 || pt1.x > img->ImgWidth - 1 || pt1.y < 0 || pt1.y > img->ImgHeight - 1) { return false; } // pt2 有效性验证 if (pt2.x < 0 || pt2.x > img->ImgWidth - 1 || pt2.y < 0 || pt2.y > img->ImgHeight - 1) { return false; } double LatResolution = (img->BoundingBox.NorthLat - img->BoundingBox.SouthLat) / img->ImgHeight; double LonResolution = (img->BoundingBox.EastLon - img->BoundingBox.WestLon) / img->ImgWidth; double Lat1 = 0.0; double Lon1 = 0.0; double Lat2 = 0.0; double Lon2 = 0.0; Lat1 = img->BoundingBox.NorthLat - LatResolution * pt1.y; Lon1 = img->BoundingBox.WestLon + LonResolution * pt1.x; Lat2 = img->BoundingBox.NorthLat - LatResolution * pt2.y; Lon2 = img->BoundingBox.WestLon + LonResolution * pt2.x; CalculateTwoPtsDistanceAzimuth(distance, azAngle, Lon1 , Lat1, Lon2, Lat2,1); return true; } catch(cv::Exception &e) { e.msg; return false; } catch(...) { return false; } } //功能:计算图像(几何校正后)中一点的经纬度 //输入: 1. img 图像数据结构体指针 // 2. point 输入点(像素坐标) //输出: 1. PtLatLon 输入点的经纬度坐标 // 2. 返回值:计算有效返回true,否则返回false bool ImgStruCalOnePtLonLat(GeoCoordinatePoint& PtLatLon, const ImgStru* img, cv::Point point) { try { // 基本条件验证 if (img == NULL || img->ImgWidth <= 0 || img->ImgHeight <= 0 || img->buff == NULL) { return false; } if (img->bitcount != 8 || img->bitcount != 24) { return false; } // 经纬度边界盒子 有效性验证 if(img->BoundingBox.WestLon < -180.0 || img->BoundingBox.EastLon > 180.0 || img->BoundingBox.EastLon - img->BoundingBox.WestLon < 0.0 || img->BoundingBox.NorthLat > 90.0 || img->BoundingBox.SouthLat < -90.0 || img->BoundingBox.NorthLat - img->BoundingBox.SouthLat < 0.0) { return false; } // point有效性验证 if (point.x < 0 || point.x > img->ImgWidth - 1 || point.y < 0 || point.y > img->ImgHeight - 1) { return false; } double LatResolution = (img->BoundingBox.NorthLat - img->BoundingBox.SouthLat) / img->ImgHeight; double LonResolution = (img->BoundingBox.EastLon - img->BoundingBox.WestLon) / img->ImgWidth; PtLatLon.Latitude = img->BoundingBox.NorthLat - LatResolution * point.y; PtLatLon.Longitude = img->BoundingBox.WestLon + LonResolution * point.x; return true; } catch(cv::Exception &e) { e.msg; return false; } catch(...) { return false; } } // 情报通用结构体 计算图像中两点间的距离和方位 //功能:计算图像中两点间的距离和方位 //输入: 1. qbData 通用情报数据结构体 // 2. pt1 起点(像素坐标) // 3. pt2 终点(像素坐标) // 4. flags:flags = 0:标识pt1、pt2为几何校正前图像中的点 // flags = 1:标识pt1、pt2为几何校正后图像中的点 //输出: 1. distance 距离 // 2. azAngle 方位,起点点到终点 // 3. 返回值:计算有效返回true,否则返回false bool QBStruCalTwoPtsDistanceAzimuth(double &distance, double &azAngle, const QBStru *qbData, cv::Point pt1, cv::Point pt2, int flags) { try { // 空指针判断 if (qbData == NULL) { return false; } // 图像数据有效 if (qbData->image.bValid == false) { return false; } // 几何校正前 if (flags == 0) { // 复接数据有效性 if (qbData->framePart.bValid == false) { return false; } else { return CalTwoPointsDistanceAzimuth(distance, azAngle, &qbData->framePart, pt1, pt2); } } else if (flags == 1) // 几何校正后 { return ImgStruCalTwoPtsDistanceAzimuth(distance, azAngle, &qbData->image.geoImg, pt1, pt2); } else { return false; } } catch(cv::Exception &e) { e.msg; return false; } catch(...) { return false; } } //功能:基于复接数据计算几何校正前图像中两点间的距离和方位 bool CalTwoPointsDistanceAzimuth(double &distance, double &azAngle, const struQB_FJ *frameData, cv::Point pt1, cv::Point pt2) { try { bool retPoint1 = false; bool retPoint2 = false; double fromLon = 0.0; double fromLat = 0.0; double fromH = 0.0; double toLon = 0.0; double toLat = 0.0; double toH = 0.0; retPoint1 = CalAnyPtCoordinate(fromLon, fromLat, fromH, frameData, int(pt1.x), int(pt1.y)); retPoint2 = CalAnyPtCoordinate(toLon, toLat, toH, frameData, int(pt2.x), int(pt2.y)); if (retPoint1 == true && retPoint2 == true) { // 计算两点间的距离和方位 郭新平 CalculateTwoPtsDistanceAzimuth(distance, azAngle, fromLon, fromLat, toLon, toLat, 1); } else { return false; } return true; } catch(cv::Exception &e) { e.msg; return false; } catch(...) { return false; } } //功能:计算图像中多点组成的多边形面积 //输入: 1. qbData 通用情报数据结构体 // 2. points 指向点坐标的指针 // 3. count: 点数目 // 4. flags:flags = 0:标识points为几何校正前图像中的点 // flags = 1:标识points为几何校正后图像中的点 //输出: 1. area :多边形面积 // 2. 返回值:计算有效返回true,否则返回false bool QBStruCalPolygonArea(double& area, const QBStru *qbData, cv::Point* points, int count, int flags) { try { if (qbData == NULL) { return false; } // 返回值 bool ret = false; // 图像数据有效 if (qbData->image.bValid == false) { return false; } // 基本条件判断 if (points == NULL || count <= 2) { return false; } // 几何校正前 if (flags == 0) { return CalPolygonArea(area, &qbData->framePart, points, count); } else if (flags == 1) // 几何校正后 { GeoCoordinatePoint* GeoPoints = NULL; GeoPoints = new GeoCoordinatePoint[count]; if (GeoPoints != NULL) { // 计算每个点对应的经纬度坐标 for(int i = 0; i < count; i++) { // 几何校正后 计算 if (ImgStruCalOnePtLonLat(GeoPoints[i], &qbData->image.geoImg, points[i]) == false) { return false; } } // 计算各个经纬度坐标组成的点构成的多边形面积 bool ret = false; ret = CalPolygonArea(area, GeoPoints, count); // 释放内存 delete [] GeoPoints; GeoPoints = NULL; return ret; } else { return false; } } else { return false; } return true; } catch(cv::Exception &e) { e.msg; return false; } catch(...) { return false; } } //功能:计算图像中多点组成的多边形面积 //输入: 1. frameData 复接数据 // 2. points 指向点坐标的指针 // 3. count: 点数目 //输出: 1. area :多边形面积 // 2. 返回值:计算有效返回true,否则返回false bool CalPolygonArea(double& area, const struQB_FJ *frameData, cv::Point* points, int count) { try { // 计算几何校正前的一点对应的经纬度坐标 GeoCoordinatePoint* GeoPoints = NULL; GeoPoints = new GeoCoordinatePoint[count]; if (GeoPoints != NULL) { // 计算每个点对应的经纬度坐标 for(int i = 0; i < count; i++) { double Hi = 0.0; // 几何校正前 计算 if (CalAnyPtCoordinate(GeoPoints[i].Longitude,GeoPoints[i].Latitude, Hi, frameData, int(points[i].x), int(points[i].y)) == false) { return false; } } // 计算各个经纬度坐标组成的点构成的多边形面积 bool ret = false; ret = CalPolygonArea(area, GeoPoints, count); // 释放内存 delete [] GeoPoints; GeoPoints = NULL; return ret; } else { return false; } } catch(cv::Exception &e) { e.msg; return false; } catch(...) { return false; } } // 功能:计算由一组经纬度点构成的多边形面积 // 输入: 1. points 指向多个经纬度坐标组的指针 // 2. count 点数目 //输出: 1. area 面积 // 2. 返回值:计算有效返回true,否则返回false bool CalPolygonArea(double& area, GeoCoordinatePoint* points, int count) { try { // 基本条件判断 if (points == NULL || count <= 2) { return false; } // 先判断第一个点,值域范围是否越界 if (points[0].Latitude < -90.0 || points[0].Latitude > 90.0 || points[0].Longitude < -180.0 || points[0].Longitude > 180.0) { return false; } cv::Point2f* CorPoint = NULL; CorPoint = new cv::Point2f[count]; if (CorPoint != NULL) { // 以第一个为基准(0,0) CorPoint[0].x = 0; CorPoint[0].y = 0; for(int i = 1; i < count; i++) { if (points[i].Latitude < -90.0 || points[i].Latitude > 90.0 || points[i].Longitude < -180.0 || points[i].Longitude > 180.0) { return false; } else { double distance = 0.0; // 距离 double azAngle = 0.0; // 方位 // 计算两点间的距离和方位 CalculateTwoPtsDistanceAzimuth(distance, azAngle, points[0].Longitude, points[0].Latitude, points[i].Longitude, points[i].Latitude, 1); azAngle = 90 - azAngle; // 计算相对坐标 CorPoint[i].x = static_cast(distance * cos(azAngle * 3.1415926536 / 180)); CorPoint[i].y = static_cast(distance * sin(azAngle * 3.1415926536 / 180)); } } // 计算面积 bool ret = false; ret = CalPolygonArea(area, CorPoint, count); // 释放分配内存 delete [] CorPoint; CorPoint = NULL; return ret; } else { return false; } return true; } catch(cv::Exception &e) { e.msg; return false; } catch(...) { return false; } } // 功能:计算由一组平面坐标点构成的多边形面积 // 输入: 1. points 指向多个点坐标组的指针 // 2. count 点数目 //输出: 1. area 面积 无单位 // 2. 返回值:计算有效返回true,否则返回false bool CalPolygonArea(double& area, cv::Point2f* points, int count) { try { if (points == NULL || count <= 2) { return false; } cv::Point2f* newPoints = NULL; newPoints = new cv::Point2f[count + 1]; if (newPoints != NULL) { int i = 0; for (i = 0; i < count; i++) { newPoints[i].x = points[i].x; newPoints[i].y = points[i].y; } newPoints[count].x = points[0].x; newPoints[count].y = points[0].y; // 多边形面积 area = 0.0; for (i = 0; i < count; i++) { area += newPoints[i].x * newPoints[i+1].y - newPoints[i+1].x * newPoints[i].y; } area = abs(area / 2.0); delete [] newPoints; newPoints = NULL; } else { return false; } return true; } catch(cv::Exception &e) { e.msg; return false; } catch(...) { return false; } }