Coverage Report

Created: 2025-11-16 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/src/geom/Point.cpp
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2011 Sandro Santilli <strk@kbt.io>
7
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
8
 * Copyright (C) 2005 2006 Refractions Research Inc.
9
 *
10
 * This is free software; you can redistribute and/or modify it under
11
 * the terms of the GNU Lesser General Public Licence as published
12
 * by the Free Software Foundation.
13
 * See the COPYING file for more information.
14
 *
15
 **********************************************************************
16
 *
17
 * Last port: geom/Point.java r320 (JTS-1.12)
18
 *
19
 **********************************************************************/
20
21
#include <geos/util/UnsupportedOperationException.h>
22
#include <geos/util/IllegalArgumentException.h>
23
#include <geos/geom/Coordinate.h>
24
#include <geos/geom/Point.h>
25
#include <geos/geom/CoordinateSequence.h>
26
#include <geos/geom/CoordinateSequenceFilter.h>
27
#include <geos/geom/CoordinateFilter.h>
28
#include <geos/geom/GeometryFilter.h>
29
#include <geos/geom/GeometryComponentFilter.h>
30
#include <geos/geom/Dimension.h>
31
#include <geos/geom/Envelope.h>
32
#include <geos/geom/GeometryCollection.h>
33
#include <geos/geom/GeometryFactory.h>
34
#include <geos/util.h>
35
36
#include <string>
37
#include <memory>
38
39
namespace geos {
40
namespace geom { // geos::geom
41
42
43
44
/*protected*/
45
Point::Point(CoordinateSequence&& newCoords, const GeometryFactory* factory)
46
11.6k
    : Geometry(factory)
47
11.6k
    , coordinates(newCoords)
48
11.6k
    , envelope(computeEnvelopeInternal())
49
11.6k
{
50
11.6k
    if (coordinates.getSize() > 1) {
51
2
        throw util::IllegalArgumentException("Point coordinate list must contain a single element");
52
2
    }
53
11.6k
}
54
55
Point::Point(const Coordinate & c, const GeometryFactory* factory)
56
5.92M
    : Geometry(factory)
57
5.92M
    , coordinates{c}
58
5.92M
    , envelope(c)
59
5.92M
{
60
5.92M
}
61
62
Point::Point(const CoordinateXY & c, const GeometryFactory* factory)
63
1
    : Geometry(factory)
64
1
    , coordinates{c}
65
1
    , envelope(c)
66
1
{
67
1
}
68
69
Point::Point(const CoordinateXYM & c, const GeometryFactory* factory)
70
0
    : Geometry(factory)
71
0
    , coordinates{c}
72
0
    , envelope(c)
73
0
{
74
0
}
75
76
Point::Point(const CoordinateXYZM & c, const GeometryFactory* factory)
77
3.89M
    : Geometry(factory)
78
      // check Z and M values because we may be constructing this from
79
      // an XYM coordinate that was stored as XYZM
80
3.89M
    , coordinates{1u, !std::isnan(c.z), !std::isnan(c.m), false}
81
3.89M
    , envelope(c)
82
3.89M
{
83
3.89M
    coordinates.setAt(c, 0);
84
3.89M
}
85
86
/*protected*/
87
Point::Point(const Point& p)
88
14.9M
    : Geometry(p)
89
14.9M
    , coordinates(p.coordinates)
90
14.9M
    , envelope(p.envelope)
91
14.9M
{}
92
93
std::unique_ptr<CoordinateSequence>
94
Point::getCoordinates() const
95
0
{
96
0
    return getCoordinatesRO()->clone();
97
0
}
98
99
std::size_t
100
Point::getNumPoints() const
101
13.0M
{
102
13.0M
    return coordinates.size();
103
13.0M
}
104
105
bool
106
Point::isEmpty() const
107
11.0M
{
108
11.0M
    return coordinates.isEmpty();
109
11.0M
}
110
111
bool
112
Point::isSimple() const
113
0
{
114
0
    return true;
115
0
}
116
117
Dimension::DimensionType
118
Point::getDimension() const
119
50.5M
{
120
50.5M
    return Dimension::P; // point
121
50.5M
}
122
123
uint8_t
124
Point::getCoordinateDimension() const
125
1.51M
{
126
1.51M
    return (uint8_t) getCoordinatesRO()->getDimension();
127
1.51M
}
128
129
bool
130
Point::hasM() const
131
16.8M
{
132
16.8M
    return getCoordinatesRO()->hasM();
133
16.8M
}
134
135
bool
136
Point::hasZ() const
137
16.8M
{
138
16.8M
    return getCoordinatesRO()->hasZ();
139
16.8M
}
140
141
int
142
Point::getBoundaryDimension() const
143
0
{
144
0
    return Dimension::False;
145
0
}
146
147
double
148
Point::getX() const
149
0
{
150
0
    if(isEmpty()) {
151
0
        throw util::UnsupportedOperationException("getX called on empty Point\n");
152
0
    }
153
0
    return getCoordinate()->x;
154
0
}
155
156
double
157
Point::getY() const
158
0
{
159
0
    if(isEmpty()) {
160
0
        throw util::UnsupportedOperationException("getY called on empty Point\n");
161
0
    }
162
0
    return getCoordinate()->y;
163
0
}
164
165
double
166
Point::getZ() const
167
0
{
168
0
    if(isEmpty()) {
169
0
        throw util::UnsupportedOperationException("getZ called on empty Point\n");
170
0
    }
171
0
    return coordinates.getOrdinate(0, CoordinateSequence::Z);
172
0
}
173
174
double
175
Point::getM() const
176
0
{
177
0
    if(isEmpty()) {
178
0
        throw util::UnsupportedOperationException("getM called on empty Point\n");
179
0
    }
180
0
    return coordinates.getOrdinate(0, CoordinateSequence::M);
181
0
}
182
183
std::string
184
Point::getGeometryType() const
185
5
{
186
5
    return "Point";
187
5
}
188
189
std::unique_ptr<Geometry>
190
Point::getBoundary() const
191
0
{
192
0
    return getFactory()->createGeometryCollection();
193
0
}
194
195
Envelope
196
Point::computeEnvelopeInternal() const
197
11.6k
{
198
11.6k
    if(isEmpty()) {
199
4.74k
        return Envelope();
200
4.74k
    }
201
202
6.91k
    return Envelope(*getCoordinate());
203
11.6k
}
204
205
void
206
Point::apply_ro(CoordinateFilter* filter) const
207
13.0M
{
208
13.0M
    coordinates.apply_ro(filter);
209
13.0M
}
210
211
void
212
Point::apply_rw(const CoordinateFilter* filter)
213
506k
{
214
506k
    coordinates.apply_rw(filter);
215
506k
}
216
217
void
218
Point::apply_rw(GeometryFilter* filter)
219
0
{
220
0
    filter->filter_rw(this);
221
0
}
222
223
void
224
Point::apply_ro(GeometryFilter* filter) const
225
20.9M
{
226
20.9M
    filter->filter_ro(this);
227
20.9M
}
228
229
void
230
Point::apply_rw(GeometryComponentFilter* filter)
231
0
{
232
0
    filter->filter_rw(this);
233
0
}
234
235
void
236
Point::apply_ro(GeometryComponentFilter* filter) const
237
197k
{
238
197k
    filter->filter_ro(this);
239
197k
}
240
241
void
242
Point::apply_rw(CoordinateSequenceFilter& filter)
243
0
{
244
0
    if(isEmpty()) {
245
0
        return;
246
0
    }
247
0
    filter.filter_rw(coordinates, 0);
248
0
    if(filter.isGeometryChanged()) {
249
0
        geometryChanged();
250
0
    }
251
0
}
252
253
void
254
Point::apply_ro(CoordinateSequenceFilter& filter) const
255
430k
{
256
430k
    if(isEmpty()) {
257
77
        return;
258
77
    }
259
430k
    filter.filter_ro(coordinates, 0);
260
430k
}
261
262
bool
263
Point::equalsExact(const Geometry* other, double tolerance) const
264
0
{
265
0
    if(!isEquivalentClass(other)) {
266
0
        return false;
267
0
    }
268
269
    // assume the isEquivalentClass would return false
270
    // if other is not a point
271
0
    assert(dynamic_cast<const Point*>(other));
272
273
0
    if(isEmpty()) {
274
0
        return other->isEmpty();
275
0
    }
276
0
    else if(other->isEmpty()) {
277
0
        return false;
278
0
    }
279
280
0
    const CoordinateXY* this_coord = getCoordinate();
281
0
    const CoordinateXY* other_coord = other->getCoordinate();
282
283
    // assume the isEmpty checks above worked :)
284
0
    assert(this_coord && other_coord);
285
286
0
    return equal(*this_coord, *other_coord, tolerance);
287
0
}
288
289
bool
290
Point::equalsIdentical(const Geometry* other) const
291
0
{
292
0
    if(!isEquivalentClass(other)) {
293
0
        return false;
294
0
    }
295
296
0
    return getCoordinatesRO()->equalsIdentical(
297
0
                *static_cast<const Point*>(other)->getCoordinatesRO());
298
0
}
299
300
int
301
Point::compareToSameClass(const Geometry* g) const
302
0
{
303
0
    const Point* p = detail::down_cast<const Point*>(g);
304
0
    return getCoordinate()->compareTo(*(p->getCoordinate()));
305
0
}
306
307
GeometryTypeId
308
Point::getGeometryTypeId() const
309
29.1M
{
310
29.1M
    return GEOS_POINT;
311
29.1M
}
312
313
/*public*/
314
const CoordinateSequence*
315
Point::getCoordinatesRO() const
316
40.0M
{
317
40.0M
    return &coordinates;
318
40.0M
}
319
320
} // namespace geos::geom
321
} // namespace geos