Coverage Report

Created: 2025-11-08 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/algorithm/locate/IndexedPointInAreaLocator.cpp
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
7
 * Copyright (C) 2018 Daniel Baston <dbaston@gmail.com>
8
 *
9
 * This is free software; you can redistribute and/or modify it under
10
 * the terms of the GNU Lesser General Public Licence as published
11
 * by the Free Software Foundation.
12
 * See the COPYING file for more information.
13
 *
14
 **********************************************************************/
15
16
17
#include <geos/algorithm/locate/IndexedPointInAreaLocator.h>
18
#include <geos/geom/Geometry.h>
19
#include <geos/geom/Polygon.h>
20
#include <geos/geom/MultiPolygon.h>
21
#include <geos/geom/LineString.h>
22
#include <geos/geom/LineSegment.h>
23
#include <geos/geom/LinearRing.h>
24
#include <geos/geom/CoordinateSequence.h>
25
#include <geos/geom/util/LinearComponentExtracter.h>
26
#include <geos/index/strtree/Interval.h>
27
#include <geos/index/strtree/TemplateSTRtree.h>
28
#include <geos/util.h>
29
#include <geos/algorithm/RayCrossingCounter.h>
30
#include <geos/index/ItemVisitor.h>
31
32
#include <algorithm>
33
34
using geos::geom::CoordinateXY;
35
36
namespace geos {
37
namespace algorithm {
38
namespace locate {
39
//
40
// private:
41
//
42
IndexedPointInAreaLocator::IntervalIndexedGeometry::IntervalIndexedGeometry(const geom::Geometry& g)
43
26.1k
{
44
26.1k
    init(g);
45
26.1k
}
46
47
void
48
IndexedPointInAreaLocator::IntervalIndexedGeometry::init(const geom::Geometry& g)
49
26.1k
{
50
26.1k
    geom::LineString::ConstVect lines;
51
26.1k
    geom::util::LinearComponentExtracter::getLines(g, lines);
52
53
    // pre-compute size of segment vector
54
26.1k
    std::size_t nsegs = 0;
55
64.4k
    for(const geom::LineString* line : lines) {
56
        //-- only include rings of Polygons or LinearRings
57
64.4k
        if (! line->isClosed())
58
159
          continue;
59
60
64.2k
        nsegs += line->getCoordinatesRO()->size() - 1;
61
64.2k
    }
62
26.1k
    index = decltype(index)(10, nsegs);
63
64
64.4k
    for(const geom::LineString* line : lines) {
65
        //-- only include rings of Polygons or LinearRings
66
64.4k
        if (! line->isClosed())
67
159
          continue;
68
69
64.2k
        addLine(line->getCoordinatesRO());
70
64.2k
    }
71
26.1k
}
72
73
void
74
IndexedPointInAreaLocator::IntervalIndexedGeometry::addLine(const geom::CoordinateSequence* pts)
75
64.2k
{
76
6.03M
    for(std::size_t i = 1, ni = pts->size(); i < ni; i++) {
77
5.96M
        SegmentView seg(&pts->getAt<CoordinateXY>(i-1), &pts->getAt<CoordinateXY>(i));
78
5.96M
        auto r = std::minmax(seg.p0().y, seg.p1().y);
79
80
5.96M
        index.insert(index::strtree::Interval(r.first, r.second), seg);
81
5.96M
    }
82
64.2k
}
83
84
85
void
86
IndexedPointInAreaLocator::buildIndex(const geom::Geometry& g)
87
26.1k
{
88
26.1k
    index = detail::make_unique<IntervalIndexedGeometry>(g);
89
26.1k
}
90
91
92
//
93
// protected:
94
//
95
96
//
97
// public:
98
//
99
IndexedPointInAreaLocator::IndexedPointInAreaLocator(const geom::Geometry& g)
100
26.2k
    : areaGeom(g)
101
26.2k
{
102
26.2k
}
103
104
geom::Location
105
IndexedPointInAreaLocator::locate(const geom::CoordinateXY* /*const*/ p)
106
333k
{
107
333k
    if (index == nullptr) {
108
26.1k
        buildIndex(areaGeom);
109
26.1k
    }
110
111
333k
    algorithm::RayCrossingCounter rcc(*p);
112
113
3.54M
    index->query(p->y, p->y, [&rcc](const SegmentView& ls) {
114
3.54M
        rcc.countSegment(ls.p0(), ls.p1());
115
3.54M
    });
116
117
333k
    return rcc.getLocation();
118
333k
}
119
120
121
} // geos::algorithm::locate
122
} // geos::algorithm
123
} // geos