Coverage Report

Created: 2025-11-16 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/MapServer/src/flatgeobuf/geometryreader.cpp
Line
Count
Source
1
#include "geometryreader.h"
2
3
using namespace mapserver::flatbuffers;
4
using namespace mapserver::FlatGeobuf;
5
6
void GeometryReader::readPoint(shapeObj *shape)
7
0
{
8
0
    lineObj *l = (lineObj *) malloc(sizeof(lineObj));
9
0
    pointObj *p = (pointObj *) malloc(sizeof(pointObj));
10
11
0
  p->x = m_xy[m_offset + 0];
12
0
  p->y = m_xy[m_offset + 1];
13
0
    if (m_has_z)
14
0
        p->z = m_geometry->z()->data()[m_offset];
15
0
    if (m_has_m)
16
0
        p->m = m_geometry->m()->data()[m_offset];
17
18
0
    l[0].numpoints = 1;
19
0
    l[0].point = p;
20
0
    shape->numlines = 1;
21
0
    shape->line = l;
22
0
    shape->type = MS_SHAPE_POINT;
23
0
}
24
25
void GeometryReader::readLineObj(lineObj *line)
26
0
{
27
0
    const double *z = m_has_z ? m_geometry->z()->data() : nullptr;
28
0
    const double *m = m_has_m ? m_geometry->m()->data() : nullptr;
29
30
0
    line->point = (pointObj *) malloc(m_length * sizeof(pointObj));
31
0
    line->numpoints = m_length;
32
33
0
    for (uint32_t i = m_offset; i < m_offset + m_length; i++) {
34
0
        pointObj *point = &line->point[i - m_offset];
35
0
        memcpy(point, &m_xy[i * 2], 2 * sizeof(double));
36
0
        if (m_has_z)
37
0
            point->z = z[i];
38
0
        if (m_has_m)
39
0
            point->m = m[i];
40
0
    }
41
0
}
42
43
void GeometryReader::readMultiPoint(shapeObj *shape)
44
0
{
45
0
    readLineString(shape);
46
0
    shape->type = MS_SHAPE_POINT;
47
0
}
48
49
void GeometryReader::readLineString(shapeObj *shape)
50
0
{
51
0
    lineObj *line = (lineObj *) malloc(sizeof(lineObj));
52
0
    readLineObj(line);
53
0
    shape->numlines = 1;
54
0
    shape->line = line;
55
0
    shape->type = MS_SHAPE_LINE;
56
0
}
57
58
void GeometryReader::readMultiLineString(shapeObj *shape)
59
0
{
60
0
    readPolygon(shape);
61
0
    shape->type = MS_SHAPE_LINE;
62
0
}
63
64
void GeometryReader::readPolygon(shapeObj *shape)
65
0
{
66
0
    const auto ends = m_geometry->ends();
67
68
0
    uint32_t nrings = 1;
69
0
    if (ends != nullptr && ends->size() > 1)
70
0
        nrings = ends->size();
71
72
0
    lineObj *line = (lineObj *) malloc(nrings * sizeof(lineObj));
73
0
    if (nrings > 1) {
74
0
        for (uint32_t i = 0; i < nrings; i++) {
75
0
            const auto e = ends->Get(i);
76
0
            m_length = e - m_offset;
77
0
            readLineObj(&line[i]);
78
0
            m_offset = e;
79
0
        }
80
0
    } else {
81
0
        readLineObj(line);
82
0
    }
83
0
    shape->numlines = nrings;
84
0
    shape->line = line;
85
0
    shape->type = MS_SHAPE_POLYGON;
86
0
}
87
88
void GeometryReader::readMultiPolygon(shapeObj *shape)
89
0
{
90
0
    const auto parts = m_geometry->parts();
91
0
    lineObj *line = (lineObj *) nullptr;
92
0
    auto numlines = 0;
93
0
    for (size_t i = 0; i < parts->size(); i++) {
94
0
        GeometryReader(m_ctx, parts->Get(i), GeometryType::Polygon).read(shape);
95
0
        lineObj *tmp = line;
96
0
        line = (lineObj *) realloc(line, (numlines + shape->numlines) * sizeof(lineObj));
97
0
        if (!line) {
98
0
            free(tmp);
99
0
            free(shape->line);
100
0
            break;
101
0
        }
102
0
        for (int j = 0; j < shape->numlines; j++)
103
0
            line[numlines + j] = shape->line[j];
104
0
        numlines += shape->numlines;
105
0
        free(shape->line);
106
0
    }
107
0
    shape->line = line;
108
0
    shape->numlines = numlines;
109
0
}
110
111
/*void GeometryReader::readGeometryCollection(shapeObj *shape)
112
{
113
    // TODO
114
    return;
115
}*/
116
117
void GeometryReader::read(shapeObj *shape)
118
0
{
119
    // nested types
120
0
    switch (m_geometry_type) {
121
        //case GeometryType::GeometryCollection: return readGeometryCollection(shape);
122
0
        case GeometryType::MultiPolygon: return readMultiPolygon(shape);
123
        /*case GeometryType::CompoundCurve: return readCompoundCurve();
124
        case GeometryType::CurvePolygon: return readCurvePolygon();
125
        case GeometryType::MultiCurve: return readMultiCurve();
126
        case GeometryType::MultiSurface: return readMultiSurface();
127
        case GeometryType::PolyhedralSurface: return readPolyhedralSurface();*/
128
0
        default: break;
129
0
    }
130
131
    // if not nested must have geometry data
132
0
    const auto pXy = m_geometry->xy();
133
0
    const auto xySize = pXy->size();
134
0
    m_xy = pXy->data();
135
0
    m_length = xySize / 2;
136
137
0
    switch (m_geometry_type) {
138
0
        case GeometryType::Point: return readPoint(shape);
139
0
        case GeometryType::MultiPoint: return readMultiPoint(shape);
140
0
        case GeometryType::LineString: return readLineString(shape);
141
0
        case GeometryType::MultiLineString: return readMultiLineString(shape);
142
0
        case GeometryType::Polygon: return readPolygon(shape);
143
        /*
144
        case GeometryType::CircularString: return readSimpleCurve<OGRCircularString>(true);
145
        case GeometryType::Triangle: return readTriangle();
146
        case GeometryType::TIN: return readTIN();
147
        */
148
0
        default: break;
149
0
    }
150
0
}