29#include "gdal/cpl_conv.h"
30#include "gdal/cpl_string.h"
38OGRS57DataSource::OGRS57DataSource()
74OGRS57DataSource::~OGRS57DataSource()
79 for (i = 0; i < nLayers; i++)
delete papoLayers[i];
83 for (i = 0; i < nModules; i++) {
84 if (papoModules[i]) papoModules[i]->Close();
85 delete papoModules[i];
93 CSLDestroy(papszOptions);
110void OGRS57DataSource::SetOptionList(
char **papszNewOptions)
113 CSLDestroy(papszOptions);
114 papszOptions = CSLDuplicate(papszNewOptions);
121const char *OGRS57DataSource::GetOption(
const char *pszOption)
124 return CSLFetchNameValue(papszOptions, pszOption);
131int OGRS57DataSource::TestCapability(
const char *)
140int OGRS57DataSource::Open(
const char *pszFilename,
int bTestOpen,
141 CallBackFunction pcallback)
145 int error_return = 0;
147 pszName = CPLStrdup(pszFilename);
157 fp = VSIFOpen(pszFilename,
"rb");
158 if (fp == NULL)
return BAD_FILE;
160 if (VSIFRead(pachLeader, 1, 10, fp) != 10 ||
161 (pachLeader[5] !=
'1' && pachLeader[5] !=
'2' &&
162 pachLeader[5] !=
'3') ||
163 pachLeader[6] !=
'L' ||
164 (pachLeader[8] !=
'1' && pachLeader[8] !=
' ')) {
175 char **papszReaderOptions = NULL;
181 CSLSetNameValue(papszReaderOptions, S57O_LNAM_REFS,
"ON");
182 if (GetOption(S57O_UPDATES) != NULL)
183 papszReaderOptions = CSLSetNameValue(papszReaderOptions, S57O_UPDATES,
184 GetOption(S57O_UPDATES));
186 if (GetOption(S57O_SPLIT_MULTIPOINT) != NULL)
188 CSLSetNameValue(papszReaderOptions, S57O_SPLIT_MULTIPOINT,
189 GetOption(S57O_SPLIT_MULTIPOINT));
191 if (GetOption(S57O_ADD_SOUNDG_DEPTH) != NULL)
193 CSLSetNameValue(papszReaderOptions, S57O_ADD_SOUNDG_DEPTH,
194 GetOption(S57O_ADD_SOUNDG_DEPTH));
196 if (GetOption(S57O_PRESERVE_EMPTY_NUMBERS) != NULL)
198 CSLSetNameValue(papszReaderOptions, S57O_PRESERVE_EMPTY_NUMBERS,
199 GetOption(S57O_PRESERVE_EMPTY_NUMBERS));
201 if (GetOption(S57O_RETURN_PRIMITIVES) != NULL)
203 CSLSetNameValue(papszReaderOptions, S57O_RETURN_PRIMITIVES,
204 GetOption(S57O_RETURN_PRIMITIVES));
206 if (GetOption(S57O_RETURN_LINKAGES) != NULL)
208 CSLSetNameValue(papszReaderOptions, S57O_RETURN_LINKAGES,
209 GetOption(S57O_RETURN_LINKAGES));
211 poModule->SetOptions(papszReaderOptions);
212 CSLDestroy(papszReaderOptions);
220 if (!poModule->Open(bTestOpen)) {
227 papoModules = (
S57Reader **)CPLMalloc(
sizeof(
void *));
228 papoModules[0] = poModule;
233 if (poRegistrar == NULL) {
236 if (!poRegistrar->LoadInfo(NULL, FALSE)) {
246 if (GetOption(S57O_RETURN_PRIMITIVES) != NULL) {
247 OGRFeatureDefn *poDefn;
249 poDefn = S57GenerateVectorPrimitiveFeatureDefn(RCNM_VI,
250 poModule->GetOptionFlags());
253 poDefn = S57GenerateVectorPrimitiveFeatureDefn(RCNM_VC,
254 poModule->GetOptionFlags());
257 poDefn = S57GenerateVectorPrimitiveFeatureDefn(RCNM_VE,
258 poModule->GetOptionFlags());
261 poDefn = S57GenerateVectorPrimitiveFeatureDefn(RCNM_VF,
262 poModule->GetOptionFlags());
298 OGRFeatureDefn *poDefn;
300 int iClass, bGeneric = FALSE;
302 for (iModule = 0; iModule < nModules; iModule++) {
303 papoModules[iModule]->SetClassBased(poRegistrar);
306 for (iModule = 0; iModule < nModules; iModule++) {
307 int ingest_error = papoModules[iModule]->Ingest(pcallback);
308 if (ingest_error) error_return = ingest_error;
311 panClassCount = (
int *)CPLCalloc(
sizeof(
int), MAX_CLASSES);
313 for (iModule = 0; iModule < nModules; iModule++)
314 papoModules[iModule]->CollectClassList(panClassCount, MAX_CLASSES);
316 for (iClass = 0; iClass < MAX_CLASSES; iClass++) {
318 if (!(*pcallback)()) {
324 if (panClassCount[iClass] > 0) {
325 poDefn = S57GenerateObjectClassDefn(poRegistrar, iClass,
326 poModule->GetOptionFlags());
329 AddLayer(
new OGRS57Layer(
this, poDefn, panClassCount[iClass]));
332 CPLDebug(
"S57",
"Unable to find definition for OBJL=%d\n", iClass);
344 CPLFree(panClassCount);
350 for (iModule = 0; iModule < nModules; iModule++) {
351 for (
int iLayer = 0; iLayer < nLayers; iLayer++) {
352 papoModules[iModule]->AddFeatureDefn(papoLayers[iLayer]->GetLayerDefn());
363int OGRS57DataSource::OpenMin(
const char *pszFilename,
int bTestOpen)
366 pszName = CPLStrdup(pszFilename);
376 fp = VSIFOpen(pszFilename,
"rb");
377 if (fp == NULL)
return FALSE;
379 if (VSIFRead(pachLeader, 1, 10, fp) != 10 ||
380 (pachLeader[5] !=
'1' && pachLeader[5] !=
'2' &&
381 pachLeader[5] !=
'3') ||
382 pachLeader[6] !=
'L' ||
383 (pachLeader[8] !=
'1' && pachLeader[8] !=
' ')) {
394 char **papszReaderOptions = NULL;
400 CSLSetNameValue(papszReaderOptions, S57O_LNAM_REFS,
"ON");
402 papszReaderOptions = CSLSetNameValue(papszReaderOptions, S57O_UPDATES,
405 if (GetOption(S57O_SPLIT_MULTIPOINT) != NULL)
407 CSLSetNameValue(papszReaderOptions, S57O_SPLIT_MULTIPOINT,
408 GetOption(S57O_SPLIT_MULTIPOINT));
410 if (GetOption(S57O_ADD_SOUNDG_DEPTH) != NULL)
412 CSLSetNameValue(papszReaderOptions, S57O_ADD_SOUNDG_DEPTH,
413 GetOption(S57O_ADD_SOUNDG_DEPTH));
415 if (GetOption(S57O_PRESERVE_EMPTY_NUMBERS) != NULL)
417 CSLSetNameValue(papszReaderOptions, S57O_PRESERVE_EMPTY_NUMBERS,
418 GetOption(S57O_PRESERVE_EMPTY_NUMBERS));
420 if (GetOption(S57O_RETURN_PRIMITIVES) != NULL)
422 CSLSetNameValue(papszReaderOptions, S57O_RETURN_PRIMITIVES,
423 GetOption(S57O_RETURN_PRIMITIVES));
425 if (GetOption(S57O_RETURN_LINKAGES) != NULL)
427 CSLSetNameValue(papszReaderOptions, S57O_RETURN_LINKAGES,
428 GetOption(S57O_RETURN_LINKAGES));
430 poModule->SetOptions(papszReaderOptions);
431 CSLDestroy(papszReaderOptions);
439 if (!poModule->Open(bTestOpen)) {
446 papoModules = (
S57Reader **)CPLMalloc(
sizeof(
void *));
447 papoModules[0] = poModule;
592 if (path == NULL || parent == NULL)
return false;
593 size_t parent_len = strlen(parent);
594 char *dir_name = CPLStrdup(CPLGetDirname(path));
595 const char *target = CPLGetFilename(dir_name);
596 bool is_match = strlen(target) == parent_len &&
597 EQUALN(target, parent, parent_len);
606OGRLayer *OGRS57DataSource::GetLayer(
int iLayer)
609 if (iLayer < 0 || iLayer >= nLayers)
612 return papoLayers[iLayer];
619void OGRS57DataSource::AddLayer(
OGRS57Layer *poNewLayer)
623 (
OGRS57Layer **)CPLRealloc(papoLayers,
sizeof(
void *) * ++nLayers);
625 papoLayers[nLayers - 1] = poNewLayer;
632S57Reader *OGRS57DataSource::GetModule(
int i)
635 if (i < 0 || i >= nModules)
638 return papoModules[i];
645OGRErr OGRS57DataSource::GetDSExtent(OGREnvelope *psExtent,
int bForce)
652 *psExtent = oExtents;
656 if (nModules == 0)
return OGRERR_FAILURE;
661 for (
int iModule = 0; iModule < nModules; iModule++) {
662 OGREnvelope oModuleEnvelope;
665 eErr = papoModules[iModule]->GetExtent(&oModuleEnvelope, bForce);
666 if (eErr != OGRERR_NONE)
return eErr;
669 oExtents = oModuleEnvelope;
671 oExtents.MinX = MIN(oExtents.MinX, oModuleEnvelope.MinX);
672 oExtents.MaxX = MAX(oExtents.MaxX, oModuleEnvelope.MaxX);
673 oExtents.MinY = MIN(oExtents.MinY, oModuleEnvelope.MinY);
674 oExtents.MaxX = MAX(oExtents.MaxY, oModuleEnvelope.MaxY);
678 *psExtent = oExtents;
bool IsSencPath(const char *path, const char *parent="SENC")
OpenCPN copies new cell files into a cache directory named 'SENC'.
Declarations for classes binding S57 support onto OGRLayer, OGRDataSource and OGRDriver.