static int32_t GetCoordinateSystemId(const char* pszProjection) { int32_t coordinateSystemId = 0; OGRSpatialReference* poSRS = BuildSRS(pszProjection); if (poSRS != nullptr) { std::string pszRoot; if (poSRS->IsProjected()) { pszRoot = "PROJCS"; } else { pszRoot = "GEOCS"; } const char *pszAuthName = poSRS->GetAuthorityName(pszRoot.c_str()); const char *pszAuthCode = poSRS->GetAuthorityCode(pszRoot.c_str()); if (pszAuthName != nullptr && EQUAL(pszAuthName, "EPSG") && pszAuthCode != nullptr) { coordinateSystemId = atoi(pszAuthCode); } } delete poSRS; return coordinateSystemId; }
GDALDataset* HF2Dataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "HF2 driver does not support source dataset with zero band.\n"); return NULL; } if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "HF2 driver only uses the first band of the dataset.\n"); if (bStrict) return NULL; } if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) ) return NULL; /* -------------------------------------------------------------------- */ /* Get source dataset info */ /* -------------------------------------------------------------------- */ int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform(adfGeoTransform); int bHasGeoTransform = !(adfGeoTransform[0] == 0 && adfGeoTransform[1] == 1 && adfGeoTransform[2] == 0 && adfGeoTransform[3] == 0 && adfGeoTransform[4] == 0 && adfGeoTransform[5] == 1); if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0) { CPLError( CE_Failure, CPLE_NotSupported, "HF2 driver does not support CreateCopy() from skewed or rotated dataset.\n"); return NULL; } GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); GDALDataType eReqDT; float fVertPres = (float) 0.01; if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16) { fVertPres = 1; eReqDT = GDT_Int16; } else eReqDT = GDT_Float32; /* -------------------------------------------------------------------- */ /* Read creation options */ /* -------------------------------------------------------------------- */ const char* pszCompressed = CSLFetchNameValue(papszOptions, "COMPRESS"); int bCompress = FALSE; if (pszCompressed) bCompress = CSLTestBoolean(pszCompressed); const char* pszVerticalPrecision = CSLFetchNameValue(papszOptions, "VERTICAL_PRECISION"); if (pszVerticalPrecision) { fVertPres = (float) CPLAtofM(pszVerticalPrecision); if (fVertPres <= 0) { CPLError(CE_Warning, CPLE_AppDefined, "Unsupported value for VERTICAL_PRECISION. Defaulting to 0.01"); fVertPres = (float) 0.01; } if (eReqDT == GDT_Int16 && fVertPres > 1) eReqDT = GDT_Float32; } const char* pszBlockSize = CSLFetchNameValue(papszOptions, "BLOCKSIZE"); int nTileSize = 256; if (pszBlockSize) { nTileSize = atoi(pszBlockSize); if (nTileSize < 8 || nTileSize > 4096) { CPLError(CE_Warning, CPLE_AppDefined, "Unsupported value for BLOCKSIZE. Defaulting to 256"); nTileSize = 256; } } /* -------------------------------------------------------------------- */ /* Parse source dataset georeferencing info */ /* -------------------------------------------------------------------- */ int nExtendedHeaderLen = 0; if (bHasGeoTransform) nExtendedHeaderLen += 58; const char* pszProjectionRef = poSrcDS->GetProjectionRef(); int nDatumCode = -2; int nUTMZone = 0; int bNorth = FALSE; int nEPSGCode = 0; int nExtentUnits = 1; if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0') { OGRSpatialReference oSRS; char* pszTemp = (char*) pszProjectionRef; if (oSRS.importFromWkt(&pszTemp) == OGRERR_NONE) { const char* pszValue = NULL; if( oSRS.GetAuthorityName( "GEOGCS|DATUM" ) != NULL && EQUAL(oSRS.GetAuthorityName( "GEOGCS|DATUM" ),"EPSG") ) nDatumCode = atoi(oSRS.GetAuthorityCode( "GEOGCS|DATUM" )); else if ((pszValue = oSRS.GetAttrValue("GEOGCS|DATUM")) != NULL) { if (strstr(pszValue, "WGS") && strstr(pszValue, "84")) nDatumCode = 6326; } nUTMZone = oSRS.GetUTMZone(&bNorth); } if( oSRS.GetAuthorityName( "PROJCS" ) != NULL && EQUAL(oSRS.GetAuthorityName( "PROJCS" ),"EPSG") ) nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" )); if( oSRS.IsGeographic() ) { nExtentUnits = 0; } else { double dfLinear = oSRS.GetLinearUnits(); if( ABS(dfLinear - 0.3048) < 0.0000001 ) nExtentUnits = 2; else if( ABS(dfLinear - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 ) nExtentUnits = 3; else nExtentUnits = 1; } } if (nDatumCode != -2) nExtendedHeaderLen += 26; if (nUTMZone != 0) nExtendedHeaderLen += 26; if (nEPSGCode) nExtendedHeaderLen += 26; /* -------------------------------------------------------------------- */ /* Create target file */ /* -------------------------------------------------------------------- */ CPLString osFilename; if (bCompress) { osFilename = "/vsigzip/"; osFilename += pszFilename; } else osFilename = pszFilename; VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "wb"); if (fp == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot create %s", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Write header */ /* -------------------------------------------------------------------- */ VSIFWriteL("HF2\0", 4, 1, fp); WriteShort(fp, 0); WriteInt(fp, nXSize); WriteInt(fp, nYSize); WriteShort(fp, (GInt16) nTileSize); WriteFloat(fp, fVertPres); float fHorizScale = (float) ((fabs(adfGeoTransform[1]) + fabs(adfGeoTransform[5])) / 2); WriteFloat(fp, fHorizScale); WriteInt(fp, nExtendedHeaderLen); /* -------------------------------------------------------------------- */ /* Write extended header */ /* -------------------------------------------------------------------- */ char szBlockName[16 + 1]; if (bHasGeoTransform) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-extents"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 34); WriteShort(fp, (GInt16) nExtentUnits); WriteDouble(fp, adfGeoTransform[0]); WriteDouble(fp, adfGeoTransform[0] + nXSize * adfGeoTransform[1]); WriteDouble(fp, adfGeoTransform[3] + nYSize * adfGeoTransform[5]); WriteDouble(fp, adfGeoTransform[3]); } if (nUTMZone != 0) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-utm"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) ((bNorth) ? nUTMZone : -nUTMZone)); } if (nDatumCode != -2) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-datum"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) nDatumCode); } if (nEPSGCode != 0) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-epsg-prj"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) nEPSGCode); } /* -------------------------------------------------------------------- */ /* Copy imagery */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nTileSize - 1) / nTileSize; int nYBlocks = (nYSize + nTileSize - 1) / nTileSize; void* pTileBuffer = (void*) VSIMalloc(nTileSize * nTileSize * (GDALGetDataTypeSize(eReqDT) / 8)); if (pTileBuffer == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory"); VSIFCloseL(fp); return NULL; } int i, j, k, l; CPLErr eErr = CE_None; for(j=0;j<nYBlocks && eErr == CE_None;j++) { for(i=0;i<nXBlocks && eErr == CE_None;i++) { int nReqXSize = MIN(nTileSize, nXSize - i * nTileSize); int nReqYSize = MIN(nTileSize, nYSize - j * nTileSize); eErr = poSrcDS->GetRasterBand(1)->RasterIO(GF_Read, i * nTileSize, MAX(0, nYSize - (j + 1) * nTileSize), nReqXSize, nReqYSize, pTileBuffer, nReqXSize, nReqYSize, eReqDT, 0, 0, NULL); if (eErr != CE_None) break; if (eReqDT == GDT_Int16) { WriteFloat(fp, 1); /* scale */ WriteFloat(fp, 0); /* offset */ for(k=0;k<nReqYSize;k++) { int nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; GByte nWordSize = 1; for(l=1;l<nReqXSize;l++) { int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; int nDiff = nVal - nLastVal; if (nDiff < -32768 || nDiff > 32767) { nWordSize = 4; break; } if (nDiff < -128 || nDiff > 127) nWordSize = 2; nLastVal = nVal; } VSIFWriteL(&nWordSize, 1, 1, fp); nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; WriteInt(fp, nLastVal); for(l=1;l<nReqXSize;l++) { int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; int nDiff = nVal - nLastVal; if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); signed char chDiff = (signed char)nDiff; VSIFWriteL(&chDiff, 1, 1, fp); } else if (nWordSize == 2) { CPLAssert(nDiff >= -32768 && nDiff <= 32767); WriteShort(fp, (short)nDiff); } else { WriteInt(fp, nDiff); } nLastVal = nVal; } } } else { float fMinVal = ((float*)pTileBuffer)[0]; float fMaxVal = fMinVal; for(k=1;k<nReqYSize*nReqXSize;k++) { float fVal = ((float*)pTileBuffer)[k]; if (fVal < fMinVal) fMinVal = fVal; if (fVal > fMaxVal) fMaxVal = fVal; } float fIntRange = (fMaxVal - fMinVal) / fVertPres; float fScale = (fMinVal == fMaxVal) ? 1 : (fMaxVal - fMinVal) / fIntRange; float fOffset = fMinVal; WriteFloat(fp, fScale); /* scale */ WriteFloat(fp, fOffset); /* offset */ for(k=0;k<nReqYSize;k++) { float fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; float fIntLastVal = (fLastVal - fOffset) / fScale; CPLAssert(fIntLastVal >= -2147483648.0f && fIntLastVal <= 2147483647.0f); int nLastVal = (int)fIntLastVal; GByte nWordSize = 1; for(l=1;l<nReqXSize;l++) { float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; float fIntVal = (fVal - fOffset) / fScale; CPLAssert(fIntVal >= -2147483648.0f && fIntVal <= 2147483647.0f); int nVal = (int)fIntVal; int nDiff = nVal - nLastVal; CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff); if (nDiff < -32768 || nDiff > 32767) { nWordSize = 4; break; } if (nDiff < -128 || nDiff > 127) nWordSize = 2; nLastVal = nVal; } VSIFWriteL(&nWordSize, 1, 1, fp); fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; fIntLastVal = (fLastVal - fOffset) / fScale; nLastVal = (int)fIntLastVal; WriteInt(fp, nLastVal); for(l=1;l<nReqXSize;l++) { float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; float fIntVal = (fVal - fOffset) / fScale; int nVal = (int)fIntVal; int nDiff = nVal - nLastVal; CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff); if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); signed char chDiff = (signed char)nDiff; VSIFWriteL(&chDiff, 1, 1, fp); } else if (nWordSize == 2) { CPLAssert(nDiff >= -32768 && nDiff <= 32767); WriteShort(fp, (short)nDiff); } else { WriteInt(fp, nDiff); } nLastVal = nVal; } } } if( pfnProgress && !pfnProgress( (j * nXBlocks + i + 1) * 1.0 / (nXBlocks * nYBlocks), NULL, pProgressData ) ) { eErr = CE_Failure; break; } } } CPLFree(pTileBuffer); VSIFCloseL(fp); if (eErr != CE_None) return NULL; return (GDALDataset*) GDALOpen(osFilename.c_str(), GA_ReadOnly); }
OGRErr OGRPGDumpLayer::CreateGeomField( OGRGeomFieldDefn *poGeomFieldIn, CPL_UNUSED int bApproxOK ) { OGRwkbGeometryType eType = poGeomFieldIn->GetType(); if( eType == wkbNone ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create geometry field of type wkbNone"); return OGRERR_FAILURE; } CPLString osCommand; OGRPGDumpGeomFieldDefn *poGeomField = new OGRPGDumpGeomFieldDefn( poGeomFieldIn ); /* -------------------------------------------------------------------- */ /* Do we want to "launder" the column names into Postgres */ /* friendly format? */ /* -------------------------------------------------------------------- */ if( bLaunderColumnNames ) { char *pszSafeName = poDS->LaunderName( poGeomField->GetNameRef() ); poGeomField->SetName( pszSafeName ); CPLFree( pszSafeName ); } OGRSpatialReference* poSRS = poGeomField->GetSpatialRef(); int nSRSId = nUnknownSRSId; if( nForcedSRSId != -2 ) nSRSId = nForcedSRSId; else if( poSRS != NULL ) { const char* pszAuthorityName = poSRS->GetAuthorityName(NULL); if( pszAuthorityName != NULL && EQUAL( pszAuthorityName, "EPSG" ) ) { /* Assume the EPSG Id is the SRS ID. Might be a wrong guess ! */ nSRSId = atoi( poSRS->GetAuthorityCode(NULL) ); } else { const char* pszGeogCSName = poSRS->GetAttrValue("GEOGCS"); if (pszGeogCSName != NULL && EQUAL(pszGeogCSName, "GCS_WGS_1984")) nSRSId = 4326; } } int nDimension = 3; if( wkbFlatten(eType) == eType ) nDimension = 2; poGeomField->nSRSId = nSRSId; poGeomField->nCoordDimension = nDimension; /* -------------------------------------------------------------------- */ /* Create the new field. */ /* -------------------------------------------------------------------- */ if (bCreateTable) { const char *pszGeometryType = OGRToOGCGeomType(poGeomField->GetType()); osCommand.Printf( "SELECT AddGeometryColumn(%s,%s,%s,%d,'%s',%d)", OGRPGDumpEscapeString(pszSchemaName).c_str(), OGRPGDumpEscapeString(poFeatureDefn->GetName()).c_str(), OGRPGDumpEscapeString(poGeomField->GetNameRef()).c_str(), nSRSId, pszGeometryType, nDimension ); poDS->Log(osCommand); if( bCreateSpatialIndexFlag ) { osCommand.Printf("CREATE INDEX %s ON %s USING GIST (%s)", OGRPGDumpEscapeColumnName( CPLSPrintf("%s_%s_geom_idx", GetName(), poGeomField->GetNameRef())).c_str(), pszSqlTableName, OGRPGDumpEscapeColumnName(poGeomField->GetNameRef()).c_str()); poDS->Log(osCommand); } } poFeatureDefn->AddGeomFieldDefn( poGeomField, FALSE ); return OGRERR_NONE; }
GDALJP2Box *GDALJP2Metadata::CreateGMLJP2( int nXSize, int nYSize ) { /* -------------------------------------------------------------------- */ /* This is a backdoor to let us embed a literal gmljp2 chunk */ /* supplied by the user as an external file. This is mostly */ /* for preparing test files with exotic contents. */ /* -------------------------------------------------------------------- */ if( CPLGetConfigOption( "GMLJP2OVERRIDE", NULL ) != NULL ) { VSILFILE *fp = VSIFOpenL( CPLGetConfigOption( "GMLJP2OVERRIDE",""), "r" ); char *pszGML = NULL; if( fp == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to open GMLJP2OVERRIDE file." ); return NULL; } VSIFSeekL( fp, 0, SEEK_END ); int nLength = (int) VSIFTellL( fp ); pszGML = (char *) CPLCalloc(1,nLength+1); VSIFSeekL( fp, 0, SEEK_SET ); VSIFReadL( pszGML, 1, nLength, fp ); VSIFCloseL( fp ); GDALJP2Box *apoGMLBoxes[2]; apoGMLBoxes[0] = GDALJP2Box::CreateLblBox( "gml.data" ); apoGMLBoxes[1] = GDALJP2Box::CreateLabelledXMLAssoc( "gml.root-instance", pszGML ); GDALJP2Box *poGMLData = GDALJP2Box::CreateAsocBox( 2, apoGMLBoxes); delete apoGMLBoxes[0]; delete apoGMLBoxes[1]; CPLFree( pszGML ); return poGMLData; } /* -------------------------------------------------------------------- */ /* Try do determine a PCS or GCS code we can use. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; char *pszWKTCopy = (char *) pszProjection; int nEPSGCode = 0; char szSRSName[100]; int bNeedAxisFlip = FALSE; if( oSRS.importFromWkt( &pszWKTCopy ) != OGRERR_NONE ) return NULL; if( oSRS.IsProjected() ) { const char *pszAuthName = oSRS.GetAuthorityName( "PROJCS" ); if( pszAuthName != NULL && EQUAL(pszAuthName,"epsg") ) { nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" )); } } else if( oSRS.IsGeographic() ) { const char *pszAuthName = oSRS.GetAuthorityName( "GEOGCS" ); if( pszAuthName != NULL && EQUAL(pszAuthName,"epsg") ) { nEPSGCode = atoi(oSRS.GetAuthorityCode( "GEOGCS" )); bNeedAxisFlip = TRUE; } } if( nEPSGCode != 0 ) sprintf( szSRSName, "urn:ogc:def:crs:EPSG::%d", nEPSGCode ); else strcpy( szSRSName, "gmljp2://xml/CRSDictionary.gml#ogrcrs1" ); /* -------------------------------------------------------------------- */ /* Prepare coverage origin and offset vectors. Take axis */ /* order into account if needed. */ /* -------------------------------------------------------------------- */ double adfOrigin[2]; double adfXVector[2]; double adfYVector[2]; adfOrigin[0] = adfGeoTransform[0] + adfGeoTransform[1] * 0.5 + adfGeoTransform[4] * 0.5; adfOrigin[1] = adfGeoTransform[3] + adfGeoTransform[2] * 0.5 + adfGeoTransform[5] * 0.5; adfXVector[0] = adfGeoTransform[1]; adfXVector[1] = adfGeoTransform[2]; adfYVector[0] = adfGeoTransform[4]; adfYVector[1] = adfGeoTransform[5]; if( bNeedAxisFlip && CSLTestBoolean( CPLGetConfigOption( "GDAL_IGNORE_AXIS_ORIENTATION", "FALSE" ) ) ) { bNeedAxisFlip = FALSE; CPLDebug( "GMLJP2", "Supressed axis flipping on write based on GDAL_IGNORE_AXIS_ORIENTATION." ); } if( bNeedAxisFlip ) { double dfTemp; CPLDebug( "GMLJP2", "Flipping GML coverage axis order." ); dfTemp = adfOrigin[0]; adfOrigin[0] = adfOrigin[1]; adfOrigin[1] = dfTemp; dfTemp = adfXVector[0]; adfXVector[0] = adfXVector[1]; adfXVector[1] = dfTemp; dfTemp = adfYVector[0]; adfYVector[0] = adfYVector[1]; adfYVector[1] = dfTemp; } /* -------------------------------------------------------------------- */ /* For now we hardcode for a minimal instance format. */ /* -------------------------------------------------------------------- */ CPLString osDoc; osDoc.Printf( "<gml:FeatureCollection\n" " xmlns:gml=\"http://www.opengis.net/gml\"\n" " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" " xsi:schemaLocation=\"http://www.opengeospatial.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlJP2Profile/1.0.0/gmlJP2Profile.xsd\">\n" " <gml:boundedBy>\n" " <gml:Null>withheld</gml:Null>\n" " </gml:boundedBy>\n" " <gml:featureMember>\n" " <gml:FeatureCollection>\n" " <gml:featureMember>\n" " <gml:RectifiedGridCoverage dimension=\"2\" gml:id=\"RGC0001\">\n" " <gml:rectifiedGridDomain>\n" " <gml:RectifiedGrid dimension=\"2\">\n" " <gml:limits>\n" " <gml:GridEnvelope>\n" " <gml:low>0 0</gml:low>\n" " <gml:high>%d %d</gml:high>\n" " </gml:GridEnvelope>\n" " </gml:limits>\n" " <gml:axisName>x</gml:axisName>\n" " <gml:axisName>y</gml:axisName>\n" " <gml:origin>\n" " <gml:Point gml:id=\"P0001\" srsName=\"%s\">\n" " <gml:pos>%.15g %.15g</gml:pos>\n" " </gml:Point>\n" " </gml:origin>\n" " <gml:offsetVector srsName=\"%s\">%.15g %.15g</gml:offsetVector>\n" " <gml:offsetVector srsName=\"%s\">%.15g %.15g</gml:offsetVector>\n" " </gml:RectifiedGrid>\n" " </gml:rectifiedGridDomain>\n" " <gml:rangeSet>\n" " <gml:File>\n" " <gml:fileName>gmljp2://codestream/0</gml:fileName>\n" " <gml:fileStructure>Record Interleaved</gml:fileStructure>\n" " </gml:File>\n" " </gml:rangeSet>\n" " </gml:RectifiedGridCoverage>\n" " </gml:featureMember>\n" " </gml:FeatureCollection>\n" " </gml:featureMember>\n" "</gml:FeatureCollection>\n", nXSize-1, nYSize-1, szSRSName, adfOrigin[0], adfOrigin[1], szSRSName, adfXVector[0], adfXVector[1], szSRSName, adfYVector[0], adfYVector[1] ); /* -------------------------------------------------------------------- */ /* If we need a user defined CRSDictionary entry, prepare it */ /* here. */ /* -------------------------------------------------------------------- */ CPLString osDictBox; if( nEPSGCode == 0 ) { char *pszGMLDef = NULL; if( oSRS.exportToXML( &pszGMLDef, NULL ) == OGRERR_NONE ) { osDictBox.Printf( "<gml:Dictionary gml:id=\"CRSU1\" \n" " xmlns:gml=\"http://www.opengis.net/gml\"\n" " xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" " <gml:dictionaryEntry>\n" "%s\n" " </gml:dictionaryEntry>\n" "</gml:Dictionary>\n", pszGMLDef ); } CPLFree( pszGMLDef ); } /* -------------------------------------------------------------------- */ /* Setup the gml.data label. */ /* -------------------------------------------------------------------- */ GDALJP2Box *apoGMLBoxes[5]; int nGMLBoxes = 0; apoGMLBoxes[nGMLBoxes++] = GDALJP2Box::CreateLblBox( "gml.data" ); /* -------------------------------------------------------------------- */ /* Setup gml.root-instance. */ /* -------------------------------------------------------------------- */ apoGMLBoxes[nGMLBoxes++] = GDALJP2Box::CreateLabelledXMLAssoc( "gml.root-instance", osDoc ); /* -------------------------------------------------------------------- */ /* Add optional dictionary. */ /* -------------------------------------------------------------------- */ if( strlen(osDictBox) > 0 ) apoGMLBoxes[nGMLBoxes++] = GDALJP2Box::CreateLabelledXMLAssoc( "CRSDictionary.gml", osDictBox ); /* -------------------------------------------------------------------- */ /* Bundle gml.data boxes into an association. */ /* -------------------------------------------------------------------- */ GDALJP2Box *poGMLData = GDALJP2Box::CreateAsocBox( nGMLBoxes, apoGMLBoxes); /* -------------------------------------------------------------------- */ /* Cleanup working boxes. */ /* -------------------------------------------------------------------- */ while( nGMLBoxes > 0 ) delete apoGMLBoxes[--nGMLBoxes]; return poGMLData; }
int OGRGeoPackageDataSource::GetSrsId(const OGRSpatialReference * cpoSRS) { char *pszWKT = NULL; char *pszSQL = NULL; int nSRSId = UNDEFINED_SRID; const char* pszAuthorityName; int nAuthorityCode = 0; OGRErr err; OGRBoolean bCanUseAuthorityCode = FALSE; if( cpoSRS == NULL ) return UNDEFINED_SRID; OGRSpatialReference *poSRS = cpoSRS->Clone(); poSRS->morphFromESRI(); pszAuthorityName = poSRS->GetAuthorityName(NULL); if ( pszAuthorityName == NULL || strlen(pszAuthorityName) == 0 ) { // Try to force identify an EPSG code poSRS->AutoIdentifyEPSG(); pszAuthorityName = poSRS->GetAuthorityName(NULL); if (pszAuthorityName != NULL && EQUAL(pszAuthorityName, "EPSG")) { const char* pszAuthorityCode = poSRS->GetAuthorityCode(NULL); if ( pszAuthorityCode != NULL && strlen(pszAuthorityCode) > 0 ) { /* Import 'clean' SRS */ poSRS->importFromEPSG( atoi(pszAuthorityCode) ); pszAuthorityName = poSRS->GetAuthorityName(NULL); } } } // Check whether the EPSG authority code is already mapped to a // SRS ID. if ( pszAuthorityName != NULL && strlen(pszAuthorityName) > 0 ) { // For the root authority name 'EPSG', the authority code // should always be integral nAuthorityCode = atoi( poSRS->GetAuthorityCode(NULL) ); pszSQL = sqlite3_mprintf( "SELECT srs_id FROM gpkg_spatial_ref_sys WHERE " "upper(organization) = upper('%q') AND organization_coordsys_id = %d", pszAuthorityName, nAuthorityCode ); nSRSId = SQLGetInteger(m_poDb, pszSQL, &err); sqlite3_free(pszSQL); // Got a match? Return it! if ( OGRERR_NONE == err ) { delete poSRS; return nSRSId; } // No match, but maybe we can use the nAuthorityCode as the nSRSId? pszSQL = sqlite3_mprintf( "SELECT Count(*) FROM gpkg_spatial_ref_sys WHERE " "srs_id = %d", nAuthorityCode ); // Yep, we can! if ( ! SQLGetInteger(m_poDb, pszSQL, &err) && err == OGRERR_NONE ) bCanUseAuthorityCode = TRUE; } // Translate SRS to WKT. if( poSRS->exportToWkt( &pszWKT ) != OGRERR_NONE ) { delete poSRS; CPLFree(pszWKT); return UNDEFINED_SRID; } // Reuse the authority code number as SRS_ID if we can if ( bCanUseAuthorityCode ) { nSRSId = nAuthorityCode; } // Otherwise, generate a new SRS_ID number (max + 1) else { // Get the current maximum srid in the srs table. int nMaxSRSId = SQLGetInteger(m_poDb, "SELECT MAX(srs_id) FROM gpkg_spatial_ref_sys", &err); if ( OGRERR_NONE != err ) { CPLFree(pszWKT); delete poSRS; return UNDEFINED_SRID; } nSRSId = nMaxSRSId + 1; } // Add new SRS row to gpkg_spatial_ref_sys if( pszAuthorityName != NULL && nAuthorityCode > 0 ) { pszSQL = sqlite3_mprintf( "INSERT INTO gpkg_spatial_ref_sys " "(srs_name,srs_id,organization,organization_coordsys_id,definition) " "VALUES ('%s', %d, upper('%s'), %d, '%q')", GetSrsName(poSRS), nSRSId, pszAuthorityName, nAuthorityCode, pszWKT ); } else { pszSQL = sqlite3_mprintf( "INSERT INTO gpkg_spatial_ref_sys " "(srs_name,srs_id,organization,organization_coordsys_id,definition) " "VALUES ('%s', %d, upper('%s'), %d, '%q')", GetSrsName(poSRS), nSRSId, "NONE", nSRSId, pszWKT ); } // Add new row to gpkg_spatial_ref_sys err = SQLCommand(m_poDb, pszSQL); // Free everything that was allocated. CPLFree(pszWKT); sqlite3_free(pszSQL); delete poSRS; return nSRSId; }
static OGRErr importGeogCSFromXML(OGRSpatialReference *poSRS, CPLXMLNode *psCRS) { const char *pszGeogName, *pszDatumName, *pszEllipsoidName, *pszPMName; double dfSemiMajor, dfInvFlattening, dfPMOffset = 0.0; /* -------------------------------------------------------------------- */ /* Set the GEOGCS name from the srsName. */ /* -------------------------------------------------------------------- */ pszGeogName = CPLGetXMLValue(psCRS, "srsName", "Unnamed GeogCS"); /* -------------------------------------------------------------------- */ /* If we don't seem to have a detailed coordinate system */ /* definition, check if we can define based on an EPSG code. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psDatum; psDatum = CPLGetXMLNode(psCRS, "usesGeodeticDatum.GeodeticDatum"); if (psDatum == NULL) { OGRSpatialReference oIdSRS; oIdSRS.SetLocalCS("dummy"); importXMLAuthority(psCRS, &oIdSRS, "srsID", "LOCAL_CS"); if (oIdSRS.GetAuthorityCode("LOCAL_CS") != NULL && oIdSRS.GetAuthorityName("LOCAL_CS") != NULL && EQUAL(oIdSRS.GetAuthorityName("LOCAL_CS"), "EPSG")) { return poSRS->importFromEPSG( atoi(oIdSRS.GetAuthorityCode("LOCAL_CS"))); } } /* -------------------------------------------------------------------- */ /* Get datum name. */ /* -------------------------------------------------------------------- */ pszDatumName = CPLGetXMLValue(psDatum, "datumName", "Unnamed Datum"); /* -------------------------------------------------------------------- */ /* Get ellipsoid information. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psE; psE = CPLGetXMLNode(psDatum, "usesEllipsoid.Ellipsoid"); pszEllipsoidName = CPLGetXMLValue(psE, "ellipsoidName", "Unnamed Ellipsoid"); dfSemiMajor = getNormalizedValue(psE, "semiMajorAxis", "Linear", SRS_WGS84_SEMIMAJOR); dfInvFlattening = getNormalizedValue(psE, "secondDefiningParameter.inverseFlattening", "Unitless", 0.0); if (dfInvFlattening == 0.0) { CPLError(CE_Failure, CPLE_AppDefined, "Ellipsoid inverseFlattening corrupt or missing."); return OGRERR_CORRUPT_DATA; } /* -------------------------------------------------------------------- */ /* Get the prime meridian. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psPM; psPM = CPLGetXMLNode(psDatum, "usesPrimeMeridian.PrimeMeridian"); if (psPM == NULL) { pszPMName = "Greenwich"; dfPMOffset = 0.0; } else { pszPMName = CPLGetXMLValue(psPM, "meridianName", "Unnamed Prime Meridian"); dfPMOffset = getNormalizedValue(psPM, "greenwichLongitude.angle", "Angular", 0.0); } /* -------------------------------------------------------------------- */ /* Set the geographic definition. */ /* -------------------------------------------------------------------- */ poSRS->SetGeogCS(pszGeogName, pszDatumName, pszEllipsoidName, dfSemiMajor, dfInvFlattening, pszPMName, dfPMOffset); /* -------------------------------------------------------------------- */ /* Look for angular units. We don't check that all axes match */ /* at this time. */ /* -------------------------------------------------------------------- */ #ifdef notdef CPLXMLNode *psAxis; psAxis = CPLGetXMLNode(psGeo2DCRS, "EllipsoidalCoordinateSystem.CoordinateAxis"); importXMLUnits(psAxis, "AngularUnit", poSRS, "GEOGCS"); #endif /* -------------------------------------------------------------------- */ /* Can we set authorities for any of the levels? */ /* -------------------------------------------------------------------- */ importXMLAuthority(psCRS, poSRS, "srsID", "GEOGCS"); importXMLAuthority(psDatum, poSRS, "datumID", "GEOGCS|DATUM"); importXMLAuthority(psE, poSRS, "ellipsoidID", "GEOGCS|DATUM|SPHEROID"); importXMLAuthority(psDatum, poSRS, "usesPrimeMeridian.PrimeMeridian.meridianID", "GEOGCS|PRIMEM"); poSRS->Fixup(); return OGRERR_NONE; }
OGRSpatialReference *OGRMySQLDataSource::FetchSRS( int nId ) { if( nId < 0 ) return nullptr; /* -------------------------------------------------------------------- */ /* First, we look through our SRID cache, is it there? */ /* -------------------------------------------------------------------- */ for( int i = 0; i < nKnownSRID; i++ ) { if( panSRID[i] == nId ) return papoSRS[i]; } OGRSpatialReference *poSRS = nullptr; // make sure to attempt to free any old results MYSQL_RES *hResult = mysql_store_result( GetConn() ); if( hResult != nullptr ) mysql_free_result( hResult ); hResult = nullptr; char szCommand[128] = {}; if( GetMajorVersion() < 8 || IsMariaDB() ) { snprintf( szCommand, sizeof(szCommand), "SELECT srtext FROM spatial_ref_sys WHERE srid = %d", nId ); } else { snprintf( szCommand, sizeof(szCommand), "SELECT DEFINITION FROM INFORMATION_SCHEMA.ST_SPATIAL_REFERENCE_SYSTEMS WHERE SRS_ID = %d", nId ); } if( !mysql_query( GetConn(), szCommand ) ) hResult = mysql_store_result( GetConn() ); char *pszWKT = nullptr; char **papszRow = nullptr; if( hResult != nullptr ) papszRow = mysql_fetch_row( hResult ); if( papszRow != nullptr && papszRow[0] != nullptr ) { pszWKT = CPLStrdup(papszRow[0]); } if( hResult != nullptr ) mysql_free_result( hResult ); hResult = nullptr; poSRS = new OGRSpatialReference(); poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); if( pszWKT == nullptr || poSRS->importFromWkt( pszWKT ) != OGRERR_NONE ) { delete poSRS; poSRS = nullptr; } CPLFree(pszWKT); if( poSRS ) { // The WKT found in MySQL 8 ST_SPATIAL_REFERENCE_SYSTEMS is not // compatible of what GDAL understands. const char* pszAuthorityName = poSRS->GetAuthorityName(nullptr); const char* pszAuthorityCode = poSRS->GetAuthorityCode(nullptr); if (pszAuthorityName != nullptr && EQUAL(pszAuthorityName, "EPSG") && pszAuthorityCode != nullptr && strlen(pszAuthorityCode) > 0 ) { /* Import 'clean' SRS */ poSRS->importFromEPSG( atoi(pszAuthorityCode) ); } } /* -------------------------------------------------------------------- */ /* Add to the cache. */ /* -------------------------------------------------------------------- */ panSRID = (int *) CPLRealloc(panSRID,sizeof(int) * (nKnownSRID+1) ); papoSRS = (OGRSpatialReference **) CPLRealloc(papoSRS, sizeof(void*) * (nKnownSRID + 1) ); panSRID[nKnownSRID] = nId; papoSRS[nKnownSRID] = poSRS; nKnownSRID ++; return poSRS; }