wktreader.cpp

来自「一个很好的vc底层代码」· C++ 代码 · 共 383 行

CPP
383
字号
/********************************************************************** * $Id: WKTReader.cpp,v 1.30 2004/12/08 13:54:43 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. * **********************************************************************/#include <geos/io.h>#include <geos/util.h>namespace geos {//WKTReader::WKTReader(){//	geometryFactory=new GeometryFactory();//	precisionModel=geometryFactory->getPrecisionModel();//}WKTReader::WKTReader(const GeometryFactory *gf){	geometryFactory=gf;	precisionModel=gf->getPrecisionModel();}WKTReader::~WKTReader(){	//delete geometryFactory;}Geometry* WKTReader::read(string wellKnownText){	auto_ptr<StringTokenizer> tokenizer(new StringTokenizer(wellKnownText));	StringTokenizer *st=tokenizer.release();	Geometry *g=NULL;	try {		g=readGeometryTaggedText(st);	}	catch (...) {		delete st;		throw;	}	delete st;	return g;}CoordinateSequence* WKTReader::getCoordinates(StringTokenizer *tokenizer) {	string nextToken=getNextEmptyOrOpener(tokenizer);	if (nextToken=="EMPTY") {		return new DefaultCoordinateSequence(); 	}	CoordinateSequence *coordinates = new DefaultCoordinateSequence();	Coordinate *coord = getPreciseCoordinate(tokenizer);	coordinates->add(*coord);	delete coord; coord=NULL;	try {		nextToken=getNextCloserOrComma(tokenizer);		while (nextToken==",") {			coord = getPreciseCoordinate(tokenizer);			coordinates->add(*coord);			delete coord; coord=NULL;			nextToken=getNextCloserOrComma(tokenizer);		}	} catch (...) {		delete coord;		delete coordinates;		throw;	}	return coordinates;}Coordinate* WKTReader::getPreciseCoordinate(StringTokenizer *tokenizer) {	Coordinate *coord=new Coordinate();	try {		coord->x=getNextNumber(tokenizer);		coord->y=getNextNumber(tokenizer);		if (isNumberNext(tokenizer)) {			coord->z=getNextNumber(tokenizer);		}		precisionModel->makePrecise(coord);	} catch (...) {		delete coord;		throw;	}	return coord;}bool WKTReader::isNumberNext(StringTokenizer *tokenizer) {	return tokenizer->peekNextToken()==StringTokenizer::TT_NUMBER;}double WKTReader::getNextNumber(StringTokenizer *tokenizer) {	int type=tokenizer->nextToken();	switch(type){		case StringTokenizer::TT_EOF:			throw new ParseException("Expected number but encountered end of stream");		case StringTokenizer::TT_EOL:			throw new ParseException("Expected number but encountered end of line");		case StringTokenizer::TT_NUMBER:			return tokenizer->getNVal();		case StringTokenizer::TT_WORD:			throw new ParseException("Expected number but encountered word",tokenizer->getSVal());		case '(':			throw new ParseException("Expected number but encountered '('");		case ')':			throw new ParseException("Expected number but encountered ')'");		case ',':			throw new ParseException("Expected number but encountered ','");	}	Assert::shouldNeverReachHere("Encountered unexpected StreamTokenizer type");	return 0;}string WKTReader::getNextEmptyOrOpener(StringTokenizer *tokenizer) {	string nextWord=getNextWord(tokenizer);	if (nextWord=="EMPTY" || nextWord=="(") {		return nextWord;	}	throw new ParseException("Expected 'EMPTY' or '(' but encountered ",nextWord);}string WKTReader::getNextCloserOrComma(StringTokenizer *tokenizer) {	string nextWord=getNextWord(tokenizer);	if (nextWord=="," || nextWord==")") {		return nextWord;	}	throw new ParseException("Expected ')' or ',' but encountered",nextWord);}string WKTReader::getNextCloser(StringTokenizer *tokenizer) {	string nextWord=getNextWord(tokenizer);	if (nextWord==")") {		return nextWord;	}	throw new ParseException("Expected ')' but encountered",nextWord);}string WKTReader::getNextWord(StringTokenizer *tokenizer) {	int type=tokenizer->nextToken();	switch(type){		case StringTokenizer::TT_EOF:			throw new ParseException("Expected word but encountered end of stream");		case StringTokenizer::TT_EOL:			throw new ParseException("Expected word but encountered end of line");		case StringTokenizer::TT_NUMBER:			throw new ParseException("Expected word but encountered number", tokenizer->getNVal());		case StringTokenizer::TT_WORD:			return tokenizer->getSVal();		case '(':			return "(";		case ')':			return ")";		case ',':			return ",";	}	Assert::shouldNeverReachHere("Encountered unexpected StreamTokenizer type");	return "";}Geometry* WKTReader::readGeometryTaggedText(StringTokenizer *tokenizer) {	string type = getNextWord(tokenizer);	if (type=="POINT") {		return readPointText(tokenizer);	} else if (type=="LINESTRING") {		return readLineStringText(tokenizer);	} else if (type=="LINEARRING") {		return readLinearRingText(tokenizer);	} else if (type=="POLYGON") {		return readPolygonText(tokenizer);	} else if (type=="MULTIPOINT") {		return readMultiPointText(tokenizer);	} else if (type=="MULTILINESTRING") {		return readMultiLineStringText(tokenizer);	} else if (type=="MULTIPOLYGON") {		return readMultiPolygonText(tokenizer);	} else if (type=="GEOMETRYCOLLECTION") {		return readGeometryCollectionText(tokenizer);	}	throw new ParseException("Unknown type",type);}Point* WKTReader::readPointText(StringTokenizer *tokenizer) {	string nextToken=getNextEmptyOrOpener(tokenizer);	if (nextToken=="EMPTY") {		return geometryFactory->createPoint(Coordinate::getNull());	}	Coordinate *coord = getPreciseCoordinate(tokenizer);	Point *pt=geometryFactory->createPoint(*coord);	delete coord;	try {		getNextCloser(tokenizer);	} catch (...) {		delete pt;		throw;	}	return pt;}LineString* WKTReader::readLineStringText(StringTokenizer *tokenizer) {	CoordinateSequence *coords = getCoordinates(tokenizer);	LineString *ret = geometryFactory->createLineString(coords);	return ret;}LinearRing* WKTReader::readLinearRingText(StringTokenizer *tokenizer) {	CoordinateSequence *coords = getCoordinates(tokenizer);	LinearRing *ret;	ret = geometryFactory->createLinearRing(coords);	return ret;}MultiPoint* WKTReader::readMultiPointText(StringTokenizer *tokenizer) {	CoordinateSequence *coords = getCoordinates(tokenizer);	MultiPoint *ret = geometryFactory->createMultiPoint(*coords);	delete coords;	return ret;}Polygon*WKTReader::readPolygonText(StringTokenizer *tokenizer){	Polygon *poly=NULL;	LinearRing *shell=NULL;	string nextToken=getNextEmptyOrOpener(tokenizer);	if (nextToken=="EMPTY") {		return geometryFactory->createPolygon(NULL,NULL);	}	vector<Geometry *> *holes=new vector<Geometry *>();	try {		shell=readLinearRingText(tokenizer);		nextToken=getNextCloserOrComma(tokenizer);		while(nextToken==",") {			LinearRing *hole=readLinearRingText(tokenizer);			holes->push_back(hole);			nextToken=getNextCloserOrComma(tokenizer);		}		poly = geometryFactory->createPolygon(shell,holes);	} catch (...) {		for (unsigned int i=0; i<holes->size(); i++)			delete (*holes)[i];		delete holes;		delete shell;		throw;	}	return poly;}MultiLineString* WKTReader::readMultiLineStringText(StringTokenizer *tokenizer) {	string nextToken=getNextEmptyOrOpener(tokenizer);	if (nextToken=="EMPTY") {		return geometryFactory->createMultiLineString(NULL);	}	vector<Geometry *> *lineStrings=new vector<Geometry *>();	LineString *lineString=readLineStringText(tokenizer);	lineStrings->push_back(lineString);	nextToken=getNextCloserOrComma(tokenizer);	while(nextToken==",") {		LineString *lineString=readLineStringText(tokenizer);		lineStrings->push_back(lineString);		nextToken=getNextCloserOrComma(tokenizer);	}	MultiLineString *ret = geometryFactory->createMultiLineString(lineStrings);	//for (int i=0; i<lineStrings->size(); i++) delete (*lineStrings)[i];	//delete lineStrings;	return ret;}MultiPolygon* WKTReader::readMultiPolygonText(StringTokenizer *tokenizer) {	string nextToken=getNextEmptyOrOpener(tokenizer);	if (nextToken=="EMPTY") {		return geometryFactory->createMultiPolygon(NULL);	}	vector<Geometry *> *polygons=new vector<Geometry *>();	Polygon *polygon=readPolygonText(tokenizer);	polygons->push_back(polygon);	nextToken=getNextCloserOrComma(tokenizer);	while(nextToken==",") {		Polygon *polygon=readPolygonText(tokenizer);		polygons->push_back(polygon);		nextToken=getNextCloserOrComma(tokenizer);	}	MultiPolygon *ret = geometryFactory->createMultiPolygon(polygons);	//for (int i=0; i<polygons->size(); i++) delete (*polygons)[i];	//delete polygons;	return ret;}GeometryCollection* WKTReader::readGeometryCollectionText(StringTokenizer *tokenizer) {	string nextToken=getNextEmptyOrOpener(tokenizer);	if (nextToken=="EMPTY") {		return geometryFactory->createGeometryCollection(NULL);	}	vector<Geometry *> *geoms=new vector<Geometry *>();	Geometry *geom;	geom=readGeometryTaggedText(tokenizer);	geoms->push_back(geom);	nextToken=getNextCloserOrComma(tokenizer);	while(nextToken==",") {		geom=readGeometryTaggedText(tokenizer);		geoms->push_back(geom);		nextToken=getNextCloserOrComma(tokenizer);	}	GeometryCollection *ret = geometryFactory->createGeometryCollection(geoms);	//for (int i=0; i<geoms->size(); i++) delete (*geoms)[i];	//delete geoms;	return ret;}}/********************************************************************** * $Log: WKTReader.cpp,v $ * Revision 1.30  2004/12/08 13:54:43  strk * gcc warnings checked and fixed, general cleanups. * * Revision 1.29  2004/10/21 17:13:59  strk * Fixed bug introduced by previous patch. * * Revision 1.28  2004/10/21 07:03:31  strk * Removed leak in ::readPolygonText reported by Carlos A. Rueda * * Revision 1.27  2004/07/08 19:34:49  strk * Mirrored JTS interface of CoordinateSequence, factory and * default implementations. * Added DefaultCoordinateSequenceFactory::instance() function. * * Revision 1.26  2004/07/07 09:38:12  strk * Dropped WKTWriter::stringOfChars (implemented by std::string). * Dropped WKTWriter default constructor (internally created GeometryFactory). * Updated XMLTester to respect the changes. * Main documentation page made nicer. * * Revision 1.25  2004/07/05 10:50:21  strk * deep-dopy construction taken out of Geometry and implemented only * in GeometryFactory. * Deep-copy geometry construction takes care of cleaning up copies * on exception. * Implemented clone() method for CoordinateSequence * Changed createMultiPoint(CoordinateSequence) signature to reflect * copy semantic (by-ref instead of by-pointer). * Cleaned up documentation. * * Revision 1.24  2004/07/02 13:28:27  strk * Fixed all #include lines to reflect headers layout change. * Added client application build tips in README. * * Revision 1.23  2004/07/01 14:12:44  strk * * Geometry constructors come now in two flavors: * 	- deep-copy args (pass-by-reference) * 	- take-ownership of args (pass-by-pointer) * Same functionality is available through GeometryFactory, * including buildGeometry(). * * Revision 1.22  2004/06/15 20:30:00  strk * fixed a typo * * Revision 1.21  2004/06/15 20:16:19  strk * updated to respect deep-copy GeometryCollection interface * * Revision 1.20  2004/05/14 12:10:54  strk * avoided leaks on malformed LinearRing * * Revision 1.19  2004/05/07 13:23:51  strk * Memory leaks fixed. * * Revision 1.18  2004/03/18 10:42:44  ybychkov * "IO" and "Util" upgraded to JTS 1.4 * "Geometry" partially upgraded. * * Revision 1.17  2003/11/07 01:23:42  pramsey * Add standard CVS headers licence notices and copyrights to all cpp and h * files. * * Revision 1.16  2003/10/15 08:52:55  strk * Memory leaks fixed. * **********************************************************************/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?