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
|
/**********************************************************************
* $Id: SIRtreePointInRing.cpp,v 1.10 2004/07/27 16:35:46 strk Exp $
*
* GEOS - Geometry Engine Open Source
* http://geos.refractions.net
*
* 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.
*
**********************************************************************
* $Log: SIRtreePointInRing.cpp,v $
* Revision 1.10 2004/07/27 16:35:46 strk
* Geometry::getEnvelopeInternal() changed to return a const Envelope *.
* This should reduce object copies as once computed the envelope of a
* geometry remains the same.
*
* Revision 1.9 2004/07/08 19:34:49 strk
* Mirrored JTS interface of CoordinateSequence, factory and
* default implementations.
* Added DefaultCoordinateSequenceFactory::instance() function.
*
* Revision 1.8 2004/07/02 13:28:26 strk
* Fixed all #include lines to reflect headers layout change.
* Added client application build tips in README.
*
* Revision 1.7 2003/11/07 01:23:42 pramsey
* Add standard CVS headers licence notices and copyrights to all cpp and h
* files.
*
* Revision 1.6 2003/10/16 08:50:00 strk
* Memory leak fixes. Improved performance by mean of more calls to
* new getCoordinatesRO() when applicable.
*
**********************************************************************/
#include <geos/geosAlgorithm.h>
#include <stdio.h>
namespace geos {
SIRtreePointInRing::SIRtreePointInRing(LinearRing *newRing){
ring=newRing;
sirTree=NULL;
crossings=0;
buildIndex();
}
void SIRtreePointInRing::buildIndex() {
//Envelope *env=ring->getEnvelopeInternal();
sirTree=new SIRtree();
const CoordinateSequence *pts=ring->getCoordinatesRO();
for(int i=1;i<pts->getSize();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++;
}
}
}
}
|