GEOS  3.9.0dev
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 
29 namespace geos {
30 namespace 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 " << index;
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
Indicates one or more illegal arguments.
Definition: IllegalArgumentException.h:34
Basic namespace for all GEOS functionalities.
Definition: IndexedNestedRingTester.h:26
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.
virtual void setAt(const Coordinate &c, std::size_t pos)=0
Copy Coordinate c to position pos.