Skip to content

Commit 61fab22

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 179fa76 + a844e18 commit 61fab22

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2823
-482
lines changed

.github/workflows/cmake_builds.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,7 @@ jobs:
103103
# Build libjxl
104104
# libjxl being still unstable, if the main branch fails to compile/test
105105
# you can replace JXL_TREEISH=main by JXL_TREEISH=sha1_of_known_working_commit
106-
# FIXME: restore JXL_TREEISH=main, once https://github.com/libjxl/libjxl/issues/4410 is solved
107-
JXL_TREEISH=a4e40af31ab4dd6d6b9ce893c4425b7180012916
106+
JXL_TREEISH=main
108107
git clone https://github.com/libjxl/libjxl.git --recursive \
109108
&& cd libjxl \
110109
&& git checkout ${JXL_TREEISH} \

.github/workflows/ubuntu_20.04/Dockerfile.ci

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ RUN mkdir tiledb \
125125
# Build libjxl
126126
# libjxl being still unstable, if the main branch fails to compile/test
127127
# you can replace JXL_TREEISH=main by JXL_TREEISH=sha1_of_known_working_commit
128-
# FIXME: restore JXL_TREEISH=main, once https://github.com/libjxl/libjxl/issues/4410 is solved
129-
ENV JXL_TREEISH=a4e40af31ab4dd6d6b9ce893c4425b7180012916
128+
ENV JXL_TREEISH=main
129+
# Mention commit 9066c91546e6bda3623fa14b83613d90cbfddfd3 to force rebuild of dep
130130
RUN git clone https://github.com/libjxl/libjxl.git --recursive \
131131
&& cd libjxl \
132132
&& git checkout ${JXL_TREEISH} \

alg/viewshed/viewshed_executor.cpp

Lines changed: 132 additions & 135 deletions
Large diffs are not rendered by default.

