shape2ogr.cpp
来自「GIS系统支持库Geospatial Data Abstraction Libr」· C++ 代码 · 共 1,155 行 · 第 1/3 页
CPP
1,155 行
nRingPoints = psShape->nVertices; nRingStart = 0; } else { if( iRing == psShape->nParts - 1 ) nRingPoints = psShape->nVertices - psShape->panPartStart[iRing]; else nRingPoints = psShape->panPartStart[iRing+1] - psShape->panPartStart[iRing]; nRingStart = psShape->panPartStart[iRing]; } poLine->setPoints( nRingPoints, psShape->padfX + nRingStart, psShape->padfY + nRingStart, psShape->padfZ + nRingStart ); poOGRMulti->addGeometryDirectly( poLine ); } } }/* -------------------------------------------------------------------- *//* Polygon *//* *//* For now we assume the first ring is an outer ring, and *//* everything else is an inner ring. This must smarten up in *//* the future. *//* -------------------------------------------------------------------- */ else if( psShape->nSHPType == SHPT_POLYGON || psShape->nSHPType == SHPT_POLYGONM || psShape->nSHPType == SHPT_POLYGONZ ) { int iRing; if ( psShape->nParts == 1 ) { /* Surely outer ring */ OGRPolygon *poOGRPoly; OGRLinearRing *poRing; poOGR = poOGRPoly = new OGRPolygon(); poRing = CreateLinearRing ( psShape, 0 ); poOGRPoly->addRingDirectly( poRing ); } else { int nOuter = 0; /* Number of outer rings */ int *direction; /* ring direction (1 CW,outer, -1 CCW, inner) */ int *outer; /* list of outer rings */ int *outside; /* outer ring index for inner rings, -1 for outer rings */ direction = (int *) CPLMalloc( psShape->nParts * sizeof(int) ); outer = (int *) CPLMalloc( psShape->nParts * sizeof(int) ); outside = (int *) CPLMalloc( psShape->nParts * sizeof(int) ); /* First distinguish outer from inner rings */ for( iRing = 0; iRing < psShape->nParts; iRing++ ) { direction[iRing] = RingDirection ( psShape, iRing); if ( direction[iRing] == 1 ) { outer[nOuter] = iRing; nOuter++; } outside[iRing] = -1; } /* Find for each inner ring outer ring it is within */ /* Note: According to specification, rings can touch by one vertex, but not along segment. */ /* It may happen that inner ring touches the outer and PointInRing() retuirns 0 (outside) */ /* because of representation error. Because of that, cycle through all vertices of inner */ /* ring is used, until outer ring is found. Of course, this may fail as well, but probability */ /* is lower. We could use also points on inner segments or centroid. */ /* In theory, it may also happen, that vertex touching outer ring falls outside its outer */ /* ring and inside another (incorrect). */ /* The problem is how to find a point on inner ring which doesn't lie on outer ring. */ for( iRing = 0; iRing < psShape->nParts; iRing++ ) { /* cycle through inner rings */ int start, end; if ( direction[iRing] != -1 ) /* is not inner ring */ continue; RingStartEnd ( psShape, iRing, &start, &end ); for ( int vert = start; vert < end; vert++ ) { /* cycle through inner ring's vertices */ double x, y; x = psShape->padfX[vert]; y = psShape->padfY[vert]; for( int oRing = 0; oRing < psShape->nParts; oRing++ ) { /* outer rings */ int inside; if ( direction[oRing] != 1 ) /* not outer */ continue; inside = PointInRing ( psShape, oRing, x, y); if ( inside ) { outside[iRing] = oRing; break; } } if ( outside[iRing] >= 0 ) /* outer ring found */ break; } } /* promote any unassigned inner rings to be outside rings */ for ( iRing = 0; iRing < psShape->nParts; iRing++ ) { /* outer rings */ if( direction[iRing] != 1 && outside[iRing] == -1 ) { direction[iRing] = 1; /* this isn't exactly true! */ outer[nOuter++] = iRing; } } if ( nOuter == 1 ) { /* One outer ring and more inner rings */ OGRPolygon *poOGRPoly; OGRLinearRing *poRing; /* Outer */ poOGR = poOGRPoly = new OGRPolygon(); poRing = CreateLinearRing ( psShape, outer[0] ); poOGRPoly->addRingDirectly( poRing ); /* Inner */ for( iRing = 0; iRing < psShape->nParts; iRing++ ) { if ( direction[iRing] == -1 ) { poRing = CreateLinearRing ( psShape, iRing ); poOGRPoly->addRingDirectly( poRing ); } } } else { OGRGeometryCollection *poOGRGeCo; poOGR = poOGRGeCo = new OGRMultiPolygon(); for ( iRing = 0; iRing < nOuter; iRing++ ) { /* outer rings */ int oRing; OGRPolygon *poOGRPoly; OGRLinearRing *poRing; oRing = outer[iRing]; /* Outer */ poOGRPoly = new OGRPolygon(); poRing = CreateLinearRing ( psShape, oRing ); poOGRPoly->addRingDirectly( poRing ); /* Inner */ for( int iRing2 = 0; iRing2 < psShape->nParts; iRing2++ ) { if ( outside[iRing2] == oRing ) { poRing = CreateLinearRing ( psShape, iRing2 ); poOGRPoly->addRingDirectly( poRing ); } } poOGRGeCo->addGeometryDirectly (poOGRPoly); } } CPLFree( direction ); CPLFree( outer ); CPLFree( outside ); } }/* -------------------------------------------------------------------- *//* Otherwise for now we just ignore the object. Eventually we *//* should implement multipatch. *//* -------------------------------------------------------------------- */ else { if( psShape->nSHPType != SHPT_NULL ) CPLDebug( "OGR", "Unsupported shape type in SHPReadOGRObject()" ); /* nothing returned */ } /* -------------------------------------------------------------------- *//* Cleanup shape, and set feature id. *//* -------------------------------------------------------------------- */ SHPDestroyObject( psShape ); return poOGR;}/************************************************************************//* SHPWriteOGRObject() *//************************************************************************/OGRErr SHPWriteOGRObject( SHPHandle hSHP, int iShape, OGRGeometry *poGeom ){/* ==================================================================== *//* Write "shape" with no geometry. *//* ==================================================================== */ if( poGeom == NULL ) { SHPObject *psShape; psShape = SHPCreateSimpleObject( SHPT_NULL, 0, NULL, NULL, NULL ); SHPWriteObject( hSHP, iShape, psShape ); SHPDestroyObject( psShape ); }/* ==================================================================== *//* Write point geometry. *//* ==================================================================== */ else if( hSHP->nShapeType == SHPT_POINT || hSHP->nShapeType == SHPT_POINTM || hSHP->nShapeType == SHPT_POINTZ ) { SHPObject *psShape; OGRPoint *poPoint = (OGRPoint *) poGeom; double dfX, dfY, dfZ = 0; if( poGeom->getGeometryType() != wkbPoint && poGeom->getGeometryType() != wkbPoint25D ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to write non-point (%s) geometry to" " point shapefile.", poGeom->getGeometryName() ); return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; } dfX = poPoint->getX(); dfY = poPoint->getY(); dfZ = poPoint->getZ(); psShape = SHPCreateSimpleObject( hSHP->nShapeType, 1, &dfX, &dfY, &dfZ ); SHPWriteObject( hSHP, iShape, psShape ); SHPDestroyObject( psShape ); }/* ==================================================================== *//* MultiPoint. *//* ==================================================================== */ else if( hSHP->nShapeType == SHPT_MULTIPOINT || hSHP->nShapeType == SHPT_MULTIPOINTM || hSHP->nShapeType == SHPT_MULTIPOINTZ ) { OGRMultiPoint *poMP = (OGRMultiPoint *) poGeom; double *padfX, *padfY, *padfZ; int iPoint; SHPObject *psShape; if( wkbFlatten(poGeom->getGeometryType()) != wkbMultiPoint ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to write non-multipoint (%s) geometry to " "multipoint shapefile.", poGeom->getGeometryName() ); return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; } padfX = (double *) CPLMalloc(sizeof(double)*poMP->getNumGeometries()); padfY = (double *) CPLMalloc(sizeof(double)*poMP->getNumGeometries()); padfZ = (double *) CPLCalloc(sizeof(double),poMP->getNumGeometries()); for( iPoint = 0; iPoint < poMP->getNumGeometries(); iPoint++ ) { OGRPoint *poPoint = (OGRPoint *) poMP->getGeometryRef(iPoint); padfX[iPoint] = poPoint->getX(); padfY[iPoint] = poPoint->getY(); padfZ[iPoint] = poPoint->getZ(); } psShape = SHPCreateSimpleObject( hSHP->nShapeType, poMP->getNumGeometries(), padfX, padfY, padfZ ); SHPWriteObject( hSHP, iShape, psShape ); SHPDestroyObject( psShape ); CPLFree( padfX ); CPLFree( padfY ); CPLFree( padfZ ); }/* ==================================================================== *//* Arcs from simple line strings. *//* ==================================================================== */ else if( (hSHP->nShapeType == SHPT_ARC || hSHP->nShapeType == SHPT_ARCM || hSHP->nShapeType == SHPT_ARCZ) && wkbFlatten(poGeom->getGeometryType()) == wkbLineString ) { OGRLineString *poArc = (OGRLineString *) poGeom; double *padfX, *padfY, *padfZ; int iPoint; SHPObject *psShape; if( poGeom->getGeometryType() != wkbLineString && poGeom->getGeometryType() != wkbLineString25D ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to write non-linestring (%s) geometry to " "ARC type shapefile.", poGeom->getGeometryName() ); return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; } padfX = (double *) CPLMalloc(sizeof(double)*poArc->getNumPoints()); padfY = (double *) CPLMalloc(sizeof(double)*poArc->getNumPoints()); padfZ = (double *) CPLCalloc(sizeof(double),poArc->getNumPoints()); for( iPoint = 0; iPoint < poArc->getNumPoints(); iPoint++ ) { padfX[iPoint] = poArc->getX( iPoint ); padfY[iPoint] = poArc->getY( iPoint ); padfZ[iPoint] = poArc->getZ( iPoint ); } psShape = SHPCreateSimpleObject( hSHP->nShapeType, poArc->getNumPoints(), padfX, padfY, padfZ ); SHPWriteObject( hSHP, iShape, psShape ); SHPDestroyObject( psShape ); CPLFree( padfX ); CPLFree( padfY ); CPLFree( padfZ ); }/* ==================================================================== *//* Arcs - Try to treat as MultiLineString. *//* ==================================================================== */ else if( hSHP->nShapeType == SHPT_ARC || hSHP->nShapeType == SHPT_ARCM || hSHP->nShapeType == SHPT_ARCZ ) { OGRMultiLineString *poML; double *padfX=NULL, *padfY=NULL, *padfZ=NULL; int iGeom, iPoint, nPointCount = 0; SHPObject *psShape; int *panRingStart; poML = (OGRMultiLineString *) OGRGeometryFactory::forceToMultiLineString( poGeom->clone() ); if( wkbFlatten(poML->getGeometryType()) != wkbMultiLineString ) { delete poML; CPLError( CE_Failure, CPLE_AppDefined, "Attempt to write non-linestring (%s) geometry to " "ARC type shapefile.", poGeom->getGeometryName() ); return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; } panRingStart = (int *) CPLMalloc(sizeof(int) * poML->getNumGeometries()); for( iGeom = 0; iGeom < poML->getNumGeometries(); iGeom++ ) { OGRLineString *poArc = (OGRLineString *) poML->getGeometryRef(iGeom); int nNewPoints = poArc->getNumPoints(); panRingStart[iGeom] = nPointCount; padfX = (double *) CPLRealloc( padfX, sizeof(double)*(nNewPoints+nPointCount) ); padfY = (double *) CPLRealloc( padfY, sizeof(double)*(nNewPoints+nPointCount) ); padfZ = (double *) CPLRealloc( padfZ, sizeof(double)*(nNewPoints+nPointCount) ); for( iPoint = 0; iPoint < nNewPoints; iPoint++ ) { padfX[nPointCount] = poArc->getX( iPoint ); padfY[nPointCount] = poArc->getY( iPoint ); padfZ[nPointCount] = poArc->getZ( iPoint ); nPointCount++; } } psShape = SHPCreateObject( hSHP->nShapeType, iShape, poML->getNumGeometries(), panRingStart, NULL,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?