Skip to content

Commit

Permalink
Merge pull request #118 from szekerest/master
Browse files Browse the repository at this point in the history
Fix for issues with sql server geography type
  • Loading branch information
NathanW2 committed Apr 12, 2012
2 parents 67c77e5 + be8f135 commit 7773ddf
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 13 deletions.
25 changes: 21 additions & 4 deletions src/providers/mssql/qgsmssqlgeometryparser.cpp
Expand Up @@ -121,6 +121,22 @@ void QgsMssqlGeometryParser::CopyBytes( void* src, int len )
nWkbLen += len;
}

/************************************************************************/
/* CopyCoordinates() */
/************************************************************************/

void QgsMssqlGeometryParser::CopyCoordinates( unsigned char* src )
{
if (IsGeography)
{
CopyBytes( src + 8, 8 ); // longitude
CopyBytes( src, 8 ); // latitude
}
else
// copy geometry coords
CopyBytes( src, nPointSize );
}

/************************************************************************/
/* CopyPoint() */
/************************************************************************/
Expand All @@ -137,7 +153,7 @@ void QgsMssqlGeometryParser::CopyPoint( int iPoint )
wkbType = QGis::WKBPoint;
CopyBytes( &wkbType, 4 );
// copy coordinates
CopyBytes( pszData + nPointPos + nPointSize * iPoint, nPointSize );
CopyCoordinates( pszData + nPointPos + nPointSize * iPoint );
}

