You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

393 lines
12 KiB

import { ecologicalProtectionMenu } from "@/config/ecologicalProtection"
export { ecologicalProtectionMenu }
const round = (value, digits = 2) => Number(Number(value || 0).toFixed(digits))
const ecologicalDirectPanelDefinitions = {
left: [
{ key: "grasslandDistribution", title: "草地分布", type: "column", variant: "plain", labelMode: "horizontal", scrollable: false, span: 1 },
{ key: "wetlandDistribution", title: "湿地面积", type: "rank", labelMode: "horizontal", scrollable: false, span: 1 },
{ key: "woodlandDistribution", title: "林地分布", type: "split", variant: "compact", span: 1 },
{ key: "grasslandProductivity", title: "草地生产力", type: "line", fixedType: true, labelMode: "horizontal", span: 1 },
],
right: [
{ key: "grasslandTypes", title: "草原类型", type: "donut", variant: "ring", span: 1 },
{ key: "grasslandLevels", title: "草原级占比", type: "rose", span: 1 },
{ key: "woodlandQuality", title: "林地质量", type: "heat", limit: 6, span: 1 },
{ key: "resourceStructure", title: "林草湿面积构成", type: "structure", span: 1 },
],
}
function buildEcologicalDirectPanels(panels = {}) {
return Object.fromEntries(
Object.entries(ecologicalDirectPanelDefinitions).map(([side, definitions]) => [
side,
definitions.map((definition) => ({
...definition,
rows: Array.isArray(panels?.[definition.key]?.rows) ? panels[definition.key].rows : [],
count: panels?.[definition.key]?.count,
})),
]),
)
}
export const buildEcologicalRedlinePanels = buildEcologicalDirectPanels
export const buildNaturalProtectedAreaPanels = buildEcologicalDirectPanels
function normalizeEcologicalRows(value = []) {
let rows = value
if (rows && typeof rows === "object" && !Array.isArray(rows) && "value" in rows) {
rows = rows.value
}
if (typeof rows === "string") {
try {
rows = JSON.parse(rows)
} catch {
rows = []
}
}
return (Array.isArray(rows) ? rows : []).map((item, index) => ({
...item,
key: item.key || `ecological-${item.name || item.zh || index}`,
name: item.name || item.zh || `统计项${index + 1}`,
value: Number.isFinite(Number(item.value)) ? round(item.value, 2) : item.value,
}))
}
function getNationalParkRows(stats, key) {
return stats?.[key]?.rows || []
}
function getNationalParkPanelRows(stats, key) {
return stats?.panels?.[key]?.rows || []
}
export function getNationalParkTopStats(stats = {}) {
return getNationalParkRows(stats, "topRows")
}
export function getNationalParkCoreRows(stats = {}) {
return getNationalParkRows(stats, "coreRows")
}
export function getNationalParkTownRows(stats = {}) {
return getNationalParkRows(stats, "townRows")
}
export function buildNationalParkPanels(stats = {}) {
return {
left: [
{
key: "park-town-grass-wet-area",
title: "草地湿地面积分布",
type: "stackColumn",
variant: "parkSlim",
showValue: true,
sharedScale: true,
unit: "万亩",
segments: [
{ key: "grassland", name: "草地面积", color: "#24f6c4" },
{ key: "wetland", name: "湿地面积", color: "#8bf7ff" },
],
rows: getNationalParkPanelRows(stats, "townResource"),
},
{
key: "park-town-productivity",
title: "草地湿地生产力",
type: "line",
fixedType: true,
labelMode: "horizontal",
showValues: true,
unit: "万吨",
rows: getNationalParkPanelRows(stats, "townProductivity"),
},
{
key: "park-town-yak",
title: "乡镇牦牛数量",
type: "bar",
variant: "parkBar",
rows: getNationalParkPanelRows(stats, "townYak"),
},
{
key: "park-town-balance",
title: "草畜平衡超载率",
type: "balanceGaugeGrid",
limit: 1,
rows: getNationalParkPanelRows(stats, "balance"),
},
],
right: [
{
key: "park-zoning-structure",
title: "红原管控区结构",
type: "donut",
rows: getNationalParkPanelRows(stats, "zoning"),
},
{
key: "park-town-household",
title: "牧户分布",
type: "split",
rows: getNationalParkPanelRows(stats, "townHousehold"),
},
{
key: "park-town-ecology-job",
title: "公益岗位分布",
type: "column",
variant: "plain",
rows: getNationalParkPanelRows(stats, "townJob"),
},
],
}
}
export function getEcologicalRestorationTopStats(stats = {}) {
return normalizeEcologicalRows(stats.topRows).map((item, index) => ({
icon: item.icon || (index % 2 === 0 ? "xiaoshoujine" : "zongxiaoliang"),
en: "",
...item,
}))
}
export function getEcologicalEngineeringAnalysisTopStats(stats = {}) {
return normalizeEcologicalRows(stats.topRows).map((item, index) => ({
icon: item.icon || (index % 2 === 0 ? "xiaoshoujine" : "zongxiaoliang"),
en: "",
...item,
}))
}
export function getEcologicalEngineeringTypeRows(stats = {}) {
return normalizeEcologicalRows(stats.engineeringTypes).map((item) => ({
...item,
value: Number(item.baseCount || 0),
unit: "个图斑",
extra: `候选面积 ${round(item.baseAreaWanMu, 2)}万亩`,
}))
}
export function getEcologicalEngineeringTownRows(stats = {}) {
return normalizeEcologicalRows(stats.townRows).map((item) => ({
...item,
value: Number(item.candidateFeatureCount || 0),
unit: "个图斑",
extra: `候选面积 ${round(item.candidateAreaWanMu, 2)}万亩`,
}))
}
function getRestorationScale(item = {}) {
const area = Number(item.areaWanMu || 0)
const length = Number(item.lengthKm || 0)
if (area > 0) return { value: round(area, 2), unit: "万亩", metric: "治理面积" }
if (length > 0) return { value: round(length, 2), unit: "公里", metric: "工程长度" }
return { value: Number(item.subjectFeatureCount || 0), unit: "个", metric: "主体要素" }
}
export function getEcologicalRestorationProjectRows(stats = {}) {
return normalizeEcologicalRows(stats.projectRows).map((item, index) => {
const scale = getRestorationScale(item)
const measure = String(item.measureTypes || "")
const townships = String(item.townships || "")
const year = item.year || "未知"
return {
...item,
index: index + 1,
name: item.projectName,
category: item.projectCategory,
year,
areaWanMu: round(item.areaWanMu, 4),
lengthKm: round(item.lengthKm, 2),
measure,
townships,
subjectFeatureCount: Number(item.subjectFeatureCount || 0),
value: scale.value,
unit: scale.unit,
metric: scale.metric,
extra: [year, measure].filter(Boolean).join(" / "),
searchText: [item.projectName, item.projectCategory, year, measure, townships].filter(Boolean).join(" "),
}
})
}
export function buildEcologicalRestorationPanels(stats = {}) {
const yearRows = normalizeEcologicalRows(stats.yearRows)
const townRows = normalizeEcologicalRows(stats.townRows)
const categoryRows = normalizeEcologicalRows(stats.categoryRows)
const measureRows = normalizeEcologicalRows(stats.measureRows)
const projectRows = getEcologicalRestorationProjectRows(stats)
return {
left: [
{
key: "restoration-year-area",
title: "治理面积分布",
type: "line",
labelMode: "horizontal",
rows: yearRows.map((item) => ({
...item,
value: round(item.areaWanMu, 2),
unit: "万亩",
extra: `${Number(item.projectCount || 0)}个项目`,
})),
},
{
key: "restoration-town-area",
title: "乡镇治理面积分布",
type: "column",
variant: "plain",
labelMode: "horizontal",
scrollable: false,
rows: townRows.map((item) => ({
...item,
value: round(item.areaWanMu, 2),
unit: "万亩",
extra: `${round(item.lengthKm, 2)}公里`,
})),
},
{
key: "restoration-category",
title: "修复类型占比",
type: "donut",
rows: categoryRows.map((item) => ({
...item,
...getRestorationScale(item),
extra: `${Number(item.subjectFeatureCount || 0)}个图斑`,
})),
},
{
key: "restoration-year-length",
title: "年度工程长度",
type: "bar",
variant: "rankBar",
labelMode: "horizontal",
rows: yearRows
.filter((item) => Number(item.lengthKm) > 0)
.map((item) => ({
...item,
value: round(item.lengthKm, 2),
unit: "公里",
extra: `${Number(item.projectCount || 0)}个项目`,
})),
},
],
right: [
{
key: "restoration-measure-area",
title: "修复措施统计",
type: "structure",
rows: measureRows.slice(0, 8).map((item) => ({
...item,
...getRestorationScale(item),
extra: `${Number(item.projectCount || 0)}个项目`,
})),
},
{
key: "restoration-year-project",
title: "年度项目数量",
type: "heat",
labelMode: "horizontal",
rows: yearRows
.filter((item) => item.name !== "未知")
.map((item) => ({
...item,
value: Number(item.projectCount || 0),
unit: "个",
extra: `${round(item.areaWanMu, 2)}万亩`,
})),
},
{
key: "restoration-projects",
title: "重点项目库",
type: "projectTable",
span: 2,
columns: [
{ key: "name", label: "项目名称", field: "name", width: "58%", className: "business-project-col-name" },
{ key: "year", label: "年份", field: "year", width: "16%", fallback: "未知", align: "right", className: "business-project-col-year" },
{ key: "category", label: "类型", field: "category", width: "26%", className: "business-project-col-category" },
],
rows: projectRows,
},
],
}
}
export const engineeringAnalysisPanels = {
left: [],
right: [],
}
export const centerMapNotes = {
"ecological-redline": {
title: "红原县生态保护红线",
subtitle: "保护范围 / 林草湿资源 / 生产力统计",
tags: ["红线范围", "草地", "湿地", "林地"],
},
"natural-protected-area": {
title: "红原县自然保护地",
subtitle: "功能分区 / 林草湿资源 / 生产力统计",
tags: ["核心保护区", "一般控制区", "草地", "湿地"],
},
"national-park": {
title: "若尔盖国家公园红原区域",
subtitle: "核心保护区 / 一般控制区 / 生态资源统计",
tags: ["植被盖度", "草地面积", "湿地面积", "牧户牦牛"],
},
restoration: {
title: "生态修复工程项目库",
subtitle: "草地修复 / 湿地修复 / 林地修复 / 水源涵养",
tags: ["项目库", "治理面积", "工程长度", "乡镇排行"],
},
"engineering-analysis": {
title: "生态工程分析",
subtitle: "工程初筛 / 乡镇筛选 / 近年项目排除",
tags: ["封山育林", "草原改良", "人工种草", "空间分析"],
},
}
export function getEcologicalMapRanking(viewKey, stats = {}) {
if (["ecological-redline", "natural-protected-area"].includes(viewKey)) {
return {
status: "success",
title: viewKey === "natural-protected-area" ? "自然保护地" : "生态保护红线",
metricLabel: "",
unit: "",
rows: [],
}
}
if (viewKey === "restoration") {
return {
status: "success",
title: "乡镇治理排行",
metricLabel: "治理面积",
unit: "万亩",
rows: normalizeEcologicalRows(stats.townRows).map((item) => ({
name: item.name,
value: round(item.areaWanMu, 2),
unit: "万亩",
})),
}
}
if (viewKey === "engineering-analysis") {
return {
status: "success",
title: "工程分析",
metricLabel: "",
unit: "",
rows: [],
}
}
return {
status: "success",
title: "国家公园乡镇划定面积",
scope: "town",
hideTownNames: false,
onlyRankedTownLabels: true,
metricLabel: "划定面积",
unit: "万亩",
rows: getNationalParkTownRows(stats).map((item) => ({
name: item.name,
value: item.value,
unit: "万亩",
metricLabel: "划定面积",
})),
}
}