Opened 7 years ago

Closed 5 years ago

#569 closed defect (fixed)

Exception when buffer a small-angle polygon

Reported by: 55 Owned by: strk
Priority: major Milestone: 3.3.9
Component: Core Version: 3.3.3
Severity: Unassigned Keywords: Buffer
Cc:

Description (last modified by strk)

I use this points as polygon coordinates:

X Y

0 0/ 50 100/ 30 130/ 124 290/ 82 144/ 129 289/ 120 140/ 170 135/ 0 0/

then:

geos::geom::Polygon* poly; poly->buffer( 25 ); throws util::TopologyException?

finally, i find the reason: default quadrantSegments is 8,so i try "poly->buffer( 25, 6 )" instead,everything is OK;

Attachments (1)

GEOS_Shiyan.cpp (3.6 KB) - added by 55 7 years ago.

Download all attachments as: .zip

Change History (9)

comment:1 Changed 7 years ago by strk

Milestone: 3.3.53.3.6

comment:2 Changed 7 years ago by strk

Description: modified (diff)
Milestone: 3.3.63.3.7

Can you still reproduce with 3.3.6 ? Can you provide an XML testcase for this ?

comment:3 Changed 7 years ago by 55

This is my test case,my ststem is WindowsXP,IDE is VS2005, still throw a error in geos 3.3.3.And i download the geos 3.3.6 just now and test this problem,the bug still exist. : GEOS_Shiyan.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"

#include <iostream> #include <fstream> #include <float.h> #include <math.h> #include <geos.h> #include <geos/operation/buffer/BufferBuilder.h> #include <geos/operation/buffer/BufferParameters.h> #include <geos/operation/buffer/BufferOp.h> #include <gl/freeglut.h>

#pragma comment( lib, "geos.lib" )

#define SHOW_GLWND

geos::geom::CoordinateArraySequence? coords; Origin data points const geos::geom::Coordinate* resultPoints; result double XMin, XMax, YMin, YMax, XRange, YRange; int pointscount;

void display(void) {

glClear (GL_COLOR_BUFFER_BIT); glPushMatrix();

glPointSize( 3 ); glColor3f( 0, 0, 1 ); glBegin( GL_LINE_LOOP );

for ( int i = 0; i < coords.getSize(); i ++ ) {

glVertex2f( coords.getAt( i ).x, coords.getAt( i ).y );

}

glEnd();

glPushClientAttrib( GL_LINE_BIT );

glLineWidth( 1.5 ); glEnable( GL_LINE_STIPPLE ); glLineStipple ( 1, 0x1C47 ); glColor3f( 1, 0, 0 ); glBegin( GL_LINE_LOOP );

for ( int i = 0; i < pointscount; i ++ ) {

glVertex2f( resultPoints[ i ].x, resultPoints[ i ].y );

}

glEnd(); glDisable( GL_LINE_STIPPLE );

glPopClientAttrib();

glPopMatrix(); glutSwapBuffers();

}

void keyfun(unsigned char key, int x, int y) {

switch ( key ) { case 27:

exit( 0 ); break;

}

}

void mouse(int button, int state, int x, int y) {

switch ( button ) { case 3: 前滚轮

break;

case 4: 后滚轮

break;

}

}

void reshape(int w, int h) {

glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D( XMin - XRange * 0.2, XMax + XRange * 0.2, YMin - YRange * 0.2, YMax + YRange * 0.2 ); glMatrixMode(GL_MODELVIEW); glLoadIdentity();

}

int main(int argc, char argv) {

read data double BufferDist? = 25; std::ifstream fid( "data.txt", std::ios::in ); char CellRow?[ 256 ]; double x, y;

while ( fid.getline( CellRow?, 256 ) ) {

sscanf( CellRow?, "%lf\t%lf", &x, &y ); coords.add( Coordinate( x, y ) );

}

fid.close();

buffer the polygon geos::geom::GeometryFactory? factory_( new geos::geom::PrecisionModel?( 1 ), 0 ); geos::geom::LinearRing? HullRing?( &coords, &factory_ ); geos::geom::LinearRing?* exterior = dynamic_cast<geos::geom::LinearRing*>( HullRing?.clone() ); std::auto_ptr< geos::geom::Polygon > HullPoly?( factory_.createPolygon( exterior, 0 ) ); geos::geom::Geometry* result = HullPoly?->buffer( BufferDist?, 8 ); !!!!!!!!!! quadrantSegments default is 8, maybe throw a exception( geos::util::TopologyException? ) pointscount = result->getNumPoints(); resultPoints = result->getCoordinate();

XMin = DBL_MAX; XMax = -DBL_MAX; YMin = DBL_MAX; YMax = -DBL_MAX;

for ( int i = 0; i < pointscount; i ++ ) {

if( resultPoints[ i ].x < XMin )

XMin = resultPoints[ i ].x;

if( resultPoints[ i ].x > XMax )

XMax = resultPoints[ i ].x;

if( resultPoints[ i ].y < YMin )

YMin = resultPoints[ i ].y;

if( resultPoints[ i ].y > YMax )

YMax = resultPoints[ i ].y;

} XRange = XMax - XMin; YRange = YMax - YMin;

display in glut window

#ifdef SHOW_GLWND

glutInit( &argc, argv ); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize (700, 600); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); glutSetWindowTitle( "buffer test" );

glClearColor( 0.91, 0.93, 0.95, 0.0 );

glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc( keyfun ); glutMouseFunc( mouse );

glutMainLoop();

#endif

return 0; exit( 0 );

}

Changed 7 years ago by 55

Attachment: GEOS_Shiyan.cpp added

comment:4 Changed 7 years ago by strk

Milestone: 3.3.73.4.0

robustness issue, probably. postponing to 3.4 series

comment:5 Changed 6 years ago by robe

is this safe enough to apply or should we push?

comment:6 Changed 6 years ago by strk

There's nothing to apply here. Only a testcase which would be nice to test against JTS in order to determine if the milestone should be 3.3, 3.5 or future.

comment:7 Changed 6 years ago by robe

Milestone: 3.4.03.5.0

comment:8 Changed 5 years ago by strk

Milestone: 3.5.03.3.9
Resolution: fixed
Status: newclosed

I do get a meaningful answer from Buffer with distance 25 and quadrant segments 8 and committed test securing it as of GEOS from 3.3.10-dev (r4042), 3.4.3-dev (r4044) and 3.5.0-dev (trunk, r4046) branches.

Assuming it was fixed by 3.3.9 already

Note: See TracTickets for help on using tickets.