コード例 #1
0
ファイル: ogrdxfwriterlayer.cpp プロジェクト: OSGeo/gdal
OGRErr OGRDXFWriterLayer::WritePOLYLINE( OGRFeature *poFeature,
                                         const OGRGeometry *poGeom )

{
/* -------------------------------------------------------------------- */
/*      For now we handle multilinestrings by writing a series of       */
/*      entities.                                                       */
/* -------------------------------------------------------------------- */
    if( poGeom == nullptr )
        poGeom = poFeature->GetGeometryRef();

    if ( poGeom->IsEmpty() )
    {
        return OGRERR_NONE;
    }

    if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon
        || wkbFlatten(poGeom->getGeometryType()) == wkbMultiLineString )
    {
        const OGRGeometryCollection *poGC = poGeom->toGeometryCollection();
        OGRErr eErr = OGRERR_NONE;
        for( auto&& poMember: *poGC )
        {
            eErr = WritePOLYLINE( poFeature, poMember );
            if( eErr != OGRERR_NONE )
                break;
        }

        return eErr;
    }

/* -------------------------------------------------------------------- */
/*      Polygons are written with on entity per ring.                   */
/* -------------------------------------------------------------------- */
    if( wkbFlatten(poGeom->getGeometryType()) == wkbPolygon
        || wkbFlatten(poGeom->getGeometryType()) == wkbTriangle)
    {
        const OGRPolygon *poPoly = poGeom->toPolygon();
        OGRErr eErr = OGRERR_NONE;
        for( auto&& poRing: *poPoly )
        {
            eErr = WritePOLYLINE( poFeature, poRing );
            if( eErr != OGRERR_NONE )
                break;
        }

        return eErr;
    }

/* -------------------------------------------------------------------- */
/*      Do we now have a geometry we can work with?                     */
/* -------------------------------------------------------------------- */
    if( wkbFlatten(poGeom->getGeometryType()) != wkbLineString )
        return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;

    const OGRLineString *poLS = poGeom->toLineString();

/* -------------------------------------------------------------------- */
/*      Write as a lightweight polygon,                                 */
/*       or as POLYLINE if the line contains different heights          */
/* -------------------------------------------------------------------- */
    int bHasDifferentZ = FALSE;
    if( poLS->getGeometryType() == wkbLineString25D )
    {
        double z0 = poLS->getZ(0);
        for( int iVert = 0; iVert < poLS->getNumPoints(); iVert++ )
        {
            if (z0 != poLS->getZ(iVert))
            {
                bHasDifferentZ = TRUE;
                break;
            }
        }
    }

    WriteValue( 0, bHasDifferentZ ? "POLYLINE" : "LWPOLYLINE" );
    WriteCore( poFeature );
    WriteValue( 100, "AcDbEntity" );
    if( bHasDifferentZ )
    {
        WriteValue( 100, "AcDb3dPolyline" );
        WriteValue( 10, 0.0 );
        WriteValue( 20, 0.0 );
        WriteValue( 30, 0.0 );
    }
    else
        WriteValue( 100, "AcDbPolyline" );
    if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) )
        WriteValue( 70, 1 + (bHasDifferentZ ? 8 : 0) );
    else
        WriteValue( 70, 0 + (bHasDifferentZ ? 8 : 0) );
    if( !bHasDifferentZ )
        WriteValue( 90, poLS->getNumPoints() );
    else
        WriteValue( 66, "1" );  // Vertex Flag

/* -------------------------------------------------------------------- */
/*      Do we have styling information?                                 */
/* -------------------------------------------------------------------- */
    OGRStyleTool *poTool = nullptr;
    OGRStyleMgr oSM;

    if( poFeature->GetStyleString() != nullptr )
    {
        oSM.InitFromFeature( poFeature );

        if( oSM.GetPartCount() > 0 )
            poTool = oSM.GetPart(0);
    }

