9namespace fishnet::__impl{
17template<
typename G,VectorGISFile F, VectorLayerWriter<G,F> VectorLayerWriterType>
18class NonOverwritingVectorLayerWriter {
20 VectorLayerWriterType writer;
24 : writer(
std::move(writer)),filenameMapper(
std::move(filenameMapper)) {}
26 Either<F,std::string> operator()(
const VectorLayer<G> & layer,
const F & destination)
const {
27 F outputFile = destination;
28 if(destination.exists()){
29 outputFile = filenameMapper(destination);
31 return writer(layer, outputFile);
36struct IncrementFilenameMapper {
37 F operator()(
const F & file)
const {
39 std::regex endsWithVersionRegex {
"_(\\d+)$"};
40 const std::string & currentFilename = file.getPath().stem().string();
42 if(std::regex_search(currentFilename,matcher,endsWithVersionRegex)){
43 size_t splitIndex = currentFilename.find_last_of(
'_');
44 std::string filename = currentFilename.substr(0,splitIndex);
45 int version = std::stoi(matcher[1].str()) + 1;
48 output.appendToFilename(
"_1");
64template<geometry::AnyGeometry G>
76template<geometry::AnyGeometry G=geometry::OGRGeometryAdapter,geometry::AnyGeometry O>
92template<geometry::AnyGeometry G,geometry::AnyGeometry O>
94 auto result = emptyCopy<G>(source);
96 auto geometry = convert(feature.getGeometry());
99 Feature<G> transformed {std::move(geometry.value())};
101 result.addFeature(std::move(transformed));
112template<geometry::OGRLayerGeometry G>
114 return transform<G>(source, [](
const auto & geometry){
115 return geometry.template narrowTo<G>();
125template<geometry::AnyGeometry O>
126requires requires(
const O & geometry){ geometry.toNative(); }
128 using G = std::remove_cvref_t<decltype(std::declval<const O&>().toNative())>;
129 return transform<G>(source, [](
const auto & geometry){
134template<VectorLayerReader Reader>
135auto tryRead(
const Reader & reader,
const typename Reader::file_type & file) -> std::remove_cvref_t<
decltype(reader(file))> {
139template<VectorLayerReader Reader>
140auto read(
const Reader & reader,
const typename Reader::file_type & file) -> std::remove_cvref_t<
decltype(
tryRead(reader,file).value())> {
141 using F =
typename Reader::file_type;
142 using G =
typename Reader::geometry_type;
144 return tryRead(reader,file).value_or_throw();
147template<geometry::OGRLayerGeometry G = geometry::OGRGeometryAdapter>
152template<geometry::OGRLayerGeometry G = geometry::OGRGeometryAdapter>
165template<geometry::OGRLayerGeometry G = geometry::OGRGeometryAdapter>
169 return std::unexpected(
"Unsupported vector file type: " + file.
getPath().string());
171 switch (fileType.value()) {
177 return std::unexpected(
"Unsupported vector file type: " + file.
getPath().string());
189template<geometry::OGRLayerGeometry G = geometry::OGRGeometryAdapter>
191 return tryRead<G>(file).value_or_throw();
195 return read<geometry::OGRPolygonAdapter>(vectorFile);
198template<geometry::OGRWritableGeometry G,VectorGISFile F>
200 return writer(layer, destination);
203template<geometry::OGRWritableGeometry G,VectorGISFile F>
205 auto nonOverwritingWriter = __impl::NonOverwritingVectorLayerWriter<G,F,std::remove_cvref_t<
decltype(writer)>>(writer,__impl::IncrementFilenameMapper<F>());
206 return tryOverwrite(nonOverwritingWriter, layer, destination);
209template<geometry::OGRWritableGeometry G,VectorGISFile F>
211 return tryWrite(writer, layer, destination).value_or_throw();
214template<geometry::OGRWritableGeometry G,VectorGISFile F>
216 return tryOverwrite(writer, layer, destination).value_or_throw();
219template<geometry::OGRWritableGeometry G>
224template<geometry::OGRWritableGeometry G>
229template<geometry::OGRWritableGeometry G>
234template<geometry::OGRWritableGeometry G>
248template<geometry::OGRWritableGeometry G>
252 throw std::runtime_error(
"Unsupported vector file type for writing: " + destination.
getPath().string());
254 switch (fileType.value()) {
257 return std::make_unique<Shapefile>(result.getPath());
261 return std::make_unique<GeoPackage>(result.getPath());
264 throw std::runtime_error(
"Unsupported vector file type for writing: " + destination.
getPath().string());
277template<geometry::OGRWritableGeometry G>
281 throw std::runtime_error(
"Unsupported vector file type for writing: " + destination.
getPath().string());
283 switch (fileType.value()) {
286 return std::make_unique<Shapefile>(result.getPath());
290 return std::make_unique<GeoPackage>(result.getPath());
293 throw std::runtime_error(
"Unsupported vector file type for writing: " + destination.
getPath().string());
const std::filesystem::path & getPath() const noexcept
Definition GISFile.hpp:65
Definition GISFile.hpp:131
Feature implementation storing a geometry and associated attributes.
Definition Feature.hpp:51
constexpr void copyAttributes(const Feature< O > &source) noexcept
Definition Feature.hpp:112
Definition GeoPackageIO.hpp:18
Definition GeoPackageIO.hpp:53
GeoPackage handle.
Definition GeoPackage.hpp:9
Definition ShapefileIO.hpp:18
Definition ShapefileIO.hpp:59
Shapefile handle implementation.
Definition Shapefile.hpp:14
Stores the geometries, wrapped in features (which hold the field values / attributes) Keeps track of ...
Definition VectorLayer.hpp:28
constexpr const OGRSpatialReference & getSpatialReference() const noexcept
Definition VectorLayer.hpp:91
constexpr void copyFields(VectorLayer< T > &other) const noexcept
Definition VectorLayer.hpp:201
constexpr util::view_of< Feature< G > > auto getFeatures() const noexcept
Definition VectorLayer.hpp:83
Interface for reading a VectorLayer from a file.
Definition IOConcepts.hpp:17
Definition IOConcepts.hpp:23
Definition FunctionalConcepts.hpp:9
Definition VectorIO.hpp:55
auto nativeCopy(const VectorLayer< O > &source)
Copy a layer of OGR backed geometries into one of the equivalent fishnet value types.
Definition VectorIO.hpp:127
auto tryRead(const Reader &reader, const typename Reader::file_type &file) -> std::remove_cvref_t< decltype(reader(file))>
Definition VectorIO.hpp:135
VectorLayer< G > emptyCopy(const VectorLayer< O > &source)
Creates an empty VectorLayer with the same spatial reference and fields as the source layer.
Definition VectorIO.hpp:77
VectorLayer< geometry::OGRPolygonAdapter > readPolygonLayer(const AbstractVectorFile &vectorFile)
Definition VectorIO.hpp:194
Either< F, std::string > tryWrite(const VectorLayerWriter< G, F > auto &writer, const VectorLayer< G > &layer, const F &destination)
Definition VectorIO.hpp:204
VectorLayer< G > empty(const OGRSpatialReference &spatialReference)
Creates an empty VectorLayer with the given spatial reference.
Definition VectorIO.hpp:65
VectorLayer< G > narrow(const VectorLayer< geometry::OGRGeometryAdapter > &source)
Bring a layer read without a geometry type into a layer of one.
Definition VectorIO.hpp:113
Either< F, std::string > tryOverwrite(const VectorLayerWriter< G, F > auto &writer, const VectorLayer< G > &layer, const F &destination)
Definition VectorIO.hpp:199
auto read(const Reader &reader, const typename Reader::file_type &file) -> std::remove_cvref_t< decltype(tryRead(reader, file).value())>
Definition VectorIO.hpp:140
F overwrite(const VectorLayerWriter< G, F > auto &writer, const VectorLayer< G > &layer, const F &destination)
Definition VectorIO.hpp:215
VectorLayer< G > transform(const VectorLayer< O > &source, auto &&convert)
Copy a layer into one of another geometry type, carrying its spatial reference, fields and attributes...
Definition VectorIO.hpp:93
F write(const VectorLayerWriter< G, F > auto &writer, const VectorLayer< G > &layer, const F &destination)
Definition VectorIO.hpp:210
std::function< R(const T &)> UnaryFunction_t
Definition FunctionalConcepts.hpp:12
static fishnet::Option< GISFileType > getGISFileType(const std::filesystem::path &path)
Definition GISFile.hpp:18
static string to_string(fishnet::geometry::GeometryType type) noexcept
Definition GeometryBase.hpp:22