Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NAS fixes #1

Closed
wants to merge 12 commits into from
2 changes: 1 addition & 1 deletion autotest/ogr/ogr_nas.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def ogr_nas_2():
if feat is None:
return 'fail'

expected_geom = 'POLYGON ((350821.045 5532031.37,350924.309 5532029.513,350938.493 5532026.622,350951.435 5532021.471,350978.7 5532007.18,351026.406 5531971.088,351032.251 5531951.162,351032.251 5531951.162,351080.623 5531942.67,351154.886 5531963.718,351154.886 5531963.718,351207.689 5532019.797,351207.689 5532019.797,351211.063 5532044.067,351203.83 5532074.034,351165.959 5532114.315,351152.85 5532135.774,351152.85 5532135.774,351141.396 5532140.355,351141.396 5532140.355,351110.659 5532137.542,351080.17 5532132.742,351080.17 5532132.742,351002.887 5532120.75,350925.682 5532108.264,350925.682 5532108.264,350848.556 5532095.285,350771.515 5532081.814,350771.515 5532081.814,350769.548 5532071.196,350812.194 5532034.716,350821.045 5532031.37))'
expected_geom = 'POLYGON ((350821.045 5532031.37,350924.309 5532029.513,350938.493 5532026.622,350951.435 5532021.471,350978.7 5532007.18,351026.406 5531971.088,351032.251 5531951.162,351080.623 5531942.67,351154.886 5531963.718,351207.689 5532019.797,351211.063 5532044.067,351203.83 5532074.034,351165.959 5532114.315,351152.85 5532135.774,351141.396 5532140.355,351110.659 5532137.542,351080.17 5532132.742,351002.887 5532120.75,350925.682 5532108.264,350848.556 5532095.285,350771.515 5532081.814,350769.548 5532071.196,350812.194 5532034.716,350821.045 5532031.37))'
if ogrtest.check_feature_geometry(feat, expected_geom) != 0:
geom = feat.GetGeometryRef()
print(geom)
Expand Down
3 changes: 2 additions & 1 deletion gdal/frmts/ogdi/makefile.vc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ OBJ = ogdidataset.obj
GDAL_ROOT = ..\..

EXTRAFLAGS = -I$(OGDIDIR)/ogdi/include -I$(OGDIDIR)/include/win32 \
-I$(OGDIDIR)/proj -DWIN32 -D_WINDOWS
-I$(OGDIDIR)/include/ogdi \
-I$(OGDIDIR)/include -DWIN32 -D_WINDOWS

!INCLUDE $(GDAL_ROOT)\nmake.opt

Expand Down
8 changes: 4 additions & 4 deletions gdal/nmake.opt
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,10 @@ INCLUDE_OGR_FRMTS = YES
# const or leave it empty. Take a look on your iconv() declaration in iconv.h.
# If the second parameter declared as const char** then you need to define
# ICONV_CONST=const otherwise leave it empty.
#LIBICONV_DIR = "C:\Program Files\GnuWin32"
#LIBICONV_INCLUDE = -I$(LIBICONV_DIR)\include
#LIBICONV_LIBRARY = $(LIBICONV_DIR)\lib\libiconv.lib
#LIBICONV_CFLAGS = -DICONV_CONST=const
LIBICONV_DIR = "C:\OSGeo4W"
LIBICONV_INCLUDE = -I$(LIBICONV_DIR)\include
LIBICONV_LIBRARY = $(LIBICONV_DIR)\lib\iconv.lib
LIBICONV_CFLAGS = -DICONV_CONST=const

