UE4.26 集成Proj4
vcpkg 编译 Proj4
- 安装proj4
.\vcpkg.exe install proj4:x64-windows
2. 导出proj4
.\vcpkg.exe export proj4:x64-windows --7zip
UE4 集成
proj4.build.cs
- 设置包含头文件
- 设置连接库
- 设置DLL依赖拷贝
- 设置相关资源拷贝
using System.IO;
using UnrealBuildTool;
using System.Collections.Generic;
public class PROJ : ModuleRules
{
public PROJ(ReadOnlyTargetRules Target) : base(Target)
{
Type = ModuleType.External;
bEnableExceptions = true;
string VcPkgInstalled = "vcpkg-installed";
if (Target.Platform == UnrealTargetPlatform.Win64)
{
// add include
PublicSystemIncludePaths.Add(Path.Combine(ModuleDirectory, VcPkgInstalled, "overlay-x64-windows", "include"));
// add lib
string LibPath = Path.Combine(ModuleDirectory, VcPkgInstalled, "overlay-x64-windows", "lib");
PublicAdditionalLibraries.Add(Path.Combine(LibPath, "proj.lib"));
PublicAdditionalLibraries.Add(Path.Combine(LibPath, "sqlite3.lib"));
// add dll
List<string> RuntimeModuleNames = new List<string>();
RuntimeModuleNames.Add("jpeg62.dll");
RuntimeModuleNames.Add("libcurl.dll");
RuntimeModuleNames.Add("lzma.dll");
RuntimeModuleNames.Add("proj.dll");
RuntimeModuleNames.Add("sqlite3.dll");
RuntimeModuleNames.Add("tiff.dll");
RuntimeModuleNames.Add("turbojpeg.dll");
RuntimeModuleNames.Add("zlib1.dll");
string ProjRedistFolder = Path.Combine(ModuleDirectory, VcPkgInstalled, "overlay-x64-windows", "bin");
foreach (string RuntimeModuleName in RuntimeModuleNames)
{
string ModulePath = Path.Combine(ProjRedistFolder, RuntimeModuleName);
if (!File.Exists(ModulePath))
{
string Err = string.Format("proj module '{0}' not found.", ModulePath);
System.Console.WriteLine(Err);
throw new BuildException(Err);
}
RuntimeDependencies.Add("$(BinaryOutputDir)/" + RuntimeModuleName, ModulePath);
}
// Copy share/proj4
// Stage Proj data files Copy
string ProjShareFolder = Path.Combine(ModuleDirectory, VcPkgInstalled, "overlay-x64-windows", "share");
RuntimeDependencies.Add("$(PluginDir)/Resources/PROJ/*", Path.Combine(ProjShareFolder, "proj4/*"), StagedFileType.SystemNonUFS);
}
}
}
Usage
- 初始化
FString BaseDir;
BaseDir = IPluginManager::Get().FindPlugin("XXXX")->GetBaseDir();
// Add on the relative location of the third party dll and load it
FString ProjDataPathPath;
ProjDataPathPath = FPaths::Combine(*BaseDir, TEXT("Resources/PROJ"));
PJ_CONTEXT* ProjContext=proj_context_create();
FTCHARToUTF8 Convert(*ProjDataPathPath);
const ANSICHAR* Temp = Convert.Get();
proj_context_set_search_paths(ProjContext, 1, &Temp);
- 投影坐标转地理坐标(经纬度)
PJ* GetPROJProjection(FString SourceCRS, FString DestinationCRS)
{
FTCHARToUTF8 ConvertSource(*SourceCRS);
FTCHARToUTF8 ConvertDestination(*DestinationCRS);
const ANSICHAR* Source = ConvertSource.Get();
const ANSICHAR* Destination = ConvertDestination.Get();
PJ* TempPJ = proj_create_crs_to_crs(ProjContext, Source, Destination, nullptr);
if (TempPJ == nullptr)
{
int ErrorNumber = proj_context_errno(ProjContext);
FString ProjError = FString(proj_errno_string(ErrorNumber));
return nullptr;
}
/* This will ensure that the order of coordinates for the input CRS */
/* will be longitude, latitude, whereas EPSG:4326 mandates latitude, longitude */
PJ* P_for_GIS = proj_normalize_for_visualization(ProjContext, TempPJ);
if (P_for_GIS == nullptr)
{
int ErrorNumber = proj_context_errno(ProjContext);
FString ProjError = FString(proj_errno_string(ErrorNumber));
}
proj_destroy(TempPJ);
return P_for_GIS;
}
// Projected -> Geographic
PJ* ProjProjectedToGeographic =GetPROJProjection("EPSG:32617", "EPSG:4326");
void ProjectedToGeographic(const FCartesianCoordinates& ProjectedCoordinates, FGeographicCoordinates& GeographicCoordinates)
{
PJ_COORD input, output;
input = proj_coord(ProjectedCoordinates.X, ProjectedCoordinates.Y, ProjectedCoordinates.Z, 0);
output = proj_trans(ProjProjectedToGeographic, PJ_FWD, input);
GeographicCoordinates.Latitude = output.lpz.phi;
GeographicCoordinates.Longitude = output.lpz.lam;
GeographicCoordinates.Altitude = output.lpz.z;
}
- destroy
proj_destroy(ProjProjectedToGeographic);