diff options
-rw-r--r-- | src/mbgl/style/expression/within.cpp | 39 | ||||
-rw-r--r-- | src/mbgl/util/geometry_within.cpp | 6 |
2 files changed, 38 insertions, 7 deletions
diff --git a/src/mbgl/style/expression/within.cpp b/src/mbgl/style/expression/within.cpp index be6db20c35..271bf8f175 100644 --- a/src/mbgl/style/expression/within.cpp +++ b/src/mbgl/style/expression/within.cpp @@ -67,24 +67,41 @@ MultiPolygon<int64_t> getTilePolygons(const Feature::geometry_type& polygonGeoSe [](const auto&) { return MultiPolygon<int64_t>(); }); } +void updatePoint(Point<int64_t>& p, WithinBBox& bbox, const WithinBBox& polyBBox, const int64_t worldSize) { + if (p.x <= polyBBox[0] || p.x >= polyBBox[2]) { + int64_t shift = 0; + shift = (p.x - polyBBox[0] > worldSize / 2) ? -worldSize : (polyBBox[0] - p.x > worldSize / 2) ? worldSize : 0; + if (shift == 0) { + shift = + (p.x - polyBBox[2] > worldSize / 2) ? -worldSize : (polyBBox[2] - p.x > worldSize / 2) ? worldSize : 0; + } + p.x += shift; + } + updateBBox(bbox, p); +} + MultiPoint<int64_t> getTilePoints(const GeometryCoordinates& points, const mbgl::CanonicalTileID& canonical, - WithinBBox& bbox) { + WithinBBox& bbox, + const WithinBBox& polyBBox) { const int64_t xShift = util::EXTENT * canonical.x; const int64_t yShift = util::EXTENT * canonical.y; + const auto worldSize = util::EXTENT * std::pow(2, canonical.z); MultiPoint<int64_t> results; results.reserve(points.size()); for (const auto& p : points) { - const auto point = Point<int64_t>(p.x + xShift, p.y + yShift); - updateBBox(bbox, point); + auto point = Point<int64_t>(p.x + xShift, p.y + yShift); + updatePoint(point, bbox, polyBBox, worldSize); results.push_back(point); } + return results; } MultiLineString<int64_t> getTileLines(const GeometryCollection& lines, const mbgl::CanonicalTileID& canonical, - WithinBBox& bbox) { + WithinBBox& bbox, + const WithinBBox& polyBBox) { const int64_t xShift = util::EXTENT * canonical.x; const int64_t yShift = util::EXTENT * canonical.y; MultiLineString<int64_t> results; @@ -99,6 +116,16 @@ MultiLineString<int64_t> getTileLines(const GeometryCollection& lines, } results.push_back(std::move(lineString)); } + + const auto worldSize = util::EXTENT * std::pow(2, canonical.z); + if (bbox[2] - bbox[0] <= worldSize / 2) { + bbox = DefaultBBox; + for (auto& line : results) { + for (auto& p : line) { + updatePoint(p, bbox, polyBBox, worldSize); + } + } + } return results; } @@ -113,7 +140,7 @@ bool featureWithinPolygons(const GeometryTileFeature& feature, case FeatureType::Point: { assert(!geometries.empty()); WithinBBox pointBBox = DefaultBBox; - MultiPoint<int64_t> points = getTilePoints(geometries.at(0), canonical, pointBBox); + MultiPoint<int64_t> points = getTilePoints(geometries.at(0), canonical, pointBBox, polyBBox); if (!boxWithinBox(pointBBox, polyBBox)) return false; return std::all_of( @@ -121,7 +148,7 @@ bool featureWithinPolygons(const GeometryTileFeature& feature, } case FeatureType::LineString: { WithinBBox lineBBox = DefaultBBox; - MultiLineString<int64_t> multiLineString = getTileLines(geometries, canonical, lineBBox); + MultiLineString<int64_t> multiLineString = getTileLines(geometries, canonical, lineBBox, polyBBox); if (!boxWithinBox(lineBBox, polyBBox)) return false; return std::all_of(multiLineString.begin(), multiLineString.end(), [&polygons](const auto& line) { diff --git a/src/mbgl/util/geometry_within.cpp b/src/mbgl/util/geometry_within.cpp index 28a53c8ebc..89e3d84fc6 100644 --- a/src/mbgl/util/geometry_within.cpp +++ b/src/mbgl/util/geometry_within.cpp @@ -47,7 +47,11 @@ bool lineIntersectLine(const Point<int64_t>& a, y2 = p2.y - q1.y; x3 = q2.x - q1.x; y3 = q2.y - q1.y; - if ((x1 * y3 - x3 * y1) * (x2 * y3 - x3 * y2) < 0) return true; + auto ret1 = (x1 * y3 - x3 * y1); + auto ret2 = (x2 * y3 - x3 * y2); + if ((ret1 > 0 && ret2 < 0) || (ret1 < 0 && ret2 > 0)) { + return true; + } return false; }; |