1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2006 Refractions Research Inc.
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.
13 ***********************************************************************
15 * Last port: operation/overlay/validate/OffsetPointGenerator.java rev. 1.1 (JTS-1.10)
17 **********************************************************************/
19 #include <geos/operation/overlay/validate/OffsetPointGenerator.h>
20 #include <geos/geom/Geometry.h>
21 #include <geos/geom/LineString.h>
22 #include <geos/geom/MultiPoint.h>
23 #include <geos/geom/CoordinateSequence.h>
24 #include <geos/geom/GeometryFactory.h>
25 #include <geos/geom/util/LinearComponentExtracter.h>
30 #include <memory> // for auto_ptr
32 #include <algorithm> // std::for_each
39 using namespace geos::geom
;
40 using namespace geos::algorithm
;
43 namespace operation
{ // geos.operation
44 namespace overlay
{ // geos.operation.overlay
45 namespace validate
{ // geos.operation.overlay.validate
48 OffsetPointGenerator::OffsetPointGenerator(const geom::Geometry
& geom
,
52 offsetDistance(offset
)
57 std::auto_ptr
< std::vector
<geom::Coordinate
> >
58 OffsetPointGenerator::getPoints()
60 assert (offsetPts
.get() == NULL
);
61 offsetPts
.reset(new vector
<Coordinate
>());
63 vector
<const LineString
*> lines
;
64 geos::geom::util::LinearComponentExtracter::getLines(g
, lines
);
65 for_each(lines
.begin(), lines
.end(),
66 bind1st(mem_fun(&OffsetPointGenerator::extractPoints
), this));
73 OffsetPointGenerator::extractPoints(const LineString
* line
)
75 const CoordinateSequence
& pts
= *(line
->getCoordinatesRO());
76 assert(pts
.size() > 1 );
78 for (size_t i
=0, n
=pts
.size()-1; i
<n
; ++i
)
80 computeOffsets(pts
[i
], pts
[i
+ 1]);
86 OffsetPointGenerator::computeOffsets(const Coordinate
& p0
,
89 double dx
= p1
.x
- p0
.x
;
90 double dy
= p1
.y
- p0
.y
;
91 double len
= sqrt(dx
* dx
+ dy
* dy
);
93 // u is the vector that is the length of the offset,
94 // in the direction of the segment
95 double ux
= offsetDistance
* dx
/ len
;
96 double uy
= offsetDistance
* dy
/ len
;
98 double midX
= (p1
.x
+ p0
.x
) / 2;
99 double midY
= (p1
.y
+ p0
.y
) / 2;
101 Coordinate
offsetLeft(midX
- uy
, midY
+ ux
);
102 Coordinate
offsetRight(midX
+ uy
, midY
- ux
);
104 offsetPts
->push_back(offsetLeft
);
105 offsetPts
->push_back(offsetRight
);
108 } // namespace geos.operation.overlay.validate
109 } // namespace geos.operation.overlay
110 } // namespace geos.operation