EVOLUTION-MANAGER
Edit File: PrecisionModel.cpp
/********************************************************************** * * GEOS - Geometry Engine Open Source * http://geos.osgeo.org * * Copyright (C) 2011 Sandro Santilli <strk@kbt.io> * 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. * ********************************************************************** * * Last port: geom/PrecisionModel.java r378 (JTS-1.12) * **********************************************************************/ #include <geos/geom/PrecisionModel.h> #include <geos/geom/Coordinate.h> #include <geos/util/IllegalArgumentException.h> #include <geos/util/math.h> #include <geos/util.h> #include <sstream> #include <string> #include <cmath> #include <iostream> #ifndef GEOS_INLINE # include <geos/geom/PrecisionModel.inl> #endif #ifndef GEOS_DEBUG #define GEOS_DEBUG 0 #endif using namespace std; namespace geos { namespace geom { // geos::geom const double PrecisionModel::maximumPreciseValue = 9007199254740992.0; /*public*/ double PrecisionModel::makePrecise(double val) const { #if GEOS_DEBUG cerr << "PrecisionModel[" << this << "]::makePrecise called" << endl; #endif if(modelType == FLOATING_SINGLE) { float floatSingleVal = static_cast<float>(val); return static_cast<double>(floatSingleVal); } if(modelType == FIXED) { // Use whatever happens to be the default rounding method const double ret = util::round(val * scale) / scale; return ret; } // modelType == FLOATING - no rounding necessary return val; } /*public*/ void PrecisionModel::makePrecise(Coordinate& coord) const { // optimization for full precision if(modelType == FLOATING) { return; } coord.x = makePrecise(coord.x); coord.y = makePrecise(coord.y); } /*public*/ PrecisionModel::PrecisionModel() : modelType(FLOATING), scale(0.0) { #if GEOS_DEBUG cerr << "PrecisionModel[" << this << "] ctor()" << endl; #endif //modelType=FLOATING; //scale=1.0; } /*public*/ PrecisionModel::PrecisionModel(Type nModelType) : modelType(nModelType), scale(1.0) { #if GEOS_DEBUG cerr << "PrecisionModel[" << this << "] ctor(Type)" << endl; #endif //modelType=nModelType; //if (modelType==FIXED) setScale(1.0); //else setScale(666); // arbitrary number for invariant testing } /*public (deprecated) */ PrecisionModel::PrecisionModel(double newScale, double newOffsetX, double newOffsetY) //throw(IllegalArgumentException *) : modelType(FIXED) { ::geos::ignore_unused_variable_warning(newOffsetX); ::geos::ignore_unused_variable_warning(newOffsetY); #if GEOS_DEBUG cerr << "PrecisionModel[" << this << "] ctor(scale,offsets)" << endl; #endif //modelType = FIXED; setScale(newScale); } /*public*/ PrecisionModel::PrecisionModel(double newScale) //throw (IllegalArgumentException *) : modelType(FIXED) { #if GEOS_DEBUG cerr << "PrecisionModel[" << this << "] ctor(scale)" << endl; #endif setScale(newScale); } PrecisionModel::PrecisionModel(const PrecisionModel& pm) : modelType(pm.modelType), scale(pm.scale) { #if GEOS_DEBUG cerr << "PrecisionModel[" << this << "] ctor(pm[" << &pm << "])" << endl; #endif } /*public*/ bool PrecisionModel::isFloating() const { return (modelType == FLOATING || modelType == FLOATING_SINGLE); } /*public*/ int PrecisionModel::getMaximumSignificantDigits() const { int maxSigDigits = 16; if(modelType == FLOATING) { maxSigDigits = 16; } else if(modelType == FLOATING_SINGLE) { maxSigDigits = 6; } else if(modelType == FIXED) { double dgtsd = std::log(getScale()) / std::log(double(10.0)); const int dgts = static_cast<int>( dgtsd > 0 ? std::ceil(dgtsd) : std::floor(dgtsd) ); maxSigDigits = dgts; } return maxSigDigits; } /*private*/ void PrecisionModel::setScale(double newScale) // throw IllegalArgumentException { if(newScale <= 0) { throw util::IllegalArgumentException("PrecisionModel scale cannot be 0"); } scale = std::fabs(newScale); } /*public*/ double PrecisionModel::getOffsetX() const { return 0; } /*public*/ double PrecisionModel::getOffsetY() const { return 0; } string PrecisionModel::toString() const { ostringstream s; if(modelType == FLOATING) { s << "Floating"; } else if(modelType == FLOATING_SINGLE) { s << "Floating-Single"; } else if(modelType == FIXED) { s << "Fixed (Scale=" << getScale() << " OffsetX=" << getOffsetX() << " OffsetY=" << getOffsetY() << ")"; } else { s << "UNKNOWN"; } return s.str(); } bool operator==(const PrecisionModel& a, const PrecisionModel& b) { return a.isFloating() == b.isFloating() && a.getScale() == b.getScale(); } /*public*/ int PrecisionModel::compareTo(const PrecisionModel* other) const { int sigDigits = getMaximumSignificantDigits(); int otherSigDigits = other->getMaximumSignificantDigits(); return sigDigits < otherSigDigits ? -1 : (sigDigits == otherSigDigits ? 0 : 1); } } // namespace geos::geom } // namespace geos