OGRGeometry *OGRGeometryFactory::forceToMultiLineString( OGRGeometry *poGeom ) { if( poGeom == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Check for the case of a geometrycollection that can be */ /* promoted to MultiLineString. */ /* -------------------------------------------------------------------- */ if( wkbFlatten(poGeom->getGeometryType()) == wkbGeometryCollection ) { int iGeom; int bAllLines = TRUE; OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom; for( iGeom = 0; iGeom < poGC->getNumGeometries(); iGeom++ ) { if( wkbFlatten(poGC->getGeometryRef(iGeom)->getGeometryType()) != wkbLineString ) bAllLines = FALSE; } if( !bAllLines ) return poGeom; OGRMultiLineString *poMP = new OGRMultiLineString(); while( poGC->getNumGeometries() > 0 ) { poMP->addGeometryDirectly( poGC->getGeometryRef(0) ); poGC->removeGeometry( 0, FALSE ); } delete poGC; return poMP; } if( wkbFlatten(poGeom->getGeometryType()) != wkbLineString ) return poGeom; OGRMultiLineString *poMP = new OGRMultiLineString(); poMP->addGeometryDirectly( poGeom ); return poMP; }
OGRFeature* OGRXPlaneAirwaySegmentLayer::AddFeature(const char* pszAirwaySegmentName, const char* pszFirstPointName, const char* pszSecondPointName, double dfLat1, double dfLon1, double dfLat2, double dfLon2, int bIsHigh, int nBaseFL, int nTopFL) { int nCount = 0; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); if (fabs(dfLon1 - dfLon2) < 270) { OGRLineString* lineString = new OGRLineString(); lineString->addPoint(dfLon1, dfLat1); lineString->addPoint(dfLon2, dfLat2); poFeature->SetGeometryDirectly( lineString ); } else { /* Crossing antemeridian */ OGRMultiLineString* multiLineString = new OGRMultiLineString(); OGRLineString* lineString1 = new OGRLineString(); OGRLineString* lineString2 = new OGRLineString(); double dfLatInt; lineString1->addPoint(dfLon1, dfLat1); if (dfLon1 < dfLon2) { dfLatInt = dfLat1 + (dfLat2 - dfLat1) * (-180 - dfLon1) / ((dfLon2 - 360) - dfLon1); lineString1->addPoint(-180, dfLatInt); lineString2->addPoint(180, dfLatInt); } else { dfLatInt = dfLat1 + (dfLat2 - dfLat1) * (180 - dfLon1) / ((dfLon2 + 360) - dfLon1); lineString1->addPoint(180, dfLatInt); lineString2->addPoint(-180, dfLatInt); } lineString2->addPoint(dfLon2, dfLat2); multiLineString->addGeometryDirectly( lineString1 ); multiLineString->addGeometryDirectly( lineString2 ); poFeature->SetGeometryDirectly( multiLineString ); } poFeature->SetField( nCount++, pszAirwaySegmentName ); poFeature->SetField( nCount++, pszFirstPointName ); poFeature->SetField( nCount++, pszSecondPointName ); poFeature->SetField( nCount++, bIsHigh ); poFeature->SetField( nCount++, nBaseFL ); poFeature->SetField( nCount++, nTopFL ); RegisterFeature(poFeature); return poFeature; }
OGRMultiLineString* make() { OGRMultiLineString* poCollection = new OGRMultiLineString(); poCollection->addGeometryDirectly(make<OGRLineString>()); poCollection->addGeometryDirectly(make<OGRLinearRing>()); return poCollection; }
OGRMultiLineString* OGRMSSQLGeometryParser::ReadMultiLineString(int iShape) { int i; OGRMultiLineString* poMultiLineString = new OGRMultiLineString(); OGRGeometry* poGeom; for (i = iShape + 1; i < nNumShapes; i++) { poGeom = NULL; if (ParentOffset(i) == (unsigned int)iShape) { if ( ShapeType(i) == ST_LINESTRING ) poGeom = ReadLineString(i); } if ( poGeom ) poMultiLineString->addGeometryDirectly( poGeom ); } return poMultiLineString; }
void ILI1Reader::ReadGeom(char **stgeom, OGRwkbGeometryType eType, OGRFeature *feature) { char **tokens = NULL; const char *firsttok = NULL; int end = FALSE; int isArc = FALSE; OGRLineString *ogrLine = NULL; //current line OGRLinearRing *ogrRing = NULL; //current ring OGRPolygon *ogrPoly = NULL; //current polygon OGRPoint ogrPoint, arcPoint, endPoint; //points for arc interpolation OGRMultiLineString *ogrMultiLine = NULL; //current multi line //tokens = ["STPT", "1111", "22222"] ogrPoint.setX(atof(stgeom[1])); ogrPoint.setY(atof(stgeom[2])); ogrLine = (eType == wkbPolygon) ? new OGRLinearRing() : new OGRLineString(); ogrLine->addPoint(&ogrPoint); //Set feature geometry if (eType == wkbMultiLineString) { ogrMultiLine = new OGRMultiLineString(); feature->SetGeometryDirectly(ogrMultiLine); } else if (eType == wkbGeometryCollection) //AREA { if (feature->GetGeometryRef()) ogrMultiLine = (OGRMultiLineString *)feature->GetGeometryRef(); else { ogrMultiLine = new OGRMultiLineString(); feature->SetGeometryDirectly(ogrMultiLine); } } else if (eType == wkbPolygon) { if (feature->GetGeometryRef()) { ogrPoly = (OGRPolygon *)feature->GetGeometryRef(); if (ogrPoly->getNumInteriorRings() > 0) ogrRing = ogrPoly->getInteriorRing(ogrPoly->getNumInteriorRings()-1); else ogrRing = ogrPoly->getExteriorRing(); if (ogrRing && !ogrRing->get_IsClosed()) ogrLine = ogrRing; //SURFACE polygon spread over multiple OBJECTs } else { ogrPoly = new OGRPolygon(); feature->SetGeometryDirectly(ogrPoly); } } else { feature->SetGeometryDirectly(ogrLine); } //Parse geometry while (!end && (tokens = ReadParseLine())) { firsttok = CSLGetField(tokens, 0); if (EQUAL(firsttok, "LIPT")) { if (isArc) { endPoint.setX(atof(tokens[1])); endPoint.setY(atof(tokens[2])); interpolateArc(ogrLine, &ogrPoint, &arcPoint, &endPoint, arcIncr); } ogrPoint.setX(atof(tokens[1])); ogrPoint.setY(atof(tokens[2])); isArc = FALSE; ogrLine->addPoint(&ogrPoint); } else if (EQUAL(firsttok, "ARCP")) { isArc = TRUE; arcPoint.setX(atof(tokens[1])); arcPoint.setY(atof(tokens[2])); } else if (EQUAL(firsttok, "ELIN")) { if (ogrMultiLine) { ogrMultiLine->addGeometryDirectly(ogrLine); } if (ogrPoly && ogrLine != ogrRing) { ogrPoly->addRingDirectly((OGRLinearRing *)ogrLine); } end = TRUE; } else if (EQUAL(firsttok, "EEDG")) { end = TRUE; } else if (EQUAL(firsttok, "LATT")) { //Line Attributes (ignored) } else if (EQUAL(firsttok, "EFLA")) { end = TRUE; } else if (EQUAL(firsttok, "ETAB")) { end = TRUE; } else { CPLDebug( "OGR_ILI", "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); } }
static OGRGeometry *GML2OGRGeometry_XMLNode( CPLXMLNode *psNode ) { const char *pszBaseGeometry = BareGMLElement( psNode->pszValue ); /* -------------------------------------------------------------------- */ /* Polygon */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"Polygon") ) { CPLXMLNode *psChild; OGRPolygon *poPolygon = new OGRPolygon(); OGRLinearRing *poRing; // Find outer ring. psChild = FindBareXMLChild( psNode, "outerBoundaryIs" ); if( psChild == NULL || psChild->psChild == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing outerBoundaryIs property on Polygon." ); delete poPolygon; return NULL; } // Translate outer ring and add to polygon. poRing = (OGRLinearRing *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poRing == NULL ) { delete poPolygon; return NULL; } if( !EQUAL(poRing->getGeometryName(),"LINEARRING") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as outerBoundaryIs instead of LINEARRING.", poRing->getGeometryName() ); delete poPolygon; delete poRing; return NULL; } poPolygon->addRingDirectly( poRing ); // Find all inner rings for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"innerBoundaryIs") ) { poRing = (OGRLinearRing *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( !EQUAL(poRing->getGeometryName(),"LINEARRING") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as innerBoundaryIs instead of LINEARRING.", poRing->getGeometryName() ); delete poPolygon; delete poRing; return NULL; } poPolygon->addRingDirectly( poRing ); } } return poPolygon; } /* -------------------------------------------------------------------- */ /* LinearRing */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"LinearRing") ) { OGRLinearRing *poLinearRing = new OGRLinearRing(); if( !ParseGMLCoordinates( psNode, poLinearRing ) ) { delete poLinearRing; return NULL; } return poLinearRing; } /* -------------------------------------------------------------------- */ /* LineString */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"LineString") ) { OGRLineString *poLine = new OGRLineString(); if( !ParseGMLCoordinates( psNode, poLine ) ) { delete poLine; return NULL; } return poLine; } /* -------------------------------------------------------------------- */ /* PointType */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"PointType") || EQUAL(pszBaseGeometry,"Point") ) { OGRPoint *poPoint = new OGRPoint(); if( !ParseGMLCoordinates( psNode, poPoint ) ) { delete poPoint; return NULL; } return poPoint; } /* -------------------------------------------------------------------- */ /* Box */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"BoxType") || EQUAL(pszBaseGeometry,"Box") ) { OGRLineString oPoints; if( !ParseGMLCoordinates( psNode, &oPoints ) ) return NULL; if( oPoints.getNumPoints() < 2 ) return NULL; OGRLinearRing *poBoxRing = new OGRLinearRing(); OGRPolygon *poBoxPoly = new OGRPolygon(); poBoxRing->setNumPoints( 5 ); poBoxRing->setPoint( 0, oPoints.getX(0), oPoints.getY(0), oPoints.getZ(0) ); poBoxRing->setPoint( 1, oPoints.getX(1), oPoints.getY(0), oPoints.getZ(0) ); poBoxRing->setPoint( 2, oPoints.getX(1), oPoints.getY(1), oPoints.getZ(1) ); poBoxRing->setPoint( 3, oPoints.getX(0), oPoints.getY(1), oPoints.getZ(0) ); poBoxRing->setPoint( 4, oPoints.getX(0), oPoints.getY(0), oPoints.getZ(0) ); poBoxPoly->addRingDirectly( poBoxRing ); return poBoxPoly; } /* -------------------------------------------------------------------- */ /* MultiPolygon */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiPolygon") ) { CPLXMLNode *psChild; OGRMultiPolygon *poMPoly = new OGRMultiPolygon(); // Find all inner rings for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"polygonMember") ) { OGRPolygon *poPolygon; poPolygon = (OGRPolygon *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poPolygon == NULL ) { delete poMPoly; return NULL; } if( !EQUAL(poPolygon->getGeometryName(),"POLYGON") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as polygonMember instead of MULTIPOLYGON.", poPolygon->getGeometryName() ); delete poPolygon; delete poMPoly; return NULL; } poMPoly->addGeometryDirectly( poPolygon ); } } return poMPoly; } /* -------------------------------------------------------------------- */ /* MultiPoint */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiPoint") ) { CPLXMLNode *psChild; OGRMultiPoint *poMP = new OGRMultiPoint(); // collect points. for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"pointMember") ) { OGRPoint *poPoint; poPoint = (OGRPoint *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poPoint == NULL || wkbFlatten(poPoint->getGeometryType()) != wkbPoint ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as pointMember instead of MULTIPOINT", poPoint ? poPoint->getGeometryName() : "NULL" ); delete poPoint; delete poMP; return NULL; } poMP->addGeometryDirectly( poPoint ); } } return poMP; } /* -------------------------------------------------------------------- */ /* MultiLineString */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiLineString") ) { CPLXMLNode *psChild; OGRMultiLineString *poMP = new OGRMultiLineString(); // collect lines for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"lineStringMember") ) { OGRGeometry *poGeom; poGeom = GML2OGRGeometry_XMLNode( psChild->psChild ); if( poGeom == NULL || wkbFlatten(poGeom->getGeometryType()) != wkbLineString ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as Member instead of LINESTRING.", poGeom ? poGeom->getGeometryName() : "NULL" ); delete poGeom; delete poMP; return NULL; } poMP->addGeometryDirectly( poGeom ); } } return poMP; } /* -------------------------------------------------------------------- */ /* GeometryCollection */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"GeometryCollection") ) { CPLXMLNode *psChild; OGRGeometryCollection *poGC = new OGRGeometryCollection(); // collect geoms for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"geometryMember") ) { OGRGeometry *poGeom; poGeom = GML2OGRGeometry_XMLNode( psChild->psChild ); if( poGeom == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to get geometry in geometryMember" ); delete poGeom; delete poGC; return NULL; } poGC->addGeometryDirectly( poGeom ); } } return poGC; } CPLError( CE_Failure, CPLE_AppDefined, "Unrecognised geometry type <%.500s>.", pszBaseGeometry ); return NULL; }
OGRErr OGRPGeoLayer::createFromShapeBin( GByte *pabyShape, OGRGeometry **ppoGeom, int nBytes ) { *ppoGeom = NULL; if( nBytes < 1 ) return OGRERR_FAILURE; int nSHPType = pabyShape[0]; // CPLDebug( "PGeo", // "Shape type read from PGeo data is nSHPType = %d", // nSHPType ); /* -------------------------------------------------------------------- */ /* type 50 appears to just be an alias for normal line */ /* strings. (#1484) */ /* Type 51 appears to just be an alias for normal polygon. (#3100) */ /* TODO: These types include additional attributes including */ /* non-linear segments and such. They should be handled. */ /* -------------------------------------------------------------------- */ switch( nSHPType ) { case 50: nSHPType = SHPT_ARC; break; case 51: nSHPType = SHPT_POLYGON; break; case 52: nSHPType = SHPT_POINT; break; case 53: nSHPType = SHPT_MULTIPOINT; break; case 54: nSHPType = SHPT_MULTIPATCH; } /* ==================================================================== */ /* Extract vertices for a Polygon or Arc. */ /* ==================================================================== */ if( nSHPType == SHPT_ARC || nSHPType == SHPT_ARCZ || nSHPType == SHPT_ARCM || nSHPType == SHPT_ARCZM || nSHPType == SHPT_POLYGON || nSHPType == SHPT_POLYGONZ || nSHPType == SHPT_POLYGONM || nSHPType == SHPT_POLYGONZM || nSHPType == SHPT_MULTIPATCH || nSHPType == SHPT_MULTIPATCHM) { GInt32 nPoints, nParts; int i, nOffset; GInt32 *panPartStart; if (nBytes < 44) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nBytes=%d, nSHPType=%d", nBytes, nSHPType); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Extract part/point count, and build vertex and part arrays */ /* to proper size. */ /* -------------------------------------------------------------------- */ memcpy( &nPoints, pabyShape + 40, 4 ); memcpy( &nParts, pabyShape + 36, 4 ); CPL_LSBPTR32( &nPoints ); CPL_LSBPTR32( &nParts ); if (nPoints < 0 || nParts < 0 || nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nPoints=%d, nParts=%d.", nPoints, nParts); return OGRERR_FAILURE; } int bHasZ = ( nSHPType == SHPT_POLYGONZ || nSHPType == SHPT_POLYGONZM || nSHPType == SHPT_ARCZ || nSHPType == SHPT_ARCZM || nSHPType == SHPT_MULTIPATCH || nSHPType == SHPT_MULTIPATCHM ); int bIsMultiPatch = ( nSHPType == SHPT_MULTIPATCH || nSHPType == SHPT_MULTIPATCHM ); /* With the previous checks on nPoints and nParts, */ /* we should not overflow here and after */ /* since 50 M * (16 + 8 + 8) = 1 600 MB */ int nRequiredSize = 44 + 4 * nParts + 16 * nPoints; if ( bHasZ ) { nRequiredSize += 16 + 8 * nPoints; } if( bIsMultiPatch ) { nRequiredSize += 4 * nParts; } if (nRequiredSize > nBytes) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nPoints=%d, nParts=%d, nBytes=%d, nSHPType=%d", nPoints, nParts, nBytes, nSHPType); return OGRERR_FAILURE; } panPartStart = (GInt32 *) VSICalloc(nParts,sizeof(GInt32)); if (panPartStart == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Not enough memory for shape (nPoints=%d, nParts=%d)", nPoints, nParts); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Copy out the part array from the record. */ /* -------------------------------------------------------------------- */ memcpy( panPartStart, pabyShape + 44, 4 * nParts ); for( i = 0; i < nParts; i++ ) { CPL_LSBPTR32( panPartStart + i ); /* We check that the offset is inside the vertex array */ if (panPartStart[i] < 0 || panPartStart[i] >= nPoints) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : panPartStart[%d] = %d, nPoints = %d", i, panPartStart[i], nPoints); CPLFree(panPartStart); return OGRERR_FAILURE; } if (i > 0 && panPartStart[i] <= panPartStart[i-1]) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : panPartStart[%d] = %d, panPartStart[%d] = %d", i, panPartStart[i], i - 1, panPartStart[i - 1]); CPLFree(panPartStart); return OGRERR_FAILURE; } } nOffset = 44 + 4*nParts; /* -------------------------------------------------------------------- */ /* If this is a multipatch, we will also have parts types. For */ /* now we ignore and skip past them. */ /* -------------------------------------------------------------------- */ if( bIsMultiPatch ) nOffset += 4*nParts; /* -------------------------------------------------------------------- */ /* Copy out the vertices from the record. */ /* -------------------------------------------------------------------- */ double *padfX = (double *) VSIMalloc(sizeof(double)*nPoints); double *padfY = (double *) VSIMalloc(sizeof(double)*nPoints); double *padfZ = (double *) VSICalloc(sizeof(double),nPoints); if (padfX == NULL || padfY == NULL || padfZ == NULL) { CPLFree( panPartStart ); CPLFree( padfX ); CPLFree( padfY ); CPLFree( padfZ ); CPLError(CE_Failure, CPLE_OutOfMemory, "Not enough memory for shape (nPoints=%d, nParts=%d)", nPoints, nParts); return OGRERR_FAILURE; } for( i = 0; i < nPoints; i++ ) { memcpy(padfX + i, pabyShape + nOffset + i * 16, 8 ); memcpy(padfY + i, pabyShape + nOffset + i * 16 + 8, 8 ); CPL_LSBPTR64( padfX + i ); CPL_LSBPTR64( padfY + i ); } nOffset += 16*nPoints; /* -------------------------------------------------------------------- */ /* If we have a Z coordinate, collect that now. */ /* -------------------------------------------------------------------- */ if( bHasZ ) { for( i = 0; i < nPoints; i++ ) { memcpy( padfZ + i, pabyShape + nOffset + 16 + i*8, 8 ); CPL_LSBPTR64( padfZ + i ); } nOffset += 16 + 8*nPoints; } /* -------------------------------------------------------------------- */ /* Build corresponding OGR objects. */ /* -------------------------------------------------------------------- */ if( nSHPType == SHPT_ARC || nSHPType == SHPT_ARCZ || nSHPType == SHPT_ARCM || nSHPType == SHPT_ARCZM ) { /* -------------------------------------------------------------------- */ /* Arc - As LineString */ /* -------------------------------------------------------------------- */ if( nParts == 1 ) { OGRLineString *poLine = new OGRLineString(); *ppoGeom = poLine; poLine->setPoints( nPoints, padfX, padfY, padfZ ); } /* -------------------------------------------------------------------- */ /* Arc - As MultiLineString */ /* -------------------------------------------------------------------- */ else { OGRMultiLineString *poMulti = new OGRMultiLineString; *ppoGeom = poMulti; for( i = 0; i < nParts; i++ ) { OGRLineString *poLine = new OGRLineString; int nVerticesInThisPart; if( i == nParts-1 ) nVerticesInThisPart = nPoints - panPartStart[i]; else nVerticesInThisPart = panPartStart[i+1] - panPartStart[i]; poLine->setPoints( nVerticesInThisPart, padfX + panPartStart[i], padfY + panPartStart[i], padfZ + panPartStart[i] ); poMulti->addGeometryDirectly( poLine ); } } } /* ARC */ /* -------------------------------------------------------------------- */ /* Polygon */ /* -------------------------------------------------------------------- */ else if( nSHPType == SHPT_POLYGON || nSHPType == SHPT_POLYGONZ || nSHPType == SHPT_POLYGONM || nSHPType == SHPT_POLYGONZM ) { OGRPolygon *poMulti = new OGRPolygon; *ppoGeom = poMulti; for( i = 0; i < nParts; i++ ) { OGRLinearRing *poRing = new OGRLinearRing; int nVerticesInThisPart; if( i == nParts-1 ) nVerticesInThisPart = nPoints - panPartStart[i]; else nVerticesInThisPart = panPartStart[i+1] - panPartStart[i]; poRing->setPoints( nVerticesInThisPart, padfX + panPartStart[i], padfY + panPartStart[i], padfZ + panPartStart[i] ); poMulti->addRingDirectly( poRing ); } } /* polygon */ /* -------------------------------------------------------------------- */ /* Multipatch */ /* -------------------------------------------------------------------- */ else if( bIsMultiPatch ) { /* return to this later */ } CPLFree( panPartStart ); CPLFree( padfX ); CPLFree( padfY ); CPLFree( padfZ ); if( !bHasZ ) (*ppoGeom)->setCoordinateDimension( 2 ); return OGRERR_NONE; } /* ==================================================================== */ /* Extract vertices for a MultiPoint. */ /* ==================================================================== */ else if( nSHPType == SHPT_MULTIPOINT || nSHPType == SHPT_MULTIPOINTM || nSHPType == SHPT_MULTIPOINTZ || nSHPType == SHPT_MULTIPOINTZM ) { #ifdef notdef int32 nPoints; int i, nOffset; memcpy( &nPoints, psSHP->pabyRec + 44, 4 ); if( bBigEndian ) SwapWord( 4, &nPoints ); psShape->nVertices = nPoints; psShape->padfX = (double *) calloc(nPoints,sizeof(double)); psShape->padfY = (double *) calloc(nPoints,sizeof(double)); psShape->padfZ = (double *) calloc(nPoints,sizeof(double)); psShape->padfM = (double *) calloc(nPoints,sizeof(double)); for( i = 0; i < nPoints; i++ ) { memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 ); memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); } nOffset = 48 + 16*nPoints; /* -------------------------------------------------------------------- */ /* Get the X/Y bounds. */ /* -------------------------------------------------------------------- */ memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) ); /* -------------------------------------------------------------------- */ /* If we have a Z coordinate, collect that now. */ /* -------------------------------------------------------------------- */ if( psShape->nSHPType == SHPT_MULTIPOINTZ || psShape->nSHPType == SHPT_MULTIPOINTZM ) { memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfZ + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); } nOffset += 16 + 8*nPoints; } /* -------------------------------------------------------------------- */ /* If we have a M measure value, then read it now. We assume */ /* that the measure can be present for any shape if the size is */ /* big enough, but really it will only occur for the Z shapes */ /* (options), and the M shapes. */ /* -------------------------------------------------------------------- */ if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) { memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfM + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); } } #endif } /* ==================================================================== */ /* Extract vertices for a point. */ /* ==================================================================== */ else if( nSHPType == SHPT_POINT || nSHPType == SHPT_POINTM || nSHPType == SHPT_POINTZ || nSHPType == SHPT_POINTZM ) { int nOffset; double dfX, dfY, dfZ = 0; int bHasZ = (nSHPType == SHPT_POINTZ || nSHPType == SHPT_POINTZM); if (nBytes < 4 + 8 + 8 + ((nSHPType == SHPT_POINTZ) ? 8 : 0)) { CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nBytes=%d, nSHPType=%d", nBytes, nSHPType); return OGRERR_FAILURE; } memcpy( &dfX, pabyShape + 4, 8 ); memcpy( &dfY, pabyShape + 4 + 8, 8 ); CPL_LSBPTR64( &dfX ); CPL_LSBPTR64( &dfY ); nOffset = 20 + 8; if( bHasZ ) { memcpy( &dfZ, pabyShape + 4 + 16, 8 ); CPL_LSBPTR64( &dfZ ); } *ppoGeom = new OGRPoint( dfX, dfY, dfZ ); if( !bHasZ ) (*ppoGeom)->setCoordinateDimension( 2 ); return OGRERR_NONE; } char* pszHex = CPLBinaryToHex( nBytes, pabyShape ); CPLDebug( "PGEO", "Unsupported geometry type:%d\nnBytes=%d, hex=%s", nSHPType, nBytes, pszHex ); CPLFree(pszHex); return OGRERR_FAILURE; }