Coverage Report

Created: 2025-03-15 06:58

/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