feature_ptr gdal_featureset::next() { if (first_) { first_ = false; #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: featureset, dataset = " << &dataset_ << std::endl; #endif query *q = boost::get<query>(&gquery_); if (q) { return get_feature(*q); } else { coord2d *p = boost::get<coord2d>(&gquery_); if (p) { return get_feature_at_point(*p); } } // should never reach here } return feature_ptr(); }
feature_ptr gdal_featureset::next() { if (first_) { first_ = false; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Next feature in Dataset=" << &dataset_; query *q = boost::get<query>(&gquery_); if (q) { return get_feature(*q); } else { coord2d *p = boost::get<coord2d>(&gquery_); if (p) { return get_feature_at_point(*p); } } // should never reach here } return feature_ptr(); }
feature_ptr rasterlite_featureset::get_feature(mapnik::query const& q) { MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Running get_feature"; feature_ptr feature(feature_factory::create(ctx_,1)); double x0, y0, x1, y1; rasterliteGetExtent (dataset_, &x0, &y0, &x1, &y1); box2d<double> raster_extent(x0, y0, x1, y1); box2d<double> intersect = raster_extent.intersect(q.get_bbox()); const int width = static_cast<int>(std::get<0>(q.resolution()) * intersect.width() + 0.5); const int height = static_cast<int>(std::get<0>(q.resolution()) * intersect.height() + 0.5); const double pixel_size = (intersect.width() >= intersect.height()) ? (intersect.width() / (double) width) : (intersect.height() / (double) height); MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Raster extent=" << raster_extent; MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: View extent=" << q.get_bbox(); MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Intersect extent=" << intersect; MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Query resolution=" << std::get<0>(q.resolution()) << "," << std::get<1>(q.resolution()); MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Size=" << width << " " << height; MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Pixel Size=" << pixel_size; if (width > 0 && height > 0) { int size = 0; void* raster = 0; if (rasterliteGetRawImageByRect(dataset_, intersect.minx(), intersect.miny(), intersect.maxx(), intersect.maxy(), pixel_size, width, height, GAIA_RGBA_ARRAY, &raster, &size) == RASTERLITE_OK) { if (size > 0) { mapnik::image_rgba8 image(width,height); unsigned char* raster_data = static_cast<unsigned char*>(raster); std::memcpy(image.bytes(), raster_data, size); feature->set_raster(std::make_shared<mapnik::raster>(intersect, std::move(image), 1.0)); MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Done"; } else { MAPNIK_LOG_ERROR(rasterlite) << "Rasterlite Plugin: Error " << rasterliteGetLastError (dataset_); } } return feature; } return feature_ptr(); }
feature_ptr sqlite_featureset::next() { if (rs_->is_valid () && rs_->step_next ()) { int size; const char* data = (const char *) rs_->column_blob (0, size); int feature_id = rs_->column_integer (1); #ifdef MAPNIK_DEBUG // clog << "feature_oid=" << feature_id << endl; #endif feature_ptr feature(new Feature(feature_id)); geometry_utils::from_wkb(*feature,data,size,multiple_geometries_,format_); for (int i = 2; i < rs_->column_count (); ++i) { const int type_oid = rs_->column_type (i); const char* fld_name = rs_->column_name (i); switch (type_oid) { case SQLITE_INTEGER: { boost::put(*feature,fld_name,rs_->column_integer (i)); break; } case SQLITE_FLOAT: { boost::put(*feature,fld_name,rs_->column_double (i)); break; } case SQLITE_TEXT: { UnicodeString ustr = tr_->transcode (rs_->column_text (i)); boost::put(*feature,fld_name,ustr); break; } case SQLITE_BLOB: case SQLITE_NULL: break; default: #ifdef MAPNIK_DEBUG clog << "unhandled type_oid=" << type_oid << endl; #endif break; } } return feature; } return feature_ptr(); }
feature_ptr rasterlite_featureset::next() { if (first_) { first_ = false; MAPNIK_LOG_DEBUG(gdal) << "rasterlite_featureset: Next feature in Dataset=" << &dataset_; return mapnik::util::apply_visitor(query_dispatch(*this), gquery_); } return feature_ptr(); }
feature_ptr gdal_featureset::next() { if (first_) { first_ = false; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Next feature in Dataset=" << &dataset_; return boost::apply_visitor(query_dispatch(*this), gquery_); } return feature_ptr(); }
feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt) { CPLErr raster_io_error = CE_None; if (band_ > 0) { unsigned raster_xsize = dataset_.GetRasterXSize(); unsigned raster_ysize = dataset_.GetRasterYSize(); double gt[6]; dataset_.GetGeoTransform(gt); double det = gt[1] * gt[5] - gt[2] * gt[4]; // subtract half a pixel width & height because gdal coord reference // is the top-left corner of a pixel, not the center. double X = pt.x - gt[0] - gt[1]/2; double Y = pt.y - gt[3] - gt[5]/2; double det1 = gt[1]*Y + gt[4]*X; double det2 = gt[2]*Y + gt[5]*X; unsigned x = static_cast<unsigned>(det2/det); unsigned y = static_cast<unsigned>(det1/det); if (x < raster_xsize && y < raster_ysize) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: pt.x=" << pt.x << " pt.y=" << pt.y; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: x=" << x << " y=" << y; GDALRasterBand* band = dataset_.GetRasterBand(band_); int raster_has_nodata; double nodata = band->GetNoDataValue(&raster_has_nodata); double value; raster_io_error = band->RasterIO(GF_Read, x, y, 1, 1, &value, 1, 1, GDT_Float64, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } if (! raster_has_nodata || value != nodata) { // construct feature feature_ptr feature = feature_factory::create(ctx_,1); feature->set_geometry(mapnik::geometry::point<double>(pt.x,pt.y)); feature->put_new("value",value); if (raster_has_nodata) { feature->put_new("nodata",nodata); } return feature; } } } return feature_ptr(); }
feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt) { if (band_ > 0) { unsigned raster_xsize = dataset_.GetRasterXSize(); unsigned raster_ysize = dataset_.GetRasterYSize(); double gt[6]; dataset_.GetGeoTransform(gt); double det = gt[1] * gt[5] - gt[2] * gt[4]; // subtract half a pixel width & height because gdal coord reference // is the top-left corner of a pixel, not the center. double X = pt.x - gt[0] - gt[1]/2; double Y = pt.y - gt[3] - gt[5]/2; double det1 = gt[1]*Y + gt[4]*X; double det2 = gt[2]*Y + gt[5]*X; unsigned x = static_cast<unsigned>(det2/det); unsigned y = static_cast<unsigned>(det1/det); if (x < raster_xsize && y < raster_ysize) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: pt.x=" << pt.x << " pt.y=" << pt.y; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: x=" << x << " y=" << y; GDALRasterBand* band = dataset_.GetRasterBand(band_); int raster_has_nodata; double nodata = band->GetNoDataValue(&raster_has_nodata); double value; band->RasterIO(GF_Read, x, y, 1, 1, &value, 1, 1, GDT_Float64, 0, 0); if (! raster_has_nodata || value != nodata) { // construct feature feature_ptr feature = feature_factory::create(ctx_,1); std::unique_ptr<geometry_type> point = std::make_unique<geometry_type>(mapnik::geometry_type::types::Point); point->move_to(pt.x, pt.y); feature->add_geometry(point.release()); feature->put_new("value",value); if (raster_has_nodata) { feature->put_new("nodata",nodata); } return feature; } } } return feature_ptr(); }
feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt) { if (band_ > 0) { unsigned raster_xsize = dataset_.GetRasterXSize(); unsigned raster_ysize = dataset_.GetRasterYSize(); double gt[6]; dataset_.GetGeoTransform(gt); double det = gt[1] * gt[5] - gt[2] * gt[4]; // subtract half a pixel width & height because gdal coord reference // is the top-left corner of a pixel, not the center. double X = pt.x - gt[0] - gt[1]/2; double Y = pt.y - gt[3] - gt[5]/2; double det1 = gt[1]*Y + gt[4]*X; double det2 = gt[2]*Y + gt[5]*X; unsigned x = det2/det, y = det1/det; if (x < raster_xsize && y < raster_ysize) { #ifdef MAPNIK_DEBUG std::clog << boost::format("GDAL Plugin: pt.x=%f pt.y=%f") % pt.x % pt.y << std::endl; std::clog << boost::format("GDAL Plugin: x=%f y=%f") % x % y << std::endl; #endif GDALRasterBand* band = dataset_.GetRasterBand(band_); int hasNoData; double nodata = band->GetNoDataValue(&hasNoData); double value; band->RasterIO(GF_Read, x, y, 1, 1, &value, 1, 1, GDT_Float64, 0, 0); if (! hasNoData || value != nodata) { // construct feature feature_ptr feature(new Feature(1)); geometry_type * point = new geometry_type(mapnik::Point); point->move_to(pt.x, pt.y); feature->add_geometry(point); (*feature)["value"] = value; return feature; } } } return feature_ptr(); }
feature_ptr rasterlite_featureset::next() { if (first_) { first_ = false; query *q = boost::get<query>(&gquery_); if(q) { return get_feature(*q); } else { coord2d *p = boost::get<coord2d>(&gquery_); if(p) { return get_feature_at_point(*p); } } // should never reach here } return feature_ptr(); }
feature_ptr kismet_featureset::next() { if (knd_list_it != knd_list_.end ()) { const kismet_network_data& knd = *knd_list_it; const std::string key = "internet_access"; std::string value; if (knd.crypt_ == crypt_none) { value = "wlan_uncrypted"; } else if (knd.crypt_ == crypt_wep) { value = "wlan_wep"; } else { value = "wlan_crypted"; } feature_ptr feature(feature_factory::create(feature_id_)); ++feature_id_; geometry_type* pt = new geometry_type(mapnik::Point); pt->move_to(knd.bestlon_, knd.bestlat_); feature->add_geometry(pt); boost::put(*feature, key, tr_->transcode(value.c_str())); ++knd_list_it; return feature; } return feature_ptr(); }
feature_ptr ogr_featureset::next() { OGRFeature *poFeature; while ((poFeature = layer_.GetNextFeature()) != NULL) { // ogr feature ids start at 0, so add one to stay // consistent with other mapnik datasources that start at 1 const int feature_id = (poFeature->GetFID() + 1); feature_ptr feature(feature_factory::create(ctx_,feature_id)); OGRGeometry* geom = poFeature->GetGeometryRef(); if (geom && ! geom->IsEmpty()) { ogr_converter::convert_geometry(geom, feature); } else { MAPNIK_LOG_DEBUG(ogr) << "ogr_featureset: Feature with null geometry=" << poFeature->GetFID(); OGRFeature::DestroyFeature( poFeature ); continue; } ++count_; int fld_count = layerdef_->GetFieldCount(); for (int i = 0; i < fld_count; i++) { OGRFieldDefn* fld = layerdef_->GetFieldDefn(i); const OGRFieldType type_oid = fld->GetType(); const std::string fld_name = fld->GetNameRef(); switch (type_oid) { case OFTInteger: { feature->put( fld_name, poFeature->GetFieldAsInteger(i)); break; } case OFTReal: { feature->put( fld_name, poFeature->GetFieldAsDouble(i)); break; } case OFTString: case OFTWideString: // deprecated ! { UnicodeString ustr = tr_->transcode(poFeature->GetFieldAsString(i)); feature->put( fld_name, ustr); break; } case OFTIntegerList: case OFTRealList: case OFTStringList: case OFTWideStringList: // deprecated ! { MAPNIK_LOG_WARN(ogr) << "ogr_featureset: Unhandled type_oid=" << type_oid; break; } case OFTBinary: { MAPNIK_LOG_WARN(ogr) << "ogr_featureset: Unhandled type_oid=" << type_oid; //feature->put(name,feat->GetFieldAsBinary (i, size)); break; } case OFTDate: case OFTTime: case OFTDateTime: // unhandled ! { MAPNIK_LOG_WARN(ogr) << "ogr_featureset: Unhandled type_oid=" << type_oid; break; } default: // unknown { MAPNIK_LOG_WARN(ogr) << "ogr_featureset: Unknown type_oid=" << type_oid; break; } } } OGRFeature::DestroyFeature( poFeature ); return feature; } MAPNIK_LOG_DEBUG(ogr) << "ogr_featureset: " << count_ << " features"; return feature_ptr(); }
feature_ptr occi_featureset::next() { while (rs_ != nullptr && rs_->next() == oracle::occi::ResultSet::DATA_AVAILABLE) { feature_ptr feature(feature_factory::create(ctx_, feature_id_)); if (use_wkb_) { Blob blob = rs_->getBlob(1); blob.open(oracle::occi::OCCI_LOB_READONLY); unsigned int size = blob.length(); if (buffer_.size() < size) { buffer_.resize(size); } oracle::occi::Stream* instream = blob.getStream(1, 0); instream->readBuffer(buffer_.data(), size); blob.closeStream(instream); blob.close(); if (! geometry_utils::from_wkb(feature->paths(), buffer_.data(), size)) { continue; } } else { const std::unique_ptr<SDOGeometry> geom(dynamic_cast<SDOGeometry*>(rs_->getObject(1))); if (geom.get()) { convert_geometry(geom.get(), feature); } else { continue; } } std::vector<MetaData> listOfColumns = rs_->getColumnListMetaData(); for (unsigned int i = 1; i < listOfColumns.size(); ++i) { MetaData columnObj = listOfColumns[i]; std::string fld_name = columnObj.getString(MetaData::ATTR_NAME); int type_oid = columnObj.getInt(MetaData::ATTR_DATA_TYPE); /* int type_code = columnObj.getInt(MetaData::ATTR_TYPECODE); if (type_code == OCCI_TYPECODE_OBJECT) { continue; } */ switch (type_oid) { case oracle::occi::OCCIBOOL: feature->put(fld_name, (rs_->getInt(i + 1) != 0)); break; case oracle::occi::OCCIINT: case oracle::occi::OCCIUNSIGNED_INT: feature->put(fld_name, static_cast<mapnik::value_integer>(rs_->getInt(i + 1))); break; case oracle::occi::OCCIFLOAT: case oracle::occi::OCCIBFLOAT: feature->put(fld_name, (double)rs_->getFloat(i + 1)); break; case oracle::occi::OCCIDOUBLE: case oracle::occi::OCCIBDOUBLE: case oracle::occi::OCCINUMBER: case oracle::occi::OCCI_SQLT_NUM: feature->put(fld_name, rs_->getDouble(i + 1)); break; case oracle::occi::OCCICHAR: case oracle::occi::OCCISTRING: case oracle::occi::OCCI_SQLT_AFC: case oracle::occi::OCCI_SQLT_AVC: case oracle::occi::OCCI_SQLT_CHR: case oracle::occi::OCCI_SQLT_LNG: case oracle::occi::OCCI_SQLT_LVC: case oracle::occi::OCCI_SQLT_STR: case oracle::occi::OCCI_SQLT_VCS: case oracle::occi::OCCI_SQLT_VNU: case oracle::occi::OCCI_SQLT_VBI: case oracle::occi::OCCI_SQLT_VST: case oracle::occi::OCCIROWID: case oracle::occi::OCCI_SQLT_RDD: case oracle::occi::OCCI_SQLT_RID: case oracle::occi::OCCIDATE: case oracle::occi::OCCI_SQLT_DAT: case oracle::occi::OCCI_SQLT_DATE: case oracle::occi::OCCI_SQLT_TIME: case oracle::occi::OCCI_SQLT_TIME_TZ: case oracle::occi::OCCITIMESTAMP: case oracle::occi::OCCI_SQLT_TIMESTAMP: case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ: case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ: feature->put(fld_name, static_cast<mapnik::value_unicode_string>(tr_->transcode(rs_->getString(i + 1).c_str()))); break; case oracle::occi::OCCIINTERVALDS: case oracle::occi::OCCIINTERVALYM: case oracle::occi::OCCI_SQLT_INTERVAL_YM: case oracle::occi::OCCI_SQLT_INTERVAL_DS: case oracle::occi::OCCIANYDATA: case oracle::occi::OCCIBLOB: case oracle::occi::OCCIBFILE: case oracle::occi::OCCIBYTES: case oracle::occi::OCCICLOB: case oracle::occi::OCCIVECTOR: case oracle::occi::OCCIMETADATA: case oracle::occi::OCCIPOBJECT: case oracle::occi::OCCIREF: case oracle::occi::OCCIREFANY: case oracle::occi::OCCISTREAM: case oracle::occi::OCCICURSOR: case oracle::occi::OCCI_SQLT_FILE: case oracle::occi::OCCI_SQLT_CFILE: case oracle::occi::OCCI_SQLT_REF: case oracle::occi::OCCI_SQLT_CLOB: case oracle::occi::OCCI_SQLT_BLOB: case oracle::occi::OCCI_SQLT_RSET: { MAPNIK_LOG_WARN(occi) << "occi_featureset: Unsupported datatype " << occi_enums::resolve_datatype(type_oid) << " (type_oid=" << type_oid << ")"; break; } default: // shouldn't get here { MAPNIK_LOG_WARN(occi) << "occi_featureset: Unknown datatype " << "(type_oid=" << type_oid << ")"; break; } } } ++feature_id_; return feature; } return feature_ptr(); }
feature_ptr gdal_featureset::get_feature(mapnik::query const& q) { feature_ptr feature = feature_factory::create(ctx_,1); int raster_has_nodata = 0; double raster_nodata = 0; GDALRasterBand * red = 0; GDALRasterBand * green = 0; GDALRasterBand * blue = 0; GDALRasterBand * alpha = 0; GDALRasterBand * grey = 0; CPLErr raster_io_error = CE_None; /* #ifdef MAPNIK_LOG double tr[6]; dataset_.GetGeoTransform(tr); const double dx = tr[1]; const double dy = tr[5]; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: dx_=" << dx_ << " dx=" << dx << " dy_=" << dy_ << "dy=" << dy; #endif */ view_transform t(raster_width_, raster_height_, raster_extent_, 0, 0); box2d<double> intersect = raster_extent_.intersect(q.get_bbox()); box2d<double> box = t.forward(intersect); //size of resized output pixel in source image domain double margin_x = 1.0 / (std::fabs(dx_) * std::get<0>(q.resolution())); double margin_y = 1.0 / (std::fabs(dy_) * std::get<1>(q.resolution())); if (margin_x < 1) { margin_x = 1.0; } if (margin_y < 1) { margin_y = 1.0; } //select minimum raster containing whole box int x_off = rint(box.minx() - margin_x); int y_off = rint(box.miny() - margin_y); int end_x = rint(box.maxx() + margin_x); int end_y = rint(box.maxy() + margin_y); //clip to available data if (x_off < 0) { x_off = 0; } if (y_off < 0) { y_off = 0; } if (end_x > (int)raster_width_) { end_x = raster_width_; } if (end_y > (int)raster_height_) { end_y = raster_height_; } int width = end_x - x_off; int height = end_y - y_off; // don't process almost invisible data if (box.width() < 0.5) { width = 0; } if (box.height() < 0.5) { height = 0; } //calculate actual box2d of returned raster box2d<double> feature_raster_extent(x_off, y_off, x_off + width, y_off + height); intersect = t.backward(feature_raster_extent); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Raster extent=" << raster_extent_; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: View extent=" << intersect; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Query resolution=" << std::get<0>(q.resolution()) << "," << std::get<1>(q.resolution()); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: StartX=" << x_off << " StartY=" << y_off << " Width=" << width << " Height=" << height; if (width > 0 && height > 0) { double width_res = std::get<0>(q.resolution()); double height_res = std::get<1>(q.resolution()); int im_width = int(width_res * intersect.width() + 0.5); int im_height = int(height_res * intersect.height() + 0.5); double filter_factor = q.get_filter_factor(); im_width = int(im_width * filter_factor + 0.5); im_height = int(im_height * filter_factor + 0.5); // case where we need to avoid upsampling so that the // image can be later scaled within raster_symbolizer if (im_width >= width || im_height >= height) { im_width = width; im_height = height; } if (im_width > 0 && im_height > 0) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Image Size=(" << im_width << "," << im_height << ")"; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Reading band=" << band_; if (band_ > 0) // we are querying a single band { GDALRasterBand * band = dataset_.GetRasterBand(band_); if (band_ > nbands_) { std::ostringstream s; s << "GDAL Plugin: " << band_ << " is an invalid band, dataset only has " << nbands_ << "bands"; throw datasource_exception(s.str()); } GDALDataType band_type = band->GetRasterDataType(); switch (band_type) { case GDT_Byte: { mapnik::image_gray8 image(im_width, im_height); image.set(std::numeric_limits<std::uint8_t>::max()); raster_nodata = band->GetNoDataValue(&raster_has_nodata); raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height, image.data(), image.width(), image.height(), GDT_Byte, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor); // set nodata value to be used in raster colorizer if (nodata_value_) raster->set_nodata(*nodata_value_); else raster->set_nodata(raster_nodata); feature->set_raster(raster); break; } case GDT_Float64: case GDT_Float32: { mapnik::image_gray32f image(im_width, im_height); image.set(std::numeric_limits<float>::max()); raster_nodata = band->GetNoDataValue(&raster_has_nodata); raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height, image.data(), image.width(), image.height(), GDT_Float32, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor); // set nodata value to be used in raster colorizer if (nodata_value_) raster->set_nodata(*nodata_value_); else raster->set_nodata(raster_nodata); feature->set_raster(raster); break; } case GDT_UInt16: { mapnik::image_gray16 image(im_width, im_height); image.set(std::numeric_limits<std::uint16_t>::max()); raster_nodata = band->GetNoDataValue(&raster_has_nodata); raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height, image.data(), image.width(), image.height(), GDT_UInt16, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor); // set nodata value to be used in raster colorizer if (nodata_value_) raster->set_nodata(*nodata_value_); else raster->set_nodata(raster_nodata); feature->set_raster(raster); break; } default: case GDT_Int16: { mapnik::image_gray16s image(im_width, im_height); image.set(std::numeric_limits<std::int16_t>::max()); raster_nodata = band->GetNoDataValue(&raster_has_nodata); raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height, image.data(), image.width(), image.height(), GDT_Int16, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor); // set nodata value to be used in raster colorizer if (nodata_value_) raster->set_nodata(*nodata_value_); else raster->set_nodata(raster_nodata); feature->set_raster(raster); break; } } } else // working with all bands { mapnik::image_rgba8 image(im_width, im_height); image.set(std::numeric_limits<std::uint32_t>::max()); for (int i = 0; i < nbands_; ++i) { GDALRasterBand * band = dataset_.GetRasterBand(i + 1); #ifdef MAPNIK_LOG get_overview_meta(band); #endif GDALColorInterp color_interp = band->GetColorInterpretation(); switch (color_interp) { case GCI_RedBand: red = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found red band"; break; case GCI_GreenBand: green = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found green band"; break; case GCI_BlueBand: blue = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found blue band"; break; case GCI_AlphaBand: alpha = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found alpha band"; break; case GCI_GrayIndex: grey = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band"; break; case GCI_PaletteIndex: { grey = band; #ifdef MAPNIK_LOG MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band, and colortable..."; GDALColorTable *color_table = band->GetColorTable(); if (color_table) { int count = color_table->GetColorEntryCount(); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color Table count=" << count; for (int j = 0; j < count; j++) { const GDALColorEntry *ce = color_table->GetColorEntry (j); if (! ce) continue; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color entry RGB=" << ce->c1 << "," <<ce->c2 << "," << ce->c3; } } #endif break; } case GCI_Undefined: #if GDAL_VERSION_NUM <= 1730 if (nbands_ == 4) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming alpha band)"; alpha = band; } else { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)"; grey = band; } #else MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)"; grey = band; #endif break; default: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Band type unknown!"; break; } } if (red && green && blue) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing rgb bands..."; raster_nodata = red->GetNoDataValue(&raster_has_nodata); GDALColorTable *color_table = red->GetColorTable(); bool has_nodata = nodata_value_ || raster_has_nodata; // we can deduce the alpha channel from nodata in the Byte case // by reusing the reading of R,G,B bands directly if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte) { double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata; // read the data in and create an alpha channel from the nodata values // TODO - we assume here the nodata value for the red band applies to all bands // more details about this at http://trac.osgeo.org/gdal/ticket/2734 float* imageData = (float*)image.bytes(); raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } int len = image.width() * image.height(); for (int i = 0; i < len; ++i) { if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_) { *reinterpret_cast<unsigned *>(&imageData[i]) = 0; } else { *reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF; } } } /* Use dataset RasterIO in priority in 99.9% of the cases */ if( red->GetBand() == 1 && green->GetBand() == 2 && blue->GetBand() == 3 ) { int nBandsToRead = 3; if( alpha != NULL && alpha->GetBand() == 4 && !raster_has_nodata ) { nBandsToRead = 4; alpha = NULL; // to avoid reading it again afterwards } raster_io_error = dataset_.RasterIO(GF_Read, x_off, y_off, width, height, image.bytes(), image.width(), image.height(), GDT_Byte, nBandsToRead, NULL, 4, 4 * image.width(), 1); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } } else { raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } raster_io_error = green->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 1, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } raster_io_error = blue->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 2, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } } // In the case we skipped initializing the alpha channel if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte) { double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata; if( apply_nodata >= 0 && apply_nodata <= 255 ) { int len = image.width() * image.height(); GByte* pabyBytes = (GByte*) image.bytes(); for (int i = 0; i < len; ++i) { // TODO - we assume here the nodata value for the red band applies to all bands // more details about this at http://trac.osgeo.org/gdal/ticket/2734 if (std::fabs(apply_nodata - pabyBytes[4*i]) < nodata_tolerance_) pabyBytes[4*i + 3] = 0; else pabyBytes[4*i + 3] = 255; } } } } else if (grey) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing gray band..."; raster_nodata = grey->GetNoDataValue(&raster_has_nodata); GDALColorTable* color_table = grey->GetColorTable(); bool has_nodata = nodata_value_ || raster_has_nodata; if (!color_table && has_nodata) { double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: applying nodata value for layer=" << apply_nodata; // first read the data in and create an alpha channel from the nodata values float* imageData = (float*)image.bytes(); raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } int len = image.width() * image.height(); for (int i = 0; i < len; ++i) { if (std::fabs(apply_nodata - imageData[i]) < nodata_tolerance_) { *reinterpret_cast<unsigned *>(&imageData[i]) = 0; } else { *reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF; } } } raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 0, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 1, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.bytes() + 2, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } if (color_table) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Loading color table..."; for (unsigned y = 0; y < image.height(); ++y) { unsigned int* row = image.get_row(y); for (unsigned x = 0; x < image.width(); ++x) { unsigned value = row[x] & 0xff; const GDALColorEntry *ce = color_table->GetColorEntry(value); if (ce) { row[x] = (ce->c4 << 24)| (ce->c3 << 16) | (ce->c2 << 8) | (ce->c1) ; } else { // make lacking color entry fully alpha // note - gdal_translate makes black row[x] = 0; } } } } } if (alpha) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: processing alpha band..."; if (!raster_has_nodata) { raster_io_error = alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.bytes() + 3, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (raster_io_error == CE_Failure) { throw datasource_exception(CPLGetLastErrorMsg()); } } else { MAPNIK_LOG_WARN(gdal) << "warning: nodata value (" << raster_nodata << ") used to set transparency instead of alpha band"; } } mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor); // set nodata value to be used in raster colorizer if (nodata_value_) raster->set_nodata(*nodata_value_); else raster->set_nodata(raster_nodata); feature->set_raster(raster); } // report actual/original source nodata in feature attributes if (raster_has_nodata) { feature->put("nodata",raster_nodata); } return feature; } } return feature_ptr(); }
feature_ptr geos_featureset::next() { if (! already_rendered_) { already_rendered_ = true; if (GEOSisValid(geometry_) && ! GEOSisEmpty(geometry_)) { bool render_geometry = true; if (*extent_ != NULL && GEOSisValid(*extent_) && ! GEOSisEmpty(*extent_)) { const int type = GEOSGeomTypeId(*extent_); render_geometry = false; switch (type) { case GEOS_POINT: if (GEOSIntersects(*extent_, geometry_)) { render_geometry = true; } break; case GEOS_POLYGON: if (GEOSContains(*extent_, geometry_) || GEOSWithin(geometry_, *extent_) || GEOSEquals(geometry_, *extent_)) { render_geometry = true; } break; default: MAPNIK_LOG_DEBUG(geos) << "geos_featureset: Unknown extent geometry_type=" << type; break; } } if (render_geometry) { geos_wkb_ptr wkb(geometry_); if (wkb.is_valid()) { feature_ptr feature(feature_factory::create(ctx_,feature_id_)); if (geometry_utils::from_wkb(feature->paths(), wkb.data(), wkb.size()) && field_ != "") { feature->put(field_name_, tr_->transcode(field_.c_str())); } return feature; } } } } return feature_ptr(); }
feature_ptr raster_featureset<LookupPolicy>::next() { if (curIter_ != endIter_) { feature_ptr feature(feature_factory::create(feature_id_)); ++feature_id_; try { std::auto_ptr<image_reader> reader(mapnik::get_image_reader(curIter_->file(),curIter_->format())); #ifdef MAPNIK_DEBUG std::clog << "Raster Plugin: READER = " << curIter_->format() << " " << curIter_->file() << " size(" << curIter_->width() << "," << curIter_->height() << ")" << std::endl; #endif if (reader.get()) { int image_width = policy_.img_width(reader->width()); int image_height = policy_.img_height(reader->height()); if (image_width > 0 && image_height > 0) { CoordTransform t(image_width, image_height, extent_, 0, 0); box2d<double> intersect = bbox_.intersect(curIter_->envelope()); box2d<double> ext = t.forward(intersect); box2d<double> rem = policy_.transform(ext); if (ext.width() > 0.5 && ext.height() > 0.5 ) { // select minimum raster containing whole ext int x_off = static_cast<int>(floor(ext.minx())); int y_off = static_cast<int>(floor(ext.miny())); int end_x = static_cast<int>(ceil(ext.maxx())); int end_y = static_cast<int>(ceil(ext.maxy())); // clip to available data if (x_off < 0) x_off = 0; if (y_off < 0) y_off = 0; if (end_x > image_width) end_x = image_width; if (end_y > image_height) end_y = image_height; int width = end_x - x_off; int height = end_y - y_off; // calculate actual box2d of returned raster box2d<double> feature_raster_extent(rem.minx() + x_off, rem.miny() + y_off, rem.maxx() + x_off + width, rem.maxy() + y_off + height); intersect = t.backward(feature_raster_extent); image_data_32 image(width,height); reader->read(x_off, y_off, image); feature->set_raster(boost::make_shared<raster>(intersect, image)); } } } } catch (mapnik::image_reader_exception const& ex) { std::cerr << "Raster Plugin: image reader exception caught: " << ex.what() << std::endl; } catch (std::exception const& ex) { std::cerr << "Raster Plugin: " << ex.what() << std::endl; } catch (...) { std::cerr << "Raster Plugin: exception caught" << std::endl; } ++curIter_; return feature; } return feature_ptr(); }
feature_ptr geos_featureset::next() { if (! already_rendered_) { already_rendered_ = true; if (GEOSisValid(geometry_) && ! GEOSisEmpty(geometry_)) { bool render_geometry = true; if (*extent_ != NULL && GEOSisValid(*extent_) && !GEOSisEmpty(*extent_)) { const int type = GEOSGeomTypeId(*extent_); render_geometry = false; switch ( type ) { case GEOS_POINT: if (GEOSIntersects(*extent_, geometry_)) { render_geometry = true; } break; case GEOS_POLYGON: if (GEOSContains(*extent_, geometry_) || GEOSWithin(geometry_, *extent_) || GEOSEquals(geometry_, *extent_)) { render_geometry = true; } break; default: #ifdef MAPNIK_DEBUG clog << "GEOS Plugin: unknown extent geometry_type=" << type << endl; #endif break; } } if (render_geometry) { geos_wkb_ptr wkb(geometry_); if (wkb.is_valid()) { feature_ptr feature(feature_factory::create(identifier_)); geometry_utils::from_wkb(*feature, wkb.data(), wkb.size(), multiple_geometries_); if (field_ != "") { boost::put(*feature, field_name_, tr_->transcode(field_.c_str())); } return feature; } } } } return feature_ptr(); }
feature_ptr rasterlite_featureset::get_feature(mapnik::query const& q) { #ifdef MAPNIK_DEBUG std::clog << "Rasterlite Plugin: get_feature" << "\n"; #endif feature_ptr feature(new Feature(1)); double x0, y0, x1, y1; rasterliteGetExtent (dataset_, &x0, &y0, &x1, &y1); box2d<double> raster_extent(x0,y0,x1,y1); box2d<double> intersect = raster_extent.intersect(q.get_bbox()); int width = static_cast<int>(q.resolution() * intersect.width() + 0.5); int height = static_cast<int>(q.resolution() * intersect.height() + 0.5); double pixel_size = (intersect.width() >= intersect.height()) ? (intersect.width() / (double) width) : (intersect.height() / (double) height); #ifdef MAPNIK_DEBUG std::clog << "Rasterlite Plugin: Raster extent=" << raster_extent << "\n"; std::clog << "Rasterlite Plugin: View extent=" << q.get_bbox() << "\n"; std::clog << "Rasterlite Plugin: Intersect extent=" << intersect << "\n"; std::clog << "Rasterlite Plugin: Query resolution=" << q.resolution() << "\n"; std::clog << "Rasterlite Plugin: Size=" << width << " " << height << "\n"; std::clog << "Rasterlite Plugin: Pixel Size=" << pixel_size << "\n"; #endif if (width > 0 && height > 0) { int size; void *raster; if (rasterliteGetRawImageByRect(dataset_, intersect.minx(), intersect.miny(), intersect.maxx(), intersect.maxy(), pixel_size, width, height, GAIA_RGBA_ARRAY, &raster, &size) == RASTERLITE_OK) { if (size > 0) { mapnik::image_data_32 image(width, height); image.set(0xffffffff); unsigned char* raster_data = static_cast<unsigned char*>(raster); unsigned char* image_data = image.getBytes(); memcpy (image_data, raster_data, size); feature->set_raster(mapnik::raster_ptr(new mapnik::raster(intersect,image))); free (raster); #ifdef MAPNIK_DEBUG std::clog << "Rasterlite Plugin: Done" << "\n"; #endif } else { #ifdef MAPNIK_DEBUG std::clog << "Rasterlite Plugin: Error=" << rasterliteGetLastError (dataset_) << "\n"; #endif } } return feature; } return feature_ptr(); }
feature_ptr ogr_featureset::next() { if (count_ == 0) { // Reset the layer reading on the first feature read // this is a hack, but needed due to https://github.com/mapnik/mapnik/issues/2048 // Proper solution is to avoid storing layer state in featureset layer_.ResetReading(); } OGRFeature *poFeature; while ((poFeature = layer_.GetNextFeature()) != nullptr) { // ogr feature ids start at 0, so add one to stay // consistent with other mapnik datasources that start at 1 mapnik::value_integer feature_id = (poFeature->GetFID() + 1); feature_ptr feature(feature_factory::create(ctx_,feature_id)); OGRGeometry* geom = poFeature->GetGeometryRef(); if (geom && ! geom->IsEmpty()) { auto geom_corrected = ogr_converter::convert_geometry(geom); mapnik::geometry::correct(geom_corrected); feature->set_geometry(std::move(geom_corrected)); } else { MAPNIK_LOG_DEBUG(ogr) << "ogr_featureset: Feature with null geometry=" << poFeature->GetFID(); OGRFeature::DestroyFeature( poFeature ); continue; } ++count_; int fld_count = layerdef_->GetFieldCount(); for (int i = 0; i < fld_count; i++) { OGRFieldDefn* fld = layerdef_->GetFieldDefn(i); const OGRFieldType type_oid = fld->GetType(); const std::string fld_name = fld->GetNameRef(); switch (type_oid) { case OFTInteger: { feature->put<mapnik::value_integer>( fld_name, poFeature->GetFieldAsInteger(i)); break; } #if GDAL_VERSION_MAJOR >= 2 case OFTInteger64: { feature->put<mapnik::value_integer>( fld_name, poFeature->GetFieldAsInteger64(i)); break; } #endif case OFTReal: { feature->put( fld_name, poFeature->GetFieldAsDouble(i)); break; } case OFTString: case OFTWideString: // deprecated ! { feature->put( fld_name, tr_->transcode(poFeature->GetFieldAsString(i))); break; } case OFTIntegerList: #if GDAL_VERSION_MAJOR >= 2 case OFTInteger64List: #endif case OFTRealList: case OFTStringList: case OFTWideStringList: // deprecated ! { MAPNIK_LOG_WARN(ogr) << "ogr_featureset: Unhandled type_oid=" << type_oid; break; } case OFTBinary: { MAPNIK_LOG_WARN(ogr) << "ogr_featureset: Unhandled type_oid=" << type_oid; //feature->put(name,feat->GetFieldAsBinary (i, size)); break; } case OFTDate: case OFTTime: case OFTDateTime: // unhandled ! { MAPNIK_LOG_WARN(ogr) << "ogr_featureset: Unhandled type_oid=" << type_oid; break; } default: // unknown { MAPNIK_LOG_WARN(ogr) << "ogr_featureset: Unknown type_oid=" << type_oid; break; } } } OGRFeature::DestroyFeature( poFeature ); return feature; } MAPNIK_LOG_DEBUG(ogr) << "ogr_featureset: " << count_ << " features"; return feature_ptr(); }
feature_ptr gdal_featureset::get_feature(mapnik::query const& q) { feature_ptr feature = feature_factory::create(ctx_,1); GDALRasterBand * red = 0; GDALRasterBand * green = 0; GDALRasterBand * blue = 0; GDALRasterBand * alpha = 0; GDALRasterBand * grey = 0; /* #ifdef MAPNIK_LOG double tr[6]; dataset_.GetGeoTransform(tr); const double dx = tr[1]; const double dy = tr[5]; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: dx_=" << dx_ << " dx=" << dx << " dy_=" << dy_ << "dy=" << dy; #endif */ CoordTransform t(raster_width_, raster_height_, raster_extent_, 0, 0); box2d<double> intersect = raster_extent_.intersect(q.get_bbox()); box2d<double> box = t.forward(intersect); //size of resized output pixel in source image domain double margin_x = 1.0 / (fabs(dx_) * boost::get<0>(q.resolution())); double margin_y = 1.0 / (fabs(dy_) * boost::get<1>(q.resolution())); if (margin_x < 1) { margin_x = 1.0; } if (margin_y < 1) { margin_y = 1.0; } //select minimum raster containing whole box int x_off = rint(box.minx() - margin_x); int y_off = rint(box.miny() - margin_y); int end_x = rint(box.maxx() + margin_x); int end_y = rint(box.maxy() + margin_y); //clip to available data if (x_off < 0) { x_off = 0; } if (y_off < 0) { y_off = 0; } if (end_x > (int)raster_width_) { end_x = raster_width_; } if (end_y > (int)raster_height_) { end_y = raster_height_; } int width = end_x - x_off; int height = end_y - y_off; // don't process almost invisible data if (box.width() < 0.5) { width = 0; } if (box.height() < 0.5) { height = 0; } //calculate actual box2d of returned raster box2d<double> feature_raster_extent(x_off, y_off, x_off + width, y_off + height); intersect = t.backward(feature_raster_extent); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Raster extent=" << raster_extent_; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: View extent=" << intersect; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Query resolution=" << boost::get<0>(q.resolution()) << "," << boost::get<1>(q.resolution()); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: StartX=" << x_off << " StartY=" << y_off << " Width=" << width << " Height=" << height; if (width > 0 && height > 0) { double width_res = boost::get<0>(q.resolution()); double height_res = boost::get<1>(q.resolution()); int im_width = int(width_res * intersect.width() + 0.5); int im_height = int(height_res * intersect.height() + 0.5); // if layer-level filter_factor is set, apply it if (filter_factor_) { im_width *= filter_factor_; im_height *= filter_factor_; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Applying layer filter_factor=" << filter_factor_; } // otherwise respect symbolizer level factor applied to query, default of 1.0 else { double sym_downsample_factor = q.get_filter_factor(); im_width *= sym_downsample_factor; im_height *= sym_downsample_factor; } // case where we need to avoid upsampling so that the // image can be later scaled within raster_symbolizer if (im_width >= width || im_height >= height) { im_width = width; im_height = height; } if (im_width > 0 && im_height > 0) { mapnik::raster_ptr raster = boost::make_shared<mapnik::raster>(intersect, im_width, im_height); feature->set_raster(raster); mapnik::image_data_32 & image = raster->data_; image.set(0xffffffff); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Image Size=(" << im_width << "," << im_height << ")"; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Reading band=" << band_; if (band_ > 0) // we are querying a single band { if (band_ > nbands_) { throw datasource_exception((boost::format("GDAL Plugin: '%d' is an invalid band, dataset only has '%d' bands\n") % band_ % nbands_).str()); } float* imageData = (float*)image.getBytes(); GDALRasterBand * band = dataset_.GetRasterBand(band_); int hasNoData(0); double nodata(0); if (nodata_value_) { hasNoData = 1; nodata = *nodata_value_; } else { nodata = band->GetNoDataValue(&hasNoData); } band->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); if (hasNoData) { feature->put("NODATA",nodata); } } else // working with all bands { for (int i = 0; i < nbands_; ++i) { GDALRasterBand * band = dataset_.GetRasterBand(i + 1); #ifdef MAPNIK_LOG get_overview_meta(band); #endif GDALColorInterp color_interp = band->GetColorInterpretation(); switch (color_interp) { case GCI_RedBand: red = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found red band"; break; case GCI_GreenBand: green = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found green band"; break; case GCI_BlueBand: blue = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found blue band"; break; case GCI_AlphaBand: alpha = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found alpha band"; break; case GCI_GrayIndex: grey = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band"; break; case GCI_PaletteIndex: { grey = band; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found gray band, and colortable..."; GDALColorTable *color_table = band->GetColorTable(); if (color_table) { int count = color_table->GetColorEntryCount(); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color Table count=" << count; for (int j = 0; j < count; j++) { const GDALColorEntry *ce = color_table->GetColorEntry (j); if (! ce) continue; MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Color entry RGB=" << ce->c1 << "," <<ce->c2 << "," << ce->c3; } } break; } case GCI_Undefined: MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Found undefined band (assumming gray band)"; grey = band; break; default: MAPNIK_LOG_WARN(gdal) << "gdal_featureset: Band type unknown!"; break; } } if (red && green && blue) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing rgb bands..."; int hasNoData = 0; double nodata = 0.0; if (nodata_value_) { hasNoData = 1; nodata = *nodata_value_; } else { nodata = red->GetNoDataValue(&hasNoData); } if (hasNoData) { feature->put("NODATA",nodata); } GDALColorTable *color_table = red->GetColorTable(); if (! alpha && hasNoData && ! color_table) { // first read the data in and create an alpha channel from the nodata values float* imageData = (float*)image.getBytes(); red->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); int len = image.width() * image.height(); for (int i = 0; i < len; ++i) { if (nodata == imageData[i]) { *reinterpret_cast<unsigned *>(&imageData[i]) = 0; } else { *reinterpret_cast<unsigned *>(&imageData[i]) = 0xFFFFFFFF; } } } red->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 0, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); green->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 1, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); blue->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 2, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); } else if (grey) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Processing gray band..."; int hasNoData(0); double nodata(0); if (nodata_value_) { hasNoData = 1; nodata = *nodata_value_; } else { nodata = grey->GetNoDataValue(&hasNoData); } GDALColorTable* color_table = grey->GetColorTable(); if (hasNoData && ! color_table) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: No data value for layer=" << nodata; feature->put("NODATA",nodata); // first read the data in and create an alpha channel from the nodata values float* imageData = (float*)image.getBytes(); grey->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); int len = image.width() * image.height(); for (int i = 0; i < len; ++i) { if (nodata == imageData[i]) { *reinterpret_cast<unsigned *>(&imageData[i]) = 0; } else { *reinterpret_cast<unsigned *> (&imageData[i]) = 0xFFFFFFFF; } } } grey->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 0, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); grey->RasterIO(GF_Read,x_off, y_off, width, height, image.getBytes() + 1, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); grey->RasterIO(GF_Read,x_off, y_off, width, height, image.getBytes() + 2, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); if (color_table) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Loading colour table..."; unsigned nodata_value = static_cast<unsigned>(nodata); if (hasNoData) { feature->put("NODATA",static_cast<int>(nodata_value)); } for (unsigned y = 0; y < image.height(); ++y) { unsigned int* row = image.getRow(y); for (unsigned x = 0; x < image.width(); ++x) { unsigned value = row[x] & 0xff; if (hasNoData && (value == nodata_value)) { // make no data fully alpha row[x] = 0; } else { const GDALColorEntry *ce = color_table->GetColorEntry(value); if (ce) { // TODO - big endian support row[x] = (ce->c4 << 24)| (ce->c3 << 16) | (ce->c2 << 8) | (ce->c1) ; } else { // make lacking color entry fully alpha // note - gdal_translate makes black row[x] = 0; } } } } } } if (alpha) { MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: processing alpha band..."; alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 3, image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); } } return feature; } } return feature_ptr(); }
feature_ptr osm_featureset<filterT>::next() { feature_ptr feature; osm_item* cur_item = dataset_->next_item(); if (!cur_item) return feature_ptr(); if (dataset_->current_item_is_node()) { feature = feature_factory::create(ctx_, cur_item->id); double lat = static_cast<osm_node*>(cur_item)->lat; double lon = static_cast<osm_node*>(cur_item)->lon; geometry_type* point = new geometry_type(mapnik::Point); point->move_to(lon, lat); feature->add_geometry(point); } else if (dataset_->current_item_is_way()) { // Loop until we find a feature which passes the filter while (cur_item) { bounds b = static_cast<osm_way*>(cur_item)->get_bounds(); if (filter_.pass(box2d<double>(b.w, b.s, b.e, b.n)) && static_cast<osm_way*>(cur_item)->nodes.size()) break; cur_item = dataset_->next_item(); } if (!cur_item) return feature_ptr(); feature = feature_factory::create(ctx_, cur_item->id); geometry_type* geom; if (static_cast<osm_way*>(cur_item)->is_polygon()) { geom = new geometry_type(mapnik::Polygon); } else { geom = new geometry_type(mapnik::LineString); } geom->move_to(static_cast<osm_way*>(cur_item)->nodes[0]->lon, static_cast<osm_way*>(cur_item)->nodes[0]->lat); for (unsigned int count = 1; count < static_cast<osm_way*>(cur_item)->nodes.size(); count++) { geom->line_to(static_cast<osm_way*>(cur_item)->nodes[count]->lon, static_cast<osm_way*>(cur_item)->nodes[count]->lat); } feature->add_geometry(geom); } else { MAPNIK_LOG_ERROR(osm_featureset) << "Current item is neither node nor way.\n"; } std::set<std::string>::const_iterator itr = attribute_names_.begin(); std::set<std::string>::const_iterator end = attribute_names_.end(); std::map<std::string,std::string>::iterator end_keyvals = cur_item->keyvals.end(); for (; itr != end; itr++) { std::map<std::string,std::string>::iterator i = cur_item->keyvals.find(*itr); if (i != end_keyvals) { feature->put_new(i->first, tr_->transcode(i->second.c_str())); } } return feature; }
feature_ptr rasterlite_featureset::get_feature_at_point(mapnik::coord2d const& pt) { return feature_ptr(); }
feature_ptr raster_featureset<LookupPolicy>::next() { if (curIter_ != endIter_) { feature_ptr feature(feature_factory::create(ctx_,feature_id_++)); try { std::auto_ptr<image_reader> reader(mapnik::get_image_reader(curIter_->file(),curIter_->format())); MAPNIK_LOG_DEBUG(raster) << "raster_featureset: Reader=" << curIter_->format() << "," << curIter_->file() << ",size(" << curIter_->width() << "," << curIter_->height() << ")"; if (reader.get()) { int image_width = policy_.img_width(reader->width()); int image_height = policy_.img_height(reader->height()); if (image_width > 0 && image_height > 0) { mapnik::CoordTransform t(image_width, image_height, extent_, 0, 0); box2d<double> intersect = bbox_.intersect(curIter_->envelope()); box2d<double> ext = t.forward(intersect); box2d<double> rem = policy_.transform(ext); if (ext.width() > 0.5 && ext.height() > 0.5 ) { // select minimum raster containing whole ext int x_off = static_cast<int>(std::floor(ext.minx())); int y_off = static_cast<int>(std::floor(ext.miny())); int end_x = static_cast<int>(std::ceil(ext.maxx())); int end_y = static_cast<int>(std::ceil(ext.maxy())); // clip to available data if (x_off < 0) x_off = 0; if (y_off < 0) y_off = 0; if (end_x > image_width) end_x = image_width; if (end_y > image_height) end_y = image_height; int width = end_x - x_off; int height = end_y - y_off; // calculate actual box2d of returned raster box2d<double> feature_raster_extent(rem.minx() + x_off, rem.miny() + y_off, rem.maxx() + x_off + width, rem.maxy() + y_off + height); intersect = t.backward(feature_raster_extent); mapnik::raster_ptr raster = boost::make_shared<mapnik::raster>(intersect, width, height); reader->read(x_off, y_off, raster->data_); raster->premultiplied_alpha_ = reader->premultiplied_alpha(); feature->set_raster(raster); } } } } catch (mapnik::image_reader_exception const& ex) { MAPNIK_LOG_ERROR(raster) << "Raster Plugin: image reader exception caught: " << ex.what(); } catch (std::exception const& ex) { MAPNIK_LOG_ERROR(raster) << "Raster Plugin: " << ex.what(); } catch (...) { MAPNIK_LOG_ERROR(raster) << "Raster Plugin: exception caught"; } ++curIter_; return feature; } return feature_ptr(); }
feature_ptr ogr_index_featureset<filterT>::next() { while (itr_ != ids_.end()) { int pos = *itr_++; layer_.SetNextByIndex (pos); OGRFeature *poFeature = layer_.GetNextFeature(); if (poFeature == nullptr) { return feature_ptr(); } // ogr feature ids start at 0, so add one to stay // consistent with other mapnik datasources that start at 1 mapnik::value_integer feature_id = (poFeature->GetFID() + 1); feature_ptr feature(feature_factory::create(ctx_,feature_id)); OGRGeometry* geom=poFeature->GetGeometryRef(); if (geom && !geom->IsEmpty()) { geom->getEnvelope(&feature_envelope_); if (!filter_.pass(mapnik::box2d<double>(feature_envelope_.MinX,feature_envelope_.MinY, feature_envelope_.MaxX,feature_envelope_.MaxY))) continue; feature->set_geometry(std::move(ogr_converter::convert_geometry(geom))); } else { MAPNIK_LOG_DEBUG(ogr) << "ogr_index_featureset: Feature with null geometry=" << poFeature->GetFID(); OGRFeature::DestroyFeature( poFeature ); continue; } int fld_count = layerdef_->GetFieldCount(); for (int i = 0; i < fld_count; i++) { OGRFieldDefn* fld = layerdef_->GetFieldDefn (i); OGRFieldType type_oid = fld->GetType (); std::string fld_name = fld->GetNameRef (); switch (type_oid) { case OFTInteger: { feature->put<mapnik::value_integer>(fld_name,poFeature->GetFieldAsInteger (i)); break; } case OFTReal: { feature->put(fld_name,poFeature->GetFieldAsDouble (i)); break; } case OFTString: case OFTWideString: // deprecated ! { feature->put(fld_name,tr_->transcode(poFeature->GetFieldAsString (i))); break; } case OFTIntegerList: case OFTRealList: case OFTStringList: case OFTWideStringList: // deprecated ! { MAPNIK_LOG_WARN(ogr) << "ogr_index_featureset: Unhandled type_oid=" << type_oid; break; } case OFTBinary: { MAPNIK_LOG_WARN(ogr) << "ogr_index_featureset: Unhandled type_oid=" << type_oid; //feature->put(name,feat->GetFieldAsBinary (i, size)); break; } case OFTDate: case OFTTime: case OFTDateTime: // unhandled ! { MAPNIK_LOG_WARN(ogr) << "ogr_index_featureset: Unhandled type_oid=" << type_oid; break; } } } OGRFeature::DestroyFeature( poFeature ); return feature; } return feature_ptr(); }
feature_ptr ogr_index_featureset<filterT>::next() { if (itr_ != ids_.end()) { int pos = *itr_++; layer_.SetNextByIndex (pos); ogr_feature_ptr feat (layer_.GetNextFeature()); if ((*feat) != NULL) { OGRGeometry* geom=(*feat)->GetGeometryRef(); if (!geom->IsEmpty()) { feature_ptr feature(new Feature((*feat)->GetFID())); ogr_converter::convert_geometry (geom, feature, multiple_geometries_); ++count_; int fld_count = layerdef_->GetFieldCount(); for (int i = 0; i < fld_count; i++) { OGRFieldDefn* fld = layerdef_->GetFieldDefn (i); OGRFieldType type_oid = fld->GetType (); std::string fld_name = fld->GetNameRef (); switch (type_oid) { case OFTInteger: { boost::put(*feature,fld_name,(*feat)->GetFieldAsInteger (i)); break; } case OFTReal: { boost::put(*feature,fld_name,(*feat)->GetFieldAsDouble (i)); break; } case OFTString: case OFTWideString: // deprecated ! { UnicodeString ustr = tr_->transcode((*feat)->GetFieldAsString (i)); boost::put(*feature,fld_name,ustr); break; } case OFTIntegerList: case OFTRealList: case OFTStringList: case OFTWideStringList: // deprecated ! { #ifdef MAPNIK_DEBUG clog << "unhandled type_oid=" << type_oid << endl; #endif break; } case OFTBinary: { #ifdef MAPNIK_DEBUG clog << "unhandled type_oid=" << type_oid << endl; #endif //boost::put(*feature,name,feat->GetFieldAsBinary (i, size)); break; } case OFTDate: case OFTTime: case OFTDateTime: // unhandled ! { #ifdef MAPNIK_DEBUG clog << "unhandled type_oid=" << type_oid << endl; #endif break; } default: // unknown { #ifdef MAPNIK_DEBUG clog << "unknown type_oid=" << type_oid << endl; #endif break; } } } return feature; } } } #ifdef MAPNIK_DEBUG clog << count_ << " features" << endl; #endif return feature_ptr(); }
feature_ptr sqlite_featureset::next() { while (rs_->is_valid () && rs_->step_next ()) { int size; const char* data = (const char*) rs_->column_blob(0, size); if (data == 0) { return feature_ptr(); } // null feature id is not acceptable if (rs_->column_type(1) == SQLITE_NULL) { MAPNIK_LOG_ERROR(postgis) << "sqlite_featureset: null value encountered for key_field"; continue; } feature_ptr feature = feature_factory::create(ctx_,rs_->column_integer64(1)); if (!geometry_utils::from_wkb(feature->paths(), data, size, format_)) continue; if (!spatial_index_) { // we are not using r-tree index, check if feature intersects bounding box if (!bbox_.intersects(feature->envelope())) continue; } for (int i = 2; i < rs_->column_count(); ++i) { const int type_oid = rs_->column_type(i); const char* fld_name = rs_->column_name(i); if (! fld_name) continue; std::string fld_name_str(fld_name); // subqueries in sqlite lead to field double quoting which we need to strip if (using_subquery_) { sqlite_utils::dequote(fld_name_str); } switch (type_oid) { case SQLITE_INTEGER: { feature->put<mapnik::value_integer>(fld_name_str, rs_->column_integer64(i)); break; } case SQLITE_FLOAT: { feature->put(fld_name_str, rs_->column_double(i)); break; } case SQLITE_TEXT: { int text_col_size; const char * text_data = rs_->column_text(i, text_col_size); feature->put(fld_name_str, tr_->transcode(text_data, text_col_size)); break; } case SQLITE_NULL: { // NOTE: we intentionally do not store null here // since it is equivalent to the attribute not existing break; } case SQLITE_BLOB: break; default: MAPNIK_LOG_WARN(sqlite) << "sqlite_featureset: Field=" << fld_name_str << " unhandled type_oid=" << type_oid; break; } } return feature; } return feature_ptr(); }
feature_ptr osm_featureset<filterT>::next() { feature_ptr feature; bool success = false; osm_item* cur_item = dataset_->next_item(); if (cur_item != NULL) { if (dataset_->current_item_is_node()) { feature = feature_factory::create(feature_id_); ++feature_id_; double lat = static_cast<osm_node*>(cur_item)->lat; double lon = static_cast<osm_node*>(cur_item)->lon; geometry_type* point = new geometry_type(mapnik::Point); point->move_to(lon, lat); feature->add_geometry(point); success = true; } else if (dataset_->current_item_is_way()) { bounds b = static_cast<osm_way*>(cur_item)->get_bounds(); // Loop until we find a feature which passes the filter while (cur_item != NULL && ! filter_.pass(box2d<double>(b.w, b.s, b.e, b.n))) { cur_item = dataset_->next_item(); if (cur_item != NULL) { b = static_cast<osm_way*>(cur_item)->get_bounds(); } } if (cur_item != NULL) { if (static_cast<osm_way*>(cur_item)->nodes.size()) { feature = feature_factory::create(feature_id_); ++feature_id_; geometry_type* geom; if (static_cast<osm_way*>(cur_item)->is_polygon()) { geom = new geometry_type(mapnik::Polygon); } else { geom = new geometry_type(mapnik::LineString); } geom->set_capacity(static_cast<osm_way*>(cur_item)->nodes.size()); geom->move_to(static_cast<osm_way*>(cur_item)->nodes[0]->lon, static_cast<osm_way*>(cur_item)->nodes[0]->lat); for (unsigned int count = 1; count < static_cast<osm_way*>(cur_item)->nodes.size(); count++) { geom->line_to(static_cast<osm_way*>(cur_item)->nodes[count]->lon, static_cast<osm_way*>(cur_item)->nodes[count]->lat); } feature->add_geometry(geom); success = true; } } } // can feature_ptr be compared to NULL? - no if (success) { std::map<std::string,std::string>::iterator i = cur_item->keyvals.begin(); // add the keyvals to the feature. the feature seems to be a map // of some sort so this should work - see dbf_file::add_attribute() while (i != cur_item->keyvals.end()) { // only add if in the specified set of attribute names if (attribute_names_.find(i->first) != attribute_names_.end()) { (*feature)[i->first] = tr_->transcode(i->second.c_str()); } i++; } return feature; } } return feature_ptr(); }
feature_ptr ogr_index_featureset<filterT>::next() { if (itr_ != ids_.end()) { int pos = *itr_++; layer_.SetNextByIndex (pos); ogr_feature_ptr feat (layer_.GetNextFeature()); if ((*feat) != NULL) { // ogr feature ids start at 0, so add one to stay // consistent with other mapnik datasources that start at 1 int feature_id = ((*feat)->GetFID() + 1); feature_ptr feature(feature_factory::create(feature_id)); OGRGeometry* geom=(*feat)->GetGeometryRef(); if (geom && !geom->IsEmpty()) { ogr_converter::convert_geometry (geom, feature, multiple_geometries_); } #ifdef MAPNIK_DEBUG else { std::clog << "### Warning: feature with null geometry: " << (*feat)->GetFID() << "\n"; } #endif int fld_count = layerdef_->GetFieldCount(); for (int i = 0; i < fld_count; i++) { OGRFieldDefn* fld = layerdef_->GetFieldDefn (i); OGRFieldType type_oid = fld->GetType (); std::string fld_name = fld->GetNameRef (); switch (type_oid) { case OFTInteger: { boost::put(*feature,fld_name,(*feat)->GetFieldAsInteger (i)); break; } case OFTReal: { boost::put(*feature,fld_name,(*feat)->GetFieldAsDouble (i)); break; } case OFTString: case OFTWideString: // deprecated ! { UnicodeString ustr = tr_->transcode((*feat)->GetFieldAsString (i)); boost::put(*feature,fld_name,ustr); break; } case OFTIntegerList: case OFTRealList: case OFTStringList: case OFTWideStringList: // deprecated ! { #ifdef MAPNIK_DEBUG std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl; #endif break; } case OFTBinary: { #ifdef MAPNIK_DEBUG std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl; #endif //boost::put(*feature,name,feat->GetFieldAsBinary (i, size)); break; } case OFTDate: case OFTTime: case OFTDateTime: // unhandled ! { #ifdef MAPNIK_DEBUG std::clog << "OGR Plugin: unhandled type_oid=" << type_oid << std::endl; #endif break; } default: // unknown { #ifdef MAPNIK_DEBUG std::clog << "OGR Plugin: unknown type_oid=" << type_oid << std::endl; #endif break; } } } return feature; } } return feature_ptr(); }
feature_ptr gdal_featureset::get_feature(mapnik::query const& q) { feature_ptr feature(new Feature(1)); GDALRasterBand * red = 0; GDALRasterBand * green = 0; GDALRasterBand * blue = 0; GDALRasterBand * alpha = 0; GDALRasterBand * grey = 0; /* double tr[6]; dataset_.GetGeoTransform(tr); double dx = tr[1]; double dy = tr[5]; std::clog << "dx_: " << dx_ << " dx: " << dx << " dy_: " << dy_ << "dy: " << dy << "\n"; */ CoordTransform t(raster_width_,raster_height_,raster_extent_,0,0); box2d<double> intersect = raster_extent_.intersect(q.get_bbox()); box2d<double> box = t.forward(intersect); //size of resized output pixel in source image domain double margin_x = 1.0/(fabs(dx_)*boost::get<0>(q.resolution())); double margin_y = 1.0/(fabs(dy_)*boost::get<1>(q.resolution())); if (margin_x < 1) margin_x = 1.0; if (margin_y < 1) margin_y = 1.0; //select minimum raster containing whole box int x_off = rint(box.minx() - margin_x); int y_off = rint(box.miny() - margin_y); int end_x = rint(box.maxx() + margin_x); int end_y = rint(box.maxy() + margin_y); //clip to available data if (x_off < 0) x_off = 0; if (y_off < 0) y_off = 0; if (end_x > (int)raster_width_) end_x = raster_width_; if (end_y > (int)raster_height_) end_y = raster_height_; int width = end_x - x_off; int height = end_y - y_off; // don't process almost invisible data if (box.width() < 0.5) width = 0; if (box.height() < 0.5) height = 0; //calculate actual box2d of returned raster box2d<double> feature_raster_extent(x_off, y_off, x_off+width, y_off+height); intersect = t.backward(feature_raster_extent); #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Raster extent=" << raster_extent_ << std::endl; std::clog << "GDAL Plugin: View extent=" << intersect << std::endl; std::clog << "GDAL Plugin: Query resolution=" << boost::get<0>(q.resolution()) << "," << boost::get<1>(q.resolution()) << std::endl; std::clog << boost::format("GDAL Plugin: StartX=%d StartY=%d Width=%d Height=%d") % x_off % y_off % width % height << std::endl; #endif if (width > 0 && height > 0) { double width_res = boost::get<0>(q.resolution()); double height_res = boost::get<1>(q.resolution()); int im_width = int(width_res * intersect.width() + 0.5); int im_height = int(height_res * intersect.height() + 0.5); // if layer-level filter_factor is set, apply it if (filter_factor_) { im_width *= filter_factor_; im_height *= filter_factor_; } // otherwise respect symbolizer level factor applied to query, default of 1.0 else { double sym_downsample_factor = q.get_filter_factor(); im_width *= sym_downsample_factor; im_height *= sym_downsample_factor; } // case where we need to avoid upsampling so that the // image can be later scaled within raster_symbolizer if (im_width >= width || im_height >= height) { im_width = width; im_height = height; } if (im_width > 0 && im_height > 0) { mapnik::image_data_32 image(im_width, im_height); image.set(0xffffffff); #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Image Size=(" << im_width << "," << im_height << ")" << std::endl; std::clog << "GDAL Plugin: Reading band " << band_ << std::endl; #endif typedef std::vector<int,int> pallete; if (band_ > 0) // we are querying a single band { if (band_ > nbands_) throw datasource_exception((boost::format("GDAL Plugin: '%d' is an invalid band, dataset only has '%d' bands\n") % band_ % nbands_).str()); float *imageData = (float*)image.getBytes(); GDALRasterBand * band = dataset_.GetRasterBand(band_); band->RasterIO(GF_Read, x_off, y_off, width, height, imageData, image.width(), image.height(), GDT_Float32, 0, 0); feature->set_raster(mapnik::raster_ptr(new mapnik::raster(intersect,image))); } else // working with all bands { for (int i = 0; i < nbands_; ++i) { GDALRasterBand * band = dataset_.GetRasterBand(i+1); #ifdef MAPNIK_DEBUG get_overview_meta(band); #endif GDALColorInterp color_interp = band->GetColorInterpretation(); switch (color_interp) { case GCI_RedBand: red = band; #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Found red band" << std::endl; #endif break; case GCI_GreenBand: green = band; #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Found green band" << std::endl; #endif break; case GCI_BlueBand: blue = band; #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Found blue band" << std::endl; #endif break; case GCI_AlphaBand: alpha = band; #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Found alpha band" << std::endl; #endif break; case GCI_GrayIndex: grey = band; #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Found gray band" << std::endl; #endif break; case GCI_PaletteIndex: { grey = band; #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Found gray band, and colortable..." << std::endl; #endif GDALColorTable *color_table = band->GetColorTable(); if ( color_table) { int count = color_table->GetColorEntryCount(); #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Color Table count = " << count << std::endl; #endif for (int j = 0; j < count; j++) { const GDALColorEntry *ce = color_table->GetColorEntry (j); if (! ce) continue; #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Color entry RGB (" << ce->c1 << "," <<ce->c2 << "," << ce->c3 << ")" << std::endl; #endif } } break; } case GCI_Undefined: #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: Found undefined band (assumming gray band)" << std::endl; #endif grey = band; break; default: #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: band type unknown!" << std::endl; #endif break; } } if (red && green && blue) { #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: processing rgb bands..." << std::endl; #endif red->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 0, image.width(),image.height(),GDT_Byte,4,4*image.width()); green->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 1, image.width(),image.height(),GDT_Byte,4,4*image.width()); blue->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 2, image.width(),image.height(),GDT_Byte,4,4*image.width()); } else if (grey) { #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: processing gray band..." << std::endl; #endif // TODO : apply colormap if present grey->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 0, image.width(),image.height(),GDT_Byte, 4, 4 * image.width()); grey->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 1, image.width(),image.height(),GDT_Byte, 4, 4 * image.width()); grey->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 2, image.width(),image.height(),GDT_Byte, 4, 4 * image.width()); } if (alpha) { #ifdef MAPNIK_DEBUG std::clog << "GDAL Plugin: processing alpha band..." << std::endl; #endif alpha->RasterIO(GF_Read,x_off,y_off,width,height,image.getBytes() + 3, image.width(),image.height(),GDT_Byte,4,4*image.width()); } feature->set_raster(mapnik::raster_ptr(new mapnik::raster(intersect,image))); } return feature; } } return feature_ptr(); }