Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: Implements OGRDGNDriver class. 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2000, Frank Warmerdam (warmerdam@pobox.com) 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "ogr_dgn.h" 14 : #include "cpl_conv.h" 15 : 16 : /************************************************************************/ 17 : /* OGRDGNDriverIdentify() */ 18 : /************************************************************************/ 19 : 20 49301 : static int OGRDGNDriverIdentify(GDALOpenInfo *poOpenInfo) 21 : 22 : { 23 53119 : if (poOpenInfo->fpL != nullptr && poOpenInfo->nHeaderBytes >= 512 && 24 3818 : DGNTestOpen(poOpenInfo->pabyHeader, poOpenInfo->nHeaderBytes)) 25 : { 26 84 : return TRUE; 27 : } 28 : 29 : // Is this is a DGNv8 file ? If so, and if the DGNV8 driver is not 30 : // available, and we are called from GDALError(), emit an explicit 31 : // error. 32 : VSIStatBuf sStat; 33 106096 : if ((poOpenInfo->nOpenFlags & GDAL_OF_FROM_GDALOPEN) != 0 && 34 7662 : poOpenInfo->papszAllowedDrivers == nullptr && 35 7662 : poOpenInfo->fpL != nullptr && poOpenInfo->nHeaderBytes >= 512 && 36 3538 : memcmp(poOpenInfo->pabyHeader, "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1", 8) == 37 6 : 0 && 38 6 : EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "DGN") && 39 56880 : VSIStat(poOpenInfo->pszFilename, &sStat) == 0 && 40 1 : GDALGetDriverByName("DGNV8") == nullptr) 41 : { 42 1 : CPLError(CE_Failure, CPLE_AppDefined, 43 : "`%s' recognized as a DGNv8 dataset, but the DGNv8 driver is " 44 : "not available in this GDAL build. Consult " 45 : "https://gdal.org/drivers/vector/dgnv8.html", 46 : poOpenInfo->pszFilename); 47 : } 48 49217 : return FALSE; 49 : } 50 : 51 : /************************************************************************/ 52 : /* Open() */ 53 : /************************************************************************/ 54 : 55 42 : static GDALDataset *OGRDGNDriverOpen(GDALOpenInfo *poOpenInfo) 56 : 57 : { 58 42 : if (!OGRDGNDriverIdentify(poOpenInfo)) 59 0 : return nullptr; 60 : 61 42 : OGRDGNDataSource *poDS = new OGRDGNDataSource(); 62 : 63 42 : if (!poDS->Open(poOpenInfo) || poDS->GetLayerCount() == 0) 64 : { 65 0 : delete poDS; 66 0 : return nullptr; 67 : } 68 : 69 42 : return poDS; 70 : } 71 : 72 : /************************************************************************/ 73 : /* Create() */ 74 : /************************************************************************/ 75 : 76 35 : static GDALDataset *OGRDGNDriverCreate(const char *, int /* nBands */, 77 : int /* nXSize */, int /* nYSize */, 78 : GDALDataType /* eDT */, 79 : char **papszOptions) 80 : { 81 35 : OGRDGNDataSource *poDS = new OGRDGNDataSource(); 82 35 : poDS->PreCreate(papszOptions); 83 35 : return poDS; 84 : } 85 : 86 : /************************************************************************/ 87 : /* RegisterOGRDGN() */ 88 : /************************************************************************/ 89 : 90 1595 : void RegisterOGRDGN() 91 : 92 : { 93 1595 : if (GDALGetDriverByName("DGN") != nullptr) 94 302 : return; 95 : 96 1293 : GDALDriver *poDriver = new GDALDriver(); 97 : 98 1293 : poDriver->SetDescription("DGN"); 99 1293 : poDriver->SetMetadataItem(GDAL_DCAP_VECTOR, "YES"); 100 1293 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE_LAYER, "YES"); 101 1293 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Microstation DGN"); 102 1293 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "dgn"); 103 1293 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/vector/dgn.html"); 104 1293 : poDriver->SetMetadataItem(GDAL_DCAP_Z_GEOMETRIES, "YES"); 105 1293 : poDriver->SetMetadataItem(GDAL_DMD_SUPPORTED_SQL_DIALECTS, "OGRSQL SQLITE"); 106 : 107 1293 : poDriver->SetMetadataItem( 108 : GDAL_DMD_OPENOPTIONLIST, 109 : "<OpenOptionList>" 110 : " <Option name='ENCODING' type='string' description=" 111 : "'Encoding name, as supported by iconv'/>" 112 1293 : "</OpenOptionList>"); 113 : 114 1293 : poDriver->SetMetadataItem( 115 : GDAL_DMD_CREATIONOPTIONLIST, 116 : "<CreationOptionList>" 117 : " <Option name='3D' type='boolean' description='whether 2D " 118 : "(seed_2d.dgn) or 3D (seed_3d.dgn) seed file should be used. This " 119 : "option is ignored if the SEED option is provided'/>" 120 : " <Option name='SEED' type='string' description='Filename of seed " 121 : "file to use'/>" 122 : " <Option name='COPY_WHOLE_SEED_FILE' type='boolean' " 123 : "description='whether the whole seed file should be copied. If not, " 124 : "only the first three elements (and potentially the color table) will " 125 : "be copied.' default='NO'/>" 126 : " <Option name='COPY_SEED_FILE_COLOR_TABLE' type='boolean' " 127 : "description='whether the color table should be copied from the seed " 128 : "file.' default='NO'/>" 129 : " <Option name='MASTER_UNIT_NAME' type='string' description='Override " 130 : "the master unit name from the seed file with the provided one or two " 131 : "character unit name.'/>" 132 : " <Option name='SUB_UNIT_NAME' type='string' description='Override " 133 : "the master unit name from the seed file with the provided one or two " 134 : "character unit name.'/>" 135 : " <Option name='MASTER_UNIT_NAME' type='string' description='Override " 136 : "the master unit name from the seed file with the provided one or two " 137 : "character unit name.'/>" 138 : " <Option name='SUB_UNIT_NAME' type='string' description='Override " 139 : "the sub unit name from the seed file with the provided one or two " 140 : "character unit name.'/>" 141 : " <Option name='SUB_UNITS_PER_MASTER_UNIT' type='int' " 142 : "description='Override the number of subunits per master unit. By " 143 : "default the seed file value is used.'/>" 144 : " <Option name='UOR_PER_SUB_UNIT' type='int' description='Override " 145 : "the number of UORs (Units of Resolution) per sub unit. By default the " 146 : "seed file value is used.'/>" 147 : " <Option name='ORIGIN' type='string' description='Value as x,y,z. " 148 : "Override the origin of the design plane. By default the origin from " 149 : "the seed file is used.'/>" 150 : " <Option name='ENCODING' type='string' description=" 151 : "'Encoding name, as supported by iconv'/>" 152 1293 : "</CreationOptionList>"); 153 : 154 1293 : poDriver->SetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST, 155 1293 : "<LayerCreationOptionList/>"); 156 1293 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 157 1293 : poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES, "YES"); 158 1293 : poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES_READ, "YES"); 159 1293 : poDriver->SetMetadataItem(GDAL_DCAP_FEATURE_STYLES_WRITE, "YES"); 160 1293 : poDriver->SetMetadataItem(GDAL_DCAP_MULTIPLE_VECTOR_LAYERS, "YES"); 161 : 162 1293 : poDriver->pfnOpen = OGRDGNDriverOpen; 163 1293 : poDriver->pfnIdentify = OGRDGNDriverIdentify; 164 1293 : poDriver->pfnCreate = OGRDGNDriverCreate; 165 : 166 1293 : GetGDALDriverManager()->RegisterDriver(poDriver); 167 : }