|
|
#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<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;
|
|
|
}
|
|
|
}
|
|
|
|