/src/geos/src/index/chain/MonotoneChainBuilder.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************** |
2 | | * |
3 | | * GEOS - Geometry Engine Open Source |
4 | | * http://geos.osgeo.org |
5 | | * |
6 | | * Copyright (C) 2001-2002 Vivid Solutions Inc. |
7 | | * |
8 | | * This is free software; you can redistribute and/or modify it under |
9 | | * the terms of the GNU Lesser General Public Licence as published |
10 | | * by the Free Software Foundation. |
11 | | * See the COPYING file for more information. |
12 | | * |
13 | | ********************************************************************** |
14 | | * |
15 | | * Last port: index/chain/MonotoneChainBuilder.java r388 (JTS-1.12) |
16 | | * |
17 | | **********************************************************************/ |
18 | | |
19 | | #include <geos/index/chain/MonotoneChainBuilder.h> |
20 | | #include <geos/index/chain/MonotoneChain.h> |
21 | | #include <geos/geom/CoordinateSequence.h> |
22 | | #include <geos/geom/CoordinateFilter.h> |
23 | | #include <geos/geom/Quadrant.h> |
24 | | |
25 | | |
26 | | #include <cassert> |
27 | | #include <cstdio> |
28 | | #include <vector> |
29 | | |
30 | | #ifndef GEOS_DEBUG |
31 | | #define GEOS_DEBUG 0 |
32 | | #endif |
33 | | |
34 | | #if GEOS_DEBUG |
35 | | #include <iostream> |
36 | | #endif |
37 | | |
38 | | |
39 | | using namespace geos::geom; |
40 | | |
41 | | namespace geos { |
42 | | namespace index { // geos.index |
43 | | namespace chain { // geos.index.chain |
44 | | |
45 | | /** \brief |
46 | | * Finds the index of the last point in each monotone chain |
47 | | * of the provided coordinate sequence. |
48 | | */ |
49 | | class ChainBuilder : public CoordinateFilter { |
50 | | public: |
51 | | ChainBuilder(const CoordinateSequence* pts, void* context, std::vector<MonotoneChain> & list) : |
52 | 55.8M | m_prev(nullptr), |
53 | 55.8M | m_i(0), |
54 | 55.8M | m_quadrant(-1), |
55 | 55.8M | m_start(0), |
56 | 55.8M | m_seq(pts), |
57 | 55.8M | m_context(context), |
58 | 55.8M | m_list(list) {} |
59 | | |
60 | 134M | void filter_ro(const CoordinateXY* c) override { |
61 | 134M | process(c); |
62 | | |
63 | 134M | m_prev = c; |
64 | 134M | m_i++; |
65 | 134M | } |
66 | | |
67 | 55.8M | void finish() { |
68 | 55.8M | finishChain(); |
69 | 55.8M | } |
70 | | |
71 | | private: |
72 | 73.0M | void finishChain() { |
73 | 73.0M | if ( m_i == 0 ) return; |
74 | 73.0M | std::size_t chainEnd = m_i - 1; |
75 | 73.0M | m_list.emplace_back(*m_seq, m_start, chainEnd, m_context); |
76 | 73.0M | m_start = chainEnd; |
77 | 73.0M | } |
78 | | |
79 | 134M | void process(const CoordinateXY* curr) { |
80 | 134M | if (m_prev == nullptr || curr->equals2D(*m_prev)) { |
81 | 55.8M | return; |
82 | 55.8M | } |
83 | | |
84 | 78.3M | int currQuad = Quadrant::quadrant(*m_prev, *curr); |
85 | | |
86 | 78.3M | if (m_quadrant < 0) { |
87 | 55.5M | m_quadrant = currQuad; |
88 | 55.5M | } |
89 | | |
90 | 78.3M | if (currQuad != m_quadrant) { |
91 | 17.1M | finishChain(); |
92 | 17.1M | m_quadrant = currQuad; |
93 | 17.1M | } |
94 | 78.3M | } |
95 | | |
96 | | const CoordinateXY* m_prev; |
97 | | std::size_t m_i; |
98 | | int m_quadrant; |
99 | | std::size_t m_start; |
100 | | const CoordinateSequence* m_seq; |
101 | | void* m_context; |
102 | | std::vector<MonotoneChain>& m_list; |
103 | | }; |
104 | | |
105 | | |
106 | | /* static public */ |
107 | | void |
108 | | MonotoneChainBuilder::getChains(const CoordinateSequence* pts, void* context, |
109 | 55.8M | std::vector<MonotoneChain>& mcList) { |
110 | 55.8M | ChainBuilder builder(pts, context, mcList); |
111 | 55.8M | pts->apply_ro(&builder); |
112 | 55.8M | builder.finish(); |
113 | 55.8M | } |
114 | | |
115 | | } // namespace geos.index.chain |
116 | | } // namespace geos.index |
117 | | } // namespace geos |
118 | | |