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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
/**********************************************************************
* $Id: SIRtreePointInRing.cpp 1986 2007-06-08 15:27:42Z mloskot $
*
* GEOS - Geometry Engine Open Source
* http://geos.refractions.net
*
* Copyright (C) 2005-2006 Refractions Research Inc.
* Copyright (C) 2001-2002 Vivid Solutions 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.
*
**********************************************************************
*
**********************************************************************/
#include <geos/algorithm/SIRtreePointInRing.h>
#include <geos/algorithm/RobustDeterminant.h>
#include <geos/index/strtree/SIRtree.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/LineSegment.h>
#include <geos/geom/Coordinate.h>
#include <vector>
using namespace std;
using namespace geos::index::strtree;
using namespace geos::geom;
namespace geos {
namespace algorithm { // geos.algorithm
SIRtreePointInRing::SIRtreePointInRing(LinearRing *newRing):
PointInRing(),
ring(newRing),
sirTree(NULL),
crossings(0)
{
buildIndex();
}
void
SIRtreePointInRing::buildIndex()
{
//Envelope *env=ring->getEnvelopeInternal();
sirTree=new SIRtree();
const CoordinateSequence *pts=ring->getCoordinatesRO();
const std::size_t npts=pts->getSize();
for(std::size_t i=1; i<npts; ++i)
{
if(pts->getAt(i-1)==pts->getAt(i)) continue; // Optimization suggested by MD. [Jon Aquino]
LineSegment *seg=new LineSegment(pts->getAt(i-1), pts->getAt(i));
sirTree->insert(seg->p0.y, seg->p1.y, seg);
}
}
bool
SIRtreePointInRing::isInside(const Coordinate& pt)
{
crossings=0;
// test all segments intersected by vertical ray at pt
vector<void*> *segs=sirTree->query(pt.y);
//System.out.println("query size=" + segs.size());
for(int i=0;i<(int)segs->size();i++) {
LineSegment *seg=(LineSegment*) (*segs)[i];
testLineSegment(pt,seg);
}
/*
* p is inside if number of crossings is odd.
*/
if ((crossings%2)==1) {
return true;
}
return false;
}
void
SIRtreePointInRing::testLineSegment(const Coordinate& p,LineSegment *seg)
{
double xInt; // x intersection of segment with ray
double x1; // translated coordinates
double y1;
double x2;
double y2;
/*
* Test if segment crosses ray from test point in positive x direction.
*/
Coordinate& p1=seg->p0;
Coordinate& p2=seg->p1;
x1=p1.x-p.x;
y1=p1.y-p.y;
x2=p2.x-p.x;
y2=p2.y-p.y;
if (((y1>0) && (y2<=0)) ||
((y2>0) && (y1<=0))) {
/*
* segment straddles x axis,so compute intersection.
*/
xInt=RobustDeterminant::signOfDet2x2(x1,y1,x2,y2)/(y2-y1);
//xsave=xInt;
/*
* crosses ray if strictly positive intersection.
*/
if (0.0<xInt) {
crossings++;
}
}
}
} // namespace geos.algorithm
} // namespace geos
/**********************************************************************
* $Log$
* Revision 1.17 2006/03/21 11:12:23 strk
* Cleanups: headers inclusion and Log section
*
* Revision 1.16 2006/03/09 16:46:46 strk
* geos::geom namespace definition, first pass at headers split
*
**********************************************************************/
|