/* -------------------------------------------------------------------- */
/*      Handle a PEN tool to control drawing color and width.           */
/*      Perhaps one day also dottedness, etc.                           */
/* -------------------------------------------------------------------- */
    if( poTool && poTool->GetType() == OGRSTCPen )
    {
        OGRStylePen *poPen = (OGRStylePen *) poTool;
        GBool bDefault;

        if( poPen->Color(bDefault) != nullptr && !bDefault )
            WriteValue( 62, ColorStringToDXFColor( poPen->Color(bDefault) ) );

        // we want to fetch the width in ground units.
        poPen->SetUnit( OGRSTUGround, 1.0 );
        const double dfWidth = poPen->Width(bDefault);

        if( !bDefault )
            WriteValue( 370, (int) floor(dfWidth * 100 + 0.5) );
    }

/* -------------------------------------------------------------------- */
/*      Do we have a Linetype for the feature?                          */
/* -------------------------------------------------------------------- */
    CPLString osLineType = poFeature->GetFieldAsString( "Linetype" );
    double dfLineTypeScale = 0.0;

    bool bGotLinetype = false;

    if( !osLineType.empty() )
    {
        std::vector<double> adfLineType =
            poDS->oHeaderDS.LookupLineType( osLineType );

        if( adfLineType.empty() && oNewLineTypes.count(osLineType) > 0 )
            adfLineType = oNewLineTypes[osLineType];

        if( !adfLineType.empty() )
        {
            bGotLinetype = true;
            WriteValue( 6, osLineType );

            // If the given linetype is proportional to the linetype data
            // in the style string, then apply a linetype scale
            if( poTool != nullptr && poTool->GetType() == OGRSTCPen )
            {
                std::vector<double> adfDefinition = PrepareLineTypeDefinition(
                    static_cast<OGRStylePen *>( poTool ) );
                
                if( !adfDefinition.empty() )
                {
                    dfLineTypeScale = IsLineTypeProportional( adfLineType,
                        adfDefinition );

                    if( dfLineTypeScale != 0.0 && 
                        fabs( dfLineTypeScale - 1.0 ) > 1e-4 )
                    {
                        WriteValue( 48, dfLineTypeScale );
                    }
                }
            }
        }
    }

    if( !bGotLinetype && poTool != nullptr && poTool->GetType() == OGRSTCPen )
    {
        std::vector<double> adfDefinition = PrepareLineTypeDefinition(
            static_cast<OGRStylePen *>( poTool ) );

        if( !adfDefinition.empty() )
        {
            // Is this definition already created and named?
            for( const auto& oPair : poDS->oHeaderDS.GetLineTypeTable() )
            {
                dfLineTypeScale = IsLineTypeProportional( oPair.second,
                    adfDefinition );
                if( dfLineTypeScale != 0.0 )
                {
                    osLineType = oPair.first;
                    break;
                }
            }

            if( dfLineTypeScale == 0.0 )
            {
                for( const auto& oPair : oNewLineTypes )
                {
                    dfLineTypeScale = IsLineTypeProportional( oPair.second,
                        adfDefinition );
                    if( dfLineTypeScale != 0.0 )
                    {
                        osLineType = oPair.first;
                        break;
                    }
                }
            }

            // If not, create an automatic name for it.
            if( osLineType == "" )
            {
                dfLineTypeScale = 1.0;
                do
                {
                    osLineType.Printf( "AutoLineType-%d", nNextAutoID++ );
                }
                while( poDS->oHeaderDS.LookupLineType(osLineType).size() > 0 );
            }

            // If it isn't already defined, add it now.
            if( poDS->oHeaderDS.LookupLineType( osLineType ).empty() &&
                oNewLineTypes.count( osLineType ) == 0 )
            {
                oNewLineTypes[osLineType] = adfDefinition;
            }

            WriteValue( 6, osLineType );

            if( dfLineTypeScale != 0.0 && fabs( dfLineTypeScale - 1.0 ) > 1e-4 )
            {
                WriteValue( 48, dfLineTypeScale );
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Write the vertices                                              */
/* -------------------------------------------------------------------- */

    if( !bHasDifferentZ && poLS->getGeometryType() == wkbLineString25D )
    {
     // if LWPOLYLINE with Z write it only once
        if( !WriteValue( 38, poLS->getZ(0) ) )
            return OGRERR_FAILURE;
    }

    for( int iVert = 0; iVert < poLS->getNumPoints(); iVert++ )
    {
        if( bHasDifferentZ )
        {
            WriteValue( 0, "VERTEX" );
            WriteValue( 100, "AcDbEntity" );
            WriteValue( 100, "AcDbVertex" );
            WriteValue( 100, "AcDb3dPolylineVertex" );
            WriteCore( poFeature );
        }
        WriteValue( 10, poLS->getX(iVert) );
        if( !WriteValue( 20, poLS->getY(iVert) ) )
            return OGRERR_FAILURE;

        if( bHasDifferentZ )
        {
            if( !WriteValue( 30 , poLS->getZ(iVert) ) )
                return OGRERR_FAILURE;
            WriteValue( 70, 32 );
        }
    }

    if( bHasDifferentZ )
    {
        WriteValue( 0, "SEQEND" );
        WriteCore( poFeature );
        WriteValue( 100, "AcDbEntity" );
    }

    delete poTool;

    return OGRERR_NONE;

#ifdef notdef
/* -------------------------------------------------------------------- */
/*      Alternate unmaintained implementation as a polyline entity.     */
/* -------------------------------------------------------------------- */
    WriteValue( 0, "POLYLINE" );
    WriteCore( poFeature );
    WriteValue( 100, "AcDbEntity" );
    WriteValue( 100, "AcDbPolyline" );
    if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) )
        WriteValue( 70, 1 );
    else
        WriteValue( 70, 0 );
    WriteValue( 66, "1" );

    for( int iVert = 0; iVert < poLS->getNumPoints(); iVert++ )
    {
        WriteValue( 0, "VERTEX" );
        WriteValue( 8, "0" );
        WriteValue( 10, poLS->getX(iVert) );
        if( !WriteValue( 20, poLS->getY(iVert) ) )
            return OGRERR_FAILURE;

        if( poLS->getGeometryType() == wkbLineString25D )
        {
            if( !WriteValue( 30, poLS->getZ(iVert) ) )
                return OGRERR_FAILURE;
        }
    }

    WriteValue( 0, "SEQEND" );
    WriteValue( 8, "0" );

    return OGRERR_NONE;
#endif
}
コード例 #2
0
OGRErr OGRDXFWriterLayer::WritePOLYLINE( OGRFeature *poFeature,
                                         OGRGeometry *poGeom )

