void set_geotif_header(char *tiff_fname, char *utm_zone, float xoff, float yoff, float scale) { // open tiff file TIFF *tif = XTIFFOpen(tiff_fname, "r+"); if (!tif) fail("failed in XTIFFOpen\n"); GTIF *gtif = GTIFNew(tif); if (!gtif) fail("failed in GTIFNew\n"); // write TIFF tags double pixsize[3] = {scale, scale, 0.0}; TIFFSetField(tif, GTIFF_PIXELSCALE, 3, pixsize); double tiepoint[6] = {0.0, 0.0, 0.0, xoff, yoff, 0.0}; TIFFSetField(tif, GTIFF_TIEPOINTS, 6, tiepoint); // write GEOTIFF keys int utm_ind = get_utm_zone_index_for_geotiff(utm_zone); GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, utm_ind); GTIFWriteKeys(gtif); // free and close GTIFFree(gtif); XTIFFClose(tif); }
void SetLinearUnitCitation(GTIF* psGTIF, char* pszLinearUOMName) { char szName[512]; CPLString osCitation; int n = 0; if( GTIFKeyGet( psGTIF, PCSCitationGeoKey, szName, 0, sizeof(szName) ) ) n = strlen(szName); if(n>0) { osCitation = szName; if(osCitation[n-1] != '|') osCitation += "|"; osCitation += "LUnits = "; osCitation += pszLinearUOMName; osCitation += "|"; } else { osCitation = "LUnits = "; osCitation += pszLinearUOMName; } GTIFKeySet( psGTIF, PCSCitationGeoKey, TYPE_ASCII, 0, osCitation.c_str() ); return; }
void SetGeogCSCitation(GTIF * psGTIF, OGRSpatialReference *poSRS, char* angUnitName, int nDatum, short nSpheroid) { int bRewriteGeogCitation = FALSE; char szName[256]; CPLString osCitation; size_t n = 0; if( GTIFKeyGet( psGTIF, GeogCitationGeoKey, szName, 0, sizeof(szName) ) ) n = strlen(szName); if (n == 0) return; if(!EQUALN(szName, "GCS Name = ", strlen("GCS Name = "))) { osCitation = "GCS Name = "; osCitation += szName; } else { osCitation = szName; } if(nDatum == KvUserDefined ) { const char* datumName = poSRS->GetAttrValue( "DATUM" ); if(datumName && strlen(datumName) > 0) { osCitation += "|Datum = "; osCitation += datumName; bRewriteGeogCitation = TRUE; } } if(nSpheroid == KvUserDefined ) { const char* spheroidName = poSRS->GetAttrValue( "SPHEROID" ); if(spheroidName && strlen(spheroidName) > 0) { osCitation += "|Ellipsoid = "; osCitation += spheroidName; bRewriteGeogCitation = TRUE; } } const char* primemName = poSRS->GetAttrValue( "PRIMEM" ); if(primemName && strlen(primemName) > 0) { osCitation += "|Primem = "; osCitation += primemName; bRewriteGeogCitation = TRUE; double primemValue = poSRS->GetPrimeMeridian(NULL); if(angUnitName && !EQUAL(angUnitName, "Degree")) { double aUnit = poSRS->GetAngularUnits(NULL); primemValue *= aUnit; } GTIFKeySet( psGTIF, GeogPrimeMeridianLongGeoKey, TYPE_DOUBLE, 1, primemValue ); } if(angUnitName && strlen(angUnitName) > 0 && !EQUAL(angUnitName, "Degree")) { osCitation += "|AUnits = "; osCitation += angUnitName; bRewriteGeogCitation = TRUE; } if (osCitation[strlen(osCitation) - 1] != '|') osCitation += "|"; if (bRewriteGeogCitation) GTIFKeySet( psGTIF, GeogCitationGeoKey, TYPE_ASCII, 0, osCitation.c_str() ); return; }
static int ReadKey(GTIF *gt, GTIFReadMethod scan, void *aux) { tagtype_t ktype; int count,outcount; int vals_now,i; geokey_t key; int icode; pinfo_t code; short *sptr; char name[1000]; char type[20]; double data[100]; double *dptr; char *vptr; int num; char message[2048]; scan(message,aux); if (!strncmp(message,FMT_KEYEND,8)) return 0; num=sscanf(message,"%[^( ] (%[^,],%d):\n",name,type,&count); if (num!=3) return StringError(message); vptr = message; FINDCHAR(vptr,':'); if (!*vptr) return StringError(message); vptr+=2; if( GTIFKeyCode(name) < 0 ) return StringError(name); else key = (geokey_t) GTIFKeyCode(name); if( GTIFTypeCode(type) < 0 ) return StringError(type); else ktype = (tagtype_t) GTIFTypeCode(type); /* skip white space */ SKIPWHITE(vptr); if (!*vptr) return StringError(message); switch (ktype) { case TYPE_ASCII: { char *cdata; int out_char = 0; FINDCHAR(vptr,'"'); if (!*vptr) return StringError(message); cdata = (char *) _GTIFcalloc( count+1 ); vptr++; while( out_char < count-1 ) { if( *vptr == '\0' ) break; else if( vptr[0] == '\\' && vptr[1] == 'n' ) { cdata[out_char++] = '\n'; vptr += 2; } else if( vptr[0] == '\\' && vptr[1] == '\\' ) { cdata[out_char++] = '\\'; vptr += 2; } else cdata[out_char++] = *(vptr++); } if( out_char < count-1 ) return StringError(message); if( *vptr != '"' ) return StringError(message); cdata[count-1] = '\0'; GTIFKeySet(gt,key,ktype,count,cdata); _GTIFFree( cdata ); } break; case TYPE_DOUBLE: outcount = count; for (dptr = data; count > 0; count-= vals_now) { vals_now = count > 3? 3: count; for (i=0; i<vals_now; i++,dptr++) { if (!sscanf(vptr,"%lg" ,dptr)) StringError(vptr); FINDCHAR(vptr,' '); SKIPWHITE(vptr); } if (vals_now<count) { scan(message,aux); vptr = message; } } if (outcount==1) GTIFKeySet(gt,key,ktype,outcount,data[0]); else GTIFKeySet(gt,key,ktype,outcount,data); break; case TYPE_SHORT: if (count==1) { icode = GTIFValueCode(key,vptr); if (icode < 0) return StringError(vptr); code = (pinfo_t) icode; GTIFKeySet(gt,key,ktype,count,code); } else /* multi-valued short - no such thing yet */ { char* cdata; memcpy(&cdata, &data, sizeof(void*)); sptr = (short *)cdata; outcount = count; for (; count > 0; count-= vals_now) { vals_now = count > 3? 3: count; for (i=0; i<vals_now; i++,sptr++) { int work_int; /* note: FMT_SHORT (%11hd) not supported on IRIX */ sscanf(message,"%11d",&work_int); *sptr = (short) work_int; scan(message,aux); } if (vals_now<count) { scan(message,aux); vptr = message; } } GTIFKeySet(gt,key,ktype,outcount,sptr); } break; default: return -1; } return 1; }
void SetUpGeoKeys(GTIF *gtif) { GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic); GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea); GTIFKeySet(gtif, GTCitationGeoKey, TYPE_ASCII, 0, "Just An Example"); GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, KvUserDefined); GTIFKeySet(gtif, GeogCitationGeoKey, TYPE_ASCII, 0, "Everest Ellipsoid Used."); GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, Angular_Degree); GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, Linear_Meter); GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT, 1, KvUserDefined); GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, Ellipse_Everest_1830_1967_Definition); GTIFKeySet(gtif, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1, (double)6377298.556); GTIFKeySet(gtif, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1, (double)300.8017); }
bool TiffDetails::addGeoKeys(TIFF* pOut, int width, int height, const SessionItem *pItem) { if ((pOut == NULL) || (width == 0) || (height == 0)) { return false; } const View* pInputView = dynamic_cast<const View*>(pItem); if (pInputView == NULL) { return false; } RasterElement* pGeoreferencedRaster = NULL; // First raster element we find with georeferencing information const ProductView* pView = dynamic_cast<const ProductView*>(pInputView); if (pView != NULL) { AnnotationLayer* pAnno = pView->getLayoutLayer(); if (pAnno == NULL) { return false; } /* NOTE: If we find more than one SpatialDataView with a georeferenced RasterElement, we will only provide geo-data for the FIRST one - because two views could theoretically screw up the geo-data if one is in Australia and the other in Canada. */ // get all the view objects std::list<GraphicObject*> objs; pAnno->getObjects(VIEW_OBJECT, objs); // for every object, find the data set with a geocoord matrix for (std::list<GraphicObject*>::iterator it = objs.begin(); it != objs.end(); ++it) { GraphicObject* pObj = *it; if (pObj != NULL) { SpatialDataView* pSpView = dynamic_cast<SpatialDataView*>(pObj->getObjectView()); if (pSpView != NULL) { LayerList* pLayerList = pSpView->getLayerList(); if (pLayerList != NULL) { RasterElement* pRaster = pLayerList->getPrimaryRasterElement(); if (pRaster != NULL && pRaster->isGeoreferenced()) { pGeoreferencedRaster = pRaster; break; } } } } } } const SpatialDataView* pSpView = dynamic_cast<const SpatialDataView*>(pInputView); if (pSpView != NULL) { LayerList* pLayerList = pSpView->getLayerList(); if (pLayerList != NULL) { RasterElement* pRaster = pLayerList->getPrimaryRasterElement(); if (pRaster != NULL && pRaster->isGeoreferenced()) { pGeoreferencedRaster = pRaster; } } } if (pGeoreferencedRaster == NULL) { return false; } GTIF* pGtif = GTIFNew(pOut); if (pGtif == NULL) { return false; } LocationType lowerLeft; LocationType upperLeft; LocationType upperRight; LocationType lowerRight; pInputView->getVisibleCorners(lowerLeft, upperLeft, upperRight, lowerRight); LocationType latLong; //get the lat/long's (0,0) latLong = pGeoreferencedRaster->convertPixelToGeocoord(upperLeft); double ll1y = latLong.mY; //delta long double ll1x = latLong.mX; //delta lat latLong = pGeoreferencedRaster->convertPixelToGeocoord(upperRight); double ll2y = latLong.mY; //long double ll2x = latLong.mX; //lat latLong = pGeoreferencedRaster->convertPixelToGeocoord(lowerLeft); double ll3y = latLong.mY; //long double ll3x = latLong.mX; //lat //compute transformation Matrix values //added slight modification, must divide by magnitude double a = (ll2y - ll1y) / width; double b = (ll3y - ll1y) / height; double d = (ll1y); double e = (ll2x - ll1x) / width; double f = (ll3x - ll1x) / height; double h = (ll1x); double tMatrix[16] = { a, b, 0.0, d, e, f, 0.0, h, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 }; TIFFSetField(pOut, GTIFF_TRANSMATRIX, 16, tMatrix); GTIFKeySet(pGtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea); GTIFKeySet(pGtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic); GTIFKeySet(pGtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84); // Here we violate the GTIF abstraction to retarget on another file. // We should just have a function for copying tags from one GTIF object // to another. pGtif->gt_tif = pOut; pGtif->gt_flags |= FLAG_FILE_MODIFIED; // Install keys and tags GTIFWriteKeys(pGtif); GTIFFree(pGtif); return true; }