alg/viewshed/viewshed_executor.h

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,30 @@ namespace gdal
2727
namespace viewshed
2828
{
2929

30+
/**
31+
* Container for lines necessary for processing.
32+
*/
33+
struct Lines
34+
{
35+
std::vector<double> cur; //!< Current line being processed
36+
std::vector<double> result; //!< Result values for current line
37+
std::vector<double> prev; //!< Height values for previous line
38+
std::vector<double>
39+
pitchMask; //!< Height/indicator values for pitch masking.
40+
41+
/// Constructor
42+
Lines() : cur(), result(), prev(), pitchMask()
43+
{
44+
}
45+
46+
/// Constructor that initializes to line length
47+
/// \param lineLen Line length.
48+
explicit Lines(size_t lineLen)
49+
: cur(lineLen), result(lineLen), prev(), pitchMask()
50+
{
51+
}
52+
};
53+
3054
class Progress;
3155

3256
/// Executes a viewshed computation on a source band, placing the result
@@ -74,30 +98,16 @@ class ViewshedExecutor
7498

7599
double calcHeightAdjFactor();
76100
void setOutput(double &dfResult, double &dfCellVal, double dfZ);
77-
bool readLine(int nLine, double *data);
101+
bool readLine(int nLine, std::vector<double> &line);
78102
bool writeLine(int nLine, std::vector<double> &vResult);
79-
bool processLine(int nLine, std::vector<double> &vLastLineVal);
80-
bool processFirstLine(std::vector<double> &vLastLineVal);
81-
void processFirstLineLeft(const LineLimits &ll,
82-
std::vector<double> &vResult,
83-
std::vector<double> &vThisLineVal);
84-
void processFirstLineRight(const LineLimits &ll,
85-
std::vector<double> &vResult,
86-
std::vector<double> &vThisLineVal);
87-
void processFirstLineTopOrBottom(const LineLimits &ll,
88-
std::vector<double> &vResult,
89-
std::vector<double> &vThisLineVal);
90-
void processLineLeft(int nYOffset, LineLimits &ll,
91-
std::vector<double> &vResult,
92-
std::vector<double> &vThisLineVal,
93-
std::vector<double> &vLastLineVal);
94-
void processLineRight(int nYOffset, LineLimits &ll,
95-
std::vector<double> &vResult,
96-
std::vector<double> &vThisLineVal,
97-
std::vector<double> &vLastLineVal);
98-
LineLimits adjustHeight(int iLine, std::vector<double> &thisLineVal,
99-
const std::vector<double> &vResult,
100-
std::vector<double> &vPitchMaskVal);
103+
bool processLine(int nLine, Lines &lines);
104+
bool processFirstLine(Lines &lines);
105+
void processFirstLineLeft(const LineLimits &ll, Lines &lines);
106+
void processFirstLineRight(const LineLimits &ll, Lines &lines);
107+
void processFirstLineTopOrBottom(const LineLimits &ll, Lines &lines);
108+
void processLineLeft(int nYOffset, LineLimits &ll, Lines &lines);
109+
void processLineRight(int nYOffset, LineLimits &ll, Lines &lines);
110+
LineLimits adjustHeight(int iLine, Lines &lines);
101111
void maskInitial(std::vector<double> &vResult, int nLine);
102112
bool maskAngleLeft(std::vector<double> &vResult, int nLine);
103113
bool maskAngleRight(std::vector<double> &vResult, int nLine);

apps/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ target_sources(appslib PRIVATE
9393
gdalalg_tee.cpp
9494
gdalalg_vector.cpp
9595
gdalalg_vector_info.cpp
96+
gdalalg_vector_change_field_type.cpp
9697
gdalalg_vector_check_coverage.cpp
9798
gdalalg_vector_check_geometry.cpp
9899
gdalalg_vector_clip.cpp

apps/gdalalg_vector.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "gdalalg_vector_info.h"
1616
#include "gdalalg_vector_buffer.h"
17+
#include "gdalalg_vector_change_field_type.h"
1718
#include "gdalalg_vector_check_geometry.h"
1819
#include "gdalalg_vector_check_coverage.h"
1920
#include "gdalalg_vector_clean_coverage.h"
@@ -67,6 +68,7 @@ class GDALVectorAlgorithm final : public GDALAlgorithm
6768

6869
RegisterSubAlgorithm<GDALVectorInfoAlgorithmStandalone>();
6970
RegisterSubAlgorithm<GDALVectorBufferAlgorithmStandalone>();
71+
RegisterSubAlgorithm<GDALVectorChangeFieldTypeAlgorithmStandalone>();
7072
RegisterSubAlgorithm<GDALVectorCheckCoverageAlgorithmStandalone>();
7173
RegisterSubAlgorithm<GDALVectorCheckGeometryAlgorithmStandalone>();
7274
RegisterSubAlgorithm<GDALVectorCleanCoverageAlgorithmStandalone>();
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
/******************************************************************************
2+
*
3+
* Project: GDAL
4+
* Purpose: "change-field-type" step of "vector pipeline"
5+
* Author: Alessandro Pasotti <elpaso at itopen dot it>
6+
*
7+
******************************************************************************
8+
* Copyright (c) 2025, Alessandro Pasotti <elpaso at itopen dot it>
9+
*
10+
* SPDX-License-Identifier: MIT
11+
****************************************************************************/
12+
13+
#include "gdalalg_vector_change_field_type.h"
14+
#include "gdal_priv.h"
15+
16+
//! @cond Doxygen_Suppress
17+
18+
#ifndef _
19+
#define _(x) (x)
20+
#endif
21+
22+
/************************************************************************/
23+
/* GDALVectorChangeFieldTypeAlgorithm() */
24+
/************************************************************************/
25+
26+
GDALVectorChangeFieldTypeAlgorithm::GDALVectorChangeFieldTypeAlgorithm(
27+
bool standaloneStep)
28+
: GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
29+
standaloneStep)
30+
{
31+
auto &layerArg = AddActiveLayerArg(&m_activeLayer);
32+
auto &fieldNameArg = AddFieldNameArg(&m_fieldName)
33+
.SetRequired()
34+
.SetMutualExclusionGroup("name-or-type");
35+
SetAutoCompleteFunctionForFieldName(fieldNameArg, layerArg, m_inputDataset);
36+
AddFieldTypeSubtypeArg(&m_srcFieldType, &m_srcFieldSubType,
37+
&m_srcFieldTypeSubTypeStr, "src-field-type",
38+
_("Source field type or subtype"))
39+
.SetRequired()
40+
.SetMutualExclusionGroup("name-or-type");
41+
AddFieldTypeSubtypeArg(&m_newFieldType, &m_newFieldSubType,
42+
&m_newFieldTypeSubTypeStr, std::string(),
43+
_("Target field type or subtype"))
44+
.AddAlias("dst-field-type")
45+
.SetRequired();
46+
AddValidationAction(
47+
[this]
48+
{
49+
if (!m_inputDataset.empty())
50+
{
51+
auto mInDS = m_inputDataset[0].GetDatasetRef();
52+
auto layer = m_activeLayer.empty()
53+
? mInDS->GetLayer(0)
54+
: mInDS->GetLayerByName(m_activeLayer.c_str());
55+
if (!layer)
56+
{
57+
CPLError(CE_Failure, CPLE_AppDefined,
58+
"Cannot find layer '%s'", m_activeLayer.c_str());
59+
return false;
60+
}
61+
if (!m_fieldName.empty() &&
62+
layer->GetLayerDefn()->GetFieldIndex(m_fieldName.c_str()) <
63+
0)
64+
{
65+
CPLError(CE_Failure, CPLE_AppDefined,
66+
"Cannot find field '%s' in layer '%s'",
67+
m_fieldName.c_str(), layer->GetName());
68+
return false;
69+
}
70+
return true;
71+
}
72+
return false;
73+
});
74+
}
75+
76+
/************************************************************************/
77+
/* GDALVectorChangeFieldTypeAlgorithmLayer */
78+
/************************************************************************/
79+
80+
namespace
81+
{
82+
class GDALVectorChangeFieldTypeAlgorithmLayer final
83+
: public GDALVectorPipelineOutputLayer
84+
{
85+
public:
86+
GDALVectorChangeFieldTypeAlgorithmLayer(
87+
OGRLayer &oSrcLayer, const std::string &activeLayer,
88+
const std::string &fieldName, const OGRFieldType srcFieldType,
89+
const OGRFieldSubType srcFieldSubType, const OGRFieldType newFieldType,
90+
const OGRFieldSubType newFieldSubType)
91+
: GDALVectorPipelineOutputLayer(oSrcLayer)
92+
{
93+
94+
m_poFeatureDefn = oSrcLayer.GetLayerDefn()->Clone();
95+
m_poFeatureDefn->Reference();
96+
97+
if (activeLayer.empty() || activeLayer == GetDescription())
98+
{
99+
if (!fieldName.empty())
100+
{
101+
m_fieldIndex =
102+
m_poFeatureDefn->GetFieldIndex(fieldName.c_str());
103+
if (m_fieldIndex >= 0)
104+
{
105+
auto poFieldDefn =
106+
m_poFeatureDefn->GetFieldDefn(m_fieldIndex);
107+
if (poFieldDefn->GetType() != newFieldType)
108+
{
109+
m_passThrough = false;
110+
}
111+
112+
// Set to OFSTNone to bypass the check that prevents changing the type
113+
poFieldDefn->SetSubType(OFSTNone);
114+
poFieldDefn->SetType(newFieldType);
115+
poFieldDefn->SetSubType(newFieldSubType);
116+
}
117+
}
118+
else
119+
{
120+
for (int i = 0; i < m_poFeatureDefn->GetFieldCount(); ++i)
121+
{
122+
auto poFieldDefn = m_poFeatureDefn->GetFieldDefn(i);
123+
if (poFieldDefn->GetType() == srcFieldType &&
124+
poFieldDefn->GetSubType() == srcFieldSubType)
125+
{
126+
m_passThrough = false;
127+
128+
// Set to OFSTNone to bypass the check that prevents changing the type
129+
poFieldDefn->SetSubType(OFSTNone);
130+
poFieldDefn->SetType(newFieldType);
131+
poFieldDefn->SetSubType(newFieldSubType);
132+
}
133+
}
134+
}
135+
136+
for (int i = 0; i < m_poFeatureDefn->GetFieldCount(); i++)
137+
{
138+
m_identityMap.push_back(i);
139+
}
140+
}
141+
}
142+
143+
~GDALVectorChangeFieldTypeAlgorithmLayer() override
144+
{
145+
m_poFeatureDefn->Release();
146+
}
147+
148+
const OGRFeatureDefn *GetLayerDefn() const override
149+
{
150+
return m_poFeatureDefn;
151+
}
152+
153+
void TranslateFeature(
154+
std::unique_ptr<OGRFeature> poSrcFeature,
155+
std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override
156+
{
157+
if (m_passThrough)
158+
{
159+
apoOutFeatures.push_back(std::move(poSrcFeature));
160+
}
161+
else
162+
{
163+
auto poDstFeature = std::make_unique<OGRFeature>(m_poFeatureDefn);
164+
const auto result{poDstFeature->SetFrom(
165+
poSrcFeature.get(), m_identityMap.data(), false, true)};
166+
if (result != OGRERR_NONE)
167+
{
168+
if (m_fieldIndex >= 0)
169+
{
170+
CPLError(CE_Warning, CPLE_AppDefined,
171+
"Cannot convert field '%s' to new type, setting "
172+
"it to NULL",
173+
m_poFeatureDefn->GetFieldDefn(m_fieldIndex)
174+
->GetNameRef());
175+
}
176+
}
177+
else
178+
{
179+
poDstFeature->SetFID(poSrcFeature->GetFID());
180+
apoOutFeatures.push_back(std::move(poDstFeature));
181+
}
182+
}
183+
}
184+
185+
int TestCapability(const char *pszCap) const override
186+
{
187+
if (EQUAL(pszCap, OLCStringsAsUTF8) ||
188+
EQUAL(pszCap, OLCCurveGeometries) ||
189+
EQUAL(pszCap, OLCZGeometries) ||
190+
EQUAL(pszCap, OLCMeasuredGeometries))
191+
return m_srcLayer.TestCapability(pszCap);
192+
return false;
193+
}
194+
195+
private:
196+
OGRFeatureDefn *m_poFeatureDefn = nullptr;
197+
int m_fieldIndex{-1};
198+
bool m_passThrough = true;
199+
std::vector<int> m_identityMap{};
200+
201+
CPL_DISALLOW_COPY_ASSIGN(GDALVectorChangeFieldTypeAlgorithmLayer)
202+
};
203+
204+
} // namespace
205+
206+
/************************************************************************/
207+
/* GDALVectorChangeFieldTypeAlgorithm::RunStep() */
208+
/************************************************************************/
209+
210+
bool GDALVectorChangeFieldTypeAlgorithm::RunStep(GDALPipelineStepRunContext &)
211+
{
212+
auto poSrcDS = m_inputDataset[0].GetDatasetRef();
213+
CPLAssert(poSrcDS);
214+
215+
CPLAssert(m_outputDataset.GetName().empty());
216+
CPLAssert(!m_outputDataset.GetDatasetRef());
217+
218+
const int nLayerCount = poSrcDS->GetLayerCount();
219+
220+
auto outDS = std::make_unique<GDALVectorPipelineOutputDataset>(*poSrcDS);
221+
222+
bool ret = true;
223+
for (int i = 0; ret && i < nLayerCount; ++i)
224+
{
225+
auto poSrcLayer = poSrcDS->GetLayer(i);
226+
ret = (poSrcLayer != nullptr);
227+
if (ret)
228+
{
229+
outDS->AddLayer(
230+
*poSrcLayer,
231+
std::make_unique<GDALVectorChangeFieldTypeAlgorithmLayer>(
232+
*poSrcLayer, m_activeLayer, m_fieldName, m_srcFieldType,
233+
m_srcFieldSubType, m_newFieldType, m_newFieldSubType));
234+
}
235+
}
236+
237+
if (ret)
238+
m_outputDataset.Set(std::move(outDS));
239+
240+
printf("ret= %d\n", ret);
241+
return ret;
242+
}
243+
244+
GDALVectorChangeFieldTypeAlgorithmStandalone::
245+
~GDALVectorChangeFieldTypeAlgorithmStandalone() = default;
246+
247+
//! @endcond

0 commit comments

Comments
 (0)