GEOS 3.11.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#pragma once
16
17#include <geos/geom/Coordinate.h>
18#include <geos/geom/CoordinateFilter.h>
19#include <geos/geom/CoordinateSequence.h>
20#include <geos/util/IllegalArgumentException.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(std::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 RETURN_UNIQUE_PTR(seq);
41 }
42
43 const Coordinate& getAt(std::size_t i) const final override {
44 return m_data[i];
45 }
46
47 void getAt(std::size_t i, Coordinate& c) const final override {
48 c = m_data[i];
49 }
50
51 std::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, std::size_t pos) final override {
60 m_data[pos] = c;
61 }
62
63 void setOrdinate(std::size_t index, std::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 std::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 assert(v.size() == N);
109 if (N > 0) {
110 std::copy(v.begin(), v.end(), m_data.begin());
111 }
112
113 }
114
115 void apply_ro(CoordinateFilter* filter) const final override {
116 std::for_each(m_data.begin(), m_data.end(),
117 [&filter](const Coordinate & c) { filter->filter_ro(&c); });
118 }
119
120 void apply_rw(const CoordinateFilter* filter) final override {
121 std::for_each(m_data.begin(), m_data.end(),
122 [&filter](Coordinate &c) { filter->filter_rw(&c); });
123 dimension = 0; // re-check (see http://trac.osgeo.org/geos/ticket/435)
124 }
125
126 private:
127 std::array<Coordinate, N> m_data;
128 mutable std::size_t dimension;
129 };
130
131}
132}
Indicates one or more illegal arguments.
Definition: IllegalArgumentException.h:33
Basic namespace for all GEOS functionalities.
Definition: geos.h:39