{
/* -------------------------------------------------------------------- */
/*      For now we handle multilinestrings by writing a series of       */
/*      entities.                                                       */
/* -------------------------------------------------------------------- */
    if( poGeom == NULL )
        poGeom = poFeature->GetGeometryRef();

    if ( poGeom->IsEmpty() )
    {
        return OGRERR_NONE;
    }
            
    if( wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon 
        || wkbFlatten(poGeom->getGeometryType()) == wkbMultiLineString )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom;
        int iGeom;
        OGRErr eErr = OGRERR_NONE;

        for( iGeom = 0; 
             eErr == OGRERR_NONE && iGeom < poGC->getNumGeometries(); 
             iGeom++ )
        {
            eErr = WritePOLYLINE( poFeature, poGC->getGeometryRef( iGeom ) );
        }

        return eErr;
    }

/* -------------------------------------------------------------------- */
/*      Polygons are written with on entity per ring.                   */
/* -------------------------------------------------------------------- */
    if( wkbFlatten(poGeom->getGeometryType()) == wkbPolygon )
    {
        OGRPolygon *poPoly = (OGRPolygon *) poGeom;
        int iGeom;
        OGRErr eErr;

        eErr = WritePOLYLINE( poFeature, poPoly->getExteriorRing() );
        for( iGeom = 0; 
             eErr == OGRERR_NONE && iGeom < poPoly->getNumInteriorRings(); 
             iGeom++ )
        {
            eErr = WritePOLYLINE( poFeature, poPoly->getInteriorRing(iGeom) );
        }

        return eErr;
    }

/* -------------------------------------------------------------------- */
/*      Do we now have a geometry we can work with?                     */
/* -------------------------------------------------------------------- */
    if( wkbFlatten(poGeom->getGeometryType()) != wkbLineString )
        return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;

    OGRLineString *poLS = (OGRLineString *) poGeom;

