File: OffsetPointGenerator.cpp

package info (click to toggle)
geos 3.0.0-5
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 10,060 kB
  • ctags: 8,674
  • sloc: cpp: 64,513; xml: 23,384; sh: 8,965; ruby: 1,295; makefile: 1,124; python: 824; ansic: 289
file content (112 lines) | stat: -rw-r--r-- 2,928 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/**********************************************************************
 * $Id: OffsetPointGenerator.cpp 1941 2006-12-13 10:55:55Z strk $
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * 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: operation/overlay/validate/OffsetPointGenerator.java rev. 1.1
 * (we should move in GEOS too, probably)
 *
 **********************************************************************/

#include <geos/operation/overlay/OffsetPointGenerator.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/LineString.h> 
#include <geos/geom/MultiPoint.h> 
#include <geos/geom/CoordinateSequence.h> 
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/util/LinearComponentExtracter.h> 

#include <cassert>
#include <functional>
#include <vector>
#include <memory> // for auto_ptr
#include <cmath>
#include <algorithm> // std::for_each

#ifndef GEOS_DEBUG
#define GEOS_DEBUG 0
#endif

using namespace std;
using namespace geos::geom;
using namespace geos::algorithm;

namespace geos {
namespace operation { // geos.operation
namespace overlay { // geos.operation.overlay

/*public*/
OffsetPointGenerator::OffsetPointGenerator(const geom::Geometry& geom,
		double offset)
	:
	g(geom),
	offsetDistance(offset)
{
}

/*public*/
std::auto_ptr< std::vector<geom::Coordinate> >
OffsetPointGenerator::getPoints()
{
	assert (offsetPts.get() == NULL);
	offsetPts.reset(new vector<Coordinate>());

	vector<const LineString*> lines;
	geos::geom::util::LinearComponentExtracter::getLines(g, lines);
	for_each(lines.begin(), lines.end(),
		bind1st(mem_fun(&OffsetPointGenerator::extractPoints), this));

	return offsetPts;
}

/*private*/
void
OffsetPointGenerator::extractPoints(const LineString* line)
{
	const CoordinateSequence& pts = *(line->getCoordinatesRO());
	assert(pts.size() > 1 );

	for (size_t i=0, n=pts.size()-1; i<n; ++i)
	{
		computeOffsets(pts[i], pts[i + 1]);
	}
}

/*private*/
void
OffsetPointGenerator::computeOffsets(const Coordinate& p0,
		const Coordinate& p1)
{
	double dx = p1.x - p0.x;
	double dy = p1.y - p0.y;
	double len = sqrt(dx * dx + dy * dy);

	// u is the vector that is the length of the offset,
	// in the direction of the segment
	double ux = offsetDistance * dx / len;
	double uy = offsetDistance * dy / len;

	double midX = (p1.x + p0.x) / 2;
	double midY = (p1.y + p0.y) / 2;

	Coordinate offsetLeft(midX - uy, midY + ux);
	Coordinate offsetRight(midX + uy, midY - ux);

	offsetPts->push_back(offsetLeft);
	offsetPts->push_back(offsetRight);
}

} // namespace geos.operation.overlay
} // namespace geos.operation
} // namespace geos