/************************************************************************/
Expand Down Expand Up @@ -216,7 +232,7 @@ void QgsMssqlGeometryParser::ReadLineString( int iShape )
i = 0;
while ( iPoint < iNextPoint )
{
CopyBytes( pszData + nPointPos + nPointSize * iPoint, nPointSize );
CopyCoordinates( pszData + nPointPos + nPointSize * iPoint );
++iPoint;
++i;
}
Expand Down Expand Up @@ -290,7 +306,7 @@ void QgsMssqlGeometryParser::ReadPolygon( int iShape )
i = 0;
while ( iPoint < iNextPoint )
{
CopyBytes( pszData + nPointPos + nPointSize * iPoint, nPointSize );
CopyCoordinates( pszData + nPointPos + nPointSize * iPoint );
++iPoint;
++i;
}
Expand Down Expand Up @@ -460,7 +476,8 @@ unsigned char* QgsMssqlGeometryParser::ParseSqlGeometry( unsigned char* pszInput
int iCount = 2;
CopyBytes( &iCount, 4 );
// copy points
CopyBytes( pszData + nPointPos, nPointSize * 2 );
CopyCoordinates( pszData + nPointPos );
CopyCoordinates( pszData + nPointPos + nPointSize );
}
else
{
Expand Down
85 changes: 76 additions & 9 deletions src/providers/mssql/qgsmssqlprovider.cpp
Expand Up @@ -341,6 +341,7 @@ void QgsMssqlProvider::loadFields()
{
mGeometryColName = mQuery.value( 3 ).toString();
mGeometryColType = sqlTypeName;
parser.IsGeography = sqlTypeName == "geography";
}
else
{
Expand Down Expand Up @@ -565,8 +566,20 @@ void QgsMssqlProvider::select( QgsAttributeList fetchAttributes,
// set spatial filter
if ( !rect.isEmpty() )
{
// polygons should be CCW for SqlGeography
QString r;
QTextStream foo( &r );

foo.setRealNumberPrecision( 8 );
foo.setRealNumberNotation( QTextStream::FixedNotation );
foo << rect.xMinimum() << " " << rect.yMinimum() << ", "
<< rect.xMaximum() << " " << rect.yMinimum() << ", "
<< rect.xMaximum() << " " << rect.yMaximum() << ", "
<< rect.xMinimum() << " " << rect.yMaximum() << ", "
<< rect.xMinimum() << " " << rect.yMinimum();

mStatement += QString( " where [%1].STIntersects([%2]::STGeomFromText('POLYGON((%3))',%4)) = 1" ).arg(
mGeometryColName, mGeometryColType, rect.asPolygon(), QString::number( mSRId ) );
mGeometryColName, mGeometryColType, r, QString::number( mSRId ) );
}
mFetchGeom = fetchGeometry;
mAttributesToFetch = fetchAttributes;
Expand All @@ -593,13 +606,23 @@ void QgsMssqlProvider::UpdateStatistics( bool estimate )
mNumberFeatures = 0;
// get features to calculate the statistics
QString statement;
bool readAll = false;
if ( estimate )
{
statement = QString( "select min([%1].STPointN(1).STX), min([%1].STPointN(1).STY), max([%1].STPointN(1).STX), max([%1].STPointN(1).STY), COUNT([%1])" ).arg( mGeometryColName );
if ( mGeometryColType == "geometry" )
statement = QString( "select min([%1].STPointN(1).STX), min([%1].STPointN(1).STY), max([%1].STPointN(1).STX), max([%1].STPointN(1).STY), COUNT([%1])" ).arg( mGeometryColName );
else
statement = QString( "select min([%1].STPointN(1).Long), min([%1].STPointN(1).Lat), max([%1].STPointN(1).Long), max([%1].STPointN(1).Lat), COUNT([%1])" ).arg( mGeometryColName );
}
else
{
statement = QString( "select min([%1].STEnvelope().STPointN(1).STX), min([%1].STEnvelope().STPointN(1).STY), max([%1].STEnvelope().STPointN(2).STX), max([%1].STEnvelope().STPointN(2).STY), count([%1])" ).arg( mGeometryColName );
if ( mGeometryColType == "geometry" )
statement = QString( "select min([%1].STEnvelope().STPointN(1).STX), min([%1].STEnvelope().STPointN(1).STY), max([%1].STEnvelope().STPointN(3).STX), max([%1].STEnvelope().STPointN(3).STY), count([%1])" ).arg( mGeometryColName );
else
{
statement = QString( "select [%1]" ).arg( mGeometryColName );
readAll = true;
}
}

if ( mSchemaName.isEmpty() )
Expand All @@ -619,13 +642,49 @@ void QgsMssqlProvider::UpdateStatistics( bool estimate )
if ( mQuery.isActive() )
{
QgsGeometry geom;
if ( mQuery.next() )
if ( !readAll )
{
mExtent.setXMinimum( mQuery.value( 0 ).toDouble() );
mExtent.setYMinimum( mQuery.value( 1 ).toDouble() );
mExtent.setXMaximum( mQuery.value( 2 ).toDouble() );
mExtent.setYMaximum( mQuery.value( 3 ).toDouble() );
mNumberFeatures = mQuery.value( 4 ).toInt();
if ( mQuery.next() )
{
mExtent.setXMinimum( mQuery.value( 0 ).toDouble() );
mExtent.setYMinimum( mQuery.value( 1 ).toDouble() );
mExtent.setXMaximum( mQuery.value( 2 ).toDouble() );
mExtent.setYMaximum( mQuery.value( 3 ).toDouble() );
mNumberFeatures = mQuery.value( 4 ).toInt();
}
}
else
{
// read all features
while ( mQuery.next() )
{
QByteArray ar = mQuery.value( 0 ).toByteArray();
unsigned char* wkb = parser.ParseSqlGeometry(( unsigned char* )ar.data(), ar.size() );
if ( wkb )
{
geom.fromWkb( wkb, parser.GetWkbLen() );
QgsRectangle rect = geom.boundingBox();

if ( mNumberFeatures > 0 )
{
if ( rect.xMinimum() < mExtent.xMinimum() )
mExtent.setXMinimum( rect.xMinimum() );
if ( rect.yMinimum() < mExtent.yMinimum() )
mExtent.setYMinimum( rect.yMinimum() );
if ( rect.xMaximum() > mExtent.xMaximum() )
mExtent.setXMaximum( rect.xMaximum() );
if ( rect.yMaximum() > mExtent.yMaximum() )
mExtent.setYMaximum( rect.yMaximum() );
}
else
{
mExtent = rect;
mWkbType = geom.wkbType();
mSRId = parser.GetSRSId();
}
++mNumberFeatures;
}
}
}
}
}
Expand Down Expand Up @@ -761,7 +820,12 @@ bool QgsMssqlProvider::addFeatures( QgsFeatureList & flist )
QString msg = mQuery.lastError().text();
QgsDebugMsg( msg );
if ( !mSkipFailures )
{
QString msg = mQuery.lastError().text();
QgsDebugMsg( msg );
pushError( msg );
return false;
}
else
continue;
}
Expand Down Expand Up @@ -826,7 +890,10 @@ bool QgsMssqlProvider::addFeatures( QgsFeatureList & flist )
QString msg = mQuery.lastError().text();
QgsDebugMsg( msg );
if ( !mSkipFailures )
{
pushError( msg );
return false;
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/providers/mssql/qgsmssqlprovider.h
Expand Up @@ -67,6 +67,7 @@ class QgsMssqlGeometryParser

protected:
void CopyBytes( void* src, int len );
void CopyCoordinates( unsigned char* src );
void CopyPoint( int iPoint );
void ReadPoint( int iShape );
void ReadMultiPoint( int iShape );
Expand All @@ -82,6 +83,8 @@ class QgsMssqlGeometryParser
int GetSRSId() { return nSRSId; };
int GetWkbLen() { return nWkbLen; };
void DumpMemoryToLog( const char* pszMsg, unsigned char* pszInput, int nLen );
/* sql geo type */
bool IsGeography;
};


Expand Down

0 comments on commit 7773ddf

Please sign in to comment.