Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: DXF Translator 4 : * Purpose: Implements OGRDXFDriver. 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "ogr_dxf.h" 14 : #include "cpl_conv.h" 15 : 16 : /************************************************************************/ 17 : /* OGRDXFDriverIdentify() */ 18 : /************************************************************************/ 19 : 20 45843 : static int OGRDXFDriverIdentify(GDALOpenInfo *poOpenInfo) 21 : 22 : { 23 45843 : if (poOpenInfo->fpL == nullptr || poOpenInfo->nHeaderBytes == 0) 24 42926 : return FALSE; 25 2917 : if (EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "dxf")) 26 202 : return TRUE; 27 2715 : const char *pszIter = (const char *)poOpenInfo->pabyHeader; 28 2715 : bool bFoundZero = false; 29 2715 : int i = 0; // Used after for. 30 1066880 : for (; pszIter[i]; i++) 31 : { 32 1064180 : if (pszIter[i] == '0') 33 : { 34 45118 : int j = i - 1; // Used after for. 35 46834 : for (; j >= 0; j--) 36 : { 37 46826 : if (pszIter[j] != ' ') 38 45110 : break; 39 : } 40 45118 : if (j < 0 || pszIter[j] == '\n' || pszIter[j] == '\r') 41 : { 42 15 : bFoundZero = true; 43 15 : break; 44 : } 45 : } 46 : } 47 2715 : if (!bFoundZero) 48 2700 : return FALSE; 49 15 : i++; 50 22 : while (pszIter[i] == ' ') 51 7 : i++; 52 18 : while (pszIter[i] == '\n' || pszIter[i] == '\r') 53 3 : i++; 54 15 : if (!STARTS_WITH_CI(pszIter + i, "SECTION")) 55 13 : return FALSE; 56 2 : i += static_cast<int>(strlen("SECTION")); 57 2 : return pszIter[i] == '\n' || pszIter[i] == '\r'; 58 : } 59 : 60 : /************************************************************************/ 61 : /* Open() */ 62 : /************************************************************************/ 63 : 64 102 : static GDALDataset *OGRDXFDriverOpen(GDALOpenInfo *poOpenInfo) 65 : 66 : { 67 102 : if (!OGRDXFDriverIdentify(poOpenInfo)) 68 0 : return nullptr; 69 : 70 102 : OGRDXFDataSource *poDS = new OGRDXFDataSource(); 71 : 72 102 : if (!poDS->Open(poOpenInfo->pszFilename, false, 73 102 : poOpenInfo->papszOpenOptions)) 74 : { 75 1 : delete poDS; 76 1 : poDS = nullptr; 77 : } 78 : 79 102 : return poDS; 80 : } 81 : 82 : /************************************************************************/ 83 : /* Create() */ 84 : /************************************************************************/ 85 : 86 : static GDALDataset * 87 45 : OGRDXFDriverCreate(const char *pszName, CPL_UNUSED int nBands, 88 : CPL_UNUSED int nXSize, CPL_UNUSED int nYSize, 89 : CPL_UNUSED GDALDataType eDT, char **papszOptions) 90 : { 91 45 : OGRDXFWriterDS *poDS = new OGRDXFWriterDS(); 92 : 93 45 : if (poDS->Open(pszName, papszOptions)) 94 44 : return poDS; 95 : else 96 : { 97 1 : delete poDS; 98 1 : return nullptr; 99 : } 100 : } 101 : 102 : /************************************************************************/ 103 : /* RegisterOGRDXF() */ 104 : /************************************************************************/ 105 : 106 1595 : void RegisterOGRDXF() 107 : 108 : { 109 1595 : if (GDALGetDriverByName("DXF") != nullptr) 110 302 : return; 111 : 112 1293 : GDALDriver *poDriver = new GDALDriver(); 113 : 114 1293 : poDriver->SetDescription("DXF"); 115 1293 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES"); 116 1293 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES"); 117 1293 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "AutoCAD DXF"); 118 1293 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "dxf"); 119 1293 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/dxf.html"); 120 1293 : poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES"); 121 1293 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE"); 122 : 123 1293 : poDriver->SetMetadataItem( 124 : GDAL_DMD_CREATIONOPTIONLIST, 125 : "<CreationOptionList>" 126 : " <Option name='HEADER' type='string' description='Template header " 127 : "file' default='header.dxf'/>" 128 : " <Option name='TRAILER' type='string' description='Template trailer " 129 : "file' default='trailer.dxf'/>" 130 : " <Option name='FIRST_ENTITY' type='int' description='Identifier of " 131 : "first entity'/>" 132 1293 : "</CreationOptionList>"); 133 : 134 1293 : poDriver->SetMetadataItem( 135 : GDAL_DMD_OPENOPTIONLIST, 136 : "<OpenOptionList>" 137 : " <Option name='CLOSED_LINE_AS_POLYGON' type='boolean' description=" 138 : "'Whether to expose closed POLYLINE/LWPOLYLINE as polygons' " 139 : "default='NO'/>" 140 : " <Option name='INLINE_BLOCKS' type='boolean' description=" 141 : "'Whether INSERT entities are exploded with the geometry of the BLOCK " 142 : "they reference' default='YES'/>" 143 : " <Option name='MERGE_BLOCK_GEOMETRIES' type='boolean' description=" 144 : "'Whether blocks should be merged into a compound geometry' " 145 : "default='YES'/>" 146 : " <Option name='TRANSLATE_ESCAPE_SEQUENCES' type='boolean' " 147 : "description=" 148 : "'Whether character escapes are honored where applicable, and MTEXT " 149 : "control sequences are stripped' default='YES'/>" 150 : " <Option name='INCLUDE_RAW_CODE_VALUES' type='boolean' description=" 151 : "'Whether a RawCodeValues field should be added to contain all group " 152 : "codes and values' default='NO'/>" 153 : " <Option name='3D_EXTENSIBLE_MODE' type='boolean' description=" 154 : "'Whether to include ASM entities with the raw ASM data stored in a " 155 : "field' default='NO'/>" 156 : " <Option name='HATCH_TOLEARNCE' type='float' description=" 157 : "'Tolerance used when looking for the next component to add to the " 158 : "hatch boundary.'/>" 159 : " <Option name='ENCODING' type='string' description=" 160 : "'Encoding name, as supported by iconv, to override $DWGCODEPAGE'/>" 161 1293 : "</OpenOptionList>"); 162 : 163 1293 : poDriver->SetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST, 164 1293 : "<LayerCreationOptionList/>"); 165 : 166 1293 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 167 1293 : poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES, "YES"); 168 1293 : poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES_READ, "YES"); 169 1293 : poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES_WRITE, "YES"); 170 1293 : poDriver->SetMetadataItem(GDAL_DCAP_MULTIPLE_VECTOR_LAYERS, "YES"); 171 : 172 1293 : poDriver->pfnOpen = OGRDXFDriverOpen; 173 1293 : poDriver->pfnIdentify = OGRDXFDriverIdentify; 174 1293 : poDriver->pfnCreate = OGRDXFDriverCreate; 175 : 176 1293 : GetGDALDriverManager()->RegisterDriver(poDriver); 177 : }