28 #include "imageclasses/ImgReaderGdal.h" 29 #include "imageclasses/ImgWriterOgr.h" 30 #include "base/Optionpk.h" 31 #include "algorithms/StatFactory.h" 34 #define PI 3.1415926535897932384626433832795 117 enum RULE_TYPE {point=0, mean=1, proportion=2, custom=3, min=4, max=5, mode=6, centroid=7, sum=8, median=9, stdev=10, percentile=11, count=12, allpoints=13};
122 int main(
int argc,
char *argv[])
124 Optionpk<string> image_opt(
"i",
"input",
"Raster input dataset containing band information");
125 Optionpk<string> sample_opt(
"s",
"sample",
"OGR vector dataset with features to be extracted from input data. Output will contain features with input band information included. Sample image can also be GDAL raster dataset.");
126 Optionpk<string> layer_opt(
"ln",
"ln",
"Layer name(s) in sample (leave empty to select all)");
127 Optionpk<unsigned int> random_opt(
"rand",
"random",
"Create simple random sample of points. Provide number of points to generate");
128 Optionpk<double> grid_opt(
"grid",
"grid",
"Create systematic grid of points. Provide cell grid size (in projected units, e.g,. m)");
130 Optionpk<int> class_opt(
"c",
"class",
"Class(es) to extract from input sample image. Leave empty to extract all valid data pixels from sample dataset. Make sure to set classes if rule is set to mode, proportion or count");
131 Optionpk<float> threshold_opt(
"t",
"threshold",
"Probability threshold for selecting samples (randomly). Provide probability in percentage (>0) or absolute (<0). Use a single threshold per vector sample layer. If using raster land cover maps as a sample dataset, you can provide a threshold value for each class (e.g. -t 80 -t 60). Use value 100 to select all pixels for selected class(es)", 100);
132 Optionpk<double> percentile_opt(
"perc",
"perc",
"Percentile value used for rule percentile",95);
133 Optionpk<string> ogrformat_opt(
"f",
"f",
"Output sample dataset format",
"SQLite");
134 Optionpk<string> ftype_opt(
"ft",
"ftype",
"Field type (only Real or Integer)",
"Real");
135 Optionpk<int> band_opt(
"b",
"band",
"Band index(es) to extract (0 based). Leave empty to use all bands");
138 Optionpk<string> rule_opt(
"r",
"rule",
"Rule how to report image information per feature (only for vector sample). point (single point within polygon), allpoints (all points within polygon), centroid, mean, stdev, median, proportion, count, min, max, mode, sum, percentile.",
"centroid");
139 Optionpk<double> srcnodata_opt(
"srcnodata",
"srcnodata",
"Invalid value(s) for input image");
140 Optionpk<int> bndnodata_opt(
"bndnodata",
"bndnodata",
"Band(s) in input image to check if pixel is valid (used for srcnodata)", 0);
141 Optionpk<float> polythreshold_opt(
"tp",
"thresholdPolygon",
"(absolute) threshold for selecting samples in each polygon");
142 Optionpk<short> buffer_opt(
"buf",
"buffer",
"Buffer for calculating statistics for point features (in number of pixels) ",0);
143 Optionpk<bool> disc_opt(
"circ",
"circular",
"Use a circular disc kernel buffer (for vector point sample datasets only, use in combination with buffer option)",
false);
144 Optionpk<short> verbose_opt(
"v",
"verbose",
"Verbose mode if > 0", 0,2);
146 bstart_opt.setHide(1);
148 bndnodata_opt.setHide(1);
149 srcnodata_opt.setHide(1);
150 polythreshold_opt.setHide(1);
151 percentile_opt.setHide(1);
152 buffer_opt.setHide(1);
157 doProcess=image_opt.retrieveOption(argc,argv);
158 sample_opt.retrieveOption(argc,argv);
159 layer_opt.retrieveOption(argc,argv);
160 random_opt.retrieveOption(argc,argv);
161 grid_opt.retrieveOption(argc,argv);
162 output_opt.retrieveOption(argc,argv);
163 class_opt.retrieveOption(argc,argv);
164 threshold_opt.retrieveOption(argc,argv);
165 percentile_opt.retrieveOption(argc,argv);
166 ogrformat_opt.retrieveOption(argc,argv);
167 ftype_opt.retrieveOption(argc,argv);
168 band_opt.retrieveOption(argc,argv);
169 bstart_opt.retrieveOption(argc,argv);
170 bend_opt.retrieveOption(argc,argv);
171 rule_opt.retrieveOption(argc,argv);
172 bndnodata_opt.retrieveOption(argc,argv);
173 srcnodata_opt.retrieveOption(argc,argv);
174 polythreshold_opt.retrieveOption(argc,argv);
175 buffer_opt.retrieveOption(argc,argv);
176 disc_opt.retrieveOption(argc,argv);
177 verbose_opt.retrieveOption(argc,argv);
179 catch(
string predefinedString){
180 std::cout << predefinedString << std::endl;
185 cout <<
"Usage: pkextractogr -i input [-s sample | -rand number | -grid size] -o output" << endl;
187 std::cout <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
191 std::map<std::string, rule::RULE_TYPE> ruleMap;
192 std::map<std::string, std::string> fieldMap;
194 ruleMap[
"point"]=rule::point;
195 ruleMap[
"centroid"]=rule::centroid;
196 ruleMap[
"mean"]=rule::mean;
197 ruleMap[
"stdev"]=rule::stdev;
198 ruleMap[
"median"]=rule::median;
199 ruleMap[
"proportion"]=rule::proportion;
200 ruleMap[
"count"]=rule::count;
201 ruleMap[
"min"]=rule::min;
202 ruleMap[
"max"]=rule::max;
203 ruleMap[
"custom"]=rule::custom;
204 ruleMap[
"mode"]=rule::mode;
205 ruleMap[
"sum"]=rule::sum;
206 ruleMap[
"percentile"]=rule::percentile;
207 ruleMap[
"allpoints"]=rule::allpoints;
209 fieldMap[
"point"]=
"point";
210 fieldMap[
"centroid"]=
"cntrd";
211 fieldMap[
"mean"]=
"mean";
212 fieldMap[
"stdev"]=
"stdev";
213 fieldMap[
"median"]=
"median";
214 fieldMap[
"proportion"]=
"prop";
215 fieldMap[
"count"]=
"count";
216 fieldMap[
"min"]=
"min";
217 fieldMap[
"max"]=
"max";
218 fieldMap[
"custom"]=
"custom";
219 fieldMap[
"mode"]=
"mode";
220 fieldMap[
"sum"]=
"sum";
221 fieldMap[
"percentile"]=
"perc";
222 fieldMap[
"allpoints"]=
"allp";
224 if(srcnodata_opt.size()){
225 while(srcnodata_opt.size()<bndnodata_opt.size())
226 srcnodata_opt.push_back(srcnodata_opt[0]);
227 stat.setNoDataValues(srcnodata_opt);
231 std::cout << class_opt << std::endl;
233 unsigned long int nsample=0;
234 unsigned long int ntotalvalid=0;
235 unsigned long int ntotalinvalid=0;
239 if(image_opt.empty()){
240 std::cerr <<
"No image dataset provided (use option -i). Use --help for help information";
243 if(output_opt.empty()){
244 std::cerr <<
"No output dataset provided (use option -o). Use --help for help information";
248 imgReader.
open(image_opt[0],GA_ReadOnly);
250 catch(std::string errorstring){
251 std::cout << errorstring << std::endl;
256 if(find(rule_opt.begin(),rule_opt.end(),
"allpoints")!=rule_opt.end()){
259 rule_opt.push_back(
"allpoints");
264 if(bstart_opt.size()){
265 if(bend_opt.size()!=bstart_opt.size()){
266 string errorstring=
"Error: options for start and end band indexes must be provided as pairs, missing end band";
270 for(
int ipair=0;ipair<bstart_opt.size();++ipair){
271 if(bend_opt[ipair]<=bstart_opt[ipair]){
272 string errorstring=
"Error: index for end band must be smaller then start band";
275 for(
int iband=bstart_opt[ipair];iband<=bend_opt[ipair];++iband)
276 band_opt.push_back(iband);
281 cerr << error << std::endl;
285 int nband=(band_opt.size()) ? band_opt.size() : imgReader.
nrOfBand();
286 if(class_opt.size()){
288 cerr <<
"Warning: using only first band or multiband image" << endl;
291 band_opt.push_back(0);
296 std::cout <<
"Number of bands in input image: " << imgReader.
nrOfBand() << std::endl;
298 OGRFieldType fieldType;
299 int ogr_typecount=11;
301 std::cout <<
"field and label types can be: ";
302 for(
int iType = 0; iType < ogr_typecount; ++iType){
304 std::cout <<
" " << OGRFieldDefn::GetFieldTypeName((OGRFieldType)iType);
305 if( OGRFieldDefn::GetFieldTypeName((OGRFieldType)iType) != NULL
306 && EQUAL(OGRFieldDefn::GetFieldTypeName((OGRFieldType)iType),
307 ftype_opt[0].c_str()))
308 fieldType=(OGRFieldType) iType;
316 std::cout << std::endl <<
"field type is: " << OGRFieldDefn::GetFieldTypeName(fieldType) << std::endl;
319 cerr <<
"field type " << OGRFieldDefn::GetFieldTypeName(fieldType) <<
" not supported" << std::endl;
324 const char* pszMessage;
325 void* pProgressArg=NULL;
326 GDALProgressFunc pfnProgress=GDALTermProgress;
330 bool sampleIsRaster=
false;
331 bool sampleIsVirtual=
false;
336 if(sample_opt.size()){
338 sampleReaderOgr.open(sample_opt[0]);
340 catch(
string errorString){
347 sampleWriterOgr.open(
"/vsimem/virtual",ogrformat_opt[0]);
348 char **papszOptions=NULL;
349 sampleIsVirtual=
true;
351 if(random_opt.size()){
353 double ulx,uly,lrx,lry;
356 sampleWriterOgr.createLayer(
"points", imgReader.
getProjection(), wkbPoint, papszOptions);
359 for(ipoint=0;ipoint<random_opt[0];++ipoint){
360 OGRFeature *pointFeature;
361 pointFeature=sampleWriterOgr.createFeature();
362 double theX=ulx+
static_cast<double>(rand())/(RAND_MAX)*(lrx-ulx);
363 double theY=uly-
static_cast<double>(rand())/(RAND_MAX)*(uly-lry);
366 pointFeature->SetGeometry( &pt );
367 if(sampleWriterOgr.createFeature(pointFeature) != OGRERR_NONE ){
368 string errorString=
"Failed to create feature in vector dataset";
374 string errorString=
"Error: no random point created";
378 else if(grid_opt.size()){
380 double ulx,uly,lrx,lry;
382 if(uly-grid_opt[0]/2<lry&&ulx+grid_opt[0]/2>lrx){
383 string errorString=
"Error: grid distance too large";
386 else if(grid_opt[0]>0)
387 sampleWriterOgr.createLayer(
"points", imgReader.
getProjection(), wkbPoint, papszOptions);
389 string errorString=
"Error: grid distance must be strictly positive number";
393 unsigned int ipoint=0;
394 for(
double theY=uly-grid_opt[0]/2;theY>lry;theY-=grid_opt[0]){
395 for(
double theX=ulx+grid_opt[0]/2;theX<lrx;theX+=grid_opt[0]){
397 cout <<
"position: " << theX <<
" " << theY << endl;
398 OGRFeature *pointFeature;
399 pointFeature=sampleWriterOgr.createFeature();
402 pointFeature->SetGeometry( &pt );
403 if(sampleWriterOgr.createFeature(pointFeature) != OGRERR_NONE ){
404 string errorString=
"Failed to create feature in vector dataset";
412 string errorString=
"Error: no points created in grid";
417 std::cerr <<
"Error: no sample dataset provided (use option -s). Use --help for help information";
420 sampleWriterOgr.close();
421 sampleReaderOgr.open(
"/vsimem/virtual");
423 catch(
string errorString){
424 cerr << errorString << endl;
430 cerr <<
"Error: sample must be vector dataset in OGR format";
435 std::cout <<
"creating image sample writer " << output_opt[0] << std::endl;
442 bool calculateSpatialStatistics=
false;
444 sampleReaderOgr.getExtent(vectords_ulx,vectords_uly,vectords_lrx,vectords_lry);
445 bool hasCoverage=((vectords_ulx < imgReader.
getLrx())&&(vectords_lrx > imgReader.
getUlx())&&(vectords_lry < imgReader.
getUly())&&(vectords_uly > imgReader.
getLry()));
448 ess <<
"No coverage in " << image_opt[0] <<
" for any layer in " << sample_opt[0] << endl;
451 ogrWriter.open(output_opt[0],ogrformat_opt[0]);
453 for(
int irule=0;irule<rule_opt.size();++irule){
454 switch(ruleMap[rule_opt[irule]]){
456 case(rule::centroid):
457 case(rule::allpoints):
459 case(rule::proportion):
463 if(class_opt.empty()){
469 imgReader.
getMinMax(minValue,maxValue,theBand);
470 int nclass=maxValue-minValue+1;
471 if(nclass<0&&nclass<256){
472 string errorString=
"Could not automatically define classes, please set class option";
475 for(
int iclass=minValue;iclass<=maxValue;++iclass)
476 class_opt.push_back(iclass);
480 calculateSpatialStatistics=
true;
485 catch(
string errorString){
486 cerr << errorString << endl;
491 int nlayerRead=sampleReaderOgr.getDataSource()->GetLayerCount();
493 unsigned long int ntotalvalid=0;
496 std::cout <<
"number of layers: " << nlayerRead << endl;
498 for(
int ilayer=0;ilayer<nlayerRead;++ilayer){
499 OGRLayer *readLayer=sampleReaderOgr.getLayer(ilayer);
500 string currentLayername=readLayer->GetName();
501 int layerIndex=ilayer;
502 if(layer_opt.size()){
503 vector<string>::const_iterator it=find(layer_opt.begin(),layer_opt.end(),currentLayername);
504 if(it==layer_opt.end())
507 layerIndex=it-layer_opt.begin();
513 sampleReaderOgr.getExtent(layer_ulx,layer_uly,layer_lrx,layer_lry,ilayer);
514 bool hasCoverage=((layer_ulx < imgReader.
getLrx())&&(layer_lrx > imgReader.
getUlx())&&(layer_lry < imgReader.
getUly())&&(layer_uly > imgReader.
getLry()));
525 if(layer_ulx<imgReader.
getUlx())
526 layer_ulx=imgReader.
getUlx();
527 if(layer_lrx>imgReader.
getLrx())
528 layer_lrx=imgReader.
getLrx();
529 if(layer_uly>imgReader.
getUly())
530 layer_uly=imgReader.
getUly();
531 if(layer_lry<imgReader.
getLry())
532 layer_lry=imgReader.
getLry();
536 vector< Vector2d<float> > readValuesReal(nband);
537 vector< Vector2d<int> > readValuesInt(nband);
543 imgReader.
geo2image(layer_ulx,layer_uly,layer_uli,layer_ulj);
544 imgReader.
geo2image(layer_lrx,layer_lry,layer_lri,layer_lrj);
546 OGRwkbGeometryType layerGeometry=readLayer->GetLayerDefn()->GetGeomType();
548 if(layerGeometry==wkbPoint){
549 if(calculateSpatialStatistics){
556 if(buffer_opt.size()){
557 layer_uli-=buffer_opt[0];
558 layer_ulj-=buffer_opt[0];
559 layer_lri+=buffer_opt[0];
560 layer_lrj+=buffer_opt[0];
564 layer_uli=(layer_uli<0)? 0 : static_cast<int>(layer_uli);
565 layer_ulj=(layer_ulj<0)? 0 : static_cast<int>(layer_ulj);
566 layer_lri=(layer_lri>=imgReader.
nrOfCol())? imgReader.
nrOfCol()-1 :
static_cast<int>(layer_lri);
567 layer_lrj=(layer_lrj>=imgReader.
nrOfRow())? imgReader.
nrOfRow()-1 :
static_cast<int>(layer_lrj);
570 for(
int iband=0;iband<nband;++iband){
571 int theBand=(band_opt.size()) ? band_opt[iband] : iband;
573 string errorString=
"Error: illegal band (must be positive and starting from 0)";
577 string errorString=
"Error: illegal band (must be lower than number of bands in input raster dataset)";
581 cout <<
"reading image band " << theBand <<
" block rows " << layer_ulj <<
"-" << layer_lrj <<
", cols " << layer_uli <<
"-" << layer_lri << endl;
584 imgReader.
readDataBlock(readValuesInt[iband],layer_uli,layer_lri,layer_ulj,layer_lrj,theBand);
588 imgReader.
readDataBlock(readValuesReal[iband],layer_uli,layer_lri,layer_ulj,layer_lrj,theBand);
593 catch(std::string e){
594 std::cout << e << std::endl;
599 float theThreshold=(threshold_opt.size()==layer_opt.size())? threshold_opt[layerIndex]: threshold_opt[0];
600 cout <<
"processing layer " << currentLayername << endl;
602 bool createPolygon=
true;
603 if(find(rule_opt.begin(),rule_opt.end(),
"allpoints")!=rule_opt.end())
606 OGRLayer *writeLayer;
610 std::cout <<
"create polygons" << std::endl;
611 char **papszOptions=NULL;
612 writeLayer=ogrWriter.createLayer(readLayer->GetName(), imgReader.
getProjection(), wkbPolygon, papszOptions);
616 std::cout <<
"create points in layer " << readLayer->GetName() << std::endl;
617 char **papszOptions=NULL;
619 writeLayer=ogrWriter.createLayer(readLayer->GetName(), imgReader.
getProjection(), wkbPoint, papszOptions);
622 std::cout <<
"copy fields from layer " << ilayer << std::flush << std::endl;
623 ogrWriter.copyFields(sampleReaderOgr,ilayer,ilayerWrite);
625 for(
int irule=0;irule<rule_opt.size();++irule){
626 for(
int iband=0;iband<nband;++iband){
627 int theBand=(band_opt.size()) ? band_opt[iband] : iband;
629 if(rule_opt.size()>1||nband==1)
630 fs << fieldMap[rule_opt[irule]];
632 fs <<
"b" << theBand;
633 switch(ruleMap[rule_opt[irule]]){
634 case(rule::proportion):
636 for(
int iclass=0;iclass<class_opt.size();++iclass){
637 ostringstream fsclass;
638 fsclass << fs.str() << class_opt[iclass];
639 ogrWriter.createField(fsclass.str(),fieldType,ilayerWrite);
643 case(rule::percentile):{
644 for(
int iperc=0;iperc<percentile_opt.size();++iperc){
645 ostringstream fsperc;
646 fsperc << fs.str() << percentile_opt[iperc];
647 ogrWriter.createField(fsperc.str(),fieldType,ilayerWrite);
652 ogrWriter.createField(fs.str(),fieldType,ilayerWrite);
657 OGRFeature *readFeature;
658 unsigned long int ifeature=0;
659 unsigned long int nfeatureLayer=sampleReaderOgr.getFeatureCount(ilayer);
660 unsigned long int ntotalvalidLayer=0;
665 pfnProgress(progress,pszMessage,pProgressArg);
666 readLayer->ResetReading();
667 while( (readFeature = readLayer->GetNextFeature()) != NULL ){
668 bool validFeature=
false;
670 std::cout <<
"reading feature " << readFeature->GetFID() << std::endl;
672 double p=
static_cast<double>(rand())/(RAND_MAX);
679 if(threshold_opt.size()==layer_opt.size()){
680 if(ntotalvalidLayer>=-theThreshold){
685 if(ntotalvalid>=-theThreshold){
691 std::cout <<
"processing feature " << readFeature->GetFID() << std::endl;
694 OGRGeometry *poGeometry;
695 poGeometry = readFeature->GetGeometryRef();
696 assert(poGeometry!=NULL);
698 if(wkbFlatten(poGeometry->getGeometryType()) == wkbPoint ){
699 OGRPoint readPoint = *((OGRPoint *) poGeometry);
701 double i_centre,j_centre;
702 imgReader.
geo2image(readPoint.getX(),readPoint.getY(),i_centre,j_centre);
704 j_centre=
static_cast<int>(j_centre);
705 i_centre=
static_cast<int>(i_centre);
707 double uli=i_centre-buffer_opt[0];
708 double ulj=j_centre-buffer_opt[0];
709 double lri=i_centre+buffer_opt[0];
710 double lrj=j_centre+buffer_opt[0];
713 ulj=
static_cast<int>(ulj);
714 uli=
static_cast<int>(uli);
715 lrj=
static_cast<int>(lrj);
716 lri=
static_cast<int>(lri);
719 if(static_cast<int>(ulj)<0||
static_cast<int>(ulj)>=imgReader.
nrOfRow())
722 if(static_cast<int>(uli)<0||
static_cast<int>(lri)>=imgReader.
nrOfCol())
725 OGRPoint ulPoint,urPoint,llPoint,lrPoint;
731 OGRPolygon writePolygon;
733 OGRLinearRing writeRing;
734 OGRFeature *writePolygonFeature;
741 unsigned short nstep = 25;
742 for(
int i=0;i<nstep;++i){
744 aPoint.setX(readPoint.getX()+imgReader.
getDeltaX()/2.0+radius*cos(2*PI*i/nstep));
745 aPoint.setY(readPoint.getY()-imgReader.
getDeltaY()/2.0+radius*sin(2*PI*i/nstep));
746 writeRing.addPoint(&aPoint);
748 writePolygon.addRing(&writeRing);
749 writePolygon.closeRings();
752 double ulx,uly,lrx,lry;
755 ulPoint.setX(ulx-imgReader.
getDeltaX()/2.0);
756 ulPoint.setY(uly+imgReader.
getDeltaY()/2.0);
757 lrPoint.setX(lrx+imgReader.
getDeltaX()/2.0);
758 lrPoint.setY(lry-imgReader.
getDeltaY()/2.0);
759 urPoint.setX(lrx+imgReader.
getDeltaX()/2.0);
760 urPoint.setY(uly+imgReader.
getDeltaY()/2.0);
761 llPoint.setX(ulx-imgReader.
getDeltaX()/2.0);
762 llPoint.setY(lry-imgReader.
getDeltaY()/2.0);
764 writeRing.addPoint(&ulPoint);
765 writeRing.addPoint(&urPoint);
766 writeRing.addPoint(&lrPoint);
767 writeRing.addPoint(&llPoint);
768 writePolygon.addRing(&writeRing);
769 writePolygon.closeRings();
771 writePolygonFeature = OGRFeature::CreateFeature(writeLayer->GetLayerDefn());
772 if(writePolygonFeature->SetFrom(readFeature)!= OGRERR_NONE)
773 cerr <<
"writing feature failed" << std::endl;
774 writePolygonFeature->SetGeometry(&writePolygon);
776 std::cout <<
"copying new fields write polygon " << std::endl;
778 std::cout <<
"write feature has " << writePolygonFeature->GetFieldCount() <<
" fields" << std::endl;
781 if(find(rule_opt.begin(),rule_opt.end(),
"centroid")!=rule_opt.end()){
783 std::cout <<
"get centroid" << std::endl;
784 writePolygon.Centroid(&readPoint);
786 imgReader.
geo2image(readPoint.getX(),readPoint.getY(),i,j);
787 int indexJ=
static_cast<int>(j-layer_ulj);
788 int indexI=
static_cast<int>(i-layer_uli);
790 valid=valid&&(indexJ>=0);
791 valid=valid&&(indexJ<imgReader.
nrOfRow());
792 valid=valid&&(indexI>=0);
793 valid=valid&&(indexI<imgReader.
nrOfCol());
796 if(srcnodata_opt.empty())
799 for(
int vband=0;vband<bndnodata_opt.size();++vband){
803 value=((readValuesInt[vband])[indexJ])[indexI];
804 if(value==srcnodata_opt[vband])
810 value=((readValuesReal[vband])[indexJ])[indexI];
811 if(value==srcnodata_opt[vband])
824 assert(readValuesReal.size()==nband);
825 for(
int iband=0;iband<nband;++iband){
826 int theBand=(band_opt.size()) ? band_opt[iband] : iband;
830 if(rule_opt.size()>1||nband==1)
831 fs << fieldMap[
"centroid"];
833 fs <<
"b" << theBand;
837 writePolygonFeature->SetField(fieldname.c_str(),
static_cast<int>(((readValuesInt[iband])[indexJ])[indexI]));
840 writePolygonFeature->SetField(fieldname.c_str(),((readValuesReal[iband])[indexJ])[indexI]);
843 std::string errorString=
"field type not supported";
850 if(find(rule_opt.begin(),rule_opt.end(),
"point")!=rule_opt.end()){
852 std::cout <<
"get point on surface" << std::endl;
853 if(writePolygon.PointOnSurface(&readPoint)!=OGRERR_NONE)
854 writePolygon.Centroid(&readPoint);
856 imgReader.
geo2image(readPoint.getX(),readPoint.getY(),i,j);
857 int indexJ=
static_cast<int>(j-layer_ulj);
858 int indexI=
static_cast<int>(i-layer_uli);
860 valid=valid&&(indexJ>=0);
861 valid=valid&&(indexJ<imgReader.
nrOfRow());
862 valid=valid&&(indexI>=0);
863 valid=valid&&(indexI<imgReader.
nrOfCol());
864 if(valid&&srcnodata_opt.size()){
865 for(
int vband=0;vband<bndnodata_opt.size();++vband){
869 value=((readValuesInt[vband])[indexJ])[indexI];
870 if(value==srcnodata_opt[vband])
876 value=((readValuesReal[vband])[indexJ])[indexI];
877 if(value==srcnodata_opt[vband])
889 for(
int iband=0;iband<nband;++iband){
890 int theBand=(band_opt.size()) ? band_opt[iband] : iband;
894 if(rule_opt.size()>1||nband==1)
895 fs << fieldMap[
"point"];
897 fs <<
"b" << theBand;
901 writePolygonFeature->SetField(fieldname.c_str(),
static_cast<int>(((readValuesInt[iband])[indexJ])[indexI]));
904 writePolygonFeature->SetField(fieldname.c_str(),((readValuesReal[iband])[indexJ])[indexI]);
907 std::string errorString=
"field type not supported";
916 if(calculateSpatialStatistics||!createPolygon){
918 vector<double> polyClassValues;
920 if(class_opt.size()){
921 polyClassValues.resize(class_opt.size());
923 for(
int iclass=0;iclass<class_opt.size();++iclass)
924 polyClassValues[iclass]=0;
926 polyValues.resize(nband);
929 for(
int j=ulj;j<=lrj;++j){
930 for(
int i=uli;i<=lri;++i){
932 if(i<0||i>=imgReader.
nrOfCol())
934 if(j<0||j>=imgReader.
nrOfRow())
936 int indexJ=j-layer_ulj;
937 int indexI=i-layer_uli;
942 if(indexJ>=imgReader.
nrOfRow())
944 if(indexI>=imgReader.
nrOfCol())
952 if(disc_opt[0]&&buffer_opt[0]>0){
954 if((theX-readPoint.getX())*(theX-readPoint.getX())+(theY-readPoint.getY())*(theY-readPoint.getY())>radius*radius)
959 if(srcnodata_opt.size()){
960 for(
int vband=0;vband<bndnodata_opt.size();++vband){
963 int value=((readValuesInt[vband])[indexJ])[indexI];
964 if(value==srcnodata_opt[vband]){
970 float value=((readValuesReal[vband])[indexJ])[indexI];
971 if(value==srcnodata_opt[vband]){
985 OGRFeature *writePointFeature;
986 if(valid&&!createPolygon){
987 if(polythreshold_opt.size())
988 if(nPointPolygon>polythreshold_opt[0])
991 writePointFeature = OGRFeature::CreateFeature(writeLayer->GetLayerDefn());
993 std::cout <<
"copying fields from point feature " << std::endl;
994 if(writePointFeature->SetFrom(readFeature)!= OGRERR_NONE)
995 cerr <<
"writing feature failed" << std::endl;
997 std::cout <<
"set geometry as point " << std::endl;
998 writePointFeature->SetGeometry(&thePoint);
999 assert(wkbFlatten(writePointFeature->GetGeometryRef()->getGeometryType()) == wkbPoint);
1000 if(verbose_opt[0]>1){
1001 std::cout <<
"write feature has " << writePointFeature->GetFieldCount() <<
" fields:" << std::endl;
1002 for(
int iField=0;iField<writePointFeature->GetFieldCount();++iField){
1003 std::string fieldname=writeLayer->GetLayerDefn()->GetFieldDefn(iField)->GetNameRef();
1004 cout << fieldname << endl;
1024 for(
int iband=0;iband<nband;++iband){
1025 int theBand=(band_opt.size()) ? band_opt[iband] : iband;
1027 switch( fieldType ){
1029 value=((readValuesInt[iband])[indexJ])[indexI];
1032 value=((readValuesReal[iband])[indexJ])[indexI];
1035 if(!iband&&class_opt.size()){
1036 for(
int iclass=0;iclass<class_opt.size();++iclass){
1037 if(value==class_opt[iclass])
1038 polyClassValues[iclass]+=1;
1041 if(verbose_opt[0]>1)
1042 std::cout <<
": " << value << std::endl;
1046 if(rule_opt.size()>1||nband==1)
1047 fs << fieldMap[
"allpoints"];
1049 fs <<
"b" << theBand;
1051 int fieldIndex=writePointFeature->GetFieldIndex(fieldname.c_str());
1053 cerr <<
"field " << fieldname <<
" was not found" << endl;
1056 if(verbose_opt[0]>1)
1057 std::cout <<
"set field " << fieldname <<
" to " << value << std::endl;
1058 switch( fieldType ){
1061 writePointFeature->SetField(fieldname.c_str(),value);
1069 polyValues[iband].push_back(value);
1073 if(valid&&!createPolygon){
1075 if(verbose_opt[0]>1)
1076 std::cout <<
"creating point feature" << std::endl;
1077 if(writeLayer->CreateFeature( writePointFeature ) != OGRERR_NONE ){
1078 std::string errorString=
"Failed to create feature in ogr vector dataset";
1093 cout <<
"no points found in polygon, continuing" << endl;
1097 for(
int irule=0;irule<rule_opt.size();++irule){
1099 if(ruleMap[rule_opt[irule]]==rule::centroid||ruleMap[rule_opt[irule]]==rule::point)
1101 for(
int iband=0;iband<nband;++iband){
1102 int theBand=(band_opt.size()) ? band_opt[iband] : iband;
1103 vector<double> theValue;
1104 vector<string> fieldname;
1106 if(rule_opt.size()>1||nband==1)
1107 fs << fieldMap[rule_opt[irule]];
1109 fs <<
"b" << theBand;
1110 switch(ruleMap[rule_opt[irule]]){
1111 case(rule::proportion):
1112 stat.normalize_pct(polyClassValues);
1114 for(
int index=0;index<polyClassValues.size();++index){
1115 theValue.push_back(polyClassValues[index]);
1116 ostringstream fsclass;
1117 fsclass << fs.str() << class_opt[index];
1118 fieldname.push_back(fsclass.str());
1125 std::cout <<
"number of points in polygon: " << nPointPolygon << std::endl;
1127 int maxClass=stat.mymin(class_opt);
1128 vector<double>::iterator maxit;
1129 maxit=stat.mymax(polyClassValues,polyClassValues.begin(),polyClassValues.end());
1130 int maxIndex=distance(polyClassValues.begin(),maxit);
1131 maxClass=class_opt[maxIndex];
1132 if(verbose_opt[0]>0)
1133 std::cout <<
"maxClass: " << maxClass << std::endl;
1134 theValue.push_back(maxClass);
1135 fieldname.push_back(fs.str());
1138 theValue.push_back(stat.mean(polyValues[iband]));
1139 fieldname.push_back(fs.str());
1142 theValue.push_back(stat.median(polyValues[iband]));
1143 fieldname.push_back(fs.str());
1146 theValue.push_back(sqrt(stat.var(polyValues[iband])));
1147 fieldname.push_back(fs.str());
1149 case(rule::percentile):{
1150 for(
int iperc=0;iperc<percentile_opt.size();++iperc){
1151 theValue.push_back(stat.percentile(polyValues[iband],polyValues[iband].begin(),polyValues[iband].end(),percentile_opt[iperc]));
1152 ostringstream fsperc;
1153 fsperc << fs.str() << percentile_opt[iperc];
1154 fieldname.push_back(fsperc.str());
1159 theValue.push_back(stat.sum(polyValues[iband]));
1160 fieldname.push_back(fs.str());
1163 theValue.push_back(stat.mymax(polyValues[iband]));
1164 fieldname.push_back(fs.str());
1167 theValue.push_back(stat.mymin(polyValues[iband]));
1168 fieldname.push_back(fs.str());
1170 case(rule::centroid):
1171 theValue.push_back(polyValues[iband].back());
1172 fieldname.push_back(fs.str());
1177 for(
int ivalue=0;ivalue<theValue.size();++ivalue){
1178 switch( fieldType ){
1180 writePolygonFeature->SetField(fieldname[ivalue].c_str(),static_cast<int>(theValue[ivalue]));
1183 writePolygonFeature->SetField(fieldname[ivalue].c_str(),theValue[ivalue]);
1186 writePolygonFeature->SetField(fieldname[ivalue].c_str(),type2string<double>(theValue[ivalue]).c_str());
1189 std::string errorString=
"field type not supported";
1199 if(createPolygon&&validFeature){
1203 if(verbose_opt[0]>1)
1204 std::cout <<
"creating polygon feature (1)" << std::endl;
1205 if(writeLayer->CreateFeature( writePolygonFeature ) != OGRERR_NONE ){
1206 std::string errorString=
"Failed to create polygon feature in ogr vector dataset";
1216 OGRPolygon readPolygon;
1217 OGRMultiPolygon readMultiPolygon;
1220 OGREnvelope* psEnvelope=
new OGREnvelope();
1222 if(wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon){
1223 readPolygon = *((OGRPolygon *) poGeometry);
1224 readPolygon.closeRings();
1225 readPolygon.getEnvelope(psEnvelope);
1227 else if(wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon){
1228 readMultiPolygon = *((OGRMultiPolygon *) poGeometry);
1229 readMultiPolygon.closeRings();
1230 readMultiPolygon.getEnvelope(psEnvelope);
1234 test=poGeometry->getGeometryName();
1236 oss <<
"geometry " << test <<
" not supported";
1240 double ulx,uly,lrx,lry;
1241 double uli,ulj,lri,lrj;
1242 ulx=psEnvelope->MinX;
1243 uly=psEnvelope->MaxY;
1244 lrx=psEnvelope->MaxX;
1245 lry=psEnvelope->MinY;
1249 if(!imgReader.
covers(ulx,uly,lrx,lry))
1252 OGRFeature *writePolygonFeature;
1253 int nPointPolygon=0;
1255 writePolygonFeature = OGRFeature::CreateFeature(writeLayer->GetLayerDefn());
1256 writePolygonFeature->SetGeometry(poGeometry);
1258 if(writePolygonFeature->SetFrom(readFeature)!= OGRERR_NONE)
1259 cerr <<
"writing feature failed" << std::endl;
1260 if(verbose_opt[0]>1)
1261 std::cout <<
"copying new fields write polygon " << std::endl;
1262 if(verbose_opt[0]>1)
1263 std::cout <<
"write feature has " << writePolygonFeature->GetFieldCount() <<
" fields" << std::endl;
1267 if(find(rule_opt.begin(),rule_opt.end(),
"centroid")!=rule_opt.end()){
1268 if(verbose_opt[0]>1)
1269 std::cout <<
"get centroid" << std::endl;
1270 if(wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon)
1271 readPolygon.Centroid(&readPoint);
1272 else if(wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon)
1273 readMultiPolygon.Centroid(&readPoint);
1276 imgReader.
geo2image(readPoint.getX(),readPoint.getY(),i,j);
1277 int indexJ=
static_cast<int>(j-layer_ulj);
1278 int indexI=
static_cast<int>(i-layer_uli);
1280 valid=valid&&(indexJ>=0);
1281 valid=valid&&(indexJ<imgReader.
nrOfRow());
1282 valid=valid&&(indexI>=0);
1283 valid=valid&&(indexI<imgReader.
nrOfCol());
1285 if(srcnodata_opt.empty())
1288 for(
int vband=0;vband<bndnodata_opt.size();++vband){
1289 switch( fieldType ){
1292 value=((readValuesInt[vband])[indexJ])[indexI];
1293 if(value==srcnodata_opt[vband])
1299 value=((readValuesReal[vband])[indexJ])[indexI];
1300 if(value==srcnodata_opt[vband])
1313 assert(readValuesReal.size()==nband);
1314 for(
int iband=0;iband<nband;++iband){
1315 int theBand=(band_opt.size()) ? band_opt[iband] : iband;
1319 if(rule_opt.size()>1||nband==1)
1320 fs << fieldMap[
"centroid"];
1322 fs <<
"b" << theBand;
1324 switch( fieldType ){
1326 writePolygonFeature->SetField(fieldname.c_str(),
static_cast<int>(((readValuesInt[iband])[indexJ])[indexI]));
1329 writePolygonFeature->SetField(fieldname.c_str(),((readValuesReal[iband])[indexJ])[indexI]);
1332 std::string errorString=
"field type not supported";
1339 if(find(rule_opt.begin(),rule_opt.end(),
"point")!=rule_opt.end()){
1340 if(verbose_opt[0]>1)
1341 std::cout <<
"get point on surface" << std::endl;
1342 if(wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon){
1343 if(readPolygon.PointOnSurface(&readPoint)!=OGRERR_NONE)
1344 readPolygon.Centroid(&readPoint);
1346 else if(wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon){
1348 readMultiPolygon.Centroid(&readPoint);
1351 imgReader.
geo2image(readPoint.getX(),readPoint.getY(),i,j);
1352 int indexJ=
static_cast<int>(j-layer_ulj);
1353 int indexI=
static_cast<int>(i-layer_uli);
1355 valid=valid&&(indexJ>=0);
1356 valid=valid&&(indexJ<imgReader.
nrOfRow());
1357 valid=valid&&(indexI>=0);
1358 valid=valid&&(indexI<imgReader.
nrOfCol());
1359 if(valid&&srcnodata_opt.size()){
1360 for(
int vband=0;vband<bndnodata_opt.size();++vband){
1361 switch( fieldType ){
1364 value=((readValuesInt[vband])[indexJ])[indexI];
1365 if(value==srcnodata_opt[vband])
1371 value=((readValuesReal[vband])[indexJ])[indexI];
1372 if(value==srcnodata_opt[vband])
1384 for(
int iband=0;iband<nband;++iband){
1385 int theBand=(band_opt.size()) ? band_opt[iband] : iband;
1389 if(rule_opt.size()>1||nband==1)
1390 fs << fieldMap[
"point"];
1392 fs <<
"b" << theBand;
1394 switch( fieldType ){
1396 writePolygonFeature->SetField(fieldname.c_str(),
static_cast<int>(((readValuesInt[iband])[indexJ])[indexI]));
1399 writePolygonFeature->SetField(fieldname.c_str(),((readValuesReal[iband])[indexJ])[indexI]);
1402 std::string errorString=
"field type not supported";
1409 if(calculateSpatialStatistics||ruleMap[rule_opt[0]]==rule::allpoints){
1413 ulj=
static_cast<int>(ulj);
1414 uli=
static_cast<int>(uli);
1415 lrj=
static_cast<int>(lrj);
1416 lri=
static_cast<int>(lri);
1418 if(verbose_opt[0]>1)
1419 std::cout <<
"bounding box for polygon feature " << ifeature <<
": " << uli <<
" " << ulj <<
" " << lri <<
" " << lrj << std::endl;
1439 vector<double> polyClassValues;
1441 if(class_opt.size()){
1442 polyClassValues.resize(class_opt.size());
1444 for(
int iclass=0;iclass<class_opt.size();++iclass)
1445 polyClassValues[iclass]=0;
1447 polyValues.resize(nband);
1450 for(
int j=ulj;j<=lrj;++j){
1451 for(
int i=uli;i<=lri;++i){
1453 if(i<0||i>=imgReader.
nrOfCol())
1455 if(j<0||j>=imgReader.
nrOfRow())
1457 int indexJ=j-layer_ulj;
1458 int indexI=i-layer_uli;
1463 thePoint.setX(theX);
1464 thePoint.setY(theY);
1466 if(wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon){
1467 if(!readPolygon.Contains(&thePoint))
1470 else if(wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon){
1471 if(!readMultiPolygon.Contains(&thePoint))
1476 if(srcnodata_opt.size()){
1477 for(
int vband=0;vband<bndnodata_opt.size();++vband){
1478 switch( fieldType ){
1480 int value=((readValuesInt[vband])[indexJ])[indexI];
1481 if(value==srcnodata_opt[vband]){
1487 float value=((readValuesReal[vband])[indexJ])[indexI];
1488 if(value==srcnodata_opt[vband]){
1501 if(verbose_opt[0]>1)
1502 std::cout <<
"point is on surface:" << thePoint.getX() <<
"," << thePoint.getY() << std::endl;
1505 OGRFeature *writePointFeature;
1507 if(polythreshold_opt.size())
1508 if(nPointPolygon>polythreshold_opt[0])
1511 writePointFeature = OGRFeature::CreateFeature(writeLayer->GetLayerDefn());
1512 if(verbose_opt[0]>1)
1513 std::cout <<
"copying fields from polygons " << std::endl;
1514 if(writePointFeature->SetFrom(readFeature)!= OGRERR_NONE)
1515 cerr <<
"writing feature failed" << std::endl;
1516 if(verbose_opt[0]>1)
1517 std::cout <<
"set geometry as point " << std::endl;
1518 writePointFeature->SetGeometry(&thePoint);
1519 assert(wkbFlatten(writePointFeature->GetGeometryRef()->getGeometryType()) == wkbPoint);
1520 if(verbose_opt[0]>1){
1521 std::cout <<
"write feature has " << writePointFeature->GetFieldCount() <<
" fields:" << std::endl;
1522 for(
int iField=0;iField<writePointFeature->GetFieldCount();++iField){
1523 std::string fieldname=writeLayer->GetLayerDefn()->GetFieldDefn(iField)->GetNameRef();
1524 cout << fieldname << endl;
1544 for(
int iband=0;iband<nband;++iband){
1545 int theBand=(band_opt.size()) ? band_opt[iband] : iband;
1547 switch( fieldType ){
1549 value=((readValuesInt[iband])[indexJ])[indexI];
1552 value=((readValuesReal[iband])[indexJ])[indexI];
1556 if(!iband&&class_opt.size()){
1557 for(
int iclass=0;iclass<class_opt.size();++iclass){
1558 if(value==class_opt[iclass])
1559 polyClassValues[iclass]+=1;
1562 if(verbose_opt[0]>1)
1563 std::cout <<
": " << value << std::endl;
1567 if(rule_opt.size()>1||nband==1)
1568 fs << fieldMap[
"allpoints"];
1570 fs <<
"b" << theBand;
1572 int fieldIndex=writePointFeature->GetFieldIndex(fieldname.c_str());
1574 cerr <<
"field " << fieldname <<
" was not found" << endl;
1577 if(verbose_opt[0]>1)
1578 std::cout <<
"set field " << fieldname <<
" to " << value << std::endl;
1579 switch( fieldType ){
1582 writePointFeature->SetField(fieldname.c_str(),value);
1590 polyValues[iband].push_back(value);
1596 if(verbose_opt[0]>1)
1597 std::cout <<
"creating point feature" << std::endl;
1598 if(writeLayer->CreateFeature( writePointFeature ) != OGRERR_NONE ){
1599 std::string errorString=
"Failed to create feature in ogr vector dataset";
1613 cout <<
"no points found in polygon, continuing" << endl;
1617 for(
int irule=0;irule<rule_opt.size();++irule){
1619 if(ruleMap[rule_opt[irule]]==rule::centroid||ruleMap[rule_opt[irule]]==rule::point)
1621 for(
int iband=0;iband<nband;++iband){
1622 int theBand=(band_opt.size()) ? band_opt[iband] : iband;
1623 vector<double> theValue;
1624 vector<string> fieldname;
1626 if(rule_opt.size()>1||nband==1)
1627 fs << fieldMap[rule_opt[irule]];
1629 fs <<
"b" << theBand;
1630 switch(ruleMap[rule_opt[irule]]){
1631 case(rule::proportion):
1632 stat.normalize_pct(polyClassValues);
1634 for(
int index=0;index<polyClassValues.size();++index){
1635 theValue.push_back(polyClassValues[index]);
1636 ostringstream fsclass;
1637 fsclass << fs.str() << class_opt[index];
1638 fieldname.push_back(fsclass.str());
1645 std::cout <<
"number of points in polygon: " << nPointPolygon << std::endl;
1647 int maxClass=stat.mymin(class_opt);
1648 vector<double>::iterator maxit;
1649 maxit=stat.mymax(polyClassValues,polyClassValues.begin(),polyClassValues.end());
1650 int maxIndex=distance(polyClassValues.begin(),maxit);
1651 maxClass=class_opt[maxIndex];
1652 if(verbose_opt[0]>0)
1653 std::cout <<
"maxClass: " << maxClass << std::endl;
1654 theValue.push_back(maxClass);
1655 fieldname.push_back(fs.str());
1659 theValue.push_back(stat.mean(polyValues[iband]));
1660 fieldname.push_back(fs.str());
1663 theValue.push_back(stat.median(polyValues[iband]));
1664 fieldname.push_back(fs.str());
1667 theValue.push_back(sqrt(stat.var(polyValues[iband])));
1668 fieldname.push_back(fs.str());
1670 case(rule::percentile):{
1671 for(
int iperc=0;iperc<percentile_opt.size();++iperc){
1672 theValue.push_back(stat.percentile(polyValues[iband],polyValues[iband].begin(),polyValues[iband].end(),percentile_opt[iperc]));
1673 ostringstream fsperc;
1674 fsperc << fs.str() << percentile_opt[iperc];
1675 fieldname.push_back(fsperc.str());
1680 theValue.push_back(stat.sum(polyValues[iband]));
1681 fieldname.push_back(fs.str());
1684 theValue.push_back(stat.mymax(polyValues[iband]));
1685 fieldname.push_back(fs.str());
1688 theValue.push_back(stat.mymin(polyValues[iband]));
1689 fieldname.push_back(fs.str());
1691 case(rule::centroid):
1692 theValue.push_back(polyValues[iband].back());
1693 fieldname.push_back(fs.str());
1698 for(
int ivalue=0;ivalue<theValue.size();++ivalue){
1699 switch( fieldType ){
1701 writePolygonFeature->SetField(fieldname[ivalue].c_str(),static_cast<int>(theValue[ivalue]));
1704 writePolygonFeature->SetField(fieldname[ivalue].c_str(),theValue[ivalue]);
1707 writePolygonFeature->SetField(fieldname[ivalue].c_str(),type2string<double>(theValue[ivalue]).c_str());
1710 std::string errorString=
"field type not supported";
1719 if(createPolygon&&validFeature){
1722 if(verbose_opt[0]>1)
1723 std::cout <<
"creating polygon feature (2)" << std::endl;
1724 if(writeLayer->CreateFeature( writePolygonFeature ) != OGRERR_NONE ){
1725 std::string errorString=
"Failed to create polygon feature in ogr vector dataset";
1736 if(threshold_opt.size()==layer_opt.size())
1737 progress=(100.0/theThreshold)*
static_cast<float>(ntotalvalidLayer)/nfeatureLayer;
1739 progress=
static_cast<float>(ntotalvalidLayer)/nfeatureLayer;
1742 progress=
static_cast<float>(ifeature+1)/(-theThreshold);
1743 pfnProgress(progress,pszMessage,pProgressArg);
1745 catch(std::string e){
1746 std::cout << e << std::endl;
1751 std::cout <<
"number of points read in polygon: " << npoint << std::endl;
1758 pfnProgress(progress,pszMessage,pProgressArg);
1761 sampleReaderOgr.close();
1765 pfnProgress(progress,pszMessage,pProgressArg);
bool covers(double x, double y) const
Check if a geolocation is covered by this dataset. Only the bounding box is checked, irrespective of no data values.
double getLry() const
Get the lower right corner y (georeferenced) coordinate of this dataset.
double getUly() const
Get the upper left corner y (georeferenced) coordinate of this dataset.
bool geo2image(double x, double y, double &i, double &j) const
Convert georeferenced coordinates (x and y) to image coordinates (column and row) ...
void close(void)
Set the memory (in MB) to cache a number of rows in memory.
int nrOfCol(void) const
Get the number of columns of this dataset.
bool getBoundingBox(double &ulx, double &uly, double &lrx, double &lry) const
Get the bounding box of this dataset in georeferenced coordinates.
double getUlx() const
Get the upper left corner x (georeferenced) coordinate of this dataset.
int nrOfRow(void) const
Get the number of rows of this dataset.
bool image2geo(double i, double j, double &x, double &y) const
Convert image coordinates (column and row) to georeferenced coordinates (x and y) ...
double getLrx() const
Get the lower right corner x (georeferenced) coordinate of this dataset.
double getDeltaX(void) const
Get the pixel cell spacing in x.
double getDeltaY(void) const
Get the pixel cell spacing in y.
void getMinMax(int startCol, int endCol, int startRow, int endRow, int band, double &minValue, double &maxValue)
Get the minimum and maximum cell values for a specific band in a region of interest defined by startC...
std::string getProjection(void) const
Get the projection string (deprecated, use getProjectionRef instead)
void readDataBlock(Vector2d< T > &buffer2d, int minCol, int maxCol, int minRow, int maxRow, int band=0)
Read pixel cell values for a range of columns and rows for a specific band (all indices start countin...
void open(const std::string &filename, const GDALAccess &readMode=GA_ReadOnly)
Open an image.
int nrOfBand(void) const
Get the number of bands of this dataset.