BufferPtr IteratorBase::fetchPointBuffer(Statement statement, sdo_pc* pc) { boost::int32_t id = statement->GetInteger(&pc->pc_id); BufferMap::const_iterator i = m_buffers.find(id); if (i != m_buffers.end()) { getReader().log()->get(logDEBUG2) << "IteratorBase::fetchPointBuffer: found existing PointBuffer with id " << id << std::endl; return i->second; } else { boost::uint32_t block_capacity(0); Schema schema = m_reader.fetchSchema(statement, pc, block_capacity, getReader().getName()); m_orientation = schema.getOrientation(); getReader().log()->get(logDEBUG2) << "Incoming schema orientation is " << m_orientation << std::endl; BufferPtr output = BufferPtr(new PointBuffer(schema, block_capacity)); std::pair<int, BufferPtr> p(id, output); m_buffers.insert(p); getReader().log()->get(logDEBUG2) << "IteratorBase::fetchPointBuffer: creating new PointBuffer with id " << id << std::endl; return p.second; } }
DimensionMapPtr IteratorBase::fetchDimensionMap(Statement statement, sdo_pc* pc, PointBuffer const& oracle_buffer, PointBuffer const& user_buffer) { boost::int32_t id = statement->GetInteger(&pc->pc_id); DimensionMaps::const_iterator i = m_dimensions.find(id); if (i != m_dimensions.end()) { getReader().log()->get(logDEBUG2) << "IteratorBase::fetchDimensionMap: found existing DimensionMap with id " << id << std::endl; return i->second; } else { DimensionMapPtr output = DimensionMapPtr(m_oracle_buffer->getSchema().mapDimensions( user_buffer.getSchema(), false /*ignore namespaces*/)); getReader().log()->get(logDEBUG2) << "DimensionMapPtr->size(): " << output->size() << std::endl; if (!output->size()) throw pdal_error("fetchDimensionMap map was unable to map any dimensions!"); for (schema::DimensionMap::const_iterator i = output->begin(); i != output->end(); ++i) { getReader().log()->get(logDEBUG2) << "mapping " << i->first->getFQName() << " to " << i->second->getFQName() << std::endl; } std::pair<int, DimensionMapPtr> p(id, output); m_dimensions.insert(p); getReader().log()->get(logDEBUG2) << "IteratorBase::fetchDimensionMap: creating new DimensionMap with id " << id << std::endl; return p.second; } }
schema::XMLSchema fetchSchema(Statement stmt, BlockPtr block) { // Fetch the XML that defines the schema for this point cloud std::ostringstream schemaQuery; OCILobLocator* metadata = NULL; schemaQuery << "DECLARE" << std::endl << "PC_TABLE VARCHAR2(32) := '" << stmt->GetString(block->pc->base_table) << "';" << std::endl << "PC_ID NUMBER := " << stmt->GetInteger(&(block->pc->pc_id)) << ";" << std::endl << "PC_COLUMN VARCHAR2(32) := '" << stmt->GetString(block->pc->base_column) << "';" << std::endl << "BEGIN" << std::endl << std::endl << "EXECUTE IMMEDIATE" << std::endl << " 'SELECT T.'||PC_COLUMN||'.PC_OTHER_ATTRS.getClobVal()" "FROM '||pc_table||' T WHERE T.ID='||" "PC_ID INTO :metadata;" << std::endl << "END;" << std::endl; Statement getSchemaStmt( block->m_connection->CreateStatement(schemaQuery.str().c_str())); getSchemaStmt->BindName(":metadata", &metadata); getSchemaStmt->Execute(); char* pc_schema = getSchemaStmt->ReadCLob(metadata); std::string pc_schema_xml; if (pc_schema) { pc_schema_xml = pc_schema; CPLFree(pc_schema); } std::ostringstream fname; int cloudId = stmt->GetInteger(&(block->pc->pc_id)) ; // fname << "schema-" << cloudId <<".xml"; // std::ostream* out = FileUtils::createFile(fname.str()); // out->write(pc_schema_xml.c_str(), pc_schema_xml.size()); // FileUtils::closeFile(out); return schema::Reader(pc_schema_xml).schema(); }
pdal::SpatialReference OciReader::fetchSpatialReference(Statement stmt, BlockPtr block) const { // Fetch the WKT for the SRID to set the coordinate system of this stage int srid = stmt->GetInteger(&(block->pc->pc_geometry.sdo_srid)); if (srid) { std::ostringstream oss; oss << "EPSG:" << srid; return pdal::SpatialReference(oss.str()); } return pdal::SpatialReference(); }
pdal::Schema Reader::fetchSchema(Statement statement, sdo_pc* pc, boost::uint32_t& capacity, std::string ns_override) const { log()->get(logDEBUG) << "Fetching schema from SDO_PC object" << std::endl; // Fetch the XML that defines the schema for this point cloud std::ostringstream select_schema; OCILobLocator* metadata = NULL; select_schema << "DECLARE" << std::endl << "PC_TABLE VARCHAR2(32) := '" << statement->GetString(pc->base_table) << "';" << std::endl << "PC_ID NUMBER := " << statement->GetInteger(&(pc->pc_id)) << ";" << std::endl << "PC_COLUMN VARCHAR2(32) := '" << statement->GetString(pc->base_column) << "';" << std::endl << "BEGIN" << std::endl << std::endl << "EXECUTE IMMEDIATE" << std::endl << " 'SELECT T.'||PC_COLUMN||'.PC_OTHER_ATTRS.getClobVal(), T.'||PC_COLUMN||'.PTN_PARAMS FROM '||pc_table||' T WHERE T.ID='||PC_ID INTO :metadata, :capacity;" << std::endl << "END;" << std::endl; Statement get_schema(m_connection->CreateStatement(select_schema.str().c_str())); get_schema->BindName(":metadata", &metadata); int ptn_params_length = 1024; char* ptn_params = (char*) malloc(sizeof(char*) * ptn_params_length); ptn_params[ptn_params_length-1] = '\0'; //added trailing null to fix ORA-01480 get_schema->BindName(":capacity", ptn_params, ptn_params_length); get_schema->Execute(); char* pc_schema = get_schema->ReadCLob(metadata); std::string write_schema_file = getOptions().getValueOrDefault<std::string>("xml_schema_dump", std::string("")); if (write_schema_file.size() > 0) { std::ostream* out = FileUtils::createFile(write_schema_file); out->write(pc_schema, strlen(pc_schema)); FileUtils::closeFile(out); } // Fetch the block capacity from the point cloud object so we // can use it later. // PTN_PARAMS is like: // 'blk_capacity=1000,work_tablespace=my_work_ts' int block_capacity = 0; boost::char_separator<char> sep_space(" "); boost::char_separator<char> sep_equal("="); std::string s_cap(ptn_params); tokenizer parameters(s_cap, sep_space); for (tokenizer::iterator t = parameters.begin(); t != parameters.end(); ++t) { tokenizer parameter((*t), sep_equal); for (tokenizer::iterator c = parameter.begin(); c != parameter.end(); ++c) { if (boost::iequals(c->c_str(), "blk_capacity")) { tokenizer::iterator d = ++c; block_capacity = atoi(d->c_str()); } } } if (block_capacity < 1) { std::ostringstream oss; oss << "Invalid block capacity for point cloud object in Oracle: " << block_capacity; throw pdal_error(oss.str()); } capacity = block_capacity; std::string pc_schema_xml(pc_schema); if (pc_schema) CPLFree(pc_schema); if (ptn_params) free(ptn_params); Schema schema = Schema::from_xml(pc_schema_xml); schema::index_by_index const& dims = schema.getDimensions().get<schema::index>(); for (schema::index_by_index::const_iterator iter = dims.begin(); iter != dims.end(); ++iter) { // For dimensions that do not have namespaces, we'll set the namespace // to the namespace of the current stage if (iter->getNamespace().size() == 0) { log()->get(logDEBUG4) << "setting namespace for dimension " << iter->getName() << " to " << getName() << std::endl; Dimension d(*iter); if (iter->getUUID().is_nil()) { d.createUUID(); } if (ns_override.size() > 0) { d.setNamespace(ns_override); } else { d.setNamespace(getName()); } schema.setDimension(d); } } return schema; }