GEOS 3.9.1
FixedSizeCoordinateSequence.h
1/**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (C) 2019 Daniel Baston
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#ifndef GEOS_GEOM_FIXEDSIZECOORDINATESEQUENCE_H
16#define GEOS_GEOM_FIXEDSIZECOORDINATESEQUENCE_H
17
18#include <geos/geom/Coordinate.h>
19#include <geos/geom/CoordinateFilter.h>
20#include <geos/geom/CoordinateSequence.h>
21#include <geos/util.h>
22
23#include <algorithm>
24#include <array>
25#include <memory>
26#include <sstream>
27#include <vector>
28
29namespace geos {
30namespace geom {
31
32 template<size_t N>
33 class FixedSizeCoordinateSequence : public CoordinateSequence {
34 public:
35 explicit FixedSizeCoordinateSequence(size_t dimension_in = 0) : dimension(dimension_in) {}
36
37 std::unique_ptr<CoordinateSequence> clone() const final override {
38 auto seq = detail::make_unique<FixedSizeCoordinateSequence<N>>(dimension);
39 seq->m_data = m_data;
40 return std::move(seq); // move needed for gcc 4.8
41 }
42
43 const Coordinate& getAt(size_t i) const final override {
44 return m_data[i];
45 }
46
47 void getAt(size_t i, Coordinate& c) const final override {
48 c = m_data[i];
49 }
50
51 size_t getSize() const final override {
52 return N;
53 }
54
55 bool isEmpty() const final override {
56 return N == 0;
57 }
58
59 void setAt(const Coordinate & c, size_t pos) final override {
60 m_data[pos] = c;
61 }
62
63 void setOrdinate(size_t index, size_t ordinateIndex, double value) final override
64 {
65 switch(ordinateIndex) {
66 case CoordinateSequence::X:
67 m_data[index].x = value;
68 break;
69 case CoordinateSequence::Y:
70 m_data[index].y = value;
71 break;
72 case CoordinateSequence::Z:
73 m_data[index].z = value;
74 break;
75 default: {
76 std::stringstream ss;
77 ss << "Unknown ordinate index " << ordinateIndex;
79 break;
80 }
81 }
82 }
83
84 size_t getDimension() const final override {
85 if(dimension != 0) {
86 return dimension;
87 }
88
89 if(isEmpty()) {
90 return 3;
91 }
92
93 if(std::isnan(m_data[0].z)) {
94 dimension = 2;
95 }
96 else {
97 dimension = 3;
98 }
99
100 return dimension;
101 }
102
103 void toVector(std::vector<Coordinate> & out) const final override {
104 out.insert(out.end(), m_data.begin(), m_data.end());
105 }
106
107 void setPoints(const std::vector<Coordinate> & v) final override {
108 std::copy(v.begin(), v.end(), m_data.begin());
109 }
110
111 void apply_ro(CoordinateFilter* filter) const final override {
112 std::for_each(m_data.begin(), m_data.end(),
113 [&filter](const Coordinate & c) { filter->filter_ro(&c); });
114 }
115
116 void apply_rw(const CoordinateFilter* filter) final override {
117 std::for_each(m_data.begin(), m_data.end(),
118 [&filter](Coordinate &c) { filter->filter_rw(&c); });
119 dimension = 0; // re-check (see http://trac.osgeo.org/geos/ticket/435)
120 }
121
122 private:
123 std::array<Coordinate, N> m_data;
124 mutable std::size_t dimension;
125 };
126
127}
128}
129
130#endif
virtual void setAt(const Coordinate &c, std::size_t pos)=0
Copy Coordinate c to position pos.
virtual void setOrdinate(std::size_t index, std::size_t ordinateIndex, double value)=0
virtual const Coordinate & getAt(std::size_t i) const =0
Returns a read-only reference to Coordinate at position i.
Indicates one or more illegal arguments.
Definition IllegalArgumentException.h:34
Basic namespace for all GEOS functionalities.
Definition IndexedNestedRingTester.h:26