Polish operation form readability
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled

This commit is contained in:
Codex
2026-06-20 02:39:44 +02:00
parent 4e6ba707cf
commit b15b123173
8 changed files with 315 additions and 121 deletions
@@ -133,29 +133,39 @@ export function RasterControls({
</div>
) : null}
<div className="dataset-tool-group">
<label>
Reproject CRS
<input
value={rasterReprojectCrs}
onChange={(event) => onSetRasterReprojectCrs(event.target.value)}
placeholder="EPSG:31370"
/>
</label>
<label>
Resampling
<select value={rasterReprojectResampling} onChange={(event) => onSetRasterReprojectResampling(event.target.value)}>
<option value="nearest">nearest</option>
<option value="bilinear">bilinear</option>
<option value="cubic">cubic</option>
</select>
</label>
<button type="button" onClick={onRunRasterReproject}>
Reproject raster
</button>
<h4 className="dataset-tool-heading">Reproject raster</h4>
<p className="dataset-tool-helper">Create a derived raster in a target CRS with the selected resampling method.</p>
<div className="dataset-tool-grid">
<label className="dataset-tool-field">
<span className="dataset-tool-label">Reproject CRS</span>
<input
value={rasterReprojectCrs}
onChange={(event) => onSetRasterReprojectCrs(event.target.value)}
placeholder="EPSG:31370"
/>
<span className="dataset-tool-helper">Target CRS for the derived raster artifact.</span>
</label>
<label className="dataset-tool-field">
<span className="dataset-tool-label">Resampling</span>
<select value={rasterReprojectResampling} onChange={(event) => onSetRasterReprojectResampling(event.target.value)}>
<option value="nearest">nearest</option>
<option value="bilinear">bilinear</option>
<option value="cubic">cubic</option>
</select>
<span className="dataset-tool-helper">Nearest preserves classes; bilinear/cubic smooth continuous rasters.</span>
</label>
</div>
<div className="dataset-tool-action-row">
<button type="button" onClick={onRunRasterReproject}>
Reproject raster
</button>
</div>
</div>
<div className="dataset-tool-group">
<label>
Clip area
<h4 className="dataset-tool-heading">Clip raster</h4>
<p className="dataset-tool-helper">Clip the selected raster to an existing project area.</p>
<label className="dataset-tool-field">
<span className="dataset-tool-label">Clip area</span>
<select value={selectedClipAreaId} onChange={(event) => onSetSelectedClipAreaId(event.target.value)}>
{areas.map((area) => (
<option key={area.id} value={area.id}>
@@ -164,43 +174,54 @@ export function RasterControls({
))}
</select>
</label>
<button type="button" onClick={onRunRasterClip} disabled={areas.length === 0}>
Clip raster by area
</button>
{areas.length === 0 ? <p className="error">Create an area before raster clipping.</p> : null}
<div className="dataset-tool-action-row">
<button type="button" onClick={onRunRasterClip} disabled={areas.length === 0}>
Clip raster by area
</button>
</div>
{areas.length === 0 ? <p className="dataset-tool-error">Create an area before raster clipping.</p> : null}
</div>
<div className="dataset-tool-group">
<label>
Tile size
<input
type="number"
min={1}
value={rasterTileSize}
onChange={(event) => onSetRasterTileSize(Number(event.target.value))}
/>
</label>
<label>
Overlap
<input
type="number"
min={0}
value={rasterTileOverlap}
onChange={(event) => onSetRasterTileOverlap(Number(event.target.value))}
/>
</label>
<label>
Tile basename
<input
value={rasterTileOutputName}
onChange={(event) => onSetRasterTileOutputName(event.target.value)}
placeholder="optional"
/>
</label>
<button type="button" onClick={onRunRasterTile} disabled={!isRasterTileInputValid}>
Generate tiles
</button>
<h4 className="dataset-tool-heading">Generate tiles</h4>
<p className="dataset-tool-helper">Create a tile manifest for downstream detection or segmentation runs.</p>
<div className="dataset-tool-grid">
<label className="dataset-tool-field">
<span className="dataset-tool-label">Tile size</span>
<input
type="number"
min={1}
value={rasterTileSize}
onChange={(event) => onSetRasterTileSize(Number(event.target.value))}
/>
<span className="dataset-tool-helper">{'Tile size must be > 0.'}</span>
</label>
<label className="dataset-tool-field">
<span className="dataset-tool-label">Overlap</span>
<input
type="number"
min={0}
value={rasterTileOverlap}
onChange={(event) => onSetRasterTileOverlap(Number(event.target.value))}
/>
<span className="dataset-tool-helper">Overlap must be smaller than tile size.</span>
</label>
<label className="dataset-tool-field">
<span className="dataset-tool-label">Tile basename</span>
<input
value={rasterTileOutputName}
onChange={(event) => onSetRasterTileOutputName(event.target.value)}
placeholder="optional"
/>
<span className="dataset-tool-helper">Optional artifact name prefix for generated tiles.</span>
</label>
</div>
<div className="dataset-tool-action-row">
<button type="button" onClick={onRunRasterTile} disabled={!isRasterTileInputValid}>
Generate tiles
</button>
</div>
{!isRasterTileInputValid ? (
<p className="error">
<p className="dataset-tool-error">
Tile size must be {'>'} 0 and overlap must be {'>='} 0 and smaller than tile size.
</p>
) : null}
@@ -209,46 +230,61 @@ export function RasterControls({
<div>
<p>Use available band indexes from the raster file (1-based).</p>
<div className="dataset-tool-group">
<p>NDVI</p>
<label>
Nir band
<input type="number" min={1} value={ndviNirBand} onChange={(event) => onSetNdviNirBand(Number(event.target.value))} />
</label>
<label>
Red band
<input type="number" min={1} value={ndviRedBand} onChange={(event) => onSetNdviRedBand(Number(event.target.value))} />
</label>
<button type="button" onClick={onRunRasterNdvi}>
Compute NDVI
</button>
<h4 className="dataset-tool-heading">NDVI</h4>
<p className="dataset-tool-helper">Vegetation index from NIR and red bands.</p>
<div className="dataset-tool-grid">
<label className="dataset-tool-field">
<span className="dataset-tool-label">NIR band</span>
<input type="number" min={1} value={ndviNirBand} onChange={(event) => onSetNdviNirBand(Number(event.target.value))} />
</label>
<label className="dataset-tool-field">
<span className="dataset-tool-label">Red band</span>
<input type="number" min={1} value={ndviRedBand} onChange={(event) => onSetNdviRedBand(Number(event.target.value))} />
</label>
</div>
<div className="dataset-tool-action-row">
<button type="button" onClick={onRunRasterNdvi}>
Compute NDVI
</button>
</div>
</div>
<div className="dataset-tool-group">
<p>NDWI</p>
<label>
Nir band
<input type="number" min={1} value={ndwiNirBand} onChange={(event) => onSetNdwiNirBand(Number(event.target.value))} />
</label>
<label>
Green band
<input type="number" min={1} value={ndwiGreenBand} onChange={(event) => onSetNdwiGreenBand(Number(event.target.value))} />
</label>
<button type="button" onClick={onRunRasterNdwi}>
Compute NDWI
</button>
<h4 className="dataset-tool-heading">NDWI</h4>
<p className="dataset-tool-helper">Water index from NIR and green bands.</p>
<div className="dataset-tool-grid">
<label className="dataset-tool-field">
<span className="dataset-tool-label">NIR band</span>
<input type="number" min={1} value={ndwiNirBand} onChange={(event) => onSetNdwiNirBand(Number(event.target.value))} />
</label>
<label className="dataset-tool-field">
<span className="dataset-tool-label">Green band</span>
<input type="number" min={1} value={ndwiGreenBand} onChange={(event) => onSetNdwiGreenBand(Number(event.target.value))} />
</label>
</div>
<div className="dataset-tool-action-row">
<button type="button" onClick={onRunRasterNdwi}>
Compute NDWI
</button>
</div>
</div>
<div className="dataset-tool-group">
<p>NDBI</p>
<label>
Swir band
<input type="number" min={1} value={ndbiSwirBand} onChange={(event) => onSetNdbiSwirBand(Number(event.target.value))} />
</label>
<label>
Nir band
<input type="number" min={1} value={ndbiNirBand} onChange={(event) => onSetNdbiNirBand(Number(event.target.value))} />
</label>
<button type="button" onClick={onRunRasterNdbi}>
Compute NDBI
</button>
<h4 className="dataset-tool-heading">NDBI</h4>
<p className="dataset-tool-helper">Built-up index from SWIR and NIR bands.</p>
<div className="dataset-tool-grid">
<label className="dataset-tool-field">
<span className="dataset-tool-label">SWIR band</span>
<input type="number" min={1} value={ndbiSwirBand} onChange={(event) => onSetNdbiSwirBand(Number(event.target.value))} />
</label>
<label className="dataset-tool-field">
<span className="dataset-tool-label">NIR band</span>
<input type="number" min={1} value={ndbiNirBand} onChange={(event) => onSetNdbiNirBand(Number(event.target.value))} />
</label>
</div>
<div className="dataset-tool-action-row">
<button type="button" onClick={onRunRasterNdbi}>
Compute NDBI
</button>
</div>
</div>
</div>
</div>
@@ -27,38 +27,57 @@ export function VectorControls({
<div className="dataset-tool-panel vector-tool-panel">
<h3>Vector operations</h3>
<div className="dataset-tool-group">
<label>
Clip area
<select value={selectedClipAreaId} onChange={(event) => onSetSelectedClipAreaId(event.target.value)}>
{areas.map((area) => (
<option key={area.id} value={area.id}>
{area.name}
</option>
))}
</select>
</label>
<button type="button" onClick={onRunVectorClip} disabled={areas.length === 0}>
Run clip
</button>
<h4 className="dataset-tool-heading">Clip vector</h4>
<p className="dataset-tool-helper">Clip features to the selected project area.</p>
<div className="dataset-tool-grid">
<label className="dataset-tool-field">
<span className="dataset-tool-label">Clip area</span>
<select value={selectedClipAreaId} onChange={(event) => onSetSelectedClipAreaId(event.target.value)}>
{areas.map((area) => (
<option key={area.id} value={area.id}>
{area.name}
</option>
))}
</select>
</label>
</div>
<div className="dataset-tool-action-row">
<button type="button" onClick={onRunVectorClip} disabled={areas.length === 0}>
Run clip
</button>
</div>
</div>
<button type="button" onClick={onRunVectorBuffer}>
Run buffer (25m)
</button>
<div className="dataset-tool-group">
<label>
Intersect target
<select value={selectedIntersectTargetId} onChange={(event) => onSetSelectedIntersectTargetId(event.target.value)}>
<option value="">auto first vector</option>
{availableVectorTargets.map((target) => (
<option key={target.id} value={target.id}>
{target.name}
</option>
))}
</select>
</label>
<button type="button" onClick={onRunVectorIntersect}>
Run intersect
</button>
<h4 className="dataset-tool-heading">Buffer vector</h4>
<p className="dataset-tool-helper">Create a 25m buffer using the existing vector operation defaults.</p>
<div className="dataset-tool-action-row">
<button type="button" onClick={onRunVectorBuffer}>
Run buffer (25m)
</button>
</div>
</div>
<div className="dataset-tool-group">
<h4 className="dataset-tool-heading">Intersect vector</h4>
<p className="dataset-tool-helper">Intersect with another persisted vector dataset.</p>
<div className="dataset-tool-grid">
<label className="dataset-tool-field">
<span className="dataset-tool-label">Intersect target</span>
<select value={selectedIntersectTargetId} onChange={(event) => onSetSelectedIntersectTargetId(event.target.value)}>
<option value="">auto first vector</option>
{availableVectorTargets.map((target) => (
<option key={target.id} value={target.id}>
{target.name}
</option>
))}
</select>
<span className="dataset-tool-helper">Leave automatic to use the first available vector target.</span>
</label>
</div>
<div className="dataset-tool-action-row">
<button type="button" onClick={onRunVectorIntersect}>
Run intersect
</button>
</div>
</div>
</div>
)
+53
View File
@@ -2148,16 +2148,69 @@ button.entity-card {
background: #ffffff;
}
.dataset-tool-heading {
margin: 0;
font-size: 0.92rem;
line-height: 1.25;
}
.dataset-tool-helper {
margin: 0;
color: var(--muted);
font-size: 0.82rem;
line-height: 1.38;
overflow-wrap: anywhere;
}
.dataset-tool-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
gap: 0.52rem;
}
.dataset-tool-group label {
min-width: 0;
}
.dataset-tool-field {
display: grid;
gap: 0.22rem;
min-width: 0;
}
.dataset-tool-label {
color: var(--text);
font-size: 0.78rem;
font-weight: 800;
line-height: 1.25;
}
.dataset-tool-group input,
.dataset-tool-group select {
width: 100%;
min-width: 0;
}
.dataset-tool-error {
margin: 0;
border: 1px solid rgba(153, 27, 27, 0.24);
border-radius: 8px;
padding: 0.52rem 0.62rem;
background: rgba(153, 27, 27, 0.07);
color: var(--danger);
font-size: 0.82rem;
font-weight: 750;
line-height: 1.35;
overflow-wrap: anywhere;
}
.dataset-tool-action-row {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
}
.dataset-tool-group button {
width: fit-content;
max-width: 100%;