Skip to content

Instantly share code, notes, and snippets.

@vpicavet
Created May 13, 2013 17:29
Show Gist options
  • Save vpicavet/5569961 to your computer and use it in GitHub Desktop.
Save vpicavet/5569961 to your computer and use it in GitHub Desktop.
diff --git a/ogr/ogrsf_frmts/mitab/mitab_bounds.cpp b/ogr/ogrsf_frmts/mitab/mitab_bounds.cpp
index f66ef0b..09d540e 100644
--- a/ogr/ogrsf_frmts/mitab/mitab_bounds.cpp
+++ b/ogr/ogrsf_frmts/mitab/mitab_bounds.cpp
@@ -85,6 +85,7 @@ static MapInfoBoundsInfo gasBoundsList[] = {
{{3, 0, 3, {-84.3666666667,41.5,42.1,43.6666666667,13123359.58,0}, 0,0,0,0, {0,0,0,0,0}}, -318674512.717618, -308729738.1419, 344921231.877618, 354866006.453336},
{{3, 0, 3, {-84.3666666667,43.3166666667,44.1833333333,45.7,19685039.37,0}, 0,0,0,0, {0,0,0,0,0}}, -334588341.234808, -332680007.139814, 373958419.974808, 375866754.069803},
{{3, 0, 3, {-87,44.7833333333,45.4833333333,47.0833333333,26246719.16,0}, 0,0,0,0, {0,0,0,0,0}}, -343541891.912548, -349200540.720143, 396035330.232548, 390376681.424953},
+{{3, 0, 7, {3,46.5,49,44,700000,6600000}, 0,0,0,0, {0,0,0,0,0}}, -357823.2365, 6037008.6939, 1313632.3628, 7230727.3772},
{{3, 0, 7, {-100,39.8333333333,40,43,500000,0}, 0,0,0,0, {0,0,0,0,0}}, -96293653.747449, -89392122.913416, 97293653.747449, 104195184.581482},
{{3, 0, 7, {-100,43.8333333333,44.4166666667,45.6833333333,600000,0}, 0,0,0,0, {0,0,0,0,0}}, -107757768.605122, -101845373.546917, 108957768.605122, 114870163.663327},
{{3, 0, 7, {-100.3333333333,29.6666666667,30.1166666667,31.8833333333,700000,3000000}, 0,0,0,0, {0,0,0,0,0}}, -70389655.9882633, -57319094.8848422, 71789655.9882633, 84860217.0916844},
diff --git a/ogr/ogrsf_frmts/mitab/mitab_coordsys.cpp b/ogr/ogrsf_frmts/mitab/mitab_coordsys.cpp
index c4090e7..52abe9a 100644
--- a/ogr/ogrsf_frmts/mitab/mitab_coordsys.cpp
+++ b/ogr/ogrsf_frmts/mitab/mitab_coordsys.cpp
@@ -1335,10 +1335,30 @@ char *MITABSpatialRef2CoordSys( OGRSpatialReference * poSR )
/* -------------------------------------------------------------------- */
/* Append Projection Parms. */
/* -------------------------------------------------------------------- */
- for( int iParm = 0; iParm < nParmCount; iParm++ )
- sprintf( szCoordSys + strlen(szCoordSys),
- ", %.15g",
- parms[iParm] );
+ if( nProjection == 3
+ && nDatum == 33
+ && nEllipsoid == 0
+ && parms[3] == 44.0
+ && parms[2] == 49.0)
+ {
+ for( int iParm = 0; iParm < nParmCount; iParm++ )
+ {
+ // Swap standard parallel 1 and 2 when writing epsg:2154 L93
+ // (MapInfo save and read these parameters in reverse order
+ // compared to spec)
+ if (iParm==2)
+ sprintf( szCoordSys + strlen(szCoordSys), ", %.15g", parms[3] );
+ else if (iParm==3)
+ sprintf( szCoordSys + strlen(szCoordSys), ", %.15g", parms[2] );
+ else
+ sprintf( szCoordSys + strlen(szCoordSys), ", %.15g", parms[iParm] );
+ }
+ }
+ else
+ for( int iParm = 0; iParm < nParmCount; iParm++ )
+ sprintf( szCoordSys + strlen(szCoordSys),
+ ", %.15g",
+ parms[iParm] );
/* -------------------------------------------------------------------- */
/* Report on translation */
diff --git a/ogr/ogrsf_frmts/mitab/mitab_mapheaderblock.cpp b/ogr/ogrsf_frmts/mitab/mitab_mapheaderblock.cpp
index 155684b..2682569 100644
--- a/ogr/ogrsf_frmts/mitab/mitab_mapheaderblock.cpp
+++ b/ogr/ogrsf_frmts/mitab/mitab_mapheaderblock.cpp
@@ -138,6 +138,12 @@
#include "mitab.h"
+#ifdef WIN32
+inline double round(double r) {
+ return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
+}
+#endif
+
/*---------------------------------------------------------------------
* Set various constants used in generating the header block.
*--------------------------------------------------------------------*/
@@ -241,6 +247,9 @@ TABMAPHeaderBlock::TABMAPHeaderBlock(TABAccess eAccessMode /*= TABRead*/):
m_sProj.dAffineParamD = 0.0;
m_sProj.dAffineParamE = 0.0;
m_sProj.dAffineParamF = 0.0;
+
+ m_XPrecision = -1; // not specified
+ m_YPrecision = -1; // not specified
}
/**********************************************************************
@@ -405,6 +414,22 @@ int TABMAPHeaderBlock::InitBlockFromData(GByte *pabyBuf,
}
}
+ if( m_sProj.nProjId == 3
+ && m_sProj.nDatumId == 33
+ && m_sProj.nEllipsoidId == 0
+ && m_sProj.adProjParams[3] == 49.0
+ && m_sProj.adProjParams[2] == 44.0)
+ {
+ // Swap SP1 and SP2 if in EPSG:2154 (L93)
+ // (MapInfo save and read these parameters in reverse order
+ // compared to spec)
+ const double swap = m_sProj.adProjParams[3];
+ m_sProj.adProjParams[3] = m_sProj.adProjParams[2];
+ m_sProj.adProjParams[2] = swap;
+ }
+
+ UpdatePrecision();
+
return 0;
}
@@ -444,6 +469,12 @@ int TABMAPHeaderBlock::Int2Coordsys(GInt32 nX, GInt32 nY,
else
dY = (nY - m_YDispl) / m_YScale;
+ if (m_XPrecision > -1.0 && m_YPrecision > -1.0)
+ {
+ dX = round(dX*m_XPrecision)/static_cast<double>(m_XPrecision);
+ dY = round(dY*m_YPrecision)/static_cast<double>(m_YPrecision);
+ }
+
//printf("Int2Coordsys: (%d, %d) -> (%.10g, %.10g)\n", nX, nY, dX, dY);
return 0;
@@ -664,6 +695,8 @@ int TABMAPHeaderBlock::SetCoordsysBounds(double dXMin, double dYMin,
m_nXMax = 1000000000;
m_nYMax = 1000000000;
+ UpdatePrecision();
+
return 0;
}
@@ -1010,6 +1043,21 @@ int TABMAPHeaderBlock::InitNewBlock(FILE *fpSrc, int nBlockSize,
/**********************************************************************
+ * TABMAPHeaderBlock::UpdatePrecision()
+ *
+ * Update x and y maximum achievable precision given current scales
+ * (m_XScale and m_YScale)
+ **********************************************************************/
+
+void TABMAPHeaderBlock::UpdatePrecision()
+{
+ const double rawXPrecision = 1.0/m_XScale;
+ m_XPrecision = static_cast<int>(pow(10.0, round(log10(1.0/rawXPrecision))));
+ const double rawYPrecision = 1.0/m_YScale;
+ m_YPrecision = static_cast<int>(pow(10.0, round(log10(1.0/rawYPrecision))));
+}
+
+/**********************************************************************
* TABMAPHeaderBlock::Dump()
*
* Dump block contents... available only in DEBUG mode.
diff --git a/ogr/ogrsf_frmts/mitab/mitab_priv.h b/ogr/ogrsf_frmts/mitab/mitab_priv.h
index 1096057..b3d0e0f 100644
--- a/ogr/ogrsf_frmts/mitab/mitab_priv.h
+++ b/ogr/ogrsf_frmts/mitab/mitab_priv.h
@@ -911,6 +911,8 @@ class TABMAPHeaderBlock: public TABRawBinBlock
int GetProjInfo(TABProjInfo *psProjInfo);
int SetProjInfo(TABProjInfo *psProjInfo);
+ void UpdatePrecision();
+
#ifdef DEBUG
virtual void Dump(FILE *fpOut = NULL);
#endif
@@ -955,6 +957,9 @@ class TABMAPHeaderBlock: public TABRawBinBlock
double m_YScale;
double m_XDispl;
double m_YDispl;
+
+ GInt32 m_XPrecision; // maximum achievable precision along X axis depending on bounds extent
+ GInt32 m_YPrecision; // maximum achievable precision along Y axis depending on bounds extent
};
diff --git a/ogr/ogrsf_frmts/mitab/mitab_spatialref.cpp b/ogr/ogrsf_frmts/mitab/mitab_spatialref.cpp
index 5a942ef..255ae4f 100644
--- a/ogr/ogrsf_frmts/mitab/mitab_spatialref.cpp
+++ b/ogr/ogrsf_frmts/mitab/mitab_spatialref.cpp
@@ -639,29 +639,12 @@ OGRSpatialReference *TABFile::GetSpatialRef()
* Lambert Conic Conformal
*-------------------------------------------------------------*/
case 3:
- if( sTABProj.nProjId == 3
- && sTABProj.nDatumId == 33
- && sTABProj.nEllipsoidId == 0
- && sTABProj.adProjParams[3] == 49.0
- && sTABProj.adProjParams[2] == 44.0)
- {
- // Swap SP1 and SP2 if in EPSG:2154 (L93)
- // (MapInfo save and read these parameters in reverse order
- // compared to spec)
- m_poSpatialRef->SetLCC( sTABProj.adProjParams[3],
- sTABProj.adProjParams[2],
- sTABProj.adProjParams[1],
- sTABProj.adProjParams[0],
- sTABProj.adProjParams[4],
- sTABProj.adProjParams[5] );
- }
- else
- m_poSpatialRef->SetLCC( sTABProj.adProjParams[2],
- sTABProj.adProjParams[3],
- sTABProj.adProjParams[1],
- sTABProj.adProjParams[0],
- sTABProj.adProjParams[4],
- sTABProj.adProjParams[5] );
+ m_poSpatialRef->SetLCC( sTABProj.adProjParams[2],
+ sTABProj.adProjParams[3],
+ sTABProj.adProjParams[1],
+ sTABProj.adProjParams[0],
+ sTABProj.adProjParams[4],
+ sTABProj.adProjParams[5] );
break;
/*--------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment