-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d4bc793
commit e4820fc
Showing
11 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
_package/tests/unit_tests/geometry_tests/multi_poly_intersector_pyt.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
"""Tests for the TriSearch class.""" | ||
import unittest | ||
|
||
import numpy as np | ||
|
||
from xms import grid | ||
|
||
|
||
class TestMultiPolyIntersector(unittest.TestCase): | ||
"""Tests for the MultiPolyIntersector class.""" | ||
|
||
def setUp(self): | ||
"""Runs before each test case.""" | ||
pass | ||
|
||
def _run_test(self, x1, y1, x2, y2, points, polys, expected_poly_ids, expected_t_values, expected_points): | ||
"""Runs the test.""" | ||
mpi = MultiPolyIntersector(points, polys) | ||
poly_ids, t_values, pts = mpi.traverse_line_segment(x1, y1, x2, y2) | ||
assert poly_ids == expected_poly_ids | ||
assert t_values == expected_t_values | ||
assert np.testing.assert_allclose(pts, expected_points) | ||
|
||
def test_create_class(self): | ||
"""Test creating class.""" | ||
mpi = grid.geometry.MultiPolyIntersector(self.pts, self.tris) | ||
self.assertIsInstance(mpi, grid.geometry.MultiPolyIntersector) | ||
|
||
def test_traverse_line_segment_1_out_out(self): | ||
"""A test.""" | ||
pts = [[0, 0, 0], [10, 0, 0], [10, 10, 0], [0, 10, 0]] | ||
polys = [[0, 1, 2, 3]] | ||
expectedIds = [1, -1] | ||
expectedTvals = [0.0833333, 0.916667] | ||
expectedPoints = [[0.0, 5.0, 0.0], [10.0, 5.0, 0.0]] | ||
self._run_test(-1, 5, 11, 5, pts, polys, expectedIds, expectedTvals, expectedPoints) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
"""Initialize the module.""" | ||
from . import geometry # NOQA: F401 | ||
from .multi_poly_intersector import MultiPolyIntersector # NOQA: F401 | ||
from .tri_search import TriSearch # NOQA: F401 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
"""Pure Python wrapper for GmMultiPolyIntersector class.""" | ||
from .._xmsgrid.geometry import GmMultiPolyIntersector | ||
|
||
|
||
class MultiPolyIntersector(object): | ||
"""Intersects a line segment with any number of polygons in 2D and returns the polygons in order with t values.""" | ||
|
||
def __init__(self, points, polys, starting_id=1, query='covered_by', **kwargs): | ||
"""Constructor. | ||
Args: | ||
points (list): The points that make up the polygon. | ||
polys (list): 0-based indexes into a_points array to define polygons. The first point is NOT repeated as | ||
the last point. | ||
starting_id (int): If the polygon IDs should start at something other than 1, specify the starting value. | ||
query (str): The query to use ('covered_by', 'intersects') | ||
**kwargs (dict): Generic keyword arguments | ||
""" | ||
if 'instance' not in kwargs: | ||
if not points: | ||
raise ValueError('points is a required arguments.') | ||
if not polys: | ||
raise ValueError('polys is a required argument.') | ||
if query not in {'covered_by', 'intersects'}: | ||
raise ValueError('query must be either "covered_by" or "intersects".') | ||
query_ = GMMPIQ_COVEREDBY if query == 'covered_by' else GMMPIQ_INTERSECTS | ||
self._instance = GmMultiPolyIntersector(points, polys, starting_id, query) | ||
else: | ||
if not isinstance(kwargs['instance'], GmMultiPolyIntersector): | ||
raise ValueError('"instance" must be of type _xmsgrid.geometry.GmMultiPolyIntersector') | ||
self._instance = kwargs['instance'] | ||
|
||
def __eq__(self, other): | ||
"""Equality operator. | ||
Args: | ||
other (MultiPolyIntersector): MultiPolyIntersector to compare | ||
Returns: | ||
bool: True if MultiPolyIntersector are equal | ||
""" | ||
other_instance = getattr(other, '_instance', None) | ||
if not other_instance or not isinstance(other_instance, GmMultiPolyIntersector): | ||
print("not instance or no value") | ||
return False | ||
return other_instance == self._instance | ||
|
||
def __ne__(self, other): | ||
"""Equality operator. | ||
Args: | ||
other (MultiPolyIntersector): MultiPolyIntersector to compare | ||
Returns: | ||
bool: True if MultiPolyIntersector are not equal | ||
""" | ||
result = self.__eq__(other) | ||
return not result | ||
|
||
def __repr__(self): | ||
"""Returns a string representation of the MultiPolyIntersector.""" | ||
return "<xms.grid.geometry.MultiPolyIntersector>" | ||
|
||
def __str__(self): | ||
"""Returns a string representation of the MultiPolyIntersector.""" | ||
return "<xms.grid.geometry.MultiPolyIntersector>" | ||
|
||
@property | ||
def query(self): | ||
"""The query to use ('covered_by', 'intersects').""" | ||
return self._instance.GetQuery() | ||
|
||
@query.setter | ||
def query(self, query): | ||
"""Set the query to use ('covered_by', 'intersects').""" | ||
self._instance.SetQuery(query) | ||
|
||
def traverse_line_segment(self, x1, y1, x2, y2): | ||
"""Intersect segment with polys and return intersected polys, t-values, and points. | ||
Args: | ||
x1: x coordinate of 1st point defining a line segment. | ||
y1: y coordinate of 1st point defining a line segment. | ||
x2: x coordinate of 2nd point defining a line segment. | ||
y2: y coordinate of 2nd point defining a line segment. | ||
Returns: | ||
tuple containing: list of poly ids, list of t values, list of points | ||
""" | ||
return self._instance.TraverseLineSegment(x1, y1, x2, y2) | ||
|
||
def polygon_from_point(self, point): | ||
"""Returns the polygon containing the point. | ||
Args: | ||
point (iterable): The point. | ||
Returns: | ||
The polygon id. | ||
""" | ||
return self._instance.PolygonFromPoint(point) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
******************** | ||
MultiPolyIntersector | ||
******************** | ||
|
||
Intersects a line segment with any number of polygons in 2D and returns the polygons in order with t values. | ||
|
||
.. autoclass:: xms.grid.geometry.MultiPolyIntersector | ||
:members: | ||
|
||
.. automethod:: __init__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
//------------------------------------------------------------------------------ | ||
/// \file | ||
/// \brief | ||
/// \copyright (C) Copyright Aquaveo 2018. Distributed under FreeBSD License | ||
/// (See accompanying file LICENSE or https://aqaveo.com/bsd/license.txt) | ||
//------------------------------------------------------------------------------ | ||
|
||
//----- Included files --------------------------------------------------------- | ||
#include <sstream> | ||
#include <pybind11/pybind11.h> | ||
#include <pybind11/numpy.h> // Needed for PyUtils.h | ||
|
||
#include <xmscore/python/misc/PyUtils.h> | ||
#include <xmsgrid/geometry/GmMultiPolyIntersector.h> | ||
#include <xmsgrid/geometry/GmMultiPolyIntersectorSorterTerse.h> | ||
#include <xmsgrid/python/geometry/geometry_py.h> | ||
|
||
//----- Namespace declaration -------------------------------------------------- | ||
namespace py = pybind11; | ||
|
||
//----- Python Interface ------------------------------------------------------- | ||
PYBIND11_DECLARE_HOLDER_TYPE(T, boost::shared_ptr<T>); | ||
|
||
void initGmMultiPolyIntersector(py::module &m) { | ||
// GmMultiPolyIntersector class | ||
py::class_<xms::GmMultiPolyIntersector, boost::shared_ptr<xms::GmMultiPolyIntersector>> | ||
gmMpi(m, "GmMultiPolyIntersector"); | ||
|
||
// --------------------------------------------------------------------------- | ||
// function: init | ||
// --------------------------------------------------------------------------- | ||
gmMpi.def(py::init([](py::iterable points, py::iterable polys, int starting_id, | ||
const std::string& query) { | ||
boost::shared_ptr<xms::VecPt3d> vec_pts = xms::VecPt3dFromPyIter(pts); | ||
boost::shared_ptr<std::vector<xms::VecInt>> vec_polys = std::vector<xms::VecIntFromPyIter(polys)>; | ||
boost::shared_ptr<GmMultiPolyIntersectionSorterTerse> sorter(new GmMultiPolyIntersectionSorterTerse); | ||
boost::shared_ptr<xms::GmMultiPolyIntersector> rval(xms::GmMultiPolyIntersector::New(vec_pts, vec_polys, sorter, | ||
starting_id)); | ||
rval->SetQuery(query); | ||
return rval; | ||
}), py::arg("points"), py::arg("polys"), py::arg("starting_id") = 1, py::arg("query") = 'covered_by') | ||
.def_property("query", &GmMultiPolyIntersector::GetQuery, &GmMultiPolyIntersector::SetQuery); | ||
// --------------------------------------------------------------------------- | ||
// function: TraverseLineSegment | ||
// --------------------------------------------------------------------------- | ||
gmMpi.def("TraverseLineSegment", [](xms::GmMultiPolyIntersector &self, double x1, double y1, | ||
double x2, double y2) -> py::tuple { | ||
std::vector<int> polyids; | ||
std::vector<double> tvalues; | ||
std::vector<Pt3d> pts; | ||
self.TraverseLineSegment(x1, y1, x2, y2, polyids, tvalues, pts); | ||
return py::make_tuple(xms::PyIterFromVecInt(polyids), xms::PyIterFromVecDbl(tvalues), xms::PyIterFromVecPt3d(pts)); | ||
}, py::arg("x1"), py::arg("y1"), py::arg("x2"), py::arg("y2")); | ||
// --------------------------------------------------------------------------- | ||
// function: PolygonFromPoint | ||
// --------------------------------------------------------------------------- | ||
gmMpi.def("PolygonFromPoint", [](xms::GmMultiPolyIntersector &self, py::iterable point) -> int { | ||
xms::Pt3d p = xms::Pt3dFromPyIter(point); | ||
return self.PolygonFromPoint(p); | ||
}, py::arg("point")); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters