mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 01:20:06 +00:00 
			
		
		
		
	Determine if a geographic area contains a point
This commit is contained in:
		
							parent
							
								
									6ec594144d
								
							
						
					
					
						commit
						8780da4148
					
				
					 5 changed files with 85 additions and 1 deletions
				
			
		|  | @ -22,6 +22,7 @@ Supercell Wx uses code from the following dependencies: | ||||||
| | [FreeType](https://freetype.org/) | [Freetype Project License](https://spdx.org/licenses/FTL.html) | | | [FreeType](https://freetype.org/) | [Freetype Project License](https://spdx.org/licenses/FTL.html) | | ||||||
| | [FreeType GL](https://github.com/rougier/freetype-gl) | [BSD 2-Clause with views sentence](https://spdx.org/licenses/BSD-2-Clause-Views.html) | | | [FreeType GL](https://github.com/rougier/freetype-gl) | [BSD 2-Clause with views sentence](https://spdx.org/licenses/BSD-2-Clause-Views.html) | | ||||||
| | [GeographicLib](https://geographiclib.sourceforge.io/) | [MIT License](https://spdx.org/licenses/MIT.html) | | | [GeographicLib](https://geographiclib.sourceforge.io/) | [MIT License](https://spdx.org/licenses/MIT.html) | | ||||||
|  | | [geos](https://libgeos.org/) | [GNU Lesser General Public License v2.1 or later](https://spdx.org/licenses/LGPL-2.1-or-later.html) | | ||||||
| | [GLEW](https://www.opengl.org/sdk/libs/GLEW/) | [MIT License](https://spdx.org/licenses/MIT.html) | | | [GLEW](https://www.opengl.org/sdk/libs/GLEW/) | [MIT License](https://spdx.org/licenses/MIT.html) | | ||||||
| | [GLM](https://github.com/g-truc/glm) | [MIT License](https://spdx.org/licenses/MIT.html) | | | [GLM](https://github.com/g-truc/glm) | [MIT License](https://spdx.org/licenses/MIT.html) | | ||||||
| | [GoogleTest](https://google.github.io/googletest/) | [BSD 3-Clause "New" or "Revised" License](https://spdx.org/licenses/BSD-3-Clause.html) | | | [GoogleTest](https://google.github.io/googletest/) | [BSD 3-Clause "New" or "Revised" License](https://spdx.org/licenses/BSD-3-Clause.html) | | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ class SupercellWxConan(ConanFile): | ||||||
|                   "cpr/1.10.5", |                   "cpr/1.10.5", | ||||||
|                   "fontconfig/2.14.2", |                   "fontconfig/2.14.2", | ||||||
|                   "geographiclib/2.3", |                   "geographiclib/2.3", | ||||||
|  |                   "geos/3.12.0", | ||||||
|                   "glew/2.2.0", |                   "glew/2.2.0", | ||||||
|                   "glm/cci.20230113", |                   "glm/cci.20230113", | ||||||
|                   "gtest/1.14.0", |                   "gtest/1.14.0", | ||||||
|  | @ -19,7 +20,8 @@ class SupercellWxConan(ConanFile): | ||||||
|     generators = ("cmake", |     generators = ("cmake", | ||||||
|                   "cmake_find_package", |                   "cmake_find_package", | ||||||
|                   "cmake_paths") |                   "cmake_paths") | ||||||
|     default_options = {"libiconv:shared"  : True, |     default_options = {"geos:shared"      : True, | ||||||
|  |                        "libiconv:shared"  : True, | ||||||
|                        "openssl:no_module": True, |                        "openssl:no_module": True, | ||||||
|                        "openssl:shared"   : True} |                        "openssl:shared"   : True} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||||||
| find_package(Boost) | find_package(Boost) | ||||||
| find_package(Fontconfig) | find_package(Fontconfig) | ||||||
| find_package(geographiclib) | find_package(geographiclib) | ||||||
|  | find_package(geos) | ||||||
| find_package(GLEW) | find_package(GLEW) | ||||||
| find_package(glm) | find_package(glm) | ||||||
| find_package(Python COMPONENTS Interpreter) | find_package(Python COMPONENTS Interpreter) | ||||||
|  | @ -533,6 +534,8 @@ target_link_libraries(scwx-qt PUBLIC Qt${QT_VERSION_MAJOR}::Widgets | ||||||
|                                      $<$<CXX_COMPILER_ID:MSVC>:opengl32> |                                      $<$<CXX_COMPILER_ID:MSVC>:opengl32> | ||||||
|                                      Fontconfig::Fontconfig |                                      Fontconfig::Fontconfig | ||||||
|                                      GeographicLib::GeographicLib |                                      GeographicLib::GeographicLib | ||||||
|  |                                      GEOS::geos | ||||||
|  |                                      GEOS::geos_cxx_flags | ||||||
|                                      GLEW::GLEW |                                      GLEW::GLEW | ||||||
|                                      glm::glm |                                      glm::glm | ||||||
|                                      imgui |                                      imgui | ||||||
|  |  | ||||||
|  | @ -1,4 +1,9 @@ | ||||||
| #include <scwx/qt/util/geographic_lib.hpp> | #include <scwx/qt/util/geographic_lib.hpp> | ||||||
|  | #include <scwx/util/logger.hpp> | ||||||
|  | 
 | ||||||
|  | #include <GeographicLib/Gnomonic.hpp> | ||||||
|  | #include <geos/algorithm/PointLocation.h> | ||||||
|  | #include <geos/geom/CoordinateSequence.h> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx | ||||||
| { | { | ||||||
|  | @ -9,6 +14,9 @@ namespace util | ||||||
| namespace GeographicLib | namespace GeographicLib | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|  | static const std::string logPrefix_ = "scwx::qt::util::geographic_lib"; | ||||||
|  | static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
| const ::GeographicLib::Geodesic& DefaultGeodesic() | const ::GeographicLib::Geodesic& DefaultGeodesic() | ||||||
| { | { | ||||||
|    static const ::GeographicLib::Geodesic geodesic_ { |    static const ::GeographicLib::Geodesic geodesic_ { | ||||||
|  | @ -18,6 +26,60 @@ const ::GeographicLib::Geodesic& DefaultGeodesic() | ||||||
|    return geodesic_; |    return geodesic_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool AreaContainsPoint(const std::vector<common::Coordinate>& area, | ||||||
|  |                        const common::Coordinate&              point) | ||||||
|  | { | ||||||
|  |    // Cannot have an area with just two points
 | ||||||
|  |    if (area.size() <= 2 || area.size() == 3 && area.front() == area.back()) | ||||||
|  |    { | ||||||
|  |       return false; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    ::GeographicLib::Gnomonic      gnomonic {}; | ||||||
|  |    geos::geom::CoordinateSequence sequence {}; | ||||||
|  |    double                         x; | ||||||
|  |    double                         y; | ||||||
|  |    bool                           areaContainsPoint = false; | ||||||
|  | 
 | ||||||
|  |    // Using a gnomonic projection with the test point as the center
 | ||||||
|  |    // latitude/longitude, the projected test point will be at (0, 0)
 | ||||||
|  |    geos::geom::CoordinateXY zero {}; | ||||||
|  | 
 | ||||||
|  |    // Create the area coordinate sequence using a gnomonic projection
 | ||||||
|  |    for (auto& areaCoordinate : area) | ||||||
|  |    { | ||||||
|  |       gnomonic.Forward(point.latitude_, | ||||||
|  |                        point.longitude_, | ||||||
|  |                        areaCoordinate.latitude_, | ||||||
|  |                        areaCoordinate.longitude_, | ||||||
|  |                        x, | ||||||
|  |                        y); | ||||||
|  |       sequence.add(x, y); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // If the sequence is not a ring, add the first point again for closure
 | ||||||
|  |    if (!sequence.isRing()) | ||||||
|  |    { | ||||||
|  |       sequence.add(sequence.front(), false); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // The sequence should be a ring at this point, but make sure
 | ||||||
|  |    if (sequence.isRing()) | ||||||
|  |    { | ||||||
|  |       try | ||||||
|  |       { | ||||||
|  |          areaContainsPoint = | ||||||
|  |             geos::algorithm::PointLocation::isInRing(zero, &sequence); | ||||||
|  |       } | ||||||
|  |       catch (const std::exception&) | ||||||
|  |       { | ||||||
|  |          logger_->trace("Invalid area sequence"); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return areaContainsPoint; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| units::angle::degrees<double> | units::angle::degrees<double> | ||||||
| GetAngle(double lat1, double lon1, double lat2, double lon2) | GetAngle(double lat1, double lon1, double lat2, double lon2) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -1,5 +1,9 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <scwx/common/geographic.hpp> | ||||||
|  | 
 | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
| #include <GeographicLib/Geodesic.hpp> | #include <GeographicLib/Geodesic.hpp> | ||||||
| #include <units/angle.h> | #include <units/angle.h> | ||||||
| #include <units/length.h> | #include <units/length.h> | ||||||
|  | @ -20,6 +24,18 @@ namespace GeographicLib | ||||||
|  */ |  */ | ||||||
| const ::GeographicLib::Geodesic& DefaultGeodesic(); | const ::GeographicLib::Geodesic& DefaultGeodesic(); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Determine if an area/ring, oriented in either direction, contains a point. A | ||||||
|  |  * point lying on the area boundary is considered to be inside the area. | ||||||
|  |  * | ||||||
|  |  * @param [in] area A vector of Coordinates representing the area | ||||||
|  |  * @param [in] point The point to check against the area | ||||||
|  |  * | ||||||
|  |  * @return true if point is inside the area | ||||||
|  |  */ | ||||||
|  | bool AreaContainsPoint(const std::vector<common::Coordinate>& area, | ||||||
|  |                        const common::Coordinate&              point); | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Get the angle between two points. |  * Get the angle between two points. | ||||||
|  * |  * | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat