generated from Grigo/AndroidTemplate
updated api
This commit is contained in:
@@ -1873,6 +1873,91 @@ function renderApiDebugViewshedLayer(geojson) {
|
||||
});
|
||||
}
|
||||
|
||||
function fitApiDebugLayer(layer) {
|
||||
const bounds = layer?.getBounds?.();
|
||||
if (bounds?.isValid?.()) {
|
||||
setMapViewProgrammatically(() => map.fitBounds(bounds, { padding: [40, 40], maxZoom: 16 }));
|
||||
}
|
||||
}
|
||||
|
||||
function renderApiDebugFresnelSlice(data) {
|
||||
clearApiDebugCoverage();
|
||||
clearApiDebugBeam();
|
||||
const layers = [];
|
||||
const pathLayer = data?.path_geojson ? L.geoJSON(data.path_geojson, {
|
||||
style: { color: '#4fc3f7', weight: 3, opacity: 0.95 }
|
||||
}) : null;
|
||||
const fresnelLayer = data?.fresnel_geojson ? L.geoJSON(data.fresnel_geojson, {
|
||||
style: {
|
||||
color: '#ffd54f',
|
||||
weight: 2,
|
||||
opacity: 0.95,
|
||||
fillColor: '#ffd54f',
|
||||
fillOpacity: 0.2
|
||||
}
|
||||
}) : null;
|
||||
const buildingsLayer = data?.buildings_geojson ? L.geoJSON(data.buildings_geojson, {
|
||||
style: {
|
||||
color: '#ff1744',
|
||||
weight: 1.5,
|
||||
opacity: 0.95,
|
||||
fillColor: '#ff1744',
|
||||
fillOpacity: 0.3
|
||||
},
|
||||
onEachFeature: (feature, layer) => {
|
||||
const p = feature.properties || {};
|
||||
const parts = [];
|
||||
if (p.height_m != null) parts.push(`height ${fmtNum(p.height_m, 1, ' m')}`);
|
||||
if (p.intersection_area_m2 != null) parts.push(`пересечение ${fmtNum(p.intersection_area_m2, 1, ' m²')}`);
|
||||
if (p.building_type) parts.push(escapeHtml(p.building_type));
|
||||
if (parts.length) layer.bindPopup(parts.join(' · '));
|
||||
}
|
||||
}) : null;
|
||||
[fresnelLayer, buildingsLayer, pathLayer].forEach(layer => {
|
||||
if (layer) layers.push(layer);
|
||||
});
|
||||
if (!layers.length) {
|
||||
apiDebugSetSummary('Ответ fresnel-slice не содержит GeoJSON слоёв.');
|
||||
return;
|
||||
}
|
||||
apiDebugCoverageLayer = L.featureGroup(layers).addTo(map);
|
||||
fitApiDebugLayer(apiDebugCoverageLayer);
|
||||
const buildings = data?.buildings_geojson?.features?.length ?? 0;
|
||||
const profilePoints = data?.profile?.length ?? 0;
|
||||
apiDebugSetSummary(
|
||||
`<b>Срез зоны Френеля:</b> ${profilePoints} точек профиля · ${buildings} зданий пересекают область<br>` +
|
||||
`Жёлтая область — горизонтальный срез 60% зоны Френеля, красные полигоны — пересекающие здания.` +
|
||||
formatDataSourcesLine(data?.data_sources)
|
||||
);
|
||||
}
|
||||
|
||||
function renderApiDebugBuildings(data) {
|
||||
const features = data?.features?.length ?? 0;
|
||||
const rendered = renderApiDebugGeoJsonLayer(data, {
|
||||
style: {
|
||||
color: '#ff1744',
|
||||
weight: 1.3,
|
||||
opacity: 0.95,
|
||||
fillColor: '#ff1744',
|
||||
fillOpacity: 0.22
|
||||
},
|
||||
onEachFeature: (feature, layer) => {
|
||||
const p = feature.properties || {};
|
||||
const parts = [];
|
||||
if (p.height_m != null) parts.push(`height ${fmtNum(p.height_m, 1, ' m')}`);
|
||||
if (p.levels != null) parts.push(`${p.levels} эт.`);
|
||||
if (p.building_type) parts.push(escapeHtml(p.building_type));
|
||||
if (p.source) parts.push(escapeHtml(p.source));
|
||||
if (parts.length) layer.bindPopup(parts.join(' · '));
|
||||
}
|
||||
});
|
||||
apiDebugSetSummary(
|
||||
rendered
|
||||
? `<b>Здания вдоль линии:</b> ${features} объектов в буфере 50 m${formatDataSourcesLine(data?.data_sources)}`
|
||||
: 'Ответ buildings/query не содержит GeoJSON features.'
|
||||
);
|
||||
}
|
||||
|
||||
async function fetchApiDebugJobArtifact(jobId) {
|
||||
const f = apiDebugReadForm();
|
||||
const url = `${f.base}/api/v1/jobs/${encodeURIComponent(jobId)}/artifact`;
|
||||
@@ -2221,6 +2306,23 @@ function buildApiDebugRequest(kind) {
|
||||
}
|
||||
};
|
||||
}
|
||||
if (kind === 'fresnelSlice') {
|
||||
return {
|
||||
method: 'POST',
|
||||
path: '/api/v1/terrain/fresnel-slice',
|
||||
body: {
|
||||
tx,
|
||||
rx,
|
||||
frequency_mhz: f.frequency,
|
||||
fresnel_fraction: 0.6,
|
||||
include_buildings: true,
|
||||
include_canopy: f.includeCanopy,
|
||||
k_factor: 1.333,
|
||||
samples: f.samples,
|
||||
building_limit: 5000
|
||||
}
|
||||
};
|
||||
}
|
||||
if (kind === 'budget') {
|
||||
return {
|
||||
method: 'POST',
|
||||
@@ -2237,6 +2339,22 @@ function buildApiDebugRequest(kind) {
|
||||
}
|
||||
};
|
||||
}
|
||||
if (kind === 'buildings') {
|
||||
return {
|
||||
method: 'POST',
|
||||
path: '/api/v1/buildings/query',
|
||||
body: {
|
||||
path: {
|
||||
type: 'LineString',
|
||||
coordinates: [
|
||||
[f.tx.lon, f.tx.lat],
|
||||
[f.rx.lon, f.rx.lat]
|
||||
]
|
||||
},
|
||||
buffer_m: 50
|
||||
}
|
||||
};
|
||||
}
|
||||
if (kind === 'landcover') {
|
||||
return {
|
||||
method: 'POST',
|
||||
@@ -2429,7 +2547,9 @@ async function runApiDebugDemo(kind) {
|
||||
}
|
||||
if (kind === 'profile') renderApiDebugProfile(data, null, null);
|
||||
else if (kind === 'los') renderApiDebugProfile(null, data, null);
|
||||
else if (kind === 'fresnelSlice') renderApiDebugFresnelSlice(data);
|
||||
else if (kind === 'budget') apiDebugSetSummary(formatApiDebugBudgetSummary(data));
|
||||
else if (kind === 'buildings') renderApiDebugBuildings(data);
|
||||
else if (kind === 'landcover') apiDebugSetSummary(formatApiDebugLandcoverSummary(data));
|
||||
else if (kind === 'elevation') apiDebugSetSummary(formatApiDebugPointSummary(data));
|
||||
else if (kind === 'beam') renderApiDebugBeam(data);
|
||||
|
||||
@@ -71,7 +71,9 @@
|
||||
<button type="button" data-api-demo="elevation">Высота TX</button>
|
||||
<button type="button" data-api-demo="profile">Только профиль</button>
|
||||
<button type="button" data-api-demo="los">Только LOS/Френель</button>
|
||||
<button type="button" data-api-demo="fresnelSlice">Срез Френеля</button>
|
||||
<button type="button" data-api-demo="budget">Только link budget</button>
|
||||
<button type="button" data-api-demo="buildings">Здания вдоль линии</button>
|
||||
<button type="button" data-api-demo="landcover">Landcover path</button>
|
||||
<button type="button" data-api-demo="beam">Сектор антенны</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user