OGRFeature *OGRDWGLayer::TranslateDIMENSION( OdDbEntityPtr poEntity ) { OdDbDimensionPtr poDim = OdDbDimension::cast( poEntity ); OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); double dfHeight = CPLAtof(poDS->GetVariable("$DIMTXT", "2.5")); OdGePoint3d oTextPos, oTarget1, oTarget2, oArrow1; CPLString osText; TranslateGenericProperties( poFeature, poEntity ); /* -------------------------------------------------------------------- */ /* Generic Dimension stuff. */ /* -------------------------------------------------------------------- */ osText = (const char *) poDim->dimensionText(); oTextPos = poDim->textPosition(); /* -------------------------------------------------------------------- */ /* Specific based on the subtype. */ /* -------------------------------------------------------------------- */ OdRxClass *poClass = poEntity->isA(); const OdString osName = poClass->name(); const char *pszEntityClassName = (const char *) osName; if( EQUAL(pszEntityClassName,"AcDbRotatedDimension") ) { OdDbRotatedDimensionPtr poRDim = OdDbDimension::cast( poEntity ); oTarget2 = poRDim->xLine1Point(); oTarget1 = poRDim->xLine2Point(); oArrow1 = poRDim->dimLinePoint(); } else if( EQUAL(pszEntityClassName,"AcDbAlignedDimension") ) { OdDbAlignedDimensionPtr poADim = OdDbDimension::cast( poEntity ); oTarget2 = poADim->xLine1Point(); oTarget1 = poADim->xLine2Point(); oArrow1 = poADim->dimLinePoint(); } /************************************************************************* DIMENSION geometry layout (11,21)(text center point) | DimText | (10,20) X<--------------------------------->X (Arrow2 - computed) (Arrow1)| | | | | X (13,23) (Target2) | X (14,24) (Target1) Given: Locations Arrow1, Target1, and Target2 we need to compute Arrow2. Steps: 1) Compute direction vector from Target1 to Arrow1 (Vec1). 2) Compute direction vector for arrow as perpendicular to Vec1 (call Vec2). 3) Compute Arrow2 location as intersection between line defined by Vec2 and Arrow1 and line defined by Target2 and direction Vec1 (call Arrow2) Then we can draw lines for the various components. Note that Vec1 and Vec2 may be horizontal, vertical or on an angle but the approach is as above in all these cases. *************************************************************************/ /* -------------------------------------------------------------------- */ /* Step 1, compute direction vector between Target1 and Arrow1. */ /* -------------------------------------------------------------------- */ double dfVec1X, dfVec1Y; dfVec1X = (oArrow1.x - oTarget1.x); dfVec1Y = (oArrow1.y - oTarget1.y); /* -------------------------------------------------------------------- */ /* Step 2, compute the direction vector from Arrow1 to Arrow2 */ /* as a perpendicular to Vec1. */ /* -------------------------------------------------------------------- */ double dfVec2X, dfVec2Y; dfVec2X = dfVec1Y; dfVec2Y = -dfVec1X; /* -------------------------------------------------------------------- */ /* Step 3, compute intersection of line from target2 along */ /* direction vector 1, with the line through Arrow1 and */ /* direction vector 2. */ /* -------------------------------------------------------------------- */ double dfL1M, dfL1B, dfL2M, dfL2B; double dfArrowX2, dfArrowY2; // special case if vec1 is vertical. if( dfVec1X == 0.0 ) { dfArrowX2 = oTarget2.x; dfArrowY2 = oArrow1.y; } // special case if vec2 is horizontal. else if( dfVec1Y == 0.0 ) { dfArrowX2 = oArrow1.x; dfArrowY2 = oTarget2.y; } else // General case for diagonal vectors. { // first convert vec1 + target2 into y = mx + b format: call this L1 dfL1M = dfVec1Y / dfVec1X; dfL1B = oTarget2.y - dfL1M * oTarget2.x; // convert vec2 + Arrow1 into y = mx + b format, call this L2 dfL2M = dfVec2Y / dfVec2X; dfL2B = oArrow1.y - dfL2M * oArrow1.x; // Compute intersection x = (b2-b1) / (m1-m2) dfArrowX2 = (dfL2B - dfL1B) / (dfL1M-dfL2M); dfArrowY2 = dfL2M * dfArrowX2 + dfL2B; } /* -------------------------------------------------------------------- */ /* Compute the text angle. */ /* -------------------------------------------------------------------- */ double dfAngle = atan2(dfVec2Y,dfVec2X) * 180.0 / M_PI; /* -------------------------------------------------------------------- */ /* Rescale the direction vectors so we can use them in */ /* constructing arrowheads. We want them to be about 3% of the */ /* length of line on which the arrows will be drawn. */ /* -------------------------------------------------------------------- */ #define VECTOR_LEN(x,y) sqrt( (x)*(x) + (y)*(y) ) #define POINT_DIST(x1,y1,x2,y2) VECTOR_LEN((x2-x1),(y2-y1)) double dfBaselineLength = POINT_DIST(oArrow1.x,oArrow1.y, dfArrowX2,dfArrowY2); double dfTargetLength = dfBaselineLength * 0.03; double dfScaleFactor; // recompute vector 2 to ensure the direction is regular dfVec2X = (dfArrowX2 - oArrow1.x); dfVec2Y = (dfArrowY2 - oArrow1.y); // vector 1 dfScaleFactor = dfTargetLength / VECTOR_LEN(dfVec1X,dfVec1Y); dfVec1X *= dfScaleFactor; dfVec1Y *= dfScaleFactor; // vector 2 dfScaleFactor = dfTargetLength / VECTOR_LEN(dfVec2X,dfVec2Y); dfVec2X *= dfScaleFactor; dfVec2Y *= dfScaleFactor; /* -------------------------------------------------------------------- */ /* Create geometries for the different components of the */ /* dimension object. */ /* -------------------------------------------------------------------- */ OGRMultiLineString *poMLS = new OGRMultiLineString(); OGRLineString oLine; // main arrow line between Arrow1 and Arrow2 oLine.setPoint( 0, oArrow1.x, oArrow1.y ); oLine.setPoint( 1, dfArrowX2, dfArrowY2 ); poMLS->addGeometry( &oLine ); // dimension line from Target1 to Arrow1 with a small extension. oLine.setPoint( 0, oTarget1.x, oTarget1.y ); oLine.setPoint( 1, oArrow1.x + dfVec1X, oArrow1.y + dfVec1Y ); poMLS->addGeometry( &oLine ); // dimension line from Target2 to Arrow2 with a small extension. oLine.setPoint( 0, oTarget2.x, oTarget2.y ); oLine.setPoint( 1, dfArrowX2 + dfVec1X, dfArrowY2 + dfVec1Y ); poMLS->addGeometry( &oLine ); // add arrow1 arrow head. oLine.setPoint( 0, oArrow1.x, oArrow1.y ); oLine.setPoint( 1, oArrow1.x + dfVec2X*3 + dfVec1X, oArrow1.y + dfVec2Y*3 + dfVec1Y ); poMLS->addGeometry( &oLine ); oLine.setPoint( 0, oArrow1.x, oArrow1.y ); oLine.setPoint( 1, oArrow1.x + dfVec2X*3 - dfVec1X, oArrow1.y + dfVec2Y*3 - dfVec1Y ); poMLS->addGeometry( &oLine ); // add arrow2 arrow head. oLine.setPoint( 0, dfArrowX2, dfArrowY2 ); oLine.setPoint( 1, dfArrowX2 - dfVec2X*3 + dfVec1X, dfArrowY2 - dfVec2Y*3 + dfVec1Y ); poMLS->addGeometry( &oLine ); oLine.setPoint( 0, dfArrowX2, dfArrowY2 ); oLine.setPoint( 1, dfArrowX2 - dfVec2X*3 - dfVec1X, dfArrowY2 - dfVec2Y*3 - dfVec1Y ); poMLS->addGeometry( &oLine ); poFeature->SetGeometryDirectly( poMLS ); PrepareLineStyle( poFeature ); /* -------------------------------------------------------------------- */ /* Is the layer disabled/hidden/frozen/off? */ /* -------------------------------------------------------------------- */ CPLString osLayer = poFeature->GetFieldAsString("Layer"); int bHidden = EQUAL(poDS->LookupLayerProperty( osLayer, "Hidden" ), "1"); /* -------------------------------------------------------------------- */ /* Work out the color for this feature. */ /* -------------------------------------------------------------------- */ int nColor = 256; if( oStyleProperties.count("Color") > 0 ) nColor = atoi(oStyleProperties["Color"]); // Use layer color? if( nColor < 1 || nColor > 255 ) { const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" ); if( pszValue != NULL ) nColor = atoi(pszValue); } if( nColor < 1 || nColor > 255 ) nColor = 8; /* -------------------------------------------------------------------- */ /* Prepare a new feature to serve as the dimension text label */ /* feature. We will push it onto the layer as a pending */ /* feature for the next feature read. */ /* -------------------------------------------------------------------- */ // a single space suppresses labeling. if( osText == " " ) return poFeature; OGRFeature *poLabelFeature = poFeature->Clone(); poLabelFeature->SetGeometryDirectly( new OGRPoint( oTextPos.x, oTextPos.y ) ); // Do we need to compute the dimension value? if( osText.empty() ) { FormatDimension( osText, POINT_DIST( oArrow1.x, oArrow1.y, dfArrowX2, dfArrowY2 ) ); } CPLString osStyle; char szBuffer[64]; char* pszComma = NULL; osStyle.Printf("LABEL(f:\"Arial\",t:\"%s\",p:5",osText.c_str()); if( dfAngle != 0.0 ) { CPLsnprintf(szBuffer, sizeof(szBuffer), "%.3g", dfAngle); pszComma = strchr(szBuffer, ','); if (pszComma) *pszComma = '.'; osStyle += CPLString().Printf(",a:%s", szBuffer); } if( dfHeight != 0.0 ) { CPLsnprintf(szBuffer, sizeof(szBuffer), "%.3g", dfHeight); pszComma = strchr(szBuffer, ','); if (pszComma) *pszComma = '.'; osStyle += CPLString().Printf(",s:%sg", szBuffer); } const unsigned char *pabyDWGColors = ACGetColorTable(); snprintf( szBuffer, sizeof(szBuffer), ",c:#%02x%02x%02x", pabyDWGColors[nColor*3+0], pabyDWGColors[nColor*3+1], pabyDWGColors[nColor*3+2] ); osStyle += szBuffer; if( bHidden ) osStyle += "00"; osStyle += ")"; poLabelFeature->SetStyleString( osStyle ); apoPendingFeatures.push( poLabelFeature ); return poFeature; }
OGRMultiLineString* make() { OGRMultiLineString* poCollection = new OGRMultiLineString(); poCollection->addGeometryDirectly(make<OGRLineString>()); poCollection->addGeometryDirectly(make<OGRLinearRing>()); return poCollection; }
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; }
OGRGeometry *OGRMultiLineString::clone() const { OGRMultiLineString *poNewGC; poNewGC = new OGRMultiLineString; poNewGC->assignSpatialReference( getSpatialReference() ); for( int i = 0; i < getNumGeometries(); i++ ) { poNewGC->addGeometry( getGeometryRef(i) ); } return poNewGC; }
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; }
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; }
bool ShpReader::Open(std::wstring fullPath, StudyControllerPtr studyController, VectorMapControllerPtr vectorMapController, ProgressDlgPtr progressDlg) { // Registers all format drivers built into GDAL/OGR. OGRRegisterAll(); OGRDataSource *OGRDataset; // Open vector file path std::string tempStr( fullPath.begin(), fullPath.end() ); OGRDataset = OGRSFDriverRegistrar::Open( tempStr.c_str(), FALSE ); // Return if no vector files are found if( OGRDataset == NULL ) { Log::Inst().Warning("(Warning) Failed to open file at " + tempStr + "."); return false; } if ( App::Inst().GetLayerTreeController()->GetNumMapLayers() >0 ) MapControllerPtr mapController= App::Inst().GetLayerTreeController()->GetLayerTreeModel()->GetStudy(0)->GetMapLayer(0)->GetMapController(); // It appears that shapefiles (*.SHP) only support up to one layer per file // This will need to be further investigated for other vector filetypes (e.g., KML) // For now just grab layer at position 0 OGRLayer *poLayer = OGRDataset->GetLayer( 0 ); // Determine the XY boundaries for the entire vector dataset OGREnvelope psEnvelope; VectorMapModelPtr vectorMapModel = vectorMapController->GetVectorMapModel(); poLayer->GetExtent( &psEnvelope ); vectorMapModel->SetVectorBoundary(psEnvelope); if(!SetupVectorProjection(OGRDataset,studyController,poLayer,vectorMapController )) { OGRDataset->DestroyDataSource(OGRDataset); return false; } if(progressDlg) { if(!progressDlg->Update(0, _T("Reading Vector Map Information..."))) { OGRDataset->DestroyDataSource(OGRDataset); return false; } } GLdouble minX, minY, maxX, maxY; minX = minY = std::numeric_limits<float>::max(); maxX = maxY = -std::numeric_limits<float>::max(); // Retrieve features from the dataset OGRFeature *poFeature; poLayer->ResetReading(); int numFeatures = poLayer->GetFeatureCount(); int count=0; //Log::Inst().Write("Loading shapefile with the following meta data:"); while ( ( poFeature = poLayer->GetNextFeature() ) != NULL ) { ///////////////////////////////////////////////// // PHASE 1: Retrieve METADATA from the dataset // ///////////////////////////////////////////////// OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn(); int iField; for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn( iField ); //if( poFieldDefn->GetType() == OFTInteger ) // printf( "%d,", poFeature->GetFieldAsInteger( iField ) ); //else if( poFieldDefn->GetType() == OFTReal ) // printf( "%.3f,", poFeature->GetFieldAsDouble(iField) ); //else if( poFieldDefn->GetType() == OFTString ) // printf( "%s,", poFeature->GetFieldAsString(iField) ); //else // printf( "%s,", poFeature->GetFieldAsString(iField) ); //ofs << poFeature->GetFieldAsString(iField) << ","; std::string metaData = poFeature->GetFieldAsString(iField); // do something with the meta data... //Log::Inst().Write(metaData); } count++; if(progressDlg) { if(!progressDlg->Update(int(50 + (float(count)/numFeatures)*50))) return false; } /////////////////////////////////////////////////// // PHASE 2: Retrieve GEOMETRIES from the dataset // /////////////////////////////////////////////////// OGRGeometry *poGeometry; poGeometry = poFeature->GetGeometryRef(); // Move to the next feature in the set if no geometry present if( poGeometry == NULL ) { OGRFeature::DestroyFeature( poFeature ); continue; } OGRwkbGeometryType whatisit = poGeometry->getGeometryType(); // Handle POINTS if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbPoint ) { GeoVector* geoVector = new GeoVector(); OGRPoint *poPoint = (OGRPoint *) poGeometry; geoVector->SetGeometryType( wkbPoint ); geoVector->SetNumberOfPoints( 1 ); if(needProjection) { double x,y; x= poPoint->getX(); y= poPoint->getY(); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[0] = x; geoVector->pointY[0] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[0] = poPoint->getX(); geoVector->pointY[0] = poPoint->getY(); } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } //Handle MultiPoint else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiPoint ) { OGRMultiPoint *poMultiPoint = (OGRMultiPoint *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiPoint->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); OGRPoint *poPoint = ( OGRPoint* )poMultiPoint->getGeometryRef( currGeometry ); geoVector->SetGeometryType( wkbPoint ); geoVector->SetNumberOfPoints( 1 ); if(needProjection) { double x,y; x= poPoint->getX(); y= poPoint->getY(); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[0] = x; geoVector->pointY[0] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[0] = poPoint->getX(); geoVector->pointY[0] = poPoint->getY(); } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } } //Handle Polylines else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbLineString ) { GeoVector* geoVector = new GeoVector(); OGRLineString *poLine = (OGRLineString *) poGeometry; geoVector->SetGeometryType( wkbLineString ); geoVector->SetNumberOfPoints( poLine->getNumPoints() ); // Convert and store the points for ( int currentPoint = 0; currentPoint < poLine->getNumPoints(); currentPoint++ ) { // Convert and store the points if(needProjection) { double x,y; x= poLine->getX( currentPoint ); y= poLine->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLine->getX( currentPoint ); geoVector->pointY[currentPoint] = poLine->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } // Handle MultiPolyLine else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiLineString ) { OGRMultiLineString *poMultiLine = (OGRMultiLineString *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiLine->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); OGRLineString *poLine = ( OGRLineString* )poMultiLine->getGeometryRef( currGeometry ); geoVector->SetGeometryType( wkbLineString ); geoVector->SetNumberOfPoints( poLine->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLine ->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLine->getX( currentPoint ); y= poLine->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLine->getX( currentPoint ); geoVector->pointY[currentPoint] = poLine->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } } // Handle POLYGONS else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbPolygon ) { GeoVector* geoVector = new GeoVector(); OGRPolygon *poPolygon = ( OGRPolygon* )poGeometry; OGRLinearRing *poLinearRing = poPolygon->getExteriorRing(); geoVector->SetGeometryType( wkbLinearRing ); geoVector->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); } // Handle MULTIPOLYGONS else if ( wkbFlatten( poGeometry->getGeometryType() ) == wkbMultiPolygon ) { OGRMultiPolygon *poMultiPolygon = (OGRMultiPolygon *) poGeometry; for ( int currGeometry = 0; currGeometry < poMultiPolygon->getNumGeometries(); currGeometry++ ) { GeoVector* geoVector = new GeoVector(); // OGRPolygon http://www.gdal.org/ogr/classOGRPolygon.html OGRPolygon *poPolygon = ( OGRPolygon* )poMultiPolygon->getGeometryRef( currGeometry ); // Retrieve the EXTERNAL ring of the multipolygon OGRLinearRing *poLinearRing = poPolygon->getExteriorRing(); geoVector->SetGeometryType( wkbLinearRing ); geoVector->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector->pointX[currentPoint] = x; geoVector->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector ); // Retrieve all the INTERNAL rings of the multipolygon for ( int currentRing = 0; currentRing < poPolygon->getNumInteriorRings(); currentRing++ ) { GeoVector* geoVector2 = new GeoVector(); poLinearRing = poPolygon->getInteriorRing( currentRing ); geoVector2->SetGeometryType( wkbLinearRing ); geoVector2->SetNumberOfPoints( poLinearRing->getNumPoints() ); for ( int currentPoint = 0; currentPoint < poLinearRing->getNumPoints(); currentPoint++ ) { if(needProjection) { double x,y; x= poLinearRing->getX( currentPoint ); y= poLinearRing->getY( currentPoint ); if(!poTransform->Transform(1, &x, &y)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } // project and store the points geoVector2->pointX[currentPoint] = x; geoVector2->pointY[currentPoint] = y; if(x < minX) minX=x; if(y < minY) minY=y; if(x > maxX) maxX=x; if(y > maxY) maxY=y; } else { geoVector2->pointX[currentPoint] = poLinearRing->getX( currentPoint ); geoVector2->pointY[currentPoint] = poLinearRing->getY( currentPoint ); } } vectorMapController->GetVectorMapModel()->AddGeoVector( geoVector2 ); } } } // Report a warning message for unhandled geometries else { Log::Inst().Warning("(Warning) Could not load vector data: unsupported geometry."); } OGRFeature::DestroyFeature( poFeature ); } if (float(minX) == float(maxX) && float(minY) == float(maxY)) { Log::Inst().Warning("(Warning) Failed to project vector map."); OGRDataset->DestroyDataSource(OGRDataset); return false; } if(needProjection) { vectorMapModel->SetVectorBoundary_MinX(minX); vectorMapModel->SetVectorBoundary_MaxX(maxX); vectorMapModel->SetVectorBoundary_MinY(minY); vectorMapModel->SetVectorBoundary_MaxY(maxY); } if(!SetupVectorScaling(vectorMapModel,progressDlg)) { OGRDataset->DestroyDataSource(OGRDataset); return false; } VectorMetaDataInfo(OGRDataset, studyController, vectorMapController); OGRDataSource::DestroyDataSource( OGRDataset ); return true; }
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); } }
//--------------------------------------------------------- bool COGR_DataSource::_Write_Geometry(CSG_Shape *pShape, OGRFeature *pFeature) { if( pShape && pFeature ) { int iPoint, iPart; TSG_Point sgPoint; OGRPoint Point; OGRMultiPoint Points; OGRLineString Line; OGRMultiLineString Lines; OGRLinearRing Ring; OGRPolygon Polygon; switch( pShape->Get_Type() ) { //------------------------------------------------- case SHAPE_TYPE_Point: sgPoint = pShape->Get_Point(0); Point.setX(sgPoint.x); Point.setY(sgPoint.y); return( pFeature->SetGeometry(&Point) == OGRERR_NONE ); //------------------------------------------------- case SHAPE_TYPE_Points: for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { for(iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++) { sgPoint = pShape->Get_Point(iPoint, iPart); Point.setX(sgPoint.x); Point.setY(sgPoint.y); Points.addGeometry(&Point); } } return( pFeature->SetGeometry(&Points) == OGRERR_NONE ); //------------------------------------------------- case SHAPE_TYPE_Line: if( pShape->Get_Part_Count() == 1 ) { _Write_Line(pShape, &Line, 0); return( pFeature->SetGeometry(&Line) == OGRERR_NONE ); } else { for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { if( _Write_Line(pShape, &Line, iPart) ) { Lines.addGeometry(&Line); } } return( pFeature->SetGeometry(&Lines) == OGRERR_NONE ); } //------------------------------------------------- case SHAPE_TYPE_Polygon: for(iPart=0; iPart<pShape->Get_Part_Count(); iPart++) { if( _Write_Line(pShape, &Ring, iPart) ) { Polygon.addRing(&Ring); } } return( pFeature->SetGeometry(&Polygon) == OGRERR_NONE ); //------------------------------------------------- default: break; } } return( false ); }
void PCLoaderArcView::load(const std::string& file, OptionsCont& oc, PCPolyContainer& toFill, PCTypeMap&) { #ifdef HAVE_GDAL GeoConvHelper& geoConvHelper = GeoConvHelper::getProcessing(); // get defaults std::string prefix = oc.getString("prefix"); std::string type = oc.getString("type"); RGBColor color = RGBColor::parseColor(oc.getString("color")); int layer = oc.getInt("layer"); std::string idField = oc.getString("shapefile.id-column"); bool useRunningID = oc.getBool("shapefile.use-running-id"); // start parsing std::string shpName = file + ".shp"; OGRRegisterAll(); OGRDataSource* poDS = OGRSFDriverRegistrar::Open(shpName.c_str(), FALSE); if (poDS == NULL) { throw ProcessError("Could not open shape description '" + shpName + "'."); } // begin file parsing OGRLayer* poLayer = poDS->GetLayer(0); poLayer->ResetReading(); // build coordinate transformation OGRSpatialReference* origTransf = poLayer->GetSpatialRef(); OGRSpatialReference destTransf; // use wgs84 as destination destTransf.SetWellKnownGeogCS("WGS84"); OGRCoordinateTransformation* poCT = OGRCreateCoordinateTransformation(origTransf, &destTransf); if (poCT == NULL) { if (oc.isSet("shapefile.guess-projection")) { OGRSpatialReference origTransf2; origTransf2.SetWellKnownGeogCS("WGS84"); poCT = OGRCreateCoordinateTransformation(&origTransf2, &destTransf); } if (poCT == 0) { WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed."); } } OGRFeature* poFeature; poLayer->ResetReading(); unsigned int runningID = 0; while ((poFeature = poLayer->GetNextFeature()) != NULL) { // read in edge attributes std::string id = useRunningID ? toString(runningID) : poFeature->GetFieldAsString(idField.c_str()); ++runningID; id = StringUtils::prune(id); if (id == "") { throw ProcessError("Missing id under '" + idField + "'"); } id = prefix + id; // read in the geometry OGRGeometry* poGeometry = poFeature->GetGeometryRef(); if (poGeometry == 0) { OGRFeature::DestroyFeature(poFeature); continue; } // try transform to wgs84 poGeometry->transform(poCT); OGRwkbGeometryType gtype = poGeometry->getGeometryType(); switch (gtype) { case wkbPoint: { OGRPoint* cgeom = (OGRPoint*) poGeometry; Position pos((SUMOReal) cgeom->getX(), (SUMOReal) cgeom->getY()); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for POI '" + id + "'."); } PointOfInterest* poi = new PointOfInterest(id, type, color, pos, (SUMOReal)layer); if (!toFill.insert(id, poi, layer)) { WRITE_ERROR("POI '" + id + "' could not be added."); delete poi; } } break; case wkbLineString: { OGRLineString* cgeom = (OGRLineString*) poGeometry; PositionVector shape; for (int j = 0; j < cgeom->getNumPoints(); j++) { Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(id, type, color, shape, false, (SUMOReal)layer); if (!toFill.insert(id, poly, layer)) { WRITE_ERROR("Polygon '" + id + "' could not be added."); delete poly; } } break; case wkbPolygon: { OGRLinearRing* cgeom = ((OGRPolygon*) poGeometry)->getExteriorRing(); PositionVector shape; for (int j = 0; j < cgeom->getNumPoints(); j++) { Position pos((SUMOReal) cgeom->getX(j), (SUMOReal) cgeom->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + id + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(id, type, color, shape, true, (SUMOReal)layer); if (!toFill.insert(id, poly, layer)) { WRITE_ERROR("Polygon '" + id + "' could not be added."); delete poly; } } break; case wkbMultiPoint: { OGRMultiPoint* cgeom = (OGRMultiPoint*) poGeometry; for (int i = 0; i < cgeom->getNumGeometries(); ++i) { OGRPoint* cgeom2 = (OGRPoint*) cgeom->getGeometryRef(i); Position pos((SUMOReal) cgeom2->getX(), (SUMOReal) cgeom2->getY()); std::string tid = id + "#" + toString(i); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for POI '" + tid + "'."); } PointOfInterest* poi = new PointOfInterest(tid, type, color, pos, (SUMOReal)layer); if (!toFill.insert(tid, poi, layer)) { WRITE_ERROR("POI '" + tid + "' could not be added."); delete poi; } } } break; case wkbMultiLineString: { OGRMultiLineString* cgeom = (OGRMultiLineString*) poGeometry; for (int i = 0; i < cgeom->getNumGeometries(); ++i) { OGRLineString* cgeom2 = (OGRLineString*) cgeom->getGeometryRef(i); PositionVector shape; std::string tid = id + "#" + toString(i); for (int j = 0; j < cgeom2->getNumPoints(); j++) { Position pos((SUMOReal) cgeom2->getX(j), (SUMOReal) cgeom2->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(tid, type, color, shape, false, (SUMOReal)layer); if (!toFill.insert(tid, poly, layer)) { WRITE_ERROR("Polygon '" + tid + "' could not be added."); delete poly; } } } break; case wkbMultiPolygon: { OGRMultiPolygon* cgeom = (OGRMultiPolygon*) poGeometry; for (int i = 0; i < cgeom->getNumGeometries(); ++i) { OGRLinearRing* cgeom2 = ((OGRPolygon*) cgeom->getGeometryRef(i))->getExteriorRing(); PositionVector shape; std::string tid = id + "#" + toString(i); for (int j = 0; j < cgeom2->getNumPoints(); j++) { Position pos((SUMOReal) cgeom2->getX(j), (SUMOReal) cgeom2->getY(j)); if (!geoConvHelper.x2cartesian(pos)) { WRITE_ERROR("Unable to project coordinates for polygon '" + tid + "'."); } shape.push_back_noDoublePos(pos); } Polygon* poly = new Polygon(tid, type, color, shape, true, (SUMOReal)layer); if (!toFill.insert(tid, poly, layer)) { WRITE_ERROR("Polygon '" + tid + "' could not be added."); delete poly; } } } break; default: WRITE_WARNING("Unsupported shape type occured (id='" + id + "')."); break; } OGRFeature::DestroyFeature(poFeature); } PROGRESS_DONE_MESSAGE(); #else WRITE_ERROR("SUMO was compiled without GDAL support."); #endif }
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; }
OGRFeature *OGRDXFLayer::TranslateHATCH() { char szLineBuf[257]; int nCode; OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); CPLString osHatchPattern; int nFillFlag = 0; OGRGeometryCollection oGC; while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 ) { switch( nCode ) { case 70: nFillFlag = atoi(szLineBuf); break; case 2: osHatchPattern = szLineBuf; poFeature->SetField( "Text", osHatchPattern.c_str() ); break; case 91: { int nBoundaryPathCount = atoi(szLineBuf); int iBoundary; for( iBoundary = 0; iBoundary < nBoundaryPathCount; iBoundary++ ) { if (CollectBoundaryPath( &oGC ) != OGRERR_NONE) break; } } break; default: TranslateGenericProperty( poFeature, nCode, szLineBuf ); break; } } if( nCode == 0 ) poDS->UnreadValue(); /* -------------------------------------------------------------------- */ /* Try to turn the set of lines into something useful. */ /* -------------------------------------------------------------------- */ OGRErr eErr; OGRGeometry* poFinalGeom = (OGRGeometry *) OGRBuildPolygonFromEdges( (OGRGeometryH) &oGC, TRUE, TRUE, 0.0000001, &eErr ); if( eErr != OGRERR_NONE ) { delete poFinalGeom; OGRMultiLineString* poMLS = new OGRMultiLineString(); for(int i=0;i<oGC.getNumGeometries();i++) poMLS->addGeometry(oGC.getGeometryRef(i)); poFinalGeom = poMLS; } ApplyOCSTransformer( poFinalGeom ); poFeature->SetGeometryDirectly( poFinalGeom ); /* -------------------------------------------------------------------- */ /* Work out the color for this feature. For now we just assume */ /* solid fill. We cannot trivially translate the various sorts */ /* of hatching. */ /* -------------------------------------------------------------------- */ CPLString osLayer = poFeature->GetFieldAsString("Layer"); int nColor = 256; if( oStyleProperties.count("Color") > 0 ) nColor = atoi(oStyleProperties["Color"]); // Use layer color? if( nColor < 1 || nColor > 255 ) { const char *pszValue = poDS->LookupLayerProperty( osLayer, "Color" ); if( pszValue != NULL ) nColor = atoi(pszValue); } /* -------------------------------------------------------------------- */ /* Setup the style string. */ /* -------------------------------------------------------------------- */ if( nColor >= 1 && nColor <= 255 ) { CPLString osStyle; const unsigned char *pabyDXFColors = ACGetColorTable(); osStyle.Printf( "BRUSH(fc:#%02x%02x%02x)", pabyDXFColors[nColor*3+0], pabyDXFColors[nColor*3+1], pabyDXFColors[nColor*3+2] ); poFeature->SetStyleString( osStyle ); } return poFeature; }
OGRDXFFeature *OGRDXFLayer::TranslateHATCH() { char szLineBuf[257]; int nCode = 0; OGRDXFFeature *poFeature = new OGRDXFFeature( poFeatureDefn ); CPLString osHatchPattern; double dfElevation = 0.0; // Z value to be used for EVERY point /* int nFillFlag = 0; */ OGRGeometryCollection oGC; while( (nCode = poDS->ReadValue(szLineBuf,sizeof(szLineBuf))) > 0 ) { switch( nCode ) { case 30: // Constant elevation. dfElevation = CPLAtof( szLineBuf ); break; case 70: /* nFillFlag = atoi(szLineBuf); */ break; case 2: osHatchPattern = szLineBuf; poFeature->SetField( "Text", osHatchPattern.c_str() ); break; case 91: { int nBoundaryPathCount = atoi(szLineBuf); for( int iBoundary = 0; iBoundary < nBoundaryPathCount; iBoundary++ ) { if (CollectBoundaryPath( &oGC, dfElevation ) != OGRERR_NONE) break; } } break; default: TranslateGenericProperty( poFeature, nCode, szLineBuf ); break; } } if( nCode < 0 ) { DXF_LAYER_READER_ERROR(); delete poFeature; return nullptr; } if( nCode == 0 ) poDS->UnreadValue(); /* -------------------------------------------------------------------- */ /* Obtain a tolerance value used when building the polygon. */ /* -------------------------------------------------------------------- */ double dfTolerance = atof( CPLGetConfigOption( "DXF_HATCH_TOLERANCE", "-1" ) ); if( dfTolerance < 0 ) { // If the configuration variable isn't set, compute the bounding box // and work out a tolerance from that OGREnvelope oEnvelope; oGC.getEnvelope( &oEnvelope ); dfTolerance = std::max( oEnvelope.MaxX - oEnvelope.MinX, oEnvelope.MaxY - oEnvelope.MinY ) * 1e-7; } /* -------------------------------------------------------------------- */ /* Try to turn the set of lines into something useful. */ /* -------------------------------------------------------------------- */ OGRErr eErr; OGRGeometry* poFinalGeom = (OGRGeometry *) OGRBuildPolygonFromEdges( (OGRGeometryH) &oGC, TRUE, TRUE, dfTolerance, &eErr ); if( eErr != OGRERR_NONE ) { delete poFinalGeom; OGRMultiLineString* poMLS = new OGRMultiLineString(); for(int i=0;i<oGC.getNumGeometries();i++) poMLS->addGeometry(oGC.getGeometryRef(i)); poFinalGeom = poMLS; } poFeature->ApplyOCSTransformer( poFinalGeom ); poFeature->SetGeometryDirectly( poFinalGeom ); PrepareBrushStyle( poFeature ); return poFeature; }
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; }
OGRFeature *OGRDGNLayer::ElementToFeature( DGNElemCore *psElement ) { OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); poFeature->SetFID( psElement->element_id ); poFeature->SetField( "Type", psElement->type ); poFeature->SetField( "Level", psElement->level ); poFeature->SetField( "GraphicGroup", psElement->graphic_group ); poFeature->SetField( "ColorIndex", psElement->color ); poFeature->SetField( "Weight", psElement->weight ); poFeature->SetField( "Style", psElement->style ); m_nFeaturesRead++; /* -------------------------------------------------------------------- */ /* Collect linkage information */ /* -------------------------------------------------------------------- */ #define MAX_LINK 100 int anEntityNum[MAX_LINK], anMSLink[MAX_LINK]; unsigned char *pabyData; int iLink=0, nLinkCount=0; anEntityNum[0] = 0; anMSLink[0] = 0; pabyData = DGNGetLinkage( hDGN, psElement, iLink, NULL, anEntityNum+iLink, anMSLink+iLink, NULL ); while( pabyData && nLinkCount < MAX_LINK ) { iLink++; if( anEntityNum[nLinkCount] != 0 || anMSLink[nLinkCount] != 0 ) nLinkCount++; anEntityNum[nLinkCount] = 0; anMSLink[nLinkCount] = 0; pabyData = DGNGetLinkage( hDGN, psElement, iLink, NULL, anEntityNum+nLinkCount, anMSLink+nLinkCount, NULL ); } /* -------------------------------------------------------------------- */ /* Apply attribute linkage to feature. */ /* -------------------------------------------------------------------- */ if( nLinkCount > 0 ) { if( EQUAL(pszLinkFormat,"FIRST") ) { poFeature->SetField( "EntityNum", anEntityNum[0] ); poFeature->SetField( "MSLink", anMSLink[0] ); } else if( EQUAL(pszLinkFormat,"LIST") ) { poFeature->SetField( "EntityNum", nLinkCount, anEntityNum ); poFeature->SetField( "MSLink", nLinkCount, anMSLink ); } else if( EQUAL(pszLinkFormat,"STRING") ) { char szEntityList[MAX_LINK*9], szMSLinkList[MAX_LINK*9]; int nEntityLen = 0, nMSLinkLen = 0; for( iLink = 0; iLink < nLinkCount; iLink++ ) { if( iLink != 0 ) { szEntityList[nEntityLen++] = ','; szMSLinkList[nMSLinkLen++] = ','; } sprintf( szEntityList + nEntityLen, "%d", anEntityNum[iLink]); sprintf( szMSLinkList + nMSLinkLen, "%d", anMSLink[iLink] ); nEntityLen += strlen(szEntityList + nEntityLen ); nMSLinkLen += strlen(szMSLinkList + nMSLinkLen ); } poFeature->SetField( "EntityNum", szEntityList ); poFeature->SetField( "MSLink", szMSLinkList ); } } /* -------------------------------------------------------------------- */ /* Lookup color. */ /* -------------------------------------------------------------------- */ char gv_color[128]; int gv_red, gv_green, gv_blue; char szFSColor[128], szPen[256]; szFSColor[0] = '\0'; if( DGNLookupColor( hDGN, psElement->color, &gv_red, &gv_green, &gv_blue ) ) { sprintf( gv_color, "%f %f %f 1.0", gv_red / 255.0, gv_green / 255.0, gv_blue / 255.0 ); sprintf( szFSColor, "c:#%02x%02x%02x", gv_red, gv_green, gv_blue ); } /* -------------------------------------------------------------------- */ /* Generate corresponding PEN style. */ /* -------------------------------------------------------------------- */ if( psElement->style == DGNS_SOLID ) sprintf( szPen, "PEN(id:\"ogr-pen-0\"" ); else if( psElement->style == DGNS_DOTTED ) sprintf( szPen, "PEN(id:\"ogr-pen-5\"" ); else if( psElement->style == DGNS_MEDIUM_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-2\"" ); else if( psElement->style == DGNS_LONG_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-4\"" ); else if( psElement->style == DGNS_DOT_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-6\"" ); else if( psElement->style == DGNS_SHORT_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-3\"" ); else if( psElement->style == DGNS_DASH_DOUBLE_DOT ) sprintf( szPen, "PEN(id:\"ogr-pen-7\"" ); else if( psElement->style == DGNS_LONG_DASH_SHORT_DASH ) sprintf( szPen, "PEN(p:\"10px 5px 4px 5px\"" ); else sprintf( szPen, "PEN(id:\"ogr-pen-0\"" ); if( strlen(szFSColor) > 0 ) sprintf( szPen+strlen(szPen), ",%s", szFSColor ); if( psElement->weight > 1 ) sprintf( szPen+strlen(szPen), ",w:%dpx", psElement->weight ); strcat( szPen, ")" ); switch( psElement->stype ) { case DGNST_MULTIPOINT: if( psElement->type == DGNT_SHAPE ) { OGRLinearRing *poLine = new OGRLinearRing(); OGRPolygon *poPolygon = new OGRPolygon(); DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; poLine->setNumPoints( psEMP->num_vertices ); for( int i = 0; i < psEMP->num_vertices; i++ ) { poLine->setPoint( i, psEMP->vertices[i].x, psEMP->vertices[i].y, psEMP->vertices[i].z ); } poPolygon->addRingDirectly( poLine ); poFeature->SetGeometryDirectly( poPolygon ); ConsiderBrush( psElement, szPen, poFeature ); } else if( psElement->type == DGNT_CURVE ) { DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; OGRLineString *poLine = new OGRLineString(); DGNPoint *pasPoints; int nPoints; nPoints = 5 * psEMP->num_vertices; pasPoints = (DGNPoint *) CPLMalloc(sizeof(DGNPoint) * nPoints); DGNStrokeCurve( hDGN, psEMP, nPoints, pasPoints ); poLine->setNumPoints( nPoints ); for( int i = 0; i < nPoints; i++ ) { poLine->setPoint( i, pasPoints[i].x, pasPoints[i].y, pasPoints[i].z ); } poFeature->SetGeometryDirectly( poLine ); CPLFree( pasPoints ); poFeature->SetStyleString( szPen ); } else { OGRLineString *poLine = new OGRLineString(); DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; if( psEMP->num_vertices > 0 ) { poLine->setNumPoints( psEMP->num_vertices ); for( int i = 0; i < psEMP->num_vertices; i++ ) { poLine->setPoint( i, psEMP->vertices[i].x, psEMP->vertices[i].y, psEMP->vertices[i].z ); } poFeature->SetGeometryDirectly( poLine ); } poFeature->SetStyleString( szPen ); } break; case DGNST_ARC: { OGRLineString *poLine = new OGRLineString(); DGNElemArc *psArc = (DGNElemArc *) psElement; DGNPoint asPoints[90]; int nPoints; nPoints = (int) (MAX(1,ABS(psArc->sweepang) / 5) + 1); DGNStrokeArc( hDGN, psArc, nPoints, asPoints ); poLine->setNumPoints( nPoints ); for( int i = 0; i < nPoints; i++ ) { poLine->setPoint( i, asPoints[i].x, asPoints[i].y, asPoints[i].z ); } poFeature->SetGeometryDirectly( poLine ); poFeature->SetStyleString( szPen ); } break; case DGNST_TEXT: { OGRPoint *poPoint = new OGRPoint(); DGNElemText *psText = (DGNElemText *) psElement; char *pszOgrFS; poPoint->setX( psText->origin.x ); poPoint->setY( psText->origin.y ); poPoint->setZ( psText->origin.z ); poFeature->SetGeometryDirectly( poPoint ); pszOgrFS = (char *) CPLMalloc(strlen(psText->string) + 150); // setup the basic label. sprintf( pszOgrFS, "LABEL(t:\"%s\"", psText->string ); // set the color if we have it. if( strlen(szFSColor) > 0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",%s", szFSColor ); // Add the size info in ground units. if( ABS(psText->height_mult) >= 6.0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%dg", (int) psText->height_mult ); else if( ABS(psText->height_mult) > 0.1 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%.3fg", psText->height_mult ); else sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%.12fg", psText->height_mult ); // Add the font name. Name it MstnFont<FONTNUMBER> if not available // in the font list. #3392 static const char *papszFontList[] = { "STANDARD", "WORKING", "FANCY", "ENGINEERING", "NEWZERO", "STENCEL", //0-5 "USTN_FANCY", "COMPRESSED", "STENCEQ", NULL, "hand", "ARCH", //6-11 "ARCHB", NULL, NULL, "IGES1001", "IGES1002", "IGES1003", //12-17 "CENTB", "MICROS", NULL, NULL, "ISOFRACTIONS", "ITALICS", //18-23 "ISO30", NULL, "GREEK", "ISOREC", "Isoeq", NULL, //24-29 "ISO_FONTLEFT", "ISO_FONTRIGHT", "INTL_ENGINEERING", "INTL_WORKING", "ISOITEQ", NULL, //30-35 "USTN FONT 26", NULL, NULL, NULL, NULL, "ARCHITECTURAL", //36-41 "BLOCK_OUTLINE", "LOW_RES_FILLED", NULL, NULL, NULL, NULL, //42-47 NULL, NULL, "UPPERCASE", NULL, NULL, NULL, //48-53 NULL, NULL, NULL, NULL, NULL, NULL, //54-49 "FONT060", "din", "dinit", "helvl", "HELVLIT", "helv", //60-65 "HELVIT", "cent", "CENTIT", "SCRIPT", NULL, NULL, //66-71 NULL, NULL, NULL, NULL, "MICROQ", "dotfont", //72-77 "DOTIT", NULL, NULL, NULL, NULL, NULL, //78-83 NULL, NULL, NULL, NULL, NULL, NULL, //84-89 NULL, NULL, "FONT092", NULL, "FONT094", NULL, //90-95 NULL, NULL, NULL, NULL, "ANSI_SYMBOLS", "FEATURE_CONTROL_SYSMBOLS", //96-101 "SYMB_FAST", NULL, NULL, "INTL_ISO", "INTL_ISO_EQUAL", "INTL_ISO_ITALIC", //102-107 "INTL_ISO_ITALIC_EQUAL" }; //108 if(psText->font_id <= 108 && papszFontList[psText->font_id] != NULL ) { sprintf( pszOgrFS+strlen(pszOgrFS), ",f:%s", papszFontList[psText->font_id] ); } else { sprintf( pszOgrFS+strlen(pszOgrFS), ",f:MstnFont%d", psText->font_id ); } // Add the angle, if not horizontal if( psText->rotation != 0.0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",a:%d", (int) (psText->rotation+0.5) ); strcat( pszOgrFS, ")" ); poFeature->SetStyleString( pszOgrFS ); CPLFree( pszOgrFS ); poFeature->SetField( "Text", psText->string ); } break; case DGNST_COMPLEX_HEADER: { DGNElemComplexHeader *psHdr = (DGNElemComplexHeader *) psElement; int iChild; OGRMultiLineString oChildren; /* collect subsequent child geometries. */ // we should disable the spatial filter ... add later. for( iChild = 0; iChild < psHdr->numelems; iChild++ ) { OGRFeature *poChildFeature = NULL; DGNElemCore *psChildElement; psChildElement = DGNReadElement( hDGN ); // should verify complex bit set, not another header. if( psChildElement != NULL ) { poChildFeature = ElementToFeature( psChildElement ); DGNFreeElement( hDGN, psChildElement ); } if( poChildFeature != NULL && poChildFeature->GetGeometryRef() != NULL ) { OGRGeometry *poGeom; poGeom = poChildFeature->GetGeometryRef(); if( wkbFlatten(poGeom->getGeometryType()) == wkbLineString ) oChildren.addGeometry( poGeom ); } if( poChildFeature != NULL ) delete poChildFeature; } // Try to assemble into polygon geometry. OGRGeometry *poGeom; if( psElement->type == DGNT_COMPLEX_SHAPE_HEADER ) poGeom = (OGRPolygon *) OGRBuildPolygonFromEdges( (OGRGeometryH) &oChildren, TRUE, TRUE, 100000, NULL ); else poGeom = oChildren.clone(); if( poGeom != NULL ) poFeature->SetGeometryDirectly( poGeom ); ConsiderBrush( psElement, szPen, poFeature ); } break; default: break; } /* -------------------------------------------------------------------- */ /* Fixup geometry dimension. */ /* -------------------------------------------------------------------- */ if( poFeature->GetGeometryRef() != NULL ) poFeature->GetGeometryRef()->setCoordinateDimension( DGNGetDimension( hDGN ) ); 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; }