/* -------------------------------------------------------------------- */
/*      Write as a lightweight polygon,                                 */
/*       or as POLYLINE if the line contains different heights          */
/* -------------------------------------------------------------------- */
    int bHasDifferentZ = FALSE;
    if( poLS->getGeometryType() == wkbLineString25D )
    {
        double z0 = poLS->getZ(0);
        for( int iVert = 0; iVert < poLS->getNumPoints(); iVert++ )
        {
            if (z0 != poLS->getZ(iVert))
            {
                bHasDifferentZ = TRUE;
                break;
            }
        }
    }

    WriteValue( 0, bHasDifferentZ ? "POLYLINE" : "LWPOLYLINE" );
    WriteCore( poFeature );
    WriteValue( 100, "AcDbEntity" );
    if( bHasDifferentZ )
    {
        WriteValue( 100, "AcDb3dPolyline" );
        WriteValue( 10, 0.0 );
        WriteValue( 20, 0.0 );
        WriteValue( 30, 0.0 );
    }
    else
        WriteValue( 100, "AcDbPolyline" );
    if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) )
        WriteValue( 70, 1 + (bHasDifferentZ ? 8 : 0) );
    else
        WriteValue( 70, 0 + (bHasDifferentZ ? 8 : 0) );
    if( !bHasDifferentZ )
        WriteValue( 90, poLS->getNumPoints() );
    else
        WriteValue( 66, "1" );  // Vertex Flag

/* -------------------------------------------------------------------- */
/*      Do we have styling information?                                 */
/* -------------------------------------------------------------------- */
    OGRStyleTool *poTool = NULL;
    OGRStyleMgr oSM;

    if( poFeature->GetStyleString() != NULL )
    {
        oSM.InitFromFeature( poFeature );

        if( oSM.GetPartCount() > 0 )
            poTool = oSM.GetPart(0);
    }

/* -------------------------------------------------------------------- */
/*      Handle a PEN tool to control drawing color and width.           */
/*      Perhaps one day also dottedness, etc.                           */
/* -------------------------------------------------------------------- */
    if( poTool && poTool->GetType() == OGRSTCPen )
    {
        OGRStylePen *poPen = (OGRStylePen *) poTool;
        GBool  bDefault;

        if( poPen->Color(bDefault) != NULL && !bDefault )
            WriteValue( 62, ColorStringToDXFColor( poPen->Color(bDefault) ) );

        // we want to fetch the width in ground units. 
        poPen->SetUnit( OGRSTUGround, 1.0 );
        double dfWidth = poPen->Width(bDefault);

        if( !bDefault )
            WriteValue( 370, (int) floor(dfWidth * 100 + 0.5) );
    }

/* -------------------------------------------------------------------- */
/*      Do we have a Linetype for the feature?                          */
/* -------------------------------------------------------------------- */
    CPLString osLineType = poFeature->GetFieldAsString( "Linetype" );

    if( osLineType.size() > 0 
        && (poDS->oHeaderDS.LookupLineType( osLineType ) != NULL 
            || oNewLineTypes.count(osLineType) > 0 ) )
    {
        // Already define -> just reference it.
        WriteValue( 6, osLineType );
    }
    else if( poTool != NULL && poTool->GetType() == OGRSTCPen )
    {
        CPLString osDefinition = PrepareLineTypeDefinition( poFeature, 
                                                            poTool );

        if( osDefinition != "" && osLineType == "" )
        {
            // Is this definition already created and named?
            std::map<CPLString,CPLString>::iterator it;

            for( it = oNewLineTypes.begin();
                 it != oNewLineTypes.end();
                 it++ )
            {
                if( (*it).second == osDefinition )
                {
                    osLineType = (*it).first;
                    break;
                }
            }

            // create an automatic name for it.
            if( osLineType == "" )
            {
                do 
                { 
                    osLineType.Printf( "AutoLineType-%d", nNextAutoID++ );
                }
                while( poDS->oHeaderDS.LookupLineType(osLineType) != NULL );
            }
        }

        // If it isn't already defined, add it now.
        if( osDefinition != "" && oNewLineTypes.count(osLineType) == 0 )
        {
            oNewLineTypes[osLineType] = osDefinition;
            WriteValue( 6, osLineType );
        }
    }

