diff --git a/cmake/options.cmake b/cmake/options.cmake index 457c4024fa..e69564c36a 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -22,6 +22,11 @@ option(BUILD_PLUGIN_GEOWAVE add_feature_info("GeoWave plugin" BUILD_PLUGIN_GEOWAVE "Read and Write data using GeoWave") +option(BUILD_PLUGIN_I3S + "Choose if I3S support should be built" FALSE) +add_feature_info("I3S plugin" BUILD_PLUGIN_I3S + "Read from a i3s server") + option(BUILD_PLUGIN_GREYHOUND "Choose if Greyhound support should be built" FALSE) add_feature_info("Greyhound plugin" BUILD_PLUGIN_GREYHOUND diff --git a/kernels/InfoKernel.cpp b/kernels/InfoKernel.cpp index 51882993a7..37057da2fd 100644 --- a/kernels/InfoKernel.cpp +++ b/kernels/InfoKernel.cpp @@ -277,7 +277,9 @@ MetadataNode InfoKernel::dumpSummary(const QuickInfo& qi) void InfoKernel::makePipeline(const std::string& filename, bool noPoints) { - if (!pdal::Utils::fileExists(filename)) + if (filename.find("://") != std::string::npos) + m_log->get(LogLevel::Debug) << "Protocol Found" << std::endl; + else if (!pdal::Utils::fileExists(filename)) throw pdal_error("File not found: " + filename); if (filename == "STDIN") diff --git a/kyle-config.sy b/kyle-config.sy new file mode 100755 index 0000000000..ae01bdeb86 --- /dev/null +++ b/kyle-config.sy @@ -0,0 +1,22 @@ +cd ubuild + +echo CMake.... + +cmake .. \ + -G "Unix Makefiles" \ + -DCMAKE_INSTALL_PREFIX=/home/kylea/Documents/I3S/PDAL/ubuild \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_MAKE_PROGRAM=make \ + -DBUILD_PLUGIN_PYTHON=ON \ + -DBUILD_PLUGIN_GREYHOUND=ON \ + -DBUILD_PLUGIN_SQLITE=ON \ + -DBUILD_PLUGIN_I3S=ON \ + -DWITH_LASZIP=ON \ + -DWITH_LAZPERF=ON \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_INSTALL_LIBDIR=lib \ + ; \ + +echo Make... + +make -j 4 diff --git a/pdal/StageExtensions.cpp b/pdal/StageExtensions.cpp index 1330c6bc0c..6995e17b08 100644 --- a/pdal/StageExtensions.cpp +++ b/pdal/StageExtensions.cpp @@ -80,7 +80,8 @@ R"PDALEXTENSIONS( "writers.sqlite" : "sqlite, gpkg", "readers.mrsid" : "sid", "readers.rxp" : "rxp", - "readers.fbx" : "fbx" + "readers.fbx" : "fbx", + "readers.i3s" : "i3s" } )PDALEXTENSIONS" diff --git a/pdal/StageFactory.cpp b/pdal/StageFactory.cpp index a0e965165d..d3594c29e1 100644 --- a/pdal/StageFactory.cpp +++ b/pdal/StageFactory.cpp @@ -51,18 +51,18 @@ namespace pdal std::string StageFactory::inferReaderDriver(const std::string& filename) { static const std::string ghPrefix("greyhound://"); - + static const std::string i3sPrefix("i3s://"); std::string ext; // filename may actually be a greyhound uri + pipelineId if (Utils::iequals(filename.substr(0, ghPrefix.size()), ghPrefix)) ext = ".greyhound"; // Make it look like an extension. + else if(Utils::iequals(filename.substr(0, i3sPrefix.size()), i3sPrefix)) + ext = ".i3s"; else ext = FileUtils::extension(filename); - // Strip off '.' and make lowercase. if (ext.length()) ext = Utils::tolower(ext.substr(1)); - PluginManager& mgr = PluginManager::get(); return mgr.extensions().defaultReader(ext); } diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 37b9c7b556..62296dea9d 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -2,6 +2,10 @@ include(${PDAL_CMAKE_DIR}/test.cmake) add_subdirectory(faux) +if(BUILD_PLUGIN_I3S) + add_subdirectory(i3s) +endif() + if(BUILD_PLUGIN_CPD) add_subdirectory(cpd) endif(BUILD_PLUGIN_CPD) diff --git a/plugins/i3s/CMakeLists.txt b/plugins/i3s/CMakeLists.txt new file mode 100644 index 0000000000..1efe38d5d7 --- /dev/null +++ b/plugins/i3s/CMakeLists.txt @@ -0,0 +1,10 @@ + +PDAL_ADD_PLUGIN(reader_libname reader i3s + FILES + io/i3sReader.cpp + LINK_WITH + ${PDAL_JSONCPP_LIB_NAME} + ${WINSOCK_LIBRARY} +) + + diff --git a/plugins/i3s/io/i3sReader.cpp b/plugins/i3s/io/i3sReader.cpp new file mode 100644 index 0000000000..882c34d0e4 --- /dev/null +++ b/plugins/i3s/io/i3sReader.cpp @@ -0,0 +1,135 @@ +// I3SReader.cpp + +#include "i3sReader.hpp" + +#include +#include +#include + + +namespace pdal +{ + static PluginInfo const s_info + { + "readers.i3s", + "Read file from i3s server", + "http://why.com/doyouthink/ihave/documentation" + }; + + CREATE_SHARED_STAGE(I3SReader, s_info) + + + + std::string I3SReader::getName() const { return s_info.name; } + + void I3SReader::initialize(PointTableRef table) + { + + Json::Value config; + if (log()->getLevel() > LogLevel::Debug4) + config["arbiter"]["verbose"] = true; + m_arbiter.reset(new arbiter::Arbiter(config)); + + + if (m_filename.size() && m_args.url.empty()) + { + m_args.url = m_filename; + const std::string pre("i3s://"); + if (m_args.url.find(pre) == 0) + m_args.url = m_args.url.substr(pre.size()); + if (m_args.url.find("https://") == std::string::npos) + m_args.url = "https://" + m_args.url; + } + + log()->get(LogLevel::Debug) << "Fetching info from " << m_args.url << + std::endl; + + + /*request 3scenelayerinfo: URL Pattern */ + try + { + m_args.body = parse(m_arbiter->get(m_args.url)); + } + catch (std::exception& e) + { + throw pdal_error(std::string("Failed to fetch info: ") + e.what()); + } + Json::StreamWriterBuilder writer; + writer.settings_["indentation"] = ""; + m_args.name = Json::writeString(writer, m_args.body["name"]); + m_args.itemId = Json::writeString(writer, m_args.body["serviceItemId"]); + } + + void I3SReader::addArgs(ProgramArgs& args) + { + args.add("url", "URL", m_args.url); + args.add("body", "JSON formatted body", m_args.body); + args.add("itemId", "ID of the current item", m_args.itemId); + args.add("name", "Name of the point cloud data", m_args.name); + + } + + void I3SReader::addDimensions(PointLayoutPtr layout) + { + Json::StreamWriterBuilder writer; + writer.settings_["indentation"] = ""; + + //register default values X, Y and Z + layout->registerDim(Dimension::Id::X); + layout->registerDim(Dimension::Id::Y); + layout->registerDim(Dimension::Id::Z); + + + Json::Value attributes = m_args.body["layers"][0]["attributeStorageInfo"]; + for(int i = 0; i < attributes.size(); i ++) + { + std::string name = Json::writeString(writer, attributes[i]["name"]); + name.erase( + remove( name.begin(), name.end(), '\"' ), + name.end() + ); + std::cout << name << "\n"; + std::string type; + + if (attributes[0].isMember("attributeValues")) { + type = Json::writeString(writer, + attributes["attributeValues"]["valueType"]); + layout->registerOrAssignDim(name, pdal::Dimension::type(type)); + } + else + layout->registerOrAssignDim(name, Dimension::Type::Double); + } + } + + void I3SReader::ready(PointTableRef) + { + + SpatialReference ref("EPSG:4385"); + setSpatialReference(ref); + } + + + + point_count_t I3SReader::read(PointViewPtr view, point_count_t count) + { +/*request 3scenelayerinfo: URL Pattern */ +//node index document: /nodes/ +//shared resources: /shared/ +//feature data: /features/ +//geometry data: /geometries/ +//texture data: /textures/ + + view->setField(pdal::Dimension::Id::X, 0, 12); + view->setField(pdal::Dimension::Id::Y, 0, 13); + view->setField(pdal::Dimension::Id::Z, 0, 14); + view->setField(pdal::Dimension::Id::INTENSITY, 0, 55); + + return 0; + } + + void I3SReader::done(PointTableRef) + { + m_stream.reset(); + } + +} //namespace pdal diff --git a/plugins/i3s/io/i3sReader.hpp b/plugins/i3s/io/i3sReader.hpp new file mode 100644 index 0000000000..207d1b9102 --- /dev/null +++ b/plugins/i3s/io/i3sReader.hpp @@ -0,0 +1,48 @@ +// I3SReader.hpp + +#pragma once + +#include +#include +#include +#include "i3sReceiver.hpp" + + +#include +#include +#include + +#include + +#include + +#include + + +namespace pdal +{ + class I3SReader : public Reader + { + public: + I3SReader() : Reader() {}; + std::string getName() const; + + private: + std::unique_ptr m_stream; + point_count_t m_index; + double m_scale_z; + std::unique_ptr m_arbiter; + + I3SArgs m_args; + Json::Value m_info; + + virtual void addArgs(ProgramArgs& args); + virtual void initialize(PointTableRef table) override; + virtual void addDimensions(PointLayoutPtr layout); + virtual void ready(PointTableRef table); + virtual point_count_t read(PointViewPtr view, point_count_t count); + virtual void done(PointTableRef table); + + + }; +}