GEOS  3.11.0rc0
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 
29 namespace geos {
30 namespace 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: Angle.h:25