You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

550 lines
11 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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. flagsflags = 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. flagsflags = 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<float>(distance * cos(azAngle * 3.1415926536 / 180));
CorPoint[i].y = static_cast<float>(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;
}
}