Boost.Geometry processed patch https://svn.boost.org/trac/boost/ticket/6166 for missing transformation

[SVN r77108]
This commit is contained in:
Barend Gehrels 2012-02-24 15:36:23 +00:00
parent 7372dfa3a4
commit 13495b06fc
8 changed files with 370 additions and 2 deletions

View File

@ -28,6 +28,9 @@ We also thank all people who discussed on the mailing lists (either at boost,
or at osgeo) about __boost_geometry__, in preview stage, or in review stage,
or after that.
Furthermore we are thankful to people supplying patches: Arnold Metselaar,
Aleksey Tulinov, Christophe Henry
Finally I (Barend) would like to thank my former employer, Geodan. They
allowed me to start a geographic library in 1995, which after a number of
incarnations, redesigns, refactorings, previews, a review and even more

View File

@ -25,7 +25,8 @@
* [@https://svn.boost.org/trac/boost/ticket/6585 6585] patch for alternative syntax multipoint, applied
* [@https://svn.boost.org/trac/boost/ticket/6584 6584] patch for bug in distance, applied
* [@https://svn.boost.org/trac/boost/ticket/5730 5730] same issue as 6584, fixed
* [@https://svn.boost.org/trac/boost/ticket/6166 6166] patch for missing transformation, applied
[*Additional functionality]

View File

@ -23,7 +23,9 @@
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/strategies/transform.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
@ -251,6 +253,23 @@ namespace detail
return false;
}
template <typename P, typename T>
inline bool cartesian_to_spherical_equatorial3(T x, T y, T z, P& p)
{
assert_dimension<P, 3>();
// http://en.wikipedia.org/wiki/List_of_canonical_coordinate_transformations#From_Cartesian_coordinates
T const r = sqrt(x * x + y * y + z * z);
set<2>(p, r);
set_from_radian<0>(p, atan2(y, x));
if (r > 0.0)
{
set_from_radian<1>(p, asin(z / r));
return true;
}
return false;
}
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
@ -361,6 +380,16 @@ struct from_cartesian_3_to_spherical_polar_3
}
};
template <typename P1, typename P2>
struct from_cartesian_3_to_spherical_equatorial_3
{
inline bool apply(P1 const& p1, P2& p2) const
{
assert_dimension<P1, 3>();
return detail::cartesian_to_spherical_equatorial3(get<0>(p1), get<1>(p1), get<2>(p1), p2);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
@ -454,6 +483,11 @@ struct default_strategy<cartesian_tag, spherical_polar_tag, CoordSys1, CoordSys2
{
typedef from_cartesian_3_to_spherical_polar_3<P1, P2> type;
};
template <typename CoordSys1, typename CoordSys2, typename P1, typename P2>
struct default_strategy<cartesian_tag, spherical_equatorial_tag, CoordSys1, CoordSys2, 3, 3, P1, P2>
{
typedef from_cartesian_3_to_spherical_equatorial_3<P1, P2> type;
};
} // namespace services

View File

@ -293,7 +293,7 @@ static std::string case_100_multi[2] =
{
// for intersection
"MULTIPOLYGON(((0 0,0 1,1 0,0 0)),((2 2,2 1,0 1,0 2,1 2,2 3,2 2)))",
"MULTIPOLYGON(((1 1,1 2,2 2,2 1,1 1)),((1 2,0 1,0 3,1 4,1 2))))"
"MULTIPOLYGON(((1 1,1 2,2 2,2 1,1 1)),((1 2,0 1,0 3,1 4,1 2)))"
};
static std::string case_101_multi[2] =

View File

@ -15,6 +15,7 @@ test-suite boost-geometry-strategies
[ run projected_point.cpp ]
[ run pythagoras.cpp ]
[ run spherical_side.cpp ]
[ run transform_cs.cpp ]
[ run transformer.cpp ]
[ run within.cpp ]
;

View File

@ -18,6 +18,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spherical_side", "spherical
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "within", "within.vcproj", "{AB13D2AC-FD34-4DE4-BD8E-4D463050E5DD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "transform_cs", "transform_cs.vcproj", "{2128A5D9-C67E-4C00-A917-A79058C78FCC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -60,6 +62,10 @@ Global
{AB13D2AC-FD34-4DE4-BD8E-4D463050E5DD}.Debug|Win32.Build.0 = Debug|Win32
{AB13D2AC-FD34-4DE4-BD8E-4D463050E5DD}.Release|Win32.ActiveCfg = Release|Win32
{AB13D2AC-FD34-4DE4-BD8E-4D463050E5DD}.Release|Win32.Build.0 = Release|Win32
{2128A5D9-C67E-4C00-A917-A79058C78FCC}.Debug|Win32.ActiveCfg = Debug|Win32
{2128A5D9-C67E-4C00-A917-A79058C78FCC}.Debug|Win32.Build.0 = Debug|Win32
{2128A5D9-C67E-4C00-A917-A79058C78FCC}.Release|Win32.ActiveCfg = Release|Win32
{2128A5D9-C67E-4C00-A917-A79058C78FCC}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,149 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <geometry_test_common.hpp>
#include <boost/geometry/strategies/strategy_transform.hpp>
#include <boost/geometry/algorithms/transform.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
template <typename T, typename P>
inline T check_distance(P const& p)
{
T x = bg::get<0>(p);
T y = bg::get<1>(p);
T z = bg::get<2>(p);
return sqrt(x * x + y * y + z * z);
}
template <typename T>
void test_transformations_spherical()
{
T const input_long = 15.0;
T const input_lat = 5.0;
T const expected_long = 0.26179938779914943653855361527329;
T const expected_lat = 0.08726646259971647884618453842443;
// Can be checked using http://www.calc3d.com/ejavascriptcoordcalc.html
// (for phi use long, in radians, for theta use lat, in radians, they are listed there as "theta, phi")
T const expected_polar_x = 0.084186;
T const expected_polar_y = 0.0225576;
T const expected_polar_z = 0.996195;
// Can be checked with same URL using 90-theta for lat.
// So for theta use 85 degrees, in radians: 0.08726646259971647884618453842443
T const expected_equatorial_x = 0.962250;
T const expected_equatorial_y = 0.257834;
T const expected_equatorial_z = 0.0871557;
// 1: Spherical-polar (lat=5, so it is near the pole - on a unit sphere)
bg::model::point<T, 2, bg::cs::spherical<bg::degree> > sp(input_long, input_lat);
// 1a: to radian
bg::model::point<T, 2, bg::cs::spherical<bg::radian> > spr;
bg::transform(sp, spr);
BOOST_CHECK_CLOSE(bg::get<0>(spr), expected_long, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(spr), expected_lat, 0.001);
// 1b: to cartesian-3d
bg::model::point<T, 3, bg::cs::cartesian> pc3;
bg::transform(sp, pc3);
BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_polar_x, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_polar_y, 0.001);
BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_polar_z, 0.001);
BOOST_CHECK_CLOSE(check_distance<T>(pc3), 1.0, 0.001);
// 1c: back
bg::transform(pc3, spr);
BOOST_CHECK_CLOSE(bg::get<0>(spr), expected_long, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(spr), expected_lat, 0.001);
// 2: Spherical-equatorial (lat=5, so it is near the equator)
bg::model::point<T, 2, bg::cs::spherical_equatorial<bg::degree> > se(input_long, input_lat);
// 2a: to radian
bg::model::point<T, 2, bg::cs::spherical_equatorial<bg::radian> > ser;
bg::transform(se, ser);
BOOST_CHECK_CLOSE(bg::get<0>(ser), expected_long, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(ser), expected_lat, 0.001);
bg::transform(se, pc3);
BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_equatorial_x, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_equatorial_y, 0.001);
BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_equatorial_z, 0.001);
BOOST_CHECK_CLOSE(check_distance<T>(pc3), 1.0, 0.001);
// 2c: back
bg::transform(pc3, ser);
BOOST_CHECK_CLOSE(bg::get<0>(spr), expected_long, 0.001); // expected_long
BOOST_CHECK_CLOSE(bg::get<1>(spr), expected_lat, 0.001); // expected_lat
// 3: Spherical-polar including radius
bg::model::point<T, 3, bg::cs::spherical<bg::degree> > sp3(input_long, input_lat, 0.5);
// 3a: to radian
bg::model::point<T, 3, bg::cs::spherical<bg::radian> > spr3;
bg::transform(sp3, spr3);
BOOST_CHECK_CLOSE(bg::get<0>(spr3), expected_long, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(spr3), expected_lat, 0.001);
BOOST_CHECK_CLOSE(bg::get<2>(spr3), 0.5, 0.001);
// 3b: to cartesian-3d
bg::transform(sp3, pc3);
BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_polar_x / 2.0, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_polar_y / 2.0, 0.001);
BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_polar_z / 2.0, 0.001);
BOOST_CHECK_CLOSE(check_distance<T>(pc3), 0.5, 0.001);
// 3c: back
bg::transform(pc3, spr3);
BOOST_CHECK_CLOSE(bg::get<0>(spr3), expected_long, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(spr3), expected_lat, 0.001);
BOOST_CHECK_CLOSE(bg::get<2>(spr3), 0.5, 0.001);
// 4: Spherical-equatorial including radius
bg::model::point<T, 3, bg::cs::spherical_equatorial<bg::degree> > se3(input_long, input_lat, 0.5);
// 4a: to radian
bg::model::point<T, 3, bg::cs::spherical_equatorial<bg::radian> > ser3;
bg::transform(se3, ser3);
BOOST_CHECK_CLOSE(bg::get<0>(ser3), expected_long, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(ser3), expected_lat, 0.001);
BOOST_CHECK_CLOSE(bg::get<2>(ser3), 0.5, 0.001);
// 4b: to cartesian-3d
bg::transform(se3, pc3);
BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_equatorial_x / 2.0, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_equatorial_y / 2.0, 0.001);
BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_equatorial_z / 2.0, 0.001);
BOOST_CHECK_CLOSE(check_distance<T>(pc3), 0.5, 0.001);
// 4c: back
bg::transform(pc3, ser3);
BOOST_CHECK_CLOSE(bg::get<0>(ser3), expected_long, 0.001);
BOOST_CHECK_CLOSE(bg::get<1>(ser3), expected_lat, 0.001);
BOOST_CHECK_CLOSE(bg::get<2>(ser3), 0.5, 0.001);
}
int test_main(int, char* [])
{
test_transformations_spherical<double>();
return 0;
}

View File

@ -0,0 +1,174 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="transform_cs"
ProjectGUID="{2128A5D9-C67E-4C00-A917-A79058C78FCC}"
RootNamespace="transform_cs"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)\transform_cs"
ConfigurationType="1"
InheritedPropertySheets="..\boost.vsprops"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../..;.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
DebugInformationFormat="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)\transform_cs"
ConfigurationType="1"
InheritedPropertySheets="..\boost.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../..;.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
UsePrecompiledHeader="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath=".\transform_cs.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>