/* -------------------------------------------------------------------- */
/*      Write the vertices                                              */
/* -------------------------------------------------------------------- */

    if( !bHasDifferentZ && poLS->getGeometryType() == wkbLineString25D )
    {
     // if LWPOLYLINE with Z write it only once
        if( !WriteValue( 38, poLS->getZ(0) ) )
            return OGRERR_FAILURE;
    }

    int iVert;

    for( iVert = 0; iVert < poLS->getNumPoints(); iVert++ )
    {
        if( bHasDifferentZ ) 
        {
            WriteValue( 0, "VERTEX" );
            WriteValue( 100, "AcDbEntity" );
            WriteValue( 100, "AcDbVertex" );
            WriteValue( 100, "AcDb3dPolylineVertex" );
            WriteCore( poFeature );
        }
        WriteValue( 10, poLS->getX(iVert) );
        if( !WriteValue( 20, poLS->getY(iVert) ) ) 
            return OGRERR_FAILURE;

        if( bHasDifferentZ )
        {
            if( !WriteValue( 30 , poLS->getZ(iVert) ) )
                return OGRERR_FAILURE;
            WriteValue( 70, 32 );
        }
    }

    if( bHasDifferentZ )
    {
        WriteValue( 0, "SEQEND" );
        WriteCore( poFeature );
        WriteValue( 100, "AcDbEntity" );
    }
    
    delete poTool;

    return OGRERR_NONE;

#ifdef notdef
/* -------------------------------------------------------------------- */
/*      Alternate unmaintained implementation as a polyline entity.     */
/* -------------------------------------------------------------------- */
    WriteValue( 0, "POLYLINE" );
    WriteCore( poFeature );
    WriteValue( 100, "AcDbEntity" );
    WriteValue( 100, "AcDbPolyline" );
    if( EQUAL( poGeom->getGeometryName(), "LINEARRING" ) )
        WriteValue( 70, 1 );
    else
        WriteValue( 70, 0 );
    WriteValue( 66, "1" );

    int iVert;

    for( iVert = 0; iVert < poLS->getNumPoints(); iVert++ )
    {
        WriteValue( 0, "VERTEX" );
        WriteValue( 8, "0" );
        WriteValue( 10, poLS->getX(iVert) );
        if( !WriteValue( 20, poLS->getY(iVert) ) ) 
            return OGRERR_FAILURE;

        if( poLS->getGeometryType() == wkbLineString25D )
        {
            if( !WriteValue( 30, poLS->getZ(iVert) ) )
                return OGRERR_FAILURE;
        }
    }

    WriteValue( 0, "SEQEND" );
    WriteValue( 8, "0" );
    
    return OGRERR_NONE;
#endif
}
コード例 #3
0
ファイル: ogrdxfwriterlayer.cpp プロジェクト: OSGeo/gdal
OGRErr OGRDXFWriterLayer::ICreateFeature( OGRFeature *poFeature )