# Comment out the following to disable BSB support.
BSB_SUPPORTED = 1
Expand Down
65 changes: 50 additions & 15 deletions gdal/ogr/gml2ogrgeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,11 +555,11 @@ static int ParseGMLCoordinates( const CPLXMLNode *psGeomNode, OGRGeometry *poGeo
static OGRPolygon *GML2FaceExtRing( OGRGeometry *poGeom )
{
OGRPolygon *poPolygon = NULL;
int bError = FALSE;
int bError = FALSE;
OGRGeometryCollection *poColl = (OGRGeometryCollection *)poGeom;
int iCount = poColl->getNumGeometries();
int iExterior = 0;
int iInterior = 0;
int iExterior = 0;
int iInterior = 0;

for( int ig = 0; ig < iCount; ig++)
{
Expand Down Expand Up @@ -634,7 +634,7 @@ OGRGeometry *GML2OGRGeometry_XMLNode( const CPLXMLNode *psNode,
if( nRecLevel == 32 )
{
CPLError( CE_Failure, CPLE_AppDefined,
"Too many recursiong level (%d) while parsing GML geometry.",
"Too many recursion levels (%d) while parsing GML geometry.",
nRecLevel );
return NULL;
}
Expand Down Expand Up @@ -775,8 +775,21 @@ OGRGeometry *GML2OGRGeometry_XMLNode( const CPLXMLNode *psNode,
return NULL;
}

// we might need to take steps to avoid duplicate points...
poLinearRing->addSubLineString( poLS );
if( poLinearRing->getNumPoints() > 0 && poLS->getNumPoints() > 0
&& fabs(poLinearRing->getX(poLinearRing->getNumPoints()-1) - poLS->getX(0)) < 1e-14
&& fabs(poLinearRing->getY(poLinearRing->getNumPoints()-1) - poLS->getY(0)) < 1e-14
&& fabs(poLinearRing->getZ(poLinearRing->getNumPoints()-1) - poLS->getZ(0)) < 1e-14 )
{
// Skip the first point of the new linestring to avoid
// invalidate duplicate points
poLinearRing->addSubLineString( poLS, 1 );
}
else
{
// Add the whole new line string
poLinearRing->addSubLineString( poLS );
}

delete poLS;
}
}
Expand Down Expand Up @@ -866,10 +879,30 @@ OGRGeometry *GML2OGRGeometry_XMLNode( const CPLXMLNode *psNode,
int nSign = (det >= 0) ? 1 : -1;

double alpha;
double dfStep =
atof(CPLGetConfigOption("OGR_ARC_STEPSIZE","4")) / 180 * PI;
if (dfStep <= 0.1)
double dfStep = atof(CPLGetConfigOption("OGR_ARC_STEPSIZE","4")) / 180 * PI;

// make sure the segments are not too short
double dfMinStepLength = atof( CPLGetConfigOption("OGR_ARC_MINLENGTH","0") );
if ( dfMinStepLength > 0.0 && dfStep * R < dfMinStepLength )
{
CPLDebug( "GML", "Increasing arc step to %lf° (was %lf° with segment length %lf at radius %lf; min segment length is %lf)",
dfMinStepLength * 180.0 / PI / R,
dfStep * 180.0 / PI,
dfStep * R,
R,
dfMinStepLength );
dfStep = dfMinStepLength / R;
}

if (dfStep < 4. / 180 * PI)
{
CPLDebug( "GML", "Increasing arc step to %lf° (was %lf° with length %lf at radius %lf).",
4. / 180 * PI,
dfStep * 180.0 / PI,
dfStep * R,
R );
dfStep = 4. / 180 * PI;
}

poLine->setNumPoints(0);

Expand Down Expand Up @@ -1186,9 +1219,10 @@ OGRGeometry *GML2OGRGeometry_XMLNode( const CPLXMLNode *psNode,


/* -------------------------------------------------------------------- */
/* MultiCurve */
/* MultiCurve / CompositeCurve */
/* -------------------------------------------------------------------- */
if( EQUAL(pszBaseGeometry,"MultiCurve") )
if( EQUAL(pszBaseGeometry,"MultiCurve") ||
EQUAL(pszBaseGeometry,"CompositeCurve") )
{
const CPLXMLNode *psChild, *psCurve;
OGRMultiLineString *poMLS = new OGRMultiLineString();
Expand Down Expand Up @@ -1272,7 +1306,7 @@ OGRGeometry *GML2OGRGeometry_XMLNode( const CPLXMLNode *psNode,
}

/* -------------------------------------------------------------------- */
/* Curve */
/* Curve */
/* -------------------------------------------------------------------- */
if( EQUAL(pszBaseGeometry,"Curve") )
{
Expand Down Expand Up @@ -1408,7 +1442,7 @@ OGRGeometry *GML2OGRGeometry_XMLNode( const CPLXMLNode *psNode,
}

/* -------------------------------------------------------------------- */
/* Directed Edge */
/* Directed Edge */
/* -------------------------------------------------------------------- */
if( EQUAL(pszBaseGeometry,"directedEdge") )
{
Expand Down Expand Up @@ -2193,8 +2227,9 @@ OGRGeometryH OGR_G_CreateFromGMLTree( const CPLXMLNode *psTree )
* MultiPoint, MultiLineString, MultiPolygon, MultiGeometry.
*
* (OGR >= 1.8.0) The following GML3 elements are parsed : Surface, MultiSurface,
* PolygonPatch, Triangle, Rectangle, Curve, MultiCurve, LineStringSegment, Arc,
* Circle, CompositeSurface, OrientableSurface, Solid, Tin, TriangulatedSurface.
* PolygonPatch, Triangle, Rectangle, Curve, MultiCurve, CompositeCurve,
* LineStringSegment, Arc, Circle, CompositeSurface, OrientableSurface, Solid,
* Tin, TriangulatedSurface.
*
* Arc and Circle elements are stroked to linestring, by using a
* 4 degrees step, unless the user has overridden the value with the
Expand Down
1 change: 1 addition & 0 deletions gdal/ogr/ogr_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ OGR_G_ApproximateArcAngles(
double dfMaxAngleStepSizeDegrees );

OGRGeometryH CPL_DLL OGR_G_ForceToPolygon( OGRGeometryH );
OGRGeometryH CPL_DLL OGR_G_ForceToLineString( OGRGeometryH );
OGRGeometryH CPL_DLL OGR_G_ForceToMultiPolygon( OGRGeometryH );
OGRGeometryH CPL_DLL OGR_G_ForceToMultiPoint( OGRGeometryH );
OGRGeometryH CPL_DLL OGR_G_ForceToMultiLineString( OGRGeometryH );
Expand Down
1 change: 1 addition & 0 deletions gdal/ogr/ogr_geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ class CPL_DLL OGRGeometryFactory
static OGRGeometry *createGeometry( OGRwkbGeometryType );

static OGRGeometry * forceToPolygon( OGRGeometry * );
static OGRGeometry * forceToLineString( OGRGeometry *, bool bOnlyInOrder = true );
static OGRGeometry * forceToMultiPolygon( OGRGeometry * );
static OGRGeometry * forceToMultiPoint( OGRGeometry * );
static OGRGeometry * forceToMultiLineString( OGRGeometry * );
Expand Down
4 changes: 2 additions & 2 deletions gdal/ogr/ogr_srs_esri.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1472,9 +1472,9 @@ OGRErr OSRMorphToESRI( OGRSpatialReferenceH hSRS )
* Adds missing TOWGS84 parameters (necessary for datum transformations),
* based on named datum and spheroid values.</td></tr>
* <tr><td>&nbsp;&nbsp;</td><td><b>DATUM</b></td><td>&nbsp;&nbsp;</td><td>
* Adds ESPG AUTHORITY nodes and sets SPHEROID name to OGR spec.</td></tr>
* Adds EPSG AUTHORITY nodes and sets SPHEROID name to OGR spec.</td></tr>
* <tr><td>&nbsp;&nbsp;</td><td><b>GEOGCS</b></td><td>&nbsp;&nbsp;</td><td>
* Adds ESPG AUTHORITY nodes and sets GEOGCS, DATUM and SPHEROID
* Adds EPSG AUTHORITY nodes and sets GEOGCS, DATUM and SPHEROID
* names to OGR spec. Effectively replaces GEOGCS node with the result of
* importFromEPSG(n), using EPSG code n corresponding to the existing GEOGCS.
* Does not impact PROJCS values.</td></tr>
Expand Down
2 changes: 1 addition & 1 deletion gdal/ogr/ogr_srs_proj4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1407,7 +1407,7 @@ OGRErr OGRSpatialReference::exportToProj4( char ** ppszProj4 ) const
{
*ppszProj4 = CPLStrdup("");
CPLError( CE_Failure, CPLE_NotSupported,
"No translation an empty SRS to PROJ.4 format is known.");
"No translation for an empty SRS to PROJ.4 format is known.");
return OGRERR_UNSUPPORTED_SRS;
}

Expand Down
19 changes: 16 additions & 3 deletions gdal/ogr/ogrfeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1926,7 +1926,12 @@ void OGR_F_SetFieldDouble( OGRFeatureH hFeat, int iField, double dfValue )
void OGRFeature::SetField( int iField, const char * pszValue )

{
OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
static int bWarn = -1;
OGRFieldDefn *poFDefn = poDefn->GetFieldDefn( iField );
char *pszLast;

if( bWarn < 0 )
bWarn = CSLTestBoolean( CPLGetConfigOption( "OGR_SETFIELD_NUMERIC_WARNING", "NO" ) );

if( poFDefn == NULL )
return;
Expand All @@ -1940,12 +1945,20 @@ void OGRFeature::SetField( int iField, const char * pszValue )
}
else if( poFDefn->GetType() == OFTInteger )
{
pauFields[iField].Integer = atoi(pszValue);
pauFields[iField].Integer = strtol(pszValue, &pszLast, 10);
if( bWarn && ( !pszLast || *pszLast ) )
CPLError(CE_Warning, CPLE_AppDefined,
"Value '%s' of field %s.%s parsed incompletely to integer %d.",
pszValue, poDefn->GetName(), poFDefn->GetNameRef(), pauFields[iField].Integer );
pauFields[iField].Set.nMarker2 = OGRUnsetMarker;
}
else if( poFDefn->GetType() == OFTReal )
{
pauFields[iField].Real = atof(pszValue);
pauFields[iField].Real = CPLStrtod(pszValue, &pszLast);
if( bWarn && ( !pszLast || *pszLast ) )
CPLError(CE_Warning, CPLE_AppDefined,
"Value '%s' of field %s.%s parsed incompletely to real %.16g.",
pszValue, poDefn->GetName(), poFDefn->GetNameRef(), pauFields[iField].Real );
}
else if( poFDefn->GetType() == OFTDate
|| poFDefn->GetType() == OFTTime
Expand Down
123 changes: 123 additions & 0 deletions gdal/ogr/ogrgeometryfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2512,3 +2512,126 @@ OGR_G_ApproximateArcAngles(
dfPrimaryRadius, dfSecondaryRadius, dfRotation,
dfStartAngle, dfEndAngle, dfMaxAngleStepSizeDegrees );
}

/************************************************************************/
/* forceToLineString() */
/************************************************************************/

/**
* \brief Convert to line string.
*
* Tries to force the provided geometry to be a line string. Currently
* this just effects a change on multilinestrings. The passed in geometry is
* consumed and a new one returned (or potentially the same one).
*
* @param poGeom the input geometry - ownership is passed to the method.
* @return new geometry.
*/

OGRGeometry *OGRGeometryFactory::forceToLineString( OGRGeometry *poGeom, bool bOnlyInOrder )

{
if( poGeom == NULL )
return NULL;

OGRwkbGeometryType eGeomType = wkbFlatten(poGeom->getGeometryType());

if( eGeomType != wkbGeometryCollection
&& eGeomType != wkbMultiLineString )
return poGeom;

// build an aggregated linestring from all the linestrings in the container.
OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom;

int iGeom0 = 0;
while( iGeom0 < poGC->getNumGeometries() )
{
if( wkbFlatten(poGC->getGeometryRef(iGeom0)->getGeometryType())
!= wkbLineString )
{
iGeom0++;
continue;
}

OGRLineString *poLineString0 = (OGRLineString *) poGC->getGeometryRef(iGeom0);

OGRPoint pointStart0, pointEnd0;
poLineString0->StartPoint( &pointStart0 );
poLineString0->EndPoint( &pointEnd0 );

int iGeom1;
for( iGeom1 = iGeom0 + 1; iGeom1 < poGC->getNumGeometries(); iGeom1++ )
{
if( wkbFlatten(poGC->getGeometryRef(iGeom1)->getGeometryType())
!= wkbLineString )
continue;

OGRLineString *poLineString1 = (OGRLineString *) poGC->getGeometryRef(iGeom1);

OGRPoint pointStart1, pointEnd1;
poLineString1->StartPoint( &pointStart1 );
poLineString1->EndPoint( &pointEnd1 );

if ( !bOnlyInOrder &&
( pointEnd0.Equals( &pointEnd1 ) || pointStart0.Equals( &pointStart1 ) ) )
{
poLineString1->reversePoints();
poLineString1->StartPoint( &pointStart1 );
poLineString1->EndPoint( &pointEnd1 );
}

if ( pointEnd0.Equals( &pointStart1 ) )
{
poLineString0->addSubLineString( poLineString1, 1 );
poGC->removeGeometry( iGeom1 );
break;
}

if( pointEnd1.Equals( &pointStart0 ) )
{
poLineString1->addSubLineString( poLineString0, 1 );
poGC->removeGeometry( iGeom0 );
break;
}
}

if ( iGeom1 == poGC->getNumGeometries() )
{
iGeom0++;
}
}

if ( poGC->getNumGeometries() == 1 )
{
OGRLineString *poLineString = (OGRLineString *) poGC->getGeometryRef(0);
poGC->removeGeometry( 0, FALSE );
delete poGC;

return poLineString;
}

return poGC;
}

/************************************************************************/
/* OGR_G_ForceToLineString() */
/************************************************************************/

/**
* \brief Convert to line string.
*
* This function is the same as the C++ method
* OGRGeometryFactory::forceToLineString().
*
* @param hGeom handle to the geometry to convert (ownership surrendered).
* @return the converted geometry (ownership to caller).
*
* @since GDAL/OGR 2.0.0
*/

OGRGeometryH OGR_G_ForceToLineString( OGRGeometryH hGeom )

{
return (OGRGeometryH)
OGRGeometryFactory::forceToLineString( (OGRGeometry *) hGeom );
}
3 changes: 3 additions & 0 deletions gdal/ogr/ogrsf_frmts/gml/gmlreader.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ class CPL_DLL GMLPropertyDefn
int GetAttributeIndex() const { return m_nIndex; }

void AnalysePropertyValue( const GMLProperty* psGMLProperty );

static bool IsSimpleType( GMLPropertyType eType )
{ return eType == GMLPT_String || eType == GMLPT_Integer || eType == GMLPT_Real; }
};

/************************************************************************/
Expand Down
Loading