18 #include <geos/export.h> 20 #include <geos/geom/Coordinate.h> 21 #include <geos/geom/CoordinateSequenceIterator.h> 33 class CoordinateFilter;
63 using iterator = CoordinateSequenceIterator<CoordinateSequence, Coordinate>;
64 using const_iterator = CoordinateSequenceIterator<const CoordinateSequence, const Coordinate>;
66 typedef std::unique_ptr<CoordinateSequence> Ptr;
162 std::unique_ptr<CoordinateSequence> clone()
const;
187 assert(stride() == 2 || stride() == 3 || stride() == 4);
189 case 2:
return m_vect.size() / 2;
190 case 4:
return m_vect.size() / 4;
191 default :
return m_vect.size() / 3;
197 return m_vect.empty();
205 switch(getCoordinateType()) {
206 case CoordinateType::XY:
return getAt<CoordinateXY>(0).isNull();
207 case CoordinateType::XYZ:
return getAt<Coordinate>(0).isNull();
208 case CoordinateType::XYZM:
return getAt<CoordinateXYZM>(0).isNull();
209 case CoordinateType::XYM:
return getAt<CoordinateXYM>(0).isNull();
210 default:
return false;
228 std::size_t getDimension()
const;
231 return m_hasdim ? m_hasz : (m_vect.empty() || !std::isnan(m_vect[2]));
239 bool hasRepeatedPoints()
const;
242 bool hasRepeatedOrInvalidPoints()
const;
249 case 4:
return CoordinateType::XYZM;
250 case 2:
return CoordinateType::XY;
251 default:
return hasM() ? CoordinateType::XYM : CoordinateType::XYZ;
262 template<
typename T=Coordinate>
263 const T&
getAt(std::size_t i)
const {
264 static_assert(std::is_base_of<CoordinateXY, T>::value,
"Must be a Coordinate class");
265 assert(
sizeof(T) <=
sizeof(
double) * stride());
266 assert(i*stride() < m_vect.size());
267 const T* orig =
reinterpret_cast<const T*
>(&m_vect[i*stride()]);
274 template<
typename T=Coordinate>
276 static_assert(std::is_base_of<CoordinateXY, T>::value,
"Must be a Coordinate class");
277 assert(
sizeof(T) <=
sizeof(
double) * stride());
278 assert(i*stride() < m_vect.size());
279 T* orig =
reinterpret_cast<T*
>(&m_vect[i*stride()]);
287 void getAt(std::size_t i, T& c)
const {
288 switch(getCoordinateType()) {
289 case CoordinateType::XY: c = getAt<CoordinateXY>(i);
break;
290 case CoordinateType::XYZ: c = getAt<Coordinate>(i);
break;
291 case CoordinateType::XYZM: c = getAt<CoordinateXYZM>(i);
break;
292 case CoordinateType::XYM: c = getAt<CoordinateXYM>(i);
break;
293 default: getAt<Coordinate>(i);
297 void getAt(std::size_t i, CoordinateXY& c)
const {
298 c = getAt<CoordinateXY>(i);
330 double getOrdinate(std::size_t index, std::size_t ordinateIndex)
const;
338 double getX(std::size_t index)
const 340 return m_vect[index * stride()];
349 double getY(std::size_t index)
const 351 return m_vect[index * stride() + 1];
355 template<
typename T=Coordinate>
358 return getAt<T>(size() - 1);
362 template<
typename T=Coordinate>
365 return getAt<T>(size() - 1);
369 template<
typename T=Coordinate>
372 return *(
reinterpret_cast<const T*
>(m_vect.data()));
376 template<
typename T=Coordinate>
379 return *(
reinterpret_cast<T*
>(m_vect.data()));
383 void toVector(std::vector<Coordinate>& coords)
const;
385 void toVector(std::vector<CoordinateXY>& coords)
const;
394 void setAt(
const T& c, std::size_t pos) {
395 switch(getCoordinateType()) {
396 case CoordinateType::XY: setAtImpl<CoordinateXY>(c, pos);
break;
397 case CoordinateType::XYZ: setAtImpl<Coordinate>(c, pos);
break;
398 case CoordinateType::XYZM: setAtImpl<CoordinateXYZM>(c, pos);
break;
399 case CoordinateType::XYM: setAtImpl<CoordinateXYM>(c, pos);
break;
400 default: setAtImpl<Coordinate>(c, pos);
412 void setOrdinate(std::size_t index, std::size_t ordinateIndex,
double value);
415 void setPoints(
const std::vector<Coordinate>& v);
425 template<
typename T=Coordinate>
437 void add(
const T& c,
bool allowRepeated)
439 if(!allowRepeated && !isEmpty()) {
440 const CoordinateXY& last = back<CoordinateXY>();
441 if(last.equals2D(c)) {
458 void add(
const T& c, std::size_t pos)
460 static_assert(std::is_base_of<CoordinateXY, T>::value,
"Must be a Coordinate class");
464 if (m_vect.size() + stride() <= m_vect.capacity()) {
466 setAt(c, static_cast<std::size_t>(pos));
470 setAt(tmp, static_cast<std::size_t>(pos));
484 void add(std::size_t i,
const T& coord,
bool allowRepeated)
487 if(! allowRepeated) {
488 std::size_t sz = size();
491 const CoordinateXY& prev = getAt<CoordinateXY>(i - 1);
492 if(prev.equals2D(coord)) {
497 const CoordinateXY& next = getAt<CoordinateXY>(i);
498 if(next.equals2D(coord)) {
508 void add(
double x,
double y) {
509 CoordinateXY c(x, y);
513 void add(
const CoordinateSequence& cs);
515 void add(
const CoordinateSequence& cs,
bool allowRepeated);
517 void add(
const CoordinateSequence& cl,
bool allowRepeated,
bool forwardDirection);
519 void add(
const CoordinateSequence& cs, std::size_t from, std::size_t to);
521 void add(
const CoordinateSequence& cs, std::size_t from, std::size_t to,
bool allowRepeated);
523 template<
typename T,
typename... Args>
524 void add(T begin, T end, Args... args) {
525 for (
auto it = begin; it != end; ++it) {
531 void add(std::size_t i, T from, T to) {
532 auto npts =
static_cast<std::size_t
>(std::distance(from, to));
535 for (
auto it = from; it != to; ++it) {
549 void reserve(std::size_t capacity) {
550 m_vect.reserve(capacity * stride());
553 void resize(std::size_t capacity) {
554 m_vect.resize(capacity * stride());
560 std::string toString()
const;
563 const CoordinateXY* minCoordinate()
const;
569 static CoordinateSequence* atLeastNCoordinatesOrNothing(std::size_t n,
570 CoordinateSequence* c);
576 static std::size_t indexOf(
const CoordinateXY* coordinate,
577 const CoordinateSequence* cl);
584 static bool equals(
const CoordinateSequence* cl1,
585 const CoordinateSequence* cl2);
592 bool equalsIdentical(
const CoordinateSequence& other)
const;
595 static void scroll(CoordinateSequence* cl,
const CoordinateXY* firstCoordinate);
614 static int increasingDirection(
const CoordinateSequence& pts);
627 void expandEnvelope(Envelope& env)
const;
629 void closeRing(
bool allowRepeated =
false);
635 template<
typename Filter>
636 void apply_rw(
const Filter* filter) {
637 switch(getCoordinateType()) {
638 case CoordinateType::XY:
for (
auto& c : items<CoordinateXY>()) { filter->filter_rw(&c); }
break;
639 case CoordinateType::XYZ:
for (
auto& c : items<Coordinate>()) { filter->filter_rw(&c); }
break;
640 case CoordinateType::XYM:
for (
auto& c : items<CoordinateXYM>()) { filter->filter_rw(&c); }
break;
641 case CoordinateType::XYZM:
for (
auto& c : items<CoordinateXYZM>()) { filter->filter_rw(&c); }
break;
643 m_hasdim = m_hasz =
false;
646 template<
typename Filter>
647 void apply_ro(Filter* filter)
const {
648 switch(getCoordinateType()) {
649 case CoordinateType::XY:
for (
const auto& c : items<CoordinateXY>()) { filter->filter_ro(&c); }
break;
650 case CoordinateType::XYZ:
for (
const auto& c : items<Coordinate>()) { filter->filter_ro(&c); }
break;
651 case CoordinateType::XYM:
for (
const auto& c : items<CoordinateXYM>()) { filter->filter_ro(&c); }
break;
652 case CoordinateType::XYZM:
for (
const auto& c : items<CoordinateXYZM>()) { filter->filter_ro(&c); }
break;
657 void forEach(F&& fun)
const {
658 switch(getCoordinateType()) {
659 case CoordinateType::XY:
for (
const auto& c : items<CoordinateXY>()) { fun(c); }
break;
660 case CoordinateType::XYZ:
for (
const auto& c : items<Coordinate>()) { fun(c); }
break;
661 case CoordinateType::XYM:
for (
const auto& c : items<CoordinateXYM>()) { fun(c); }
break;
662 case CoordinateType::XYZM:
for (
const auto& c : items<CoordinateXYZM>()) { fun(c); }
break;
666 template<
typename T,
typename F>
667 void forEach(F&& fun)
const 669 for (std::size_t i = 0; i < size(); i++) {
674 template<
typename T,
typename F>
675 void forEach(std::size_t from, std::size_t to, F&& fun)
const 677 for (std::size_t i = from; i <= to; i++) {
685 using SequenceType =
typename std::conditional<std::is_const<T>::value,
const CoordinateSequence, CoordinateSequence>::type;
687 explicit Coordinates(SequenceType* seq) : m_seq(seq) {}
689 CoordinateSequenceIterator<SequenceType, T> begin() {
693 CoordinateSequenceIterator<SequenceType, T> end() {
694 return {m_seq, m_seq->getSize()};
697 CoordinateSequenceIterator<const SequenceType, typename std::add_const<T>::type>
699 return CoordinateSequenceIterator<const SequenceType, typename std::add_const<T>::type>{m_seq};
702 CoordinateSequenceIterator<const SequenceType, typename std::add_const<T>::type>
704 return CoordinateSequenceIterator<const SequenceType, typename std::add_const<T>::type>{m_seq, m_seq->getSize()};
707 CoordinateSequenceIterator<const SequenceType, typename std::add_const<T>::type>
709 return CoordinateSequenceIterator<const SequenceType, typename std::add_const<T>::type>{m_seq};
712 CoordinateSequenceIterator<const SequenceType, typename std::add_const<T>::type>
714 return CoordinateSequenceIterator<const SequenceType, typename std::add_const<T>::type>{m_seq, m_seq->getSize()};
722 Coordinates<typename std::add_const<T>::type> items()
const {
723 return Coordinates<typename std::add_const<T>::type>(
this);
727 Coordinates<T> items() {
728 return Coordinates<T>(
this);
735 return m_vect.data();
738 const double* data()
const {
739 return m_vect.data();
743 std::vector<double> m_vect;
747 mutable bool m_hasdim;
755 template<
typename T1,
typename T2>
756 void setAtImpl(
const T2& c, std::size_t pos) {
757 auto& orig = getAt<T1>(pos);
761 void make_space(std::size_t pos, std::size_t n) {
762 m_vect.insert(std::next(m_vect.begin(),
static_cast<std::ptrdiff_t
>(pos * stride())),
767 std::uint8_t stride()
const {
773 GEOS_DLL std::ostream& operator<< (std::ostream& os,
const CoordinateSequence& cs);
775 GEOS_DLL
bool operator== (
const CoordinateSequence& s1,
const CoordinateSequence& s2);
777 GEOS_DLL
bool operator!= (
const CoordinateSequence& s1,
const CoordinateSequence& s2);
static CoordinateSequence XYM(std::size_t size)
Definition: CoordinateSequence.h:155
size_t size() const
Returns the number of Coordinates.
Definition: CoordinateSequence.h:185
An Envelope defines a rectangulare region of the 2D coordinate plane.
Definition: Envelope.h:58
static CoordinateSequence XYZM(std::size_t size)
Definition: CoordinateSequence.h:146
bool isEmpty() const
Returns true if list contains no coordinates.
Definition: CoordinateSequence.h:196
double getY(std::size_t index) const
Definition: CoordinateSequence.h:349
CoordinateType getCoordinateType() const
Definition: CoordinateSequence.h:247
bool isNullPoint() const
Returns true if there is 1 coordinate and if it is null.
Definition: CoordinateSequence.h:201
Coordinate is the lightweight class used to store coordinates.
Definition: Coordinate.h:216
T & getAt(std::size_t i)
Returns a reference to Coordinate at position i.
Definition: CoordinateSequence.h:275
const T & front() const
Return first Coordinate in the sequence.
Definition: CoordinateSequence.h:370
double getX(std::size_t index) const
Definition: CoordinateSequence.h:338
void add(const T &c, bool allowRepeated)
Definition: CoordinateSequence.h:437
std::size_t getSize() const
Returns the number of Coordinates.
Definition: CoordinateSequence.h:178
const T & getAt(std::size_t i) const
Returns a read-only reference to Coordinate at position i.
Definition: CoordinateSequence.h:263
T & front()
Return first Coordinate in the sequence.
Definition: CoordinateSequence.h:377
Basic namespace for all GEOS functionalities.
Definition: Angle.h:25
void add(const T &c, std::size_t pos)
Inserts the specified coordinate at the specified position in this sequence. If multiple coordinates ...
Definition: CoordinateSequence.h:458
void add(const T &c)
Definition: CoordinateSequence.h:426
T & back()
Return last Coordinate in the sequence.
Definition: CoordinateSequence.h:363
static CoordinateSequence XY(std::size_t size)
Definition: CoordinateSequence.h:128
void setAt(const T &c, std::size_t pos)
Copy Coordinate c to position pos.
Definition: CoordinateSequence.h:394
void getAt(std::size_t i, T &c) const
Write Coordinate at position i to given Coordinate.
Definition: CoordinateSequence.h:287
The internal representation of a list of coordinates inside a Geometry.
Definition: CoordinateSequence.h:56
const Coordinate & operator[](std::size_t i) const
Definition: CoordinateSequence.h:305
void add(std::size_t i, const T &coord, bool allowRepeated)
Inserts the specified coordinate at the specified position in this list.
Definition: CoordinateSequence.h:484
Coordinate & operator[](std::size_t i)
Definition: CoordinateSequence.h:315
const T & back() const
Return last Coordinate in the sequence.
Definition: CoordinateSequence.h:356
static CoordinateSequence XYZ(std::size_t size)
Definition: CoordinateSequence.h:137