{
    OGRGeometry *poGeom = poFeature->GetGeometryRef();
    OGRwkbGeometryType eGType = wkbNone;

    if( poGeom != nullptr )
    {
        if( !poGeom->IsEmpty() )
        {
            OGREnvelope sEnvelope;
            poGeom->getEnvelope(&sEnvelope);
            poDS->UpdateExtent(&sEnvelope);
        }
        eGType = wkbFlatten(poGeom->getGeometryType());
    }

    if( eGType == wkbPoint )
    {
        const char *pszBlockName = poFeature->GetFieldAsString("BlockName");

        // We don't want to treat as a blocks ref if the block is not defined
        if( pszBlockName
            && poDS->oHeaderDS.LookupBlock(pszBlockName) == nullptr )
        {
            if( poDS->poBlocksLayer == nullptr
                || poDS->poBlocksLayer->FindBlock(pszBlockName) == nullptr )
                pszBlockName = nullptr;
        }

        if( pszBlockName != nullptr )
            return WriteINSERT( poFeature );

        else if( poFeature->GetStyleString() != nullptr
            && STARTS_WITH_CI(poFeature->GetStyleString(), "LABEL") )
            return WriteTEXT( poFeature );
        else
            return WritePOINT( poFeature );
    }
    else if( eGType == wkbLineString
             || eGType == wkbMultiLineString )
        return WritePOLYLINE( poFeature );

    else if( eGType == wkbPolygon
             || eGType == wkbTriangle
             || eGType == wkbMultiPolygon)
    {
        if( bWriteHatch )
            return WriteHATCH( poFeature );
        else
            return WritePOLYLINE( poFeature );
    }

    // Explode geometry collections into multiple entities.
    else if( eGType == wkbGeometryCollection )
    {
        OGRGeometryCollection *poGC =
            poFeature->StealGeometry()->toGeometryCollection();
        for( auto&& poMember: poGC )
        {
            poFeature->SetGeometry( poMember );

            OGRErr eErr = CreateFeature( poFeature );

            if( eErr != OGRERR_NONE )
            {
                delete poGC;
                return eErr;
            }
        }

        poFeature->SetGeometryDirectly( poGC );
        return OGRERR_NONE;
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "No known way to write feature with geometry '%s'.",
                  OGRGeometryTypeToName(eGType) );
        return OGRERR_FAILURE;
    }
}
コード例 #4
0
OGRErr OGRDXFWriterLayer::ICreateFeature( OGRFeature *poFeature )

{
    OGRGeometry *poGeom = poFeature->GetGeometryRef();
    OGRwkbGeometryType eGType = wkbNone;
    
    if( poGeom != NULL )
    {
        if( !poGeom->IsEmpty() )
        {
            OGREnvelope sEnvelope;
            poGeom->getEnvelope(&sEnvelope);
            poDS->UpdateExtent(&sEnvelope);
        }
        eGType = wkbFlatten(poGeom->getGeometryType());
    }

    if( eGType == wkbPoint )
    {
        const char *pszBlockName = poFeature->GetFieldAsString("BlockName");

        // we don't want to treat as a block ref if we are writing blocks layer
        if( pszBlockName != NULL
            && poDS->poBlocksLayer != NULL 
            && poFeature->GetDefnRef() == poDS->poBlocksLayer->GetLayerDefn())
            pszBlockName = NULL;

        // We don't want to treat as a blocks ref if the block is not defined
        if( pszBlockName 
            && poDS->oHeaderDS.LookupBlock(pszBlockName) == NULL )
        {
            if( poDS->poBlocksLayer == NULL
                || poDS->poBlocksLayer->FindBlock(pszBlockName) == NULL )
                pszBlockName = NULL;
        }
                                  
        if( pszBlockName != NULL )
            return WriteINSERT( poFeature );
            
        else if( poFeature->GetStyleString() != NULL
            && EQUALN(poFeature->GetStyleString(),"LABEL",5) )
            return WriteTEXT( poFeature );
        else
            return WritePOINT( poFeature );
    }
    else if( eGType == wkbLineString 
             || eGType == wkbMultiLineString )
        return WritePOLYLINE( poFeature );

    else if( eGType == wkbPolygon 
             || eGType == wkbMultiPolygon )
    {
        if( bWriteHatch )
            return WriteHATCH( poFeature );
        else
            return WritePOLYLINE( poFeature );
    }

    // Explode geometry collections into multiple entities.
    else if( eGType == wkbGeometryCollection )
    {
        OGRGeometryCollection *poGC = (OGRGeometryCollection *)
            poFeature->StealGeometry();
        int iGeom;

        for( iGeom = 0; iGeom < poGC->getNumGeometries(); iGeom++ )
        {
            poFeature->SetGeometry( poGC->getGeometryRef(iGeom) );
                                    
            OGRErr eErr = CreateFeature( poFeature );
            
            if( eErr != OGRERR_NONE )
                return eErr;

        }
        
        poFeature->SetGeometryDirectly( poGC );
        return OGRERR_NONE;
    }
    else 
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "No known way to write feature with geometry '%s'.",
                  OGRGeometryTypeToName(eGType) );
        return OGRERR_FAILURE;
    }
}