int main( int nArgc, char ** papszArgv ) { int nFirstSourceDataset = -1, bLayersWildcarded = TRUE, iArg; const char *pszFormat = "ESRI Shapefile"; const char *pszTileIndexField = "LOCATION"; const char *pszOutputName = NULL; int write_absolute_path = FALSE; int skip_different_projection = FALSE; char* current_path = NULL; int accept_different_schemas = FALSE; int bFirstWarningForNonMatchingAttributes = TRUE; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(papszArgv[0])) exit(1); /* -------------------------------------------------------------------- */ /* Register format(s). */ /* -------------------------------------------------------------------- */ OGRRegisterAll(); /* -------------------------------------------------------------------- */ /* Processing command line arguments. */ /* -------------------------------------------------------------------- */ for( iArg = 1; iArg < nArgc; iArg++ ) { if( EQUAL(papszArgv[iArg], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(papszArgv[iArg],"-f") && iArg < nArgc-1 ) { pszFormat = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg],"-write_absolute_path")) { write_absolute_path = TRUE; } else if( EQUAL(papszArgv[iArg],"-skip_different_projection")) { skip_different_projection = TRUE; } else if( EQUAL(papszArgv[iArg],"-accept_different_schemas")) { accept_different_schemas = TRUE; } else if( EQUAL(papszArgv[iArg],"-tileindex") && iArg < nArgc-1 ) { pszTileIndexField = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg],"-lnum") || EQUAL(papszArgv[iArg],"-lname") ) { iArg++; bLayersWildcarded = FALSE; } else if( papszArgv[iArg][0] == '-' ) Usage(); else if( pszOutputName == NULL ) pszOutputName = papszArgv[iArg]; else if( nFirstSourceDataset == -1 ) nFirstSourceDataset = iArg; } if( pszOutputName == NULL || nFirstSourceDataset == -1 ) Usage(); /* -------------------------------------------------------------------- */ /* Try to open as an existing dataset for update access. */ /* -------------------------------------------------------------------- */ GDALDataset *poDstDS; OGRLayer *poDstLayer = NULL; poDstDS = (GDALDataset*) OGROpen( pszOutputName, TRUE, NULL ); /* -------------------------------------------------------------------- */ /* If that failed, find the driver so we can create the tile index.*/ /* -------------------------------------------------------------------- */ if( poDstDS == NULL ) { OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar(); GDALDriver *poDriver = NULL; int iDriver; for( iDriver = 0; iDriver < poR->GetDriverCount() && poDriver == NULL; iDriver++ ) { if( EQUAL(poR->GetDriver(iDriver)->GetDescription(),pszFormat) ) { poDriver = poR->GetDriver(iDriver); } } if( poDriver == NULL ) { fprintf( stderr, "Unable to find driver `%s'.\n", pszFormat ); fprintf( stderr, "The following drivers are available:\n" ); for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ ) { fprintf( stderr, " -> `%s'\n", poR->GetDriver(iDriver)->GetDescription() ); } exit( 1 ); } if( !CSLTestBoolean( CSLFetchNameValueDef(poDriver->GetMetadata(), GDAL_DCAP_CREATE, "FALSE") ) ) { fprintf( stderr, "%s driver does not support data source creation.\n", pszFormat ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Now create it. */ /* -------------------------------------------------------------------- */ poDstDS = poDriver->Create( pszOutputName, 0, 0, 0, GDT_Unknown, NULL ); if( poDstDS == NULL ) { fprintf( stderr, "%s driver failed to create %s\n", pszFormat, pszOutputName ); exit( 1 ); } if( poDstDS->GetLayerCount() == 0 ) { OGRFieldDefn oLocation( pszTileIndexField, OFTString ); oLocation.SetWidth( 200 ); if( nFirstSourceDataset < nArgc && papszArgv[nFirstSourceDataset][0] == '-' ) { nFirstSourceDataset++; } OGRSpatialReference* poSrcSpatialRef = NULL; /* Fetches the SRS of the first layer and use it when creating the tileindex layer */ if (nFirstSourceDataset < nArgc) { GDALDataset* poDS = (GDALDataset*) OGROpen(papszArgv[nFirstSourceDataset], FALSE, NULL); if (poDS) { int iLayer; for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { int bRequested = bLayersWildcarded; OGRLayer *poLayer = poDS->GetLayer(iLayer); for( iArg = 1; iArg < nArgc && !bRequested; iArg++ ) { if( EQUAL(papszArgv[iArg],"-lnum") && atoi(papszArgv[iArg+1]) == iLayer ) bRequested = TRUE; else if( EQUAL(papszArgv[iArg],"-lname") && EQUAL(papszArgv[iArg+1], poLayer->GetLayerDefn()->GetName()) ) bRequested = TRUE; } if( !bRequested ) continue; if ( poLayer->GetSpatialRef() ) poSrcSpatialRef = poLayer->GetSpatialRef()->Clone(); break; } } GDALClose( (GDALDatasetH)poDS ); } poDstLayer = poDstDS->CreateLayer( "tileindex", poSrcSpatialRef ); poDstLayer->CreateField( &oLocation, OFTString ); OGRSpatialReference::DestroySpatialReference( poSrcSpatialRef ); } } /* -------------------------------------------------------------------- */ /* Identify target layer and field. */ /* -------------------------------------------------------------------- */ int iTileIndexField; poDstLayer = poDstDS->GetLayer(0); if( poDstLayer == NULL ) { fprintf( stderr, "Can't find any layer in output tileindex!\n" ); exit( 1 ); } iTileIndexField = poDstLayer->GetLayerDefn()->GetFieldIndex( pszTileIndexField ); if( iTileIndexField == -1 ) { fprintf( stderr, "Can't find %s field in tile index dataset.\n", pszTileIndexField ); exit( 1 ); } OGRFeatureDefn* poFeatureDefn = NULL; /* Load in memory existing file names in SHP */ int nExistingLayers = 0; char** existingLayersTab = NULL; OGRSpatialReference* alreadyExistingSpatialRef = NULL; int alreadyExistingSpatialRefValid = FALSE; nExistingLayers = poDstLayer->GetFeatureCount(); if (nExistingLayers) { int i; existingLayersTab = (char**)CPLMalloc(nExistingLayers * sizeof(char*)); for(i=0;i<nExistingLayers;i++) { OGRFeature* feature = poDstLayer->GetNextFeature(); existingLayersTab[i] = CPLStrdup(feature->GetFieldAsString( iTileIndexField)); if (i == 0) { GDALDataset *poDS; char* filename = CPLStrdup(existingLayersTab[i]); int j; for(j=strlen(filename)-1;j>=0;j--) { if (filename[j] == ',') break; } if (j >= 0) { int iLayer = atoi(filename + j + 1); filename[j] = 0; poDS = (GDALDataset*) OGROpen(filename, FALSE, NULL); if (poDS) { OGRLayer *poLayer = poDS->GetLayer(iLayer); if (poLayer) { alreadyExistingSpatialRefValid = TRUE; alreadyExistingSpatialRef = (poLayer->GetSpatialRef()) ? poLayer->GetSpatialRef()->Clone() : NULL; if (poFeatureDefn == NULL) poFeatureDefn = poLayer->GetLayerDefn()->Clone(); } GDALClose( (GDALDatasetH)poDS ); } } } } } if (write_absolute_path) { current_path = CPLGetCurrentDir(); if (current_path == NULL) { fprintf( stderr, "This system does not support the CPLGetCurrentDir call. " "The option -write_absolute_path will have no effect\n"); write_absolute_path = FALSE; } } /* ==================================================================== */ /* Process each input datasource in turn. */ /* ==================================================================== */ for(; nFirstSourceDataset < nArgc; nFirstSourceDataset++ ) { int i; GDALDataset *poDS; if( papszArgv[nFirstSourceDataset][0] == '-' ) { nFirstSourceDataset++; continue; } char* fileNameToWrite; VSIStatBuf sStatBuf; if (write_absolute_path && CPLIsFilenameRelative( papszArgv[nFirstSourceDataset] ) && VSIStat( papszArgv[nFirstSourceDataset], &sStatBuf ) == 0) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path,papszArgv[nFirstSourceDataset])); } else { fileNameToWrite = CPLStrdup(papszArgv[nFirstSourceDataset]); } poDS = (GDALDataset*) OGROpen( papszArgv[nFirstSourceDataset], FALSE, NULL ); if( poDS == NULL ) { fprintf( stderr, "Failed to open dataset %s, skipping.\n", papszArgv[nFirstSourceDataset] ); CPLFree(fileNameToWrite); continue; } /* -------------------------------------------------------------------- */ /* Check all layers, and see if they match requests. */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { int bRequested = bLayersWildcarded; OGRLayer *poLayer = poDS->GetLayer(iLayer); for( iArg = 1; iArg < nArgc && !bRequested; iArg++ ) { if( EQUAL(papszArgv[iArg],"-lnum") && atoi(papszArgv[iArg+1]) == iLayer ) bRequested = TRUE; else if( EQUAL(papszArgv[iArg],"-lname") && EQUAL(papszArgv[iArg+1], poLayer->GetLayerDefn()->GetName()) ) bRequested = TRUE; } if( !bRequested ) continue; /* Checks that the layer is not already in tileindex */ for(i=0;i<nExistingLayers;i++) { char szLocation[5000]; sprintf( szLocation, "%s,%d", fileNameToWrite, iLayer ); if (EQUAL(szLocation, existingLayersTab[i])) { fprintf(stderr, "Layer %d of %s is already in tileindex. Skipping it.\n", iLayer, papszArgv[nFirstSourceDataset]); break; } } if (i != nExistingLayers) { continue; } OGRSpatialReference* spatialRef = poLayer->GetSpatialRef(); if (alreadyExistingSpatialRefValid) { if ((spatialRef != NULL && alreadyExistingSpatialRef != NULL && spatialRef->IsSame(alreadyExistingSpatialRef) == FALSE) || ((spatialRef != NULL) != (alreadyExistingSpatialRef != NULL))) { fprintf(stderr, "Warning : layer %d of %s is not using the same projection system as " "other files in the tileindex. This may cause problems when " "using it in MapServer for example.%s\n", iLayer, papszArgv[nFirstSourceDataset], (skip_different_projection) ? " Skipping it" : ""); if (skip_different_projection) { continue; } } } else { alreadyExistingSpatialRefValid = TRUE; alreadyExistingSpatialRef = (spatialRef) ? spatialRef->Clone() : NULL; } /* -------------------------------------------------------------------- */ /* Check if all layers in dataset have the same attributes schema. */ /* -------------------------------------------------------------------- */ if( poFeatureDefn == NULL ) { poFeatureDefn = poLayer->GetLayerDefn()->Clone(); } else if ( !accept_different_schemas ) { OGRFeatureDefn* poFeatureDefnCur = poLayer->GetLayerDefn(); assert(NULL != poFeatureDefnCur); int fieldCount = poFeatureDefnCur->GetFieldCount(); if( fieldCount != poFeatureDefn->GetFieldCount()) { fprintf( stderr, "Number of attributes of layer %s of %s does not match ... skipping it.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]); if (bFirstWarningForNonMatchingAttributes) { fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n" "but this may result in a tileindex incompatible with MapServer\n"); bFirstWarningForNonMatchingAttributes = FALSE; } continue; } int bSkip = FALSE; for( int fn = 0; fn < poFeatureDefnCur->GetFieldCount(); fn++ ) { OGRFieldDefn* poField = poFeatureDefn->GetFieldDefn(fn); OGRFieldDefn* poFieldCur = poFeatureDefnCur->GetFieldDefn(fn); /* XXX - Should those pointers be checked against NULL? */ assert(NULL != poField); assert(NULL != poFieldCur); if( poField->GetType() != poFieldCur->GetType() || poField->GetWidth() != poFieldCur->GetWidth() || poField->GetPrecision() != poFieldCur->GetPrecision() || !EQUAL( poField->GetNameRef(), poFieldCur->GetNameRef() ) ) { fprintf( stderr, "Schema of attributes of layer %s of %s does not match ... skipping it.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]); if (bFirstWarningForNonMatchingAttributes) { fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n" "but this may result in a tileindex incompatible with MapServer\n"); bFirstWarningForNonMatchingAttributes = FALSE; } bSkip = TRUE; break; } } if (bSkip) continue; } /* -------------------------------------------------------------------- */ /* Get layer extents, and create a corresponding polygon */ /* geometry. */ /* -------------------------------------------------------------------- */ OGREnvelope sExtents; OGRPolygon oRegion; OGRLinearRing oRing; if( poLayer->GetExtent( &sExtents, TRUE ) != OGRERR_NONE ) { fprintf( stderr, "GetExtent() failed on layer %s of %s, skipping.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset] ); continue; } oRing.addPoint( sExtents.MinX, sExtents.MinY ); oRing.addPoint( sExtents.MinX, sExtents.MaxY ); oRing.addPoint( sExtents.MaxX, sExtents.MaxY ); oRing.addPoint( sExtents.MaxX, sExtents.MinY ); oRing.addPoint( sExtents.MinX, sExtents.MinY ); oRegion.addRing( &oRing ); /* -------------------------------------------------------------------- */ /* Add layer to tileindex. */ /* -------------------------------------------------------------------- */ char szLocation[5000]; OGRFeature oTileFeat( poDstLayer->GetLayerDefn() ); sprintf( szLocation, "%s,%d", fileNameToWrite, iLayer ); oTileFeat.SetGeometry( &oRegion ); oTileFeat.SetField( iTileIndexField, szLocation ); if( poDstLayer->CreateFeature( &oTileFeat ) != OGRERR_NONE ) { fprintf( stderr, "Failed to create feature on tile index ... terminating." ); GDALClose( (GDALDatasetH) poDstDS ); exit( 1 ); } } /* -------------------------------------------------------------------- */ /* Cleanup this data source. */ /* -------------------------------------------------------------------- */ CPLFree(fileNameToWrite); GDALClose( (GDALDatasetH)poDS ); } /* -------------------------------------------------------------------- */ /* Close tile index and clear buffers. */ /* -------------------------------------------------------------------- */ GDALClose( (GDALDatasetH) poDstDS ); OGRFeatureDefn::DestroyFeatureDefn( poFeatureDefn ); if (alreadyExistingSpatialRef != NULL) OGRSpatialReference::DestroySpatialReference( alreadyExistingSpatialRef ); CPLFree(current_path); if (nExistingLayers) { int i; for(i=0;i<nExistingLayers;i++) { CPLFree(existingLayersTab[i]); } CPLFree(existingLayersTab); } OGRCleanupAll(); return 0; }
OGRGeometry* KMLNode::getGeometry(Nodetype eType) { unsigned int nCount, nCount2, nCountP; OGRGeometry* poGeom = NULL; KMLNode* poCoor = NULL; Coordinate* psCoord = NULL; if (sName_.compare("Point") == 0) { // Search coordinate Element for(nCount = 0; nCount < pvpoChildren_->size(); nCount++) { if((*pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0) { poCoor = (*pvpoChildren_)[nCount]; for(nCountP = 0; nCountP < poCoor->pvsContent_->size(); nCountP++) { psCoord = ParseCoordinate((*poCoor->pvsContent_)[nCountP]); if(psCoord != NULL) { if (psCoord->bHasZ) poGeom = new OGRPoint(psCoord->dfLongitude, psCoord->dfLatitude, psCoord->dfAltitude); else poGeom = new OGRPoint(psCoord->dfLongitude, psCoord->dfLatitude); delete psCoord; return poGeom; } } } } poGeom = new OGRPoint(); } else if (sName_.compare("LineString") == 0) { // Search coordinate Element poGeom = new OGRLineString(); for(nCount = 0; nCount < pvpoChildren_->size(); nCount++) { if((*pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0) { poCoor = (*pvpoChildren_)[nCount]; for(nCountP = 0; nCountP < poCoor->pvsContent_->size(); nCountP++) { psCoord = ParseCoordinate((*poCoor->pvsContent_)[nCountP]); if(psCoord != NULL) { if (psCoord->bHasZ) ((OGRLineString*)poGeom)->addPoint(psCoord->dfLongitude, psCoord->dfLatitude, psCoord->dfAltitude); else ((OGRLineString*)poGeom)->addPoint(psCoord->dfLongitude, psCoord->dfLatitude); delete psCoord; } } } } } else if (sName_.compare("Polygon") == 0) { //********************************* // Search outerBoundaryIs Element //********************************* poGeom = new OGRPolygon(); for(nCount = 0; nCount < pvpoChildren_->size(); nCount++) { if((*pvpoChildren_)[nCount]->sName_.compare("outerBoundaryIs") == 0 && (*pvpoChildren_)[nCount]->pvpoChildren_->size() > 0) { poCoor = (*(*pvpoChildren_)[nCount]->pvpoChildren_)[0]; } } // No outer boundary found if(poCoor == NULL) { return poGeom; } // Search coordinate Element OGRLinearRing* poLinearRing = NULL; for(nCount = 0; nCount < poCoor->pvpoChildren_->size(); nCount++) { if((*poCoor->pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0) { for(nCountP = 0; nCountP < (*poCoor->pvpoChildren_)[nCount]->pvsContent_->size(); nCountP++) { psCoord = ParseCoordinate((*(*poCoor->pvpoChildren_)[nCount]->pvsContent_)[nCountP]); if(psCoord != NULL) { if (poLinearRing == NULL) { poLinearRing = new OGRLinearRing(); } if (psCoord->bHasZ) poLinearRing->addPoint(psCoord->dfLongitude, psCoord->dfLatitude, psCoord->dfAltitude); else poLinearRing->addPoint(psCoord->dfLongitude, psCoord->dfLatitude); delete psCoord; } } } } // No outer boundary coordinates found if(poLinearRing == NULL) { return poGeom; } ((OGRPolygon*)poGeom)->addRingDirectly(poLinearRing); poLinearRing = NULL; //********************************* // Search innerBoundaryIs Elements //********************************* for(nCount2 = 0; nCount2 < pvpoChildren_->size(); nCount2++) { if((*pvpoChildren_)[nCount2]->sName_.compare("innerBoundaryIs") == 0) { if (poLinearRing) ((OGRPolygon*)poGeom)->addRingDirectly(poLinearRing); poLinearRing = NULL; if ((*pvpoChildren_)[nCount2]->pvpoChildren_->size() == 0) continue; poLinearRing = new OGRLinearRing(); poCoor = (*(*pvpoChildren_)[nCount2]->pvpoChildren_)[0]; // Search coordinate Element for(nCount = 0; nCount < poCoor->pvpoChildren_->size(); nCount++) { if((*poCoor->pvpoChildren_)[nCount]->sName_.compare("coordinates") == 0) { for(nCountP = 0; nCountP < (*poCoor->pvpoChildren_)[nCount]->pvsContent_->size(); nCountP++) { psCoord = ParseCoordinate((*(*poCoor->pvpoChildren_)[nCount]->pvsContent_)[nCountP]); if(psCoord != NULL) { if (psCoord->bHasZ) poLinearRing->addPoint(psCoord->dfLongitude, psCoord->dfLatitude, psCoord->dfAltitude); else poLinearRing->addPoint(psCoord->dfLongitude, psCoord->dfLatitude); delete psCoord; } } } } } } if (poLinearRing) ((OGRPolygon*)poGeom)->addRingDirectly(poLinearRing); } else if (sName_.compare("MultiGeometry") == 0) { if (eType == MultiPoint) poGeom = new OGRMultiPoint(); else if (eType == MultiLineString) poGeom = new OGRMultiLineString(); else if (eType == MultiPolygon) poGeom = new OGRMultiPolygon(); else poGeom = new OGRGeometryCollection(); for(nCount = 0; nCount < pvpoChildren_->size(); nCount++) { OGRGeometry* poSubGeom = (*pvpoChildren_)[nCount]->getGeometry(); if (poSubGeom) ((OGRGeometryCollection*)poGeom)->addGeometryDirectly(poSubGeom); } } return poGeom; }
OGRFeature *OGROpenAirLayer::GetNextRawFeature() { const char* pszLine; CPLString osCLASS, osNAME, osFLOOR, osCEILING; OGRLinearRing oLR; double dfLastLat = 0, dfLastLon = 0; int bFirst = TRUE; int bClockWise = TRUE; double dfCenterLat = 0, dfCenterLon = 0; int bHasCenter = FALSE; OpenAirStyle sStyle; sStyle.penStyle = -1; sStyle.penWidth = -1; sStyle.penR = sStyle.penG = sStyle.penB = -1; sStyle.fillR = sStyle.fillG = sStyle.fillB = -1; if (bEOF) return NULL; while(TRUE) { if (bFirst && bHasLastLine) { pszLine = osLastLine.c_str(); bFirst = FALSE; } else { pszLine = CPLReadLine2L(fpOpenAir, 1024, NULL); if (pszLine == NULL) { bEOF = TRUE; if (oLR.getNumPoints() == 0) return NULL; if (osCLASS.size() != 0 && oStyleMap.find(osCLASS) != oStyleMap.end()) { memcpy(&sStyle, oStyleMap[osCLASS], sizeof(sStyle)); } break; } osLastLine = pszLine; bHasLastLine = TRUE; } if (pszLine[0] == '*' || pszLine[0] == '\0') continue; if (EQUALN(pszLine, "AC ", 3) || EQUALN(pszLine, "AC,", 3)) { if (osCLASS.size() != 0) { if (sStyle.penStyle != -1 || sStyle.fillR != -1) { if (oLR.getNumPoints() == 0) { OpenAirStyle* psStyle; if (oStyleMap.find(osCLASS) == oStyleMap.end()) { psStyle = (OpenAirStyle*)CPLMalloc( sizeof(OpenAirStyle)); oStyleMap[osCLASS] = psStyle; } else psStyle = oStyleMap[osCLASS]; memcpy(psStyle, &sStyle, sizeof(sStyle)); } else break; } else if (oStyleMap.find(osCLASS) != oStyleMap.end()) { memcpy(&sStyle, oStyleMap[osCLASS], sizeof(sStyle)); break; } else break; } sStyle.penStyle = -1; sStyle.penWidth = -1; sStyle.penR = sStyle.penG = sStyle.penB = -1; sStyle.fillR = sStyle.fillG = sStyle.fillB = -1; osCLASS = pszLine + 3; bClockWise = TRUE; bHasCenter = FALSE; } else if (EQUALN(pszLine, "AN ", 3)) { if (osNAME.size() != 0) break; osNAME = pszLine + 3; } else if (EQUALN(pszLine, "AH ", 3)) osCEILING = pszLine + 3; else if (EQUALN(pszLine, "AL ", 3)) osFLOOR = pszLine + 3; else if (EQUALN(pszLine, "AT ", 3)) { /* Ignored for that layer*/ } else if (EQUALN(pszLine, "SP ", 3)) { if (osCLASS.size() != 0) { char** papszTokens = CSLTokenizeString2(pszLine+3, ", ", 0); if (CSLCount(papszTokens) == 5) { sStyle.penStyle = atoi(papszTokens[0]); sStyle.penWidth = atoi(papszTokens[1]); sStyle.penR = atoi(papszTokens[2]); sStyle.penG = atoi(papszTokens[3]); sStyle.penB = atoi(papszTokens[4]); } CSLDestroy(papszTokens); } } else if (EQUALN(pszLine, "SB ", 3)) { if (osCLASS.size() != 0) { char** papszTokens = CSLTokenizeString2(pszLine+3, ", ", 0); if (CSLCount(papszTokens) == 3) { sStyle.fillR = atoi(papszTokens[0]); sStyle.fillG = atoi(papszTokens[1]); sStyle.fillB = atoi(papszTokens[2]); } CSLDestroy(papszTokens); } } else if (EQUALN(pszLine, "DP ", 3)) { pszLine += 3; double dfLat, dfLon; if (!OGROpenAirGetLatLon(pszLine, dfLat, dfLon)) continue; oLR.addPoint(dfLon, dfLat); dfLastLat = dfLat; dfLastLon = dfLon; } else if (EQUALN(pszLine, "DA ", 3)) { pszLine += 3; char* pszStar = strchr((char*)pszLine, '*'); if (pszStar) *pszStar = 0; char** papszTokens = CSLTokenizeString2(pszLine, ",", 0); if (bHasCenter && CSLCount(papszTokens) == 3) { double dfRadius = atof(papszTokens[0]) * 1852; double dfStartAngle = atof(papszTokens[1]); double dfEndAngle = atof(papszTokens[2]); if (bClockWise && dfEndAngle < dfStartAngle) dfEndAngle += 360; else if (!bClockWise && dfStartAngle < dfEndAngle) dfEndAngle -= 360; double dfStartDistance = dfRadius; double dfEndDistance = dfRadius; int nSign = (bClockWise) ? 1 : -1; double dfAngle; double dfLat, dfLon; for(dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign) { double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle); double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct; OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfEndDistance, dfEndAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } CSLDestroy(papszTokens); } else if (EQUALN(pszLine, "DB ", 3)) { pszLine += 3; char* pszStar = strchr((char*)pszLine, '*'); if (pszStar) *pszStar = 0; char** papszTokens = CSLTokenizeString2(pszLine, ",", 0); double dfFirstLat, dfFirstLon; double dfSecondLat, dfSecondLon; if (bHasCenter && CSLCount(papszTokens) == 2 && OGROpenAirGetLatLon(papszTokens[0], dfFirstLat, dfFirstLon) && OGROpenAirGetLatLon(papszTokens[1], dfSecondLat, dfSecondLon)) { double dfStartDistance =OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfFirstLat, dfFirstLon); double dfEndDistance = OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfSecondLat, dfSecondLon); double dfStartAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfFirstLat, dfFirstLon); double dfEndAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfSecondLat, dfSecondLon); if (bClockWise && dfEndAngle < dfStartAngle) dfEndAngle += 360; else if (!bClockWise && dfStartAngle < dfEndAngle) dfEndAngle -= 360; int nSign = (bClockWise) ? 1 : -1; double dfAngle; for(dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign) { double dfLat, dfLon; double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle); double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct; OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } oLR.addPoint(dfSecondLon, dfSecondLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } CSLDestroy(papszTokens); } else if ((EQUALN(pszLine, "DC ", 3) || EQUALN(pszLine, "DC=", 3)) && (bHasCenter || strstr(pszLine, "V X=") != NULL)) { if (!bHasCenter) { const char* pszVX = strstr(pszLine, "V X="); bHasCenter = OGROpenAirGetLatLon(pszVX, dfCenterLat, dfCenterLon); } if (bHasCenter) { pszLine += 3; double dfRADIUS = atof(pszLine) * 1852; double dfAngle; double dfLat, dfLon; for(dfAngle = 0; dfAngle < 360; dfAngle += 1) { OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, 0, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } } else if (EQUALN(pszLine, "V X=", 4)) { bHasCenter = OGROpenAirGetLatLon(pszLine + 4, dfCenterLat, dfCenterLon); } else if (EQUALN(pszLine, "V D=-", 5)) { bClockWise = FALSE; } else if (EQUALN(pszLine, "V D=+", 5)) { bClockWise = TRUE; } else { //CPLDebug("OpenAir", "Unexpected content : %s", pszLine); } } OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, osCLASS.c_str()); poFeature->SetField(1, osNAME.c_str()); poFeature->SetField(2, osFLOOR.c_str()); poFeature->SetField(3, osCEILING.c_str()); if (sStyle.penStyle != -1 || sStyle.fillR != -1) { CPLString osStyle; if (sStyle.penStyle != -1) { osStyle += CPLString().Printf("PEN(c:#%02X%02X%02X,w:%dpt", sStyle.penR, sStyle.penG, sStyle.penB, sStyle.penWidth); if (sStyle.penStyle == 1) osStyle += ",p:\"5px 5px\""; osStyle += ")"; } if (sStyle.fillR != -1) { if (osStyle.size() != 0) osStyle += ";"; osStyle += CPLString().Printf("BRUSH(fc:#%02X%02X%02X)", sStyle.fillR, sStyle.fillG, sStyle.fillB); } else { if (osStyle.size() != 0) osStyle += ";"; osStyle += "BRUSH(fc:#00000000,id:\"ogr-brush-1\")"; } if (osStyle.size() != 0) poFeature->SetStyleString(osStyle); } OGRPolygon* poPoly = new OGRPolygon(); oLR.closeRings(); poPoly->addRing(&oLR); poPoly->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly(poPoly); poFeature->SetFID(nNextFID++); return poFeature; }
OGRFeature *OGRHTFPolygonLayer::GetNextRawFeature() { OGRFeature* poFeature = new OGRFeature(poFeatureDefn); const char* pszLine; OGRLinearRing oLR; bool bHasFirstCoord = false; double dfFirstEasting = 0; double dfFirstNorthing = 0; double dfIslandEasting = 0; double dfIslandNorthing = 0; bool bInIsland = false; OGRPolygon* poPoly = new OGRPolygon(); while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL) { if (pszLine[0] == ';') { /* comment */ ; } else if (pszLine[0] == 0) { /* end of polygon is marked by a blank line */ break; } else if (STARTS_WITH(pszLine, "POLYGON DESCRIPTION: ")) { poFeature->SetField(0, pszLine + strlen("POLYGON DESCRIPTION: ")); } else if (STARTS_WITH(pszLine, "POLYGON IDENTIFIER: ")) { poFeature->SetField(1, pszLine + strlen("POLYGON IDENTIFIER: ")); } else if (STARTS_WITH(pszLine, "SEAFLOOR COVERAGE: ")) { const char* pszVal = pszLine + strlen("SEAFLOOR COVERAGE: "); if (*pszVal != '*') poFeature->SetField(2, pszVal); } else if (STARTS_WITH(pszLine, "POSITION ACCURACY: ")) { const char* pszVal = pszLine + strlen("POSITION ACCURACY: "); if (*pszVal != '*') poFeature->SetField(3, pszVal); } else if (STARTS_WITH(pszLine, "DEPTH ACCURACY: ")) { const char* pszVal = pszLine + strlen("DEPTH ACCURACY: "); if (*pszVal != '*') poFeature->SetField(4, pszVal); } else if (strcmp(pszLine, "END OF POLYGON DATA") == 0) { bEOF = true; break; } else { char** papszTokens = CSLTokenizeString(pszLine); if (CSLCount(papszTokens) == 4) { const double dfEasting = CPLAtof(papszTokens[2]); const double dfNorthing = CPLAtof(papszTokens[3]); if (!bHasFirstCoord) { bHasFirstCoord = true; dfFirstEasting = dfEasting; dfFirstNorthing = dfNorthing; oLR.addPoint(dfEasting, dfNorthing); } else if (dfFirstEasting == dfEasting && dfFirstNorthing == dfNorthing) { if (!bInIsland) { oLR.addPoint(dfEasting, dfNorthing); poPoly->addRing(&oLR); oLR.empty(); bInIsland = true; } } else if (bInIsland && oLR.getNumPoints() == 0) { dfIslandEasting = dfEasting; dfIslandNorthing = dfNorthing; oLR.addPoint(dfEasting, dfNorthing); } else if (bInIsland && dfIslandEasting == dfEasting && dfIslandNorthing == dfNorthing) { oLR.addPoint(dfEasting, dfNorthing); poPoly->addRing(&oLR); oLR.empty(); } else { oLR.addPoint(dfEasting, dfNorthing); } } CSLDestroy(papszTokens); } } if (pszLine == NULL) bEOF = true; if (oLR.getNumPoints() >= 3) { oLR.closeRings(); poPoly->addRing(&oLR); } poPoly->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly(poPoly); poFeature->SetFID(nNextFID++); return poFeature; }
bool Shape::save(const std::string& filename) { if (shapeType == -1) { std::cout << "Shape type is not set." << std::endl; return false; } if (shapeObjects.size() == 0) { std::cout << "No shape exists." << std::endl; return false; } const char *pszDriverName = "ESRI Shapefile"; GDALDriver *poDriver; GDALAllRegister(); poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName); if (poDriver == NULL) { printf("%s driver not available.\n", pszDriverName); return false; } GDALDataset *poDS; poDS = poDriver->Create(filename.c_str(), 0, 0, 0, GDT_Unknown, NULL); if (poDS == NULL) { printf("Creation of output file failed.\n"); return false; } OGRLayer *poLayer; if (shapeType == wkbPoint) { poLayer = poDS->CreateLayer("point_out", NULL, wkbPoint, NULL); } else if (shapeType == wkbLineString) { poLayer = poDS->CreateLayer("point_out", NULL, wkbLineString, NULL); } else if (shapeType == wkbPolygon) { poLayer = poDS->CreateLayer("point_out", NULL, wkbPolygon, NULL); } if (poLayer == NULL) { printf("Layer creation failed.\n"); return false; } for (auto it = shapeObjects[0].attributes.begin(); it != shapeObjects[0].attributes.end(); ++it) { OGRFieldDefn oField(it->first.c_str(), static_cast<OGRFieldType>(it->second.type)); if (it->second.type == OFTString) { oField.SetWidth(it->second.stringValue().size()); } if (poLayer->CreateField(&oField) != OGRERR_NONE) { printf("Creating Name field failed.\n"); return false; } } for (int i = 0; i < shapeObjects.size(); ++i) { if (shapeObjects[i].parts.size() == 0) continue; OGRFeature *poFeature; poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn()); // 属性をセット for (auto it = shapeObjects[i].attributes.begin(); it != shapeObjects[i].attributes.end(); ++it) { poFeature->SetField(it->first.c_str(), it->second.stringValue().c_str()); } // ジオメトリ情報をセット if (shapeType == wkbPoint) { OGRPoint point; point.setX(shapeObjects[i].parts[0].points[0].x); point.setY(shapeObjects[i].parts[0].points[0].y); point.setZ(shapeObjects[i].parts[0].points[0].z); poFeature->SetGeometry(&point); } else if (shapeType == wkbLineString) { OGRLineString lineString; for (int k = 0; k < shapeObjects[i].parts[0].points.size(); ++k) { lineString.addPoint(shapeObjects[i].parts[0].points[k].x, shapeObjects[i].parts[0].points[k].y, shapeObjects[i].parts[0].points[k].z); } poFeature->SetGeometry(&lineString); } else if (shapeType == wkbPolygon) { OGRPolygon polygon; for (int j = 0; j < shapeObjects[i].parts.size(); ++j) { OGRLinearRing linearRing; for (int k = 0; k < shapeObjects[i].parts[j].points.size(); ++k) { linearRing.addPoint(shapeObjects[i].parts[j].points[k].x, shapeObjects[i].parts[j].points[k].y, shapeObjects[i].parts[j].points[k].z); } polygon.addRing(&linearRing); } poFeature->SetGeometry(&polygon); } if (poLayer->CreateFeature(poFeature) != OGRERR_NONE) { printf("Failed to create feature in shapefile.\n"); return false; } OGRFeature::DestroyFeature(poFeature); } GDALClose(poDS); return true; }
OGRFeature *OGRCADLayer::GetFeature( GIntBig nFID ) { if( poCADLayer.getGeometryCount() <= static_cast<size_t>(nFID) || nFID < 0 ) { return nullptr; } OGRFeature *poFeature = nullptr; CADGeometry *poCADGeometry = poCADLayer.getGeometry( static_cast<size_t>(nFID) ); if( nullptr == poCADGeometry || GetLastErrorCode() != CADErrorCodes::SUCCESS ) { CPLError( CE_Failure, CPLE_NotSupported, "Failed to get geometry with ID = " CPL_FRMT_GIB " from layer \"%s\". Libopencad errorcode: %d", nFID, poCADLayer.getName().c_str(), GetLastErrorCode() ); return nullptr; } poFeature = new OGRFeature( poFeatureDefn ); poFeature->SetFID( nFID ); poFeature->SetField( FIELD_NAME_THICKNESS, poCADGeometry->getThickness() ); if( !poCADGeometry->getEED().empty() ) { std::vector<std::string> asGeometryEED = poCADGeometry->getEED(); std::string sEEDAsOneString = ""; for ( std::vector<std::string>::const_iterator iter = asGeometryEED.cbegin(); iter != asGeometryEED.cend(); ++iter ) { sEEDAsOneString += *iter; sEEDAsOneString += ' '; } poFeature->SetField( FIELD_NAME_EXT_DATA, sEEDAsOneString.c_str() ); } RGBColor stRGB = poCADGeometry->getColor(); CPLString sHexColor; sHexColor.Printf("#%02X%02X%02X%02X", stRGB.R, stRGB.G, stRGB.B, 255); poFeature->SetField( FIELD_NAME_COLOR, sHexColor ); CPLString sStyle; sStyle.Printf("PEN(c:%s,w:5px)", sHexColor.c_str()); poFeature->SetStyleString( sStyle ); std::vector< CADAttrib > oBlockAttrs = poCADGeometry->getBlockAttributes(); for( const CADAttrib& oAttrib : oBlockAttrs ) { CPLString osTag = oAttrib.getTag(); auto featureAttrIt = asFeaturesAttributes.find( osTag ); if( featureAttrIt != asFeaturesAttributes.end()) { poFeature->SetField(*featureAttrIt, oAttrib.getTextValue().c_str()); } } switch( poCADGeometry->getType() ) { case CADGeometry::POINT: { CADPoint3D * const poCADPoint = ( CADPoint3D* ) poCADGeometry; CADVector stPositionVector = poCADPoint->getPosition(); poFeature->SetGeometryDirectly( new OGRPoint( stPositionVector.getX(), stPositionVector.getY(), stPositionVector.getZ() ) ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADPoint" ); break; } case CADGeometry::LINE: { CADLine * const poCADLine = ( CADLine* ) poCADGeometry; OGRLineString *poLS = new OGRLineString(); poLS->addPoint( poCADLine->getStart().getPosition().getX(), poCADLine->getStart().getPosition().getY(), poCADLine->getStart().getPosition().getZ() ); poLS->addPoint( poCADLine->getEnd().getPosition().getX(), poCADLine->getEnd().getPosition().getY(), poCADLine->getEnd().getPosition().getZ() ); poFeature->SetGeometryDirectly( poLS ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADLine" ); break; } case CADGeometry::SOLID: { CADSolid * const poCADSolid = ( CADSolid* ) poCADGeometry; OGRPolygon * poPoly = new OGRPolygon(); OGRLinearRing * poLR = new OGRLinearRing(); std::vector<CADVector> astSolidCorners = poCADSolid->getCorners(); for( size_t i = 0; i < astSolidCorners.size(); ++i ) { poLR->addPoint( astSolidCorners[i].getX(), astSolidCorners[i].getY(), astSolidCorners[i].getZ()); } poPoly->addRingDirectly( poLR ); poPoly->closeRings(); poFeature->SetGeometryDirectly( poPoly ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADSolid" ); break; } case CADGeometry::CIRCLE: { CADCircle * poCADCircle = static_cast<CADCircle*>(poCADGeometry); OGRCircularString * poCircle = new OGRCircularString(); CADVector stCircleCenter = poCADCircle->getPosition(); OGRPoint oCirclePoint1; oCirclePoint1.setX( stCircleCenter.getX() - poCADCircle->getRadius() ); oCirclePoint1.setY( stCircleCenter.getY() ); oCirclePoint1.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint1 ); OGRPoint oCirclePoint2; oCirclePoint2.setX( stCircleCenter.getX() ); oCirclePoint2.setY( stCircleCenter.getY() + poCADCircle->getRadius() ); oCirclePoint2.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint2 ); OGRPoint oCirclePoint3; oCirclePoint3.setX( stCircleCenter.getX() + poCADCircle->getRadius() ); oCirclePoint3.setY( stCircleCenter.getY() ); oCirclePoint3.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint3 ); OGRPoint oCirclePoint4; oCirclePoint4.setX( stCircleCenter.getX() ); oCirclePoint4.setY( stCircleCenter.getY() - poCADCircle->getRadius() ); oCirclePoint4.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint4 ); // Close the circle poCircle->addPoint( &oCirclePoint1 ); /*NOTE: The alternative way: OGRGeometry *poCircle = OGRGeometryFactory::approximateArcAngles( poCADCircle->getPosition().getX(), poCADCircle->getPosition().getY(), poCADCircle->getPosition().getZ(), poCADCircle->getRadius(), poCADCircle->getRadius(), 0.0, 0.0, 360.0, 0.0 ); */ poFeature->SetGeometryDirectly( poCircle ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADCircle" ); break; } case CADGeometry::ARC: { CADArc * poCADArc = static_cast<CADArc*>(poCADGeometry); OGRCircularString * poCircle = new OGRCircularString(); // Need at least 3 points in arc double dfStartAngle = poCADArc->getStartingAngle() * DEG2RAD; double dfEndAngle = poCADArc->getEndingAngle() * DEG2RAD; double dfMidAngle = (dfEndAngle + dfStartAngle) / 2; CADVector stCircleCenter = poCADArc->getPosition(); OGRPoint oCirclePoint; oCirclePoint.setX( stCircleCenter.getX() + poCADArc->getRadius() * cos( dfStartAngle ) ); oCirclePoint.setY( stCircleCenter.getY() + poCADArc->getRadius() * sin( dfStartAngle ) ); oCirclePoint.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint ); oCirclePoint.setX( stCircleCenter.getX() + poCADArc->getRadius() * cos( dfMidAngle ) ); oCirclePoint.setY( stCircleCenter.getY() + poCADArc->getRadius() * sin( dfMidAngle ) ); oCirclePoint.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint ); oCirclePoint.setX( stCircleCenter.getX() + poCADArc->getRadius() * cos( dfEndAngle ) ); oCirclePoint.setY( stCircleCenter.getY() + poCADArc->getRadius() * sin( dfEndAngle ) ); oCirclePoint.setZ( stCircleCenter.getZ() ); poCircle->addPoint( &oCirclePoint ); /*NOTE: alternative way: OGRGeometry * poArc = OGRGeometryFactory::approximateArcAngles( poCADArc->getPosition().getX(), poCADArc->getPosition().getY(), poCADArc->getPosition().getZ(), poCADArc->getRadius(), poCADArc->getRadius(), 0.0, dfStartAngle, dfStartAngle > dfEndAngle ? ( dfEndAngle + 360.0f ) : dfEndAngle, 0.0 ); */ poFeature->SetGeometryDirectly( poCircle ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADArc" ); break; } case CADGeometry::FACE3D: { CADFace3D * const poCADFace = ( CADFace3D* ) poCADGeometry; OGRPolygon * poPoly = new OGRPolygon(); OGRLinearRing * poLR = new OGRLinearRing(); for ( size_t i = 0; i < 3; ++i ) { poLR->addPoint( poCADFace->getCorner( i ).getX(), poCADFace->getCorner( i ).getY(), poCADFace->getCorner( i ).getZ() ); } if ( !(poCADFace->getCorner( 2 ) == poCADFace->getCorner( 3 )) ) { poLR->addPoint( poCADFace->getCorner( 3 ).getX(), poCADFace->getCorner( 3 ).getY(), poCADFace->getCorner( 3 ).getZ() ); } poPoly->addRingDirectly( poLR ); poPoly->closeRings(); poFeature->SetGeometryDirectly( poPoly ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADFace3D" ); break; } case CADGeometry::LWPOLYLINE: { CADLWPolyline * const poCADLWPolyline = ( CADLWPolyline* ) poCADGeometry; poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADLWPolyline" ); /* * Excessive check, like in DXF driver. * I tried to make a single-point polyline, but couldn't make it. * Probably this check should be removed. */ if( poCADLWPolyline->getVertexCount() == 1 ) { poFeature->SetGeometryDirectly( new OGRPoint( poCADLWPolyline->getVertex(0).getX(), poCADLWPolyline->getVertex(0).getY(), poCADLWPolyline->getVertex(0).getZ() ) ); break; } /* * If polyline has no arcs, handle it in easy way. */ OGRLineString * poLS = new OGRLineString(); if( poCADLWPolyline->getBulges().empty() ) { for( size_t i = 0; i < poCADLWPolyline->getVertexCount(); ++i ) { CADVector stVertex = poCADLWPolyline->getVertex( i ); poLS->addPoint( stVertex.getX(), stVertex.getY(), stVertex.getZ() ); } poFeature->SetGeometryDirectly( poLS ); break; } /* * Last case - if polyline has mixed arcs and lines. */ bool bLineStringStarted = false; std::vector< double > adfBulges = poCADLWPolyline->getBulges(); const size_t nCount = std::min(adfBulges.size(), poCADLWPolyline->getVertexCount()); for( size_t iCurrentVertex = 0; iCurrentVertex + 1 < nCount; iCurrentVertex++ ) { CADVector stCurrentVertex = poCADLWPolyline->getVertex( iCurrentVertex ); CADVector stNextVertex = poCADLWPolyline->getVertex( iCurrentVertex + 1 ); double dfLength = sqrt( pow( stNextVertex.getX() - stCurrentVertex.getX(), 2 ) + pow( stNextVertex.getY() - stCurrentVertex.getY(), 2 ) ); /* * Handling straight polyline segment. */ if( ( dfLength == 0 ) || ( adfBulges[iCurrentVertex] == 0 ) ) { if( !bLineStringStarted ) { poLS->addPoint( stCurrentVertex.getX(), stCurrentVertex.getY(), stCurrentVertex.getZ() ); bLineStringStarted = true; } poLS->addPoint( stNextVertex.getX(), stNextVertex.getY(), stNextVertex.getZ() ); } else { double dfSegmentBulge = adfBulges[iCurrentVertex]; double dfH = ( dfSegmentBulge * dfLength ) / 2; if( dfH == 0.0 ) dfH = 1.0; // just to avoid a division by zero double dfRadius = ( dfH / 2 ) + ( dfLength * dfLength / ( 8 * dfH ) ); double dfOgrArcRotation = 0, dfOgrArcRadius = fabs( dfRadius ); /* * Set arc's direction and keep bulge positive. */ bool bClockwise = ( dfSegmentBulge < 0 ); if( bClockwise ) dfSegmentBulge *= -1; /* * Get arc's center point. */ double dfSaggita = fabs( dfSegmentBulge * ( dfLength / 2.0 ) ); double dfApo = bClockwise ? -( dfOgrArcRadius - dfSaggita ) : -( dfSaggita - dfOgrArcRadius ); CADVector stVertex; stVertex.setX( stCurrentVertex.getX() - stNextVertex.getX() ); stVertex.setY( stCurrentVertex.getY() - stNextVertex.getY() ); stVertex.setZ( stCurrentVertex.getZ() ); CADVector stMidPoint; stMidPoint.setX( stNextVertex.getX() + 0.5 * stVertex.getX() ); stMidPoint.setY( stNextVertex.getY() + 0.5 * stVertex.getY() ); stMidPoint.setZ( stVertex.getZ() ); CADVector stPperp; stPperp.setX( stVertex.getY() ); stPperp.setY( -stVertex.getX() ); double dfStPperpLength = sqrt( stPperp.getX() * stPperp.getX() + stPperp.getY() * stPperp.getY() ); // TODO: Check that length isnot 0 stPperp.setX( stPperp.getX() / dfStPperpLength ); stPperp.setY( stPperp.getY() / dfStPperpLength ); CADVector stOgrArcCenter; stOgrArcCenter.setX( stMidPoint.getX() + ( stPperp.getX() * dfApo ) ); stOgrArcCenter.setY( stMidPoint.getY() + ( stPperp.getY() * dfApo ) ); /* * Get the line's general vertical direction ( -1 = down, +1 = up ). */ double dfLineDir = stNextVertex.getY() > stCurrentVertex.getY() ? 1.0f : -1.0f; /* * Get arc's starting angle. */ double dfA = atan2( ( stOgrArcCenter.getY() - stCurrentVertex.getY() ), ( stOgrArcCenter.getX() - stCurrentVertex.getX() ) ) * DEG2RAD; if( bClockwise && ( dfLineDir == 1.0 ) ) dfA += ( dfLineDir * 180.0 ); double dfOgrArcStartAngle = dfA > 0.0 ? -( dfA - 180.0 ) : -( dfA + 180.0 ); /* * Get arc's ending angle. */ dfA = atan2( ( stOgrArcCenter.getY() - stNextVertex.getY() ), ( stOgrArcCenter.getX() - stNextVertex.getX() ) ) * DEG2RAD; if( bClockwise && ( dfLineDir == 1.0 ) ) dfA += ( dfLineDir * 180.0 ); double dfOgrArcEndAngle = dfA > 0.0 ? -( dfA - 180.0 ) : -( dfA + 180.0 ); if( !bClockwise && ( dfOgrArcStartAngle < dfOgrArcEndAngle) ) dfOgrArcEndAngle = -180.0 + ( dfLineDir * dfA ); if( bClockwise && ( dfOgrArcStartAngle > dfOgrArcEndAngle ) ) dfOgrArcEndAngle += 360.0; /* * Flip arc's rotation if necessary. */ if( bClockwise && ( dfLineDir == 1.0 ) ) dfOgrArcRotation = dfLineDir * 180.0; /* * Tessellate the arc segment and append to the linestring. */ OGRLineString * poArcpoLS = ( OGRLineString * ) OGRGeometryFactory::approximateArcAngles( stOgrArcCenter.getX(), stOgrArcCenter.getY(), stOgrArcCenter.getZ(), dfOgrArcRadius, dfOgrArcRadius, dfOgrArcRotation, dfOgrArcStartAngle,dfOgrArcEndAngle, 0.0 ); poLS->addSubLineString( poArcpoLS ); delete( poArcpoLS ); } } if( poCADLWPolyline->isClosed() ) { poLS->addPoint( poCADLWPolyline->getVertex(0).getX(), poCADLWPolyline->getVertex(0).getY(), poCADLWPolyline->getVertex(0).getZ() ); } poFeature->SetGeometryDirectly( poLS ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADLWPolyline" ); break; } // TODO: Unsupported smooth lines case CADGeometry::POLYLINE3D: { CADPolyline3D * const poCADPolyline3D = ( CADPolyline3D* ) poCADGeometry; OGRLineString * poLS = new OGRLineString(); for( size_t i = 0; i < poCADPolyline3D->getVertexCount(); ++i ) { CADVector stVertex = poCADPolyline3D->getVertex( i ); poLS->addPoint( stVertex.getX(), stVertex.getY(), stVertex.getZ() ); } poFeature->SetGeometryDirectly( poLS ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADPolyline3D" ); break; } case CADGeometry::TEXT: { CADText * const poCADText = ( CADText * ) poCADGeometry; OGRPoint * poPoint = new OGRPoint( poCADText->getPosition().getX(), poCADText->getPosition().getY(), poCADText->getPosition().getZ() ); CPLString sTextValue = CADRecode( poCADText->getTextValue(), nDWGEncoding ); poFeature->SetField( FIELD_NAME_TEXT, sTextValue ); poFeature->SetGeometryDirectly( poPoint ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADText" ); sStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",c:%s)", sTextValue.c_str(), sHexColor.c_str()); poFeature->SetStyleString( sStyle ); break; } case CADGeometry::MTEXT: { CADMText * const poCADMText = ( CADMText * ) poCADGeometry; OGRPoint * poPoint = new OGRPoint( poCADMText->getPosition().getX(), poCADMText->getPosition().getY(), poCADMText->getPosition().getZ() ); CPLString sTextValue = CADRecode( poCADMText->getTextValue(), nDWGEncoding ); poFeature->SetField( FIELD_NAME_TEXT, sTextValue ); poFeature->SetGeometryDirectly( poPoint ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADMText" ); sStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",c:%s)", sTextValue.c_str(), sHexColor.c_str()); poFeature->SetStyleString( sStyle ); break; } case CADGeometry::SPLINE: { CADSpline * const poCADSpline = ( CADSpline * ) poCADGeometry; OGRLineString * poLS = new OGRLineString(); // TODO: Interpolate spline as points or curves for( size_t i = 0; i < poCADSpline->getControlPoints().size(); ++i ) { poLS->addPoint( poCADSpline->getControlPoints()[i].getX(), poCADSpline->getControlPoints()[i].getY(), poCADSpline->getControlPoints()[i].getZ() ); } poFeature->SetGeometryDirectly( poLS ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADSpline" ); break; } case CADGeometry::ELLIPSE: { CADEllipse * poCADEllipse = static_cast<CADEllipse*>(poCADGeometry); // FIXME: Start/end angles should be swapped to work exactly as DXF driver. // is it correct? double dfStartAngle = -1 * poCADEllipse->getEndingAngle() * DEG2RAD; double dfEndAngle = -1 * poCADEllipse->getStartingAngle() * DEG2RAD; double dfAxisRatio = poCADEllipse->getAxisRatio(); dfStartAngle = fmod(dfStartAngle, 360.0); dfEndAngle = fmod(dfEndAngle, 360.0); if( dfStartAngle > dfEndAngle ) dfEndAngle += 360.0; CADVector vectPosition = poCADEllipse->getPosition(); CADVector vectSMAxis = poCADEllipse->getSMAxis(); double dfPrimaryRadius, dfSecondaryRadius; double dfRotation; dfPrimaryRadius = sqrt( vectSMAxis.getX() * vectSMAxis.getX() + vectSMAxis.getY() * vectSMAxis.getY() + vectSMAxis.getZ() * vectSMAxis.getZ() ); dfSecondaryRadius = dfAxisRatio * dfPrimaryRadius; dfRotation = -1 * atan2( vectSMAxis.getY(), vectSMAxis.getX() ) * DEG2RAD; OGRGeometry *poEllipse = OGRGeometryFactory::approximateArcAngles( vectPosition.getX(), vectPosition.getY(), vectPosition.getZ(), dfPrimaryRadius, dfSecondaryRadius, dfRotation, dfStartAngle, dfEndAngle, 0.0 ); poFeature->SetGeometryDirectly( poEllipse ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADEllipse" ); break; } case CADGeometry::ATTDEF: { CADAttdef * const poCADAttdef = ( CADAttdef* ) poCADGeometry; OGRPoint * poPoint = new OGRPoint( poCADAttdef->getPosition().getX(), poCADAttdef->getPosition().getY(), poCADAttdef->getPosition().getZ() ); CPLString sTextValue = CADRecode( poCADAttdef->getTag(), nDWGEncoding ); poFeature->SetField( FIELD_NAME_TEXT, sTextValue ); poFeature->SetGeometryDirectly( poPoint ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADAttdef" ); sStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",c:%s)", sTextValue.c_str(), sHexColor.c_str()); poFeature->SetStyleString( sStyle ); break; } default: { CPLError( CE_Warning, CPLE_NotSupported, "Unhandled feature. Skipping it." ); poFeature->SetField( FIELD_NAME_GEOMTYPE, "CADUnknown" ); delete poCADGeometry; return poFeature; } } delete poCADGeometry; poFeature->GetGeometryRef()->assignSpatialReference( poSpatialRef ); return poFeature; }
void SavePolygons( const std::vector< std::string > InFilenames, const char *OutFilename, const cv::Mat klabels, const std::vector< cv::Mat > raster, const std::vector< u_int32_t > labelpixels, const std::vector< std::vector <double> > sumCH, const std::vector< std::vector <double> > avgCH, const std::vector< std::vector <double> > stdCH, std::vector< std::vector< LINE > >& linelists ) { CPLLocaleC oLocaleCForcer(); CPLErrorReset(); const char *pszDriverName = "ESRI Shapefile"; GDALDriver *liDriver; liDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName ); if( liDriver == NULL ) { printf( "\nERROR: %s driver not available.\n", pszDriverName ); exit( 1 ); } const size_t m_bands = raster.size(); const size_t m_labels = labelpixels.size(); GDALDataset *liDS; liDS = liDriver->Create( OutFilename, 0, 0, 0, GDT_Unknown, NULL ); if( liDS == NULL ) { printf( "\nERROR: Creation of output file failed.\n" ); exit( 1 ); } // dataset GDALDataset* piDataset; piDataset = (GDALDataset*) GDALOpen(InFilenames[0].c_str(), GA_ReadOnly); // spatialref OGRSpatialReference oSRS; oSRS.SetProjCS( piDataset->GetProjectionRef() ); OGRLayer *liLayer; liLayer = liDS->CreateLayer( "segments", &oSRS, wkbPolygon, NULL ); if( liLayer == NULL ) { printf( "\nERROR: Layer creation failed.\n" ); exit( 1 ); } // spatial transform double adfGeoTransform[6]; double oX = 0.0f; double oY = 0.0f; double mX = 1.0f; double mY = -1.0f; if( piDataset->GetGeoTransform( adfGeoTransform ) == CE_None ) { oX = adfGeoTransform[0]; oY = adfGeoTransform[3]; mX = adfGeoTransform[1]; mY = adfGeoTransform[5]; } GDALClose( (GDALDatasetH) piDataset ); OGRFieldDefn *clsIdField = new OGRFieldDefn( "CLASS", OFTInteger ); liLayer->CreateField( clsIdField ); OGRFieldDefn *pixArField = new OGRFieldDefn( "AREA", OFTInteger ); liLayer->CreateField( pixArField ); for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_AVERAGE"; OGRFieldDefn *lavrgField = new OGRFieldDefn( FieldName.c_str(), OFTReal ); liLayer->CreateField( lavrgField ); } for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_STDDEV"; OGRFieldDefn *lavrgField = new OGRFieldDefn( FieldName.c_str(), OFTReal ); liLayer->CreateField( lavrgField ); } int multiring = 0; printf ("Write File: %s (polygon)\n", OutFilename); for (size_t k = 0; k < m_labels; k++) { if (multiring == 1) { k = k - 1; multiring = 0; } if (linelists[k].size() == 0) continue; // insert field data OGRFeature *liFeature; liFeature = OGRFeature::CreateFeature( liLayer->GetLayerDefn() ); liFeature->SetField( "CLASS", (int) k ); liFeature->SetField( "AREA", (int) labelpixels.at(k) ); for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_AVERAGE"; liFeature->SetField( FieldName.c_str(), (double) avgCH[b].at(k) ); } for ( size_t b = 0; b < m_bands; b++ ) { stringstream value; value << b+1; std::string FieldName = value.str() + "_STDDEV"; liFeature->SetField( FieldName.c_str(), stdCH[b].at(k) ); } // initiate polygon start OGRLinearRing linestring; linestring.setCoordinateDimension(2); linestring.addPoint( oX + (double) linelists[k][0].sX * mX, oY + mY * (double) linelists[k][0].sY ); linestring.addPoint( oX + (double) linelists[k][0].eX * mX, oY + mY * (double) linelists[k][0].eY ); linelists[k].erase( linelists[k].begin() ); // construct polygon from lines while ( linelists[k].size() > 0 ) { if (multiring == 1) break; vector<LINE>::iterator it = linelists[k].begin(); for (; it != linelists[k].end(); ++it) { double ltX = linestring.getX(linestring.getNumPoints()-1); double ltY = linestring.getY(linestring.getNumPoints()-1); double csX = oX + (double) it->sX * mX; double csY = oY + mY * (double) it->sY; double ceX = oX + (double) it->eX * mX; double ceY = oY + mY * (double) it->eY; if ( ( csX == ltX ) && ( csY == ltY ) ) { linestring.addPoint(ceX, ceY); linelists[k].erase(it); break; } if ( ( ceX == ltX ) && ( ceY == ltY ) ) { linestring.addPoint(csX, csY); linelists[k].erase(it); break; } if (it == linelists[k].end()-1) { multiring = 1; break; } } } OGRPolygon polygon; linestring.closeRings(); // simplify poligons // remove colinear vertices OGRLinearRing linesimple; float pointPrevX = 0, pointPrevY = 0; for (int i = 0; i < linestring.getNumPoints(); i++) { OGRPoint point; linestring.getPoint(i, &point); // start if ( i == 0) { linesimple.addPoint( &point ); pointPrevX = point.getX(); pointPrevY = point.getY(); continue; } // end vertex if ( i == linestring.getNumPoints() - 1 ) { linesimple.addPoint( &point ); continue; } OGRPoint pointNext; linestring.getPoint(i+1, &pointNext); // | x1 y1 1 | // det | x2 y2 1 | = 0 => p1,p2,p3 are colinear // | x3 y3 1 | // x1*(y2-y3) + x2*(y3-y1) + x3*(y1-y2) == 0 // only if not colinear with previous and next if ( pointPrevX*(point.getY()-pointNext.getY()) + point.getX()*(pointNext.getY()-pointPrevY) + pointNext.getX()*(pointPrevY-point.getY()) != 0 ) { linesimple.addPoint( &point ); pointPrevX = point.getX(); pointPrevY = point.getY(); } } // as polygon geometry polygon.addRing( &linesimple ); liFeature->SetGeometry( &polygon ); if( liLayer->CreateFeature( liFeature ) != OGRERR_NONE ) { printf( "\nERROR: Failed to create feature in shapefile.\n" ); exit( 1 ); } OGRFeature::DestroyFeature( liFeature ); GDALTermProgress( (float)(k+1) / (float)(m_labels), NULL, NULL ); } GDALTermProgress( 1.0f, NULL, NULL ); GDALClose( liDS ); }
OGRFeature *OGRSUALayer::GetNextRawFeature() { const char* pszLine; CPLString osTYPE, osCLASS, osTITLE, osTOPS, osBASE; OGRLinearRing oLR; double dfLastLat = 0, dfLastLon = 0; int bFirst = TRUE; if (bEOF) return NULL; while( true ) { if (bFirst && bHasLastLine) { pszLine = osLastLine.c_str(); bFirst = FALSE; } else { pszLine = CPLReadLine2L(fpSUA, 1024, NULL); if (pszLine == NULL) { bEOF = TRUE; if (oLR.getNumPoints() == 0) return NULL; break; } osLastLine = pszLine; bHasLastLine = TRUE; } if (pszLine[0] == '#' || pszLine[0] == '\0') continue; if (STARTS_WITH_CI(pszLine, "TYPE=")) { if (osTYPE.size() != 0) break; osTYPE = pszLine + 5; } else if (STARTS_WITH_CI(pszLine, "CLASS=")) { if (osCLASS.size() != 0) break; osCLASS = pszLine + 6; } else if (STARTS_WITH_CI(pszLine, "TITLE=")) { if (osTITLE.size() != 0) break; osTITLE = pszLine + 6; } else if (STARTS_WITH_CI(pszLine, "TOPS=")) osTOPS = pszLine + 5; else if (STARTS_WITH_CI(pszLine, "BASE=")) osBASE = pszLine + 5; else if (STARTS_WITH_CI(pszLine, "POINT=")) { pszLine += 6; if (strlen(pszLine) != 16) continue; double dfLat, dfLon; if (!GetLatLon(pszLine, dfLat, dfLon)) continue; oLR.addPoint(dfLon, dfLat); dfLastLat = dfLat; dfLastLon = dfLon; } else if (STARTS_WITH_CI(pszLine, "CLOCKWISE") || STARTS_WITH_CI(pszLine, "ANTI-CLOCKWISE")) { if (oLR.getNumPoints() == 0) continue; int bClockWise = STARTS_WITH_CI(pszLine, "CLOCKWISE"); /*const char* pszRADIUS = strstr(pszLine, "RADIUS="); if (pszRADIUS == NULL) continue; double dfRADIUS = CPLAtof(pszRADIUS + 7) * 1852;*/ const char* pszCENTRE = strstr(pszLine, "CENTRE="); if (pszCENTRE == NULL) continue; pszCENTRE += 7; if (strlen(pszCENTRE) < 17 || pszCENTRE[16] != ' ') continue; double dfCenterLat, dfCenterLon; if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon)) continue; const char* pszTO = strstr(pszLine, "TO="); if (pszTO == NULL) continue; pszTO += 3; if (strlen(pszTO) != 16) continue; double dfToLat, dfToLon; if (!GetLatLon(pszTO, dfToLat, dfToLon)) continue; double dfStartDistance = OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon); double dfEndDistance = OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfToLat, dfToLon); double dfStartAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon); double dfEndAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfToLat, dfToLon); if (bClockWise && dfEndAngle < dfStartAngle) dfEndAngle += 360; else if (!bClockWise && dfStartAngle < dfEndAngle) dfEndAngle -= 360; int nSign = (bClockWise) ? 1 : -1; double dfAngle; for(dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign) { double dfLat, dfLon; double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle); double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct; OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } oLR.addPoint(dfToLon, dfToLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } else if (STARTS_WITH_CI(pszLine, "CIRCLE")) { const char* pszRADIUS = strstr(pszLine, "RADIUS="); if (pszRADIUS == NULL) continue; double dfRADIUS = CPLAtof(pszRADIUS + 7) * 1852; const char* pszCENTRE = strstr(pszLine, "CENTRE="); if (pszCENTRE == NULL) continue; pszCENTRE += 7; if (strlen(pszCENTRE) != 16) continue; double dfCenterLat, dfCenterLon; if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon)) continue; double dfAngle; double dfLat, dfLon; for(dfAngle = 0; dfAngle < 360; dfAngle += 1) { OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, 0, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } else if (STARTS_WITH_CI(pszLine, "INCLUDE") || STARTS_WITH_CI(pszLine, "END")) { } else { CPLDebug("SUA", "Unexpected content : %s", pszLine); } } OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, osTYPE.c_str()); poFeature->SetField(1, osCLASS.c_str()); poFeature->SetField(2, osTITLE.c_str()); poFeature->SetField(3, osTOPS.c_str()); poFeature->SetField(4, osBASE.c_str()); OGRPolygon* poPoly = new OGRPolygon(); poPoly->assignSpatialReference(poSRS); oLR.closeRings(); poPoly->addRing(&oLR); poFeature->SetGeometryDirectly(poPoly); poFeature->SetFID(nNextFID++); return poFeature; }
OGRFeature *OGRGmtLayer::GetNextRawFeature() { #if 0 int bMultiVertex = poFeatureDefn->GetGeomType() != wkbPoint && poFeatureDefn->GetGeomType() != wkbUnknown; #endif CPLString osFieldData; OGRGeometry *poGeom = NULL; /* -------------------------------------------------------------------- */ /* Read lines associated with this feature. */ /* -------------------------------------------------------------------- */ for( ; true; ReadLine() ) { if( osLine.length() == 0 ) break; if( osLine[0] == '>' ) { if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon ) { OGRMultiPolygon *poMP = (OGRMultiPolygon *) poGeom; if( ScanAheadForHole() ) { // Add a hole to the current polygon. ((OGRPolygon *) poMP->getGeometryRef( poMP->getNumGeometries()-1 ))-> addRingDirectly( new OGRLinearRing() ); } else if( !NextIsFeature() ) { OGRPolygon *poPoly = new OGRPolygon(); poPoly->addRingDirectly( new OGRLinearRing() ); poMP->addGeometryDirectly( poPoly ); } else break; /* done geometry */ } else if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbPolygon) { if( ScanAheadForHole() ) ((OGRPolygon *)poGeom)-> addRingDirectly( new OGRLinearRing() ); else break; /* done geometry */ } else if( poGeom != NULL && (wkbFlatten(poGeom->getGeometryType()) == wkbMultiLineString) && !NextIsFeature() ) { ((OGRMultiLineString *) poGeom)-> addGeometryDirectly( new OGRLineString() ); } else if( poGeom != NULL ) { break; } else if( poFeatureDefn->GetGeomType() == wkbUnknown ) { poFeatureDefn->SetGeomType( wkbLineString ); /* bMultiVertex = TRUE; */ } } else if( osLine[0] == '#' ) { for( int i = 0; papszKeyedValues != NULL && papszKeyedValues[i] != NULL; i++ ) { if( papszKeyedValues[i][0] == 'D' ) osFieldData = papszKeyedValues[i] + 1; } } else { // Parse point line. double dfX; double dfY; double dfZ = 0.0; const int nDim = CPLsscanf( osLine, "%lf %lf %lf", &dfX, &dfY, &dfZ ); if( nDim >= 2 ) { if( poGeom == NULL ) { switch( poFeatureDefn->GetGeomType() ) { case wkbLineString: poGeom = new OGRLineString(); break; case wkbPolygon: poGeom = new OGRPolygon(); reinterpret_cast<OGRPolygon *>(poGeom)->addRingDirectly( new OGRLinearRing() ); break; case wkbMultiPolygon: { OGRPolygon *poPoly = new OGRPolygon(); poPoly->addRingDirectly( new OGRLinearRing() ); poGeom = new OGRMultiPolygon(); reinterpret_cast<OGRMultiPolygon *>(poGeom)-> addGeometryDirectly( poPoly ); } break; case wkbMultiPoint: poGeom = new OGRMultiPoint(); break; case wkbMultiLineString: poGeom = new OGRMultiLineString(); reinterpret_cast<OGRMultiLineString *>(poGeom)-> addGeometryDirectly(new OGRLineString() ); break; case wkbPoint: case wkbUnknown: default: poGeom = new OGRPoint(); break; } } switch( wkbFlatten(poGeom->getGeometryType()) ) { case wkbPoint: reinterpret_cast<OGRPoint *>(poGeom)->setX( dfX ); reinterpret_cast<OGRPoint *>(poGeom)->setY( dfY ); if( nDim == 3 ) reinterpret_cast<OGRPoint *>(poGeom)->setZ( dfZ ); break; case wkbLineString: if( nDim == 3 ) reinterpret_cast<OGRLineString *>(poGeom)-> addPoint( dfX, dfY, dfZ); else reinterpret_cast<OGRLineString *>(poGeom)-> addPoint( dfX, dfY ); break; case wkbPolygon: case wkbMultiPolygon: { OGRPolygon *poPoly = NULL; if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon ) { OGRMultiPolygon *poMP = (OGRMultiPolygon *) poGeom; poPoly = (OGRPolygon*) poMP->getGeometryRef( poMP->getNumGeometries() - 1 ); } else poPoly = reinterpret_cast<OGRPolygon *>(poGeom); OGRLinearRing *poRing = NULL; if( poPoly->getNumInteriorRings() == 0 ) poRing = poPoly->getExteriorRing(); else poRing = poPoly->getInteriorRing( poPoly->getNumInteriorRings()-1 ); if( nDim == 3 ) poRing->addPoint( dfX, dfY, dfZ ); else poRing->addPoint( dfX, dfY ); } break; case wkbMultiLineString: { OGRMultiLineString *poML = (OGRMultiLineString *) poGeom; OGRLineString *poLine = reinterpret_cast<OGRLineString *>( poML->getGeometryRef( poML->getNumGeometries() -1 ) ); if( nDim == 3 ) poLine->addPoint( dfX, dfY, dfZ ); else poLine->addPoint( dfX, dfY ); } break; default: CPLAssert( FALSE ); } } } if( poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint ) { ReadLine(); break; } } if( poGeom == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Create feature. */ /* -------------------------------------------------------------------- */ OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); poGeom->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly( poGeom ); poFeature->SetFID( iNextFID++ ); /* -------------------------------------------------------------------- */ /* Process field values. */ /* -------------------------------------------------------------------- */ char **papszFD = CSLTokenizeStringComplex( osFieldData, "|", TRUE, TRUE ); for( int iField = 0; papszFD != NULL && papszFD[iField] != NULL; iField++ ) { if( iField >= poFeatureDefn->GetFieldCount() ) break; poFeature->SetField( iField, papszFD[iField] ); } CSLDestroy( papszFD ); m_nFeaturesRead++; return poFeature; }