fix(tactical): remove label spam on terrain grid, refine realistic cliff gradient >= 28 deg, and soften overlay opacities
This commit is contained in:
@@ -551,11 +551,11 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
'fill-opacity': [
|
||||
'match',
|
||||
['get', 'layerType'],
|
||||
'cliff', 0.50,
|
||||
'urban', 0.28,
|
||||
'hazard', 0.32,
|
||||
'slope-sector', 0.18,
|
||||
0.2
|
||||
'cliff', 0.38,
|
||||
'urban', 0.20,
|
||||
'hazard', 0.24,
|
||||
'slope-sector', 0.14,
|
||||
0.15
|
||||
]
|
||||
}
|
||||
});
|
||||
@@ -566,18 +566,17 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
source: 'tactical-terrain-spatial-src',
|
||||
filter: ['==', '$type', 'Polygon'],
|
||||
paint: {
|
||||
'line-color': ['get', 'color'],
|
||||
'line-color': [
|
||||
'match',
|
||||
['get', 'layerType'],
|
||||
'cliff', '#ef4444',
|
||||
'rgba(255, 255, 255, 0.10)'
|
||||
],
|
||||
'line-width': [
|
||||
'match',
|
||||
['get', 'layerType'],
|
||||
'cliff', 3.5,
|
||||
2
|
||||
],
|
||||
'line-dasharray': [
|
||||
'match',
|
||||
['get', 'layerType'],
|
||||
'cliff', ['literal', [2, 1]],
|
||||
['literal', [3, 2]]
|
||||
'cliff', 1.8,
|
||||
0.4
|
||||
]
|
||||
}
|
||||
});
|
||||
@@ -592,10 +591,10 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
'line-width': [
|
||||
'match',
|
||||
['get', 'layerType'],
|
||||
'cliff', 4.5,
|
||||
'road', 4.5,
|
||||
'wadi', 3.5,
|
||||
3
|
||||
'cliff', 3.5,
|
||||
'road', 4.0,
|
||||
'wadi', 3.0,
|
||||
2.5
|
||||
],
|
||||
'line-dasharray': [
|
||||
'match',
|
||||
@@ -608,21 +607,37 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
}
|
||||
});
|
||||
|
||||
initialMap.addLayer({
|
||||
id: 'tactical-terrain-spatial-points',
|
||||
type: 'circle',
|
||||
source: 'tactical-terrain-spatial-src',
|
||||
filter: ['==', '$type', 'Point'],
|
||||
paint: {
|
||||
'circle-radius': 5,
|
||||
'circle-color': ['coalesce', ['get', 'color'], '#38bdf8'],
|
||||
'circle-stroke-width': 2,
|
||||
'circle-stroke-color': '#ffffff'
|
||||
}
|
||||
});
|
||||
|
||||
initialMap.addLayer({
|
||||
id: 'tactical-terrain-spatial-labels',
|
||||
type: 'symbol',
|
||||
source: 'tactical-terrain-spatial-src',
|
||||
filter: ['all', ['==', '$type', 'Point'], ['has', 'title']],
|
||||
layout: {
|
||||
'text-field': ['get', 'title'],
|
||||
'text-size': 11,
|
||||
'text-size': 12,
|
||||
'text-font': ['Noto Sans Bold', 'Open Sans Bold'],
|
||||
'text-anchor': 'center',
|
||||
'symbol-placement': 'point'
|
||||
'text-anchor': 'bottom',
|
||||
'text-offset': [0, -0.6],
|
||||
'symbol-placement': 'point',
|
||||
'text-allow-overlap': false
|
||||
},
|
||||
paint: {
|
||||
'text-color': '#ffffff',
|
||||
'text-halo-color': '#0f172a',
|
||||
'text-halo-width': 2
|
||||
'text-halo-width': 2.5
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1674,14 +1689,14 @@ ${terrainResult.tacticalRecommendations.map((r, i) => `${i + 1}. ${r}`).join('\n
|
||||
<div style={{ height: 10, width: '100%', display: 'flex', borderRadius: 5, overflow: 'hidden', marginBottom: 6 }}>
|
||||
<div style={{ width: `${terrainResult.slopeDistribution.flatPercentage}%`, background: '#22c55e' }} title={`منبسط (<7°): ${terrainResult.slopeDistribution.flatPercentage}%`} />
|
||||
<div style={{ width: `${terrainResult.slopeDistribution.moderatePercentage}%`, background: '#eab308' }} title={`تضاريس متموجة (7-15°): ${terrainResult.slopeDistribution.moderatePercentage}%`} />
|
||||
<div style={{ width: `${terrainResult.slopeDistribution.steepPercentage}%`, background: '#f97316' }} title={`انحدار وعر (15-25°): ${terrainResult.slopeDistribution.steepPercentage}%`} />
|
||||
<div style={{ width: `${terrainResult.slopeDistribution.cliffPercentage}%`, background: '#ef4444' }} title={`قواطع وجروف صخرية (>25°): ${terrainResult.slopeDistribution.cliffPercentage}%`} />
|
||||
<div style={{ width: `${terrainResult.slopeDistribution.steepPercentage}%`, background: '#f97316' }} title={`انحدار وعر (15-28°): ${terrainResult.slopeDistribution.steepPercentage}%`} />
|
||||
<div style={{ width: `${terrainResult.slopeDistribution.cliffPercentage}%`, background: '#ef4444' }} title={`قواطع وجروف صخرية (≥28°): ${terrainResult.slopeDistribution.cliffPercentage}%`} />
|
||||
</div>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '3px 8px', fontSize: '0.66rem', color: '#94a3b8' }}>
|
||||
<span style={{ color: '#4ade80' }}>■ منبسط (<7°): {terrainResult.slopeDistribution.flatPercentage}%</span>
|
||||
<span style={{ color: '#facc15' }}>■ متموج (7-15°): {terrainResult.slopeDistribution.moderatePercentage}%</span>
|
||||
<span style={{ color: '#fb923c' }}>■ وعر (15-25°): {terrainResult.slopeDistribution.steepPercentage}%</span>
|
||||
<span style={{ color: '#f87171' }}>■ جروف صخرية (>25°): {terrainResult.slopeDistribution.cliffPercentage}%</span>
|
||||
<span style={{ color: '#fb923c' }}>■ وعر (15-28°): {terrainResult.slopeDistribution.steepPercentage}%</span>
|
||||
<span style={{ color: '#f87171' }}>■ جروف صخرية (≥28°): {terrainResult.slopeDistribution.cliffPercentage}%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -837,11 +837,11 @@ export async function calculateTerrainStudy(
|
||||
const p4 = [p4Coord.lng, p4Coord.lat];
|
||||
|
||||
// Military Grade Slope & Barrier Classification:
|
||||
// - Flat (GO): < 7°
|
||||
// - Rolling (SLOW-GO): 7° - 15°
|
||||
// - Rugged / Steep (SEVERE SLOW-GO): 15° - 25°
|
||||
// - Cliffs & Natural Rock Barriers (NO-GO): > 25° or vertical drop >= 12m
|
||||
const isCliff = slopeDeg >= 25 || (slopeDeg >= 18 && localDrop >= 10) || localDrop >= 18;
|
||||
// - Flat (GO): < 7° (< 12%)
|
||||
// - Rolling (SLOW-GO): 7° - 15° (12% - 27%)
|
||||
// - Rugged / Mountainous (SEVERE SLOW-GO): 15° - 28° (27% - 53%)
|
||||
// - Natural Cliffs & Rock Escarpments (NO-GO): >= 28° (Physical vertical barrier)
|
||||
const isCliff = slopeDeg >= 28;
|
||||
|
||||
if (isCliff) {
|
||||
cliffCount++;
|
||||
@@ -850,18 +850,17 @@ export async function calculateTerrainStudy(
|
||||
lng: Number(cellCenterLng.toFixed(5)),
|
||||
dropMeters: localDrop,
|
||||
slopeDegrees: slopeDeg,
|
||||
label: `🧗♂️ قاطع صخري وجرف حاد (سقوط ${localDrop}م - ميل ${slopeDeg}°)`,
|
||||
label: `🧗♂️ جرف صخري حاد (${localDrop}م / ${slopeDeg}°)`,
|
||||
tacticalImpact: 'مانع طبيعي قطعي - غير قابل لاجتياز الدروع والآليات، يفرض ممرات إجبارية'
|
||||
});
|
||||
|
||||
// Add prominent cliff barrier polygon & line
|
||||
// Add cliff barrier polygon without title label spam
|
||||
spatialFeatures.push({
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
layerType: 'cliff',
|
||||
category: 'natural-obstacle',
|
||||
color: '#dc2626',
|
||||
title: `🧗♂️ قاطع صخري وجرف حاد (${localDrop}م / ${slopeDeg}°)`,
|
||||
color: '#ef4444',
|
||||
slope: slopeDeg,
|
||||
drop: localDrop,
|
||||
elevation: cellElevAvg
|
||||
@@ -879,7 +878,6 @@ export async function calculateTerrainStudy(
|
||||
layerType: 'slope-sector',
|
||||
category: 'severe-slow-go',
|
||||
color: '#f97316',
|
||||
title: `انحدار جبلي وعر (SEVERE SLOW-GO) [${slopeDeg}°]`,
|
||||
slope: slopeDeg,
|
||||
elevation: cellElevAvg
|
||||
},
|
||||
@@ -896,7 +894,6 @@ export async function calculateTerrainStudy(
|
||||
layerType: 'slope-sector',
|
||||
category: 'slow-go',
|
||||
color: '#eab308',
|
||||
title: `تضاريس متموجة (SLOW-GO) [${slopeDeg}°]`,
|
||||
slope: slopeDeg,
|
||||
elevation: cellElevAvg
|
||||
},
|
||||
@@ -913,7 +910,6 @@ export async function calculateTerrainStudy(
|
||||
layerType: 'slope-sector',
|
||||
category: 'go',
|
||||
color: '#22c55e',
|
||||
title: `ممر حركة منبسط (GO) [${slopeDeg}°]`,
|
||||
slope: slopeDeg,
|
||||
elevation: cellElevAvg
|
||||
},
|
||||
@@ -926,6 +922,37 @@ export async function calculateTerrainStudy(
|
||||
}
|
||||
}
|
||||
|
||||
// Add Key Terrain POI Points (Only these will display text badges on the map)
|
||||
spatialFeatures.push({
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
category: 'peak',
|
||||
layerType: 'poi',
|
||||
title: `▲ أعلى قمة: ${highestPoint.elevation}م`,
|
||||
elevation: highestPoint.elevation,
|
||||
color: '#22c55e'
|
||||
},
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [highestPoint.lng, highestPoint.lat]
|
||||
}
|
||||
});
|
||||
|
||||
spatialFeatures.push({
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
category: 'valley',
|
||||
layerType: 'poi',
|
||||
title: `▼ أخفض نقطة: ${lowestPoint.elevation}م`,
|
||||
elevation: lowestPoint.elevation,
|
||||
color: '#06b6d4'
|
||||
},
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [lowestPoint.lng, lowestPoint.lat]
|
||||
}
|
||||
});
|
||||
|
||||
// 5. Statistics of Slope Distribution
|
||||
const totalCells = Math.max(1, slopeValues.length);
|
||||
const flatPct = Math.round((flatCount / totalCells) * 100);
|
||||
|
||||
Reference in New Issue
Block a user