1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2006 Refractions Research Inc.
7 * Copyright (C) 2001-2002 Vivid Solutions Inc.
9 * This is free software; you can redistribute and/or modify it under
10 * the terms of the GNU Lesser General Public Licence as published
11 * by the Free Software Foundation.
12 * See the COPYING file for more information.
14 **********************************************************************/
16 #include <geos/profiler.h>
17 #include <geos/geom/CoordinateSequence.h>
18 // FIXME: we should probably not be using CoordinateArraySequenceFactory
19 #include <geos/geom/CoordinateArraySequenceFactory.h>
20 #include <geos/geom/Coordinate.h>
21 #include <geos/geom/Envelope.h>
32 namespace geom
{ // geos::geom
35 static Profiler
*profiler
= Profiler::instance();
39 CoordinateSequence::hasRepeatedPoints() const
41 const std::size_t size
=getSize();
42 for(std::size_t i
=1; i
<size
; i
++) {
43 if (getAt(i
-1)==getAt(i
)) {
51 * Returns either the given coordinate array if its length is greater than the
52 * given amount, or an empty coordinate array.
55 CoordinateSequence::atLeastNCoordinatesOrNothing(size_t n
,
56 CoordinateSequence
*c
)
58 if ( c
->getSize() >= n
)
64 // FIXME: return NULL rather then empty coordinate array
65 return CoordinateArraySequenceFactory::instance()->create(NULL
);
71 CoordinateSequence::hasRepeatedPoints(const CoordinateSequence
*cl
)
73 const std::size_t size
=cl
->getSize();
74 for(std::size_t i
=1;i
<size
; i
++) {
75 if (cl
->getAt(i
-1)==cl
->getAt(i
)) {
83 CoordinateSequence::minCoordinate() const
85 const Coordinate
* minCoord
=NULL
;
86 const std::size_t size
=getSize();
87 for(std::size_t i
=0; i
<size
; i
++) {
88 if(minCoord
==NULL
|| minCoord
->compareTo(getAt(i
))>0) {
96 CoordinateSequence::minCoordinate(CoordinateSequence
*cl
)
98 const Coordinate
* minCoord
=NULL
;
99 const std::size_t size
=cl
->getSize();
100 for(std::size_t i
=0;i
<size
; i
++) {
101 if(minCoord
==NULL
|| minCoord
->compareTo(cl
->getAt(i
))>0) {
102 minCoord
=&(cl
->getAt(i
));
109 CoordinateSequence::indexOf(const Coordinate
*coordinate
,
110 const CoordinateSequence
*cl
)
112 size_t size
=cl
->getSize();
113 for (size_t i
=0; i
<size
; ++i
)
115 if ((*coordinate
)==cl
->getAt(i
))
117 return static_cast<int>(i
); // FIXME: what if we overflow the int ?
124 CoordinateSequence::scroll(CoordinateSequence
* cl
,
125 const Coordinate
* firstCoordinate
)
127 // FIXME: use a standard algorithm instead
129 std::size_t ind
=indexOf(firstCoordinate
,cl
);
131 return; // not found or already first
133 const std::size_t length
=cl
->getSize();
134 vector
<Coordinate
> v(length
);
135 for (i
=ind
; i
<length
; i
++) {
138 for (i
=0; i
<ind
; i
++) {
145 CoordinateSequence::increasingDirection(const CoordinateSequence
& pts
)
147 size_t ptsize
= pts
.size();
148 for (size_t i
=0, n
=ptsize
/2; i
<n
; ++i
)
150 size_t j
= ptsize
- 1 - i
;
151 // skip equal points on both ends
152 int comp
= pts
[i
].compareTo(pts
[j
]);
153 if (comp
!= 0) return comp
;
155 // array must be a palindrome - defined to be in positive direction
160 CoordinateSequence::reverse(CoordinateSequence
*cl
)
163 // FIXME: use a standard algorithm
164 int last
= static_cast<int>(cl
->getSize()) - 1;
166 for(int i
=0;i
<=mid
;i
++) {
167 const Coordinate tmp
=cl
->getAt(i
);
168 cl
->setAt(cl
->getAt(last
-i
),i
);
169 cl
->setAt(tmp
,last
-i
);
174 CoordinateSequence::equals(const CoordinateSequence
*cl1
,
175 const CoordinateSequence
*cl2
)
177 // FIXME: use std::equals()
179 if (cl1
==cl2
) return true;
180 if (cl1
==NULL
||cl2
==NULL
) return false;
181 size_t npts1
=cl1
->getSize();
182 if (npts1
!=cl2
->getSize()) return false;
183 for (size_t i
=0; i
<npts1
; i
++) {
184 if (!(cl1
->getAt(i
)==cl2
->getAt(i
))) return false;
191 CoordinateSequence::add(const vector
<Coordinate
>* vc
, bool allowRepeated
)
194 for(size_t i
=0; i
<vc
->size(); ++i
)
196 add((*vc
)[i
], allowRepeated
);
202 CoordinateSequence::add(const Coordinate
& c
, bool allowRepeated
)
204 if (!allowRepeated
) {
205 std::size_t npts
=getSize();
207 const Coordinate
& last
=getAt(npts
-1);
208 if (last
.equals2D(c
))
215 /* Here for backward compatibility */
217 //CoordinateSequence::add(CoordinateSequence *cl, bool allowRepeated,
220 // add(cl, allowRepeated, direction);
225 CoordinateSequence::add(const CoordinateSequence
*cl
,
226 bool allowRepeated
, bool direction
)
228 // FIXME: don't rely on negative values for 'j' (the reverse case)
230 const int npts
= static_cast<int>(cl
->getSize());
232 for (int i
=0; i
<npts
; i
++) {
233 add(cl
->getAt(i
), allowRepeated
);
236 for (int j
=npts
-1; j
>=0; j
--) {
237 add(cl
->getAt(j
), allowRepeated
);
245 CoordinateSequence::removeRepeatedPoints(const CoordinateSequence
*cl
)
248 static Profile
*prof
= profiler
->get("CoordinateSequence::removeRepeatedPoints()");
251 const vector
<Coordinate
> *v
=cl
->toVector();
253 vector
<Coordinate
> *nv
=new vector
<Coordinate
>;
254 nv
->reserve(v
->size());
255 unique_copy(v
->begin(), v
->end(), back_inserter(*nv
));
256 CoordinateSequence
* ret
=CoordinateArraySequenceFactory::instance()->create(nv
);
265 CoordinateSequence::expandEnvelope(Envelope
&env
) const
267 const std::size_t size
= getSize();
268 for (std::size_t i
=0; i
<size
; i
++)
269 env
.expandToInclude(getAt(i
));
272 std::ostream
& operator<< (std::ostream
& os
, const CoordinateSequence
& cs
)
275 for (size_t i
=0, n
=cs
.size(); i
<n
; ++i
)
277 const Coordinate
& c
= cs
[i
];
286 bool operator== ( const CoordinateSequence
& s1
, const CoordinateSequence
& s2
)
288 return CoordinateSequence::equals(&s1
, &s2
);
291 bool operator!= ( const CoordinateSequence
& s1
, const CoordinateSequence
& s2
)
293 return ! CoordinateSequence::equals(&s1
, &s2
);
296 } // namespace geos::geom
299 /**********************************************************************
301 * Revision 1.21 2006/06/12 16:51:23 strk
302 * Added equality and inequality operators and tests
304 * Revision 1.20 2006/06/12 16:36:22 strk
305 * indentation, notes about things to be fixed.
307 * Revision 1.19 2006/06/12 10:10:39 strk
308 * Fixed getGeometryN() to take size_t rather then int, changed unsigned int parameters to size_t.
310 * Revision 1.18 2006/05/03 19:47:27 strk
311 * added operator<< for CoordinateSequence
313 **********************************************************************/