245 lines
5.4 KiB
C
245 lines
5.4 KiB
C
|
/**********************************************************************
|
||
|
*
|
||
|
* GEOS - Geometry Engine Open Source
|
||
|
* http://geos.osgeo.org
|
||
|
*
|
||
|
* Copyright (C) 2010 Sandro Santilli <strk@kbt.io>
|
||
|
* Copyright (C) 2006 Refractions Research Inc.
|
||
|
*
|
||
|
* This is free software; you can redistribute and/or modify it under
|
||
|
* the terms of the GNU Lesser General Public Licence as published
|
||
|
* by the Free Software Foundation.
|
||
|
* See the COPYING file for more information.
|
||
|
*
|
||
|
**********************************************************************
|
||
|
*
|
||
|
* Last port: geom/CoordinateList.java ?? (never been in complete sync)
|
||
|
*
|
||
|
**********************************************************************/
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <geos/export.h>
|
||
|
#include <geos/geom/Coordinate.h>
|
||
|
#include <geos/geom/CoordinateSequence.h>
|
||
|
#include <geos/util.h>
|
||
|
|
||
|
#include <list>
|
||
|
#include <ostream> // for operator<<
|
||
|
#include <memory> // for unique_ptr
|
||
|
|
||
|
#ifdef _MSC_VER
|
||
|
#pragma warning(push)
|
||
|
#pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class
|
||
|
#endif
|
||
|
|
||
|
// Forward declarations
|
||
|
namespace geos {
|
||
|
namespace geom {
|
||
|
//class Coordinate;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
namespace geos {
|
||
|
namespace geom { // geos::geom
|
||
|
|
||
|
/** \brief
|
||
|
* A list of {@link Coordinate}s, which may
|
||
|
* be set to prevent repeated coordinates from occurring in the list.
|
||
|
*
|
||
|
* Use this class when fast insertions and removal at arbitrary
|
||
|
* position is needed.
|
||
|
* The class keeps ownership of the Coordinates.
|
||
|
*
|
||
|
*/
|
||
|
class GEOS_DLL CoordinateList {
|
||
|
|
||
|
public:
|
||
|
|
||
|
typedef std::list<Coordinate>::iterator iterator;
|
||
|
typedef std::list<Coordinate>::const_iterator const_iterator;
|
||
|
|
||
|
friend std::ostream& operator<< (std::ostream& os,
|
||
|
const CoordinateList& cl);
|
||
|
|
||
|
/** \brief
|
||
|
* Constructs a new list from an array of Coordinates, allowing
|
||
|
* repeated points.
|
||
|
*
|
||
|
* (I.e. this constructor produces a {@link CoordinateList} with
|
||
|
* exactly the same set of points as the input array.)
|
||
|
*
|
||
|
* @param v the initial coordinates
|
||
|
*/
|
||
|
template<typename T>
|
||
|
CoordinateList(const T& v)
|
||
|
:
|
||
|
coords(v.begin(), v.end())
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CoordinateList(const CoordinateSequence& v)
|
||
|
: CoordinateList(v.items<Coordinate>())
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CoordinateList()
|
||
|
:
|
||
|
coords()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
size_t
|
||
|
size() const
|
||
|
{
|
||
|
return coords.size();
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
empty() const
|
||
|
{
|
||
|
return coords.empty();
|
||
|
}
|
||
|
|
||
|
iterator
|
||
|
begin()
|
||
|
{
|
||
|
return coords.begin();
|
||
|
}
|
||
|
|
||
|
iterator
|
||
|
end()
|
||
|
{
|
||
|
return coords.end();
|
||
|
}
|
||
|
|
||
|
const_iterator
|
||
|
begin() const
|
||
|
{
|
||
|
return coords.begin();
|
||
|
}
|
||
|
|
||
|
const_iterator
|
||
|
end() const
|
||
|
{
|
||
|
return coords.end();
|
||
|
}
|
||
|
|
||
|
/** \brief
|
||
|
* Inserts the specified coordinate at the specified position in this list.
|
||
|
*
|
||
|
* @param pos the position at which to insert
|
||
|
* @param c the coordinate to insert
|
||
|
* @param allowRepeated if set to false, repeated coordinates are collapsed
|
||
|
*
|
||
|
* @return an iterator to the newly installed coordinate
|
||
|
* (or previous, if equal and repeated are not allowed)
|
||
|
*
|
||
|
* NOTE: when allowRepeated is false _next_ point is not checked
|
||
|
* this matches JTS behavior
|
||
|
*/
|
||
|
iterator
|
||
|
insert(iterator pos, const Coordinate& c, bool allowRepeated)
|
||
|
{
|
||
|
if(!allowRepeated && pos != coords.begin()) {
|
||
|
iterator prev = pos;
|
||
|
--prev;
|
||
|
if(c.equals2D(*prev)) {
|
||
|
return prev;
|
||
|
}
|
||
|
}
|
||
|
return coords.insert(pos, c);
|
||
|
}
|
||
|
|
||
|
iterator
|
||
|
add(const Coordinate& c, bool allowRepeated)
|
||
|
{
|
||
|
return insert(coords.end(), c, allowRepeated);
|
||
|
}
|
||
|
|
||
|
iterator
|
||
|
insert(iterator pos, const Coordinate& c)
|
||
|
{
|
||
|
return coords.insert(pos, c);
|
||
|
}
|
||
|
|
||
|
iterator
|
||
|
erase(iterator pos)
|
||
|
{
|
||
|
return coords.erase(pos);
|
||
|
}
|
||
|
|
||
|
iterator
|
||
|
erase(iterator first, iterator last)
|
||
|
{
|
||
|
return coords.erase(first, last);
|
||
|
}
|
||
|
|
||
|
std::unique_ptr<Coordinate::Vect>
|
||
|
toCoordinateArray() const
|
||
|
{
|
||
|
std::unique_ptr<Coordinate::Vect> ret(new Coordinate::Vect);
|
||
|
ret->assign(coords.begin(), coords.end());
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
std::unique_ptr<geom::CoordinateSequence>
|
||
|
toCoordinateSequence() const
|
||
|
{
|
||
|
auto ret = detail::make_unique<geom::CoordinateSequence>();
|
||
|
ret->add(begin(), end());
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
closeRing()
|
||
|
{
|
||
|
if(!coords.empty() && !(*(coords.begin())).equals(*(coords.rbegin()))) {
|
||
|
const Coordinate& c = *(coords.begin());
|
||
|
coords.insert(coords.end(), c);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
closeRing(std::vector<Coordinate>& coords)
|
||
|
{
|
||
|
if(!coords.empty() && !(*(coords.begin())).equals(*(coords.rbegin()))) {
|
||
|
const Coordinate& c = *(coords.begin());
|
||
|
coords.insert(coords.end(), c);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
std::list<Coordinate> coords;
|
||
|
};
|
||
|
|
||
|
inline
|
||
|
std::ostream&
|
||
|
operator<< (std::ostream& os, const CoordinateList& cl)
|
||
|
{
|
||
|
os << "(";
|
||
|
for(CoordinateList::const_iterator
|
||
|
it = cl.begin(), end = cl.end();
|
||
|
it != end;
|
||
|
++it) {
|
||
|
const Coordinate& c = *it;
|
||
|
if(it != cl.begin()) {
|
||
|
os << ", ";
|
||
|
}
|
||
|
os << c;
|
||
|
}
|
||
|
os << ")";
|
||
|
|
||
|
return os;
|
||
|
}
|
||
|
|
||
|
} // namespace geos::geom
|
||
|
} // namespace geos
|
||
|
|
||
|
#ifdef _MSC_VER
|
||
|
#pragma warning(pop)
|
||
|
#endif
|
||
|
|