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
|