|
|
|
@ -228,7 +228,7 @@ const topicBusinessFields = { |
|
|
|
[["management_control_requirement"], "管控要求"], |
|
|
|
[["management_control_requirement"], "管控要求"], |
|
|
|
[["reserve_level", "natural_protected_area_level"], "保护地级别"], |
|
|
|
[["reserve_level", "natural_protected_area_level"], "保护地级别"], |
|
|
|
[["reserve_type", "natural_protected_area_type"], "保护地类型"], |
|
|
|
[["reserve_type", "natural_protected_area_type"], "保护地类型"], |
|
|
|
[["area_mu", "area_m2"], "图斑面积"], |
|
|
|
[["area_source_mj", "area_mu", "area_m2"], "图斑面积"], |
|
|
|
[["original_area_m2"], "原始面积"], |
|
|
|
[["original_area_m2"], "原始面积"], |
|
|
|
[["adjusted_area_m2"], "调整面积"], |
|
|
|
[["adjusted_area_m2"], "调整面积"], |
|
|
|
[["remarks"], "备注"], |
|
|
|
[["remarks"], "备注"], |
|
|
|
@ -527,6 +527,7 @@ const fieldLabels = { |
|
|
|
redline_type: "红线类型", |
|
|
|
redline_type: "红线类型", |
|
|
|
ecosystem_service_type: "生态系统服务类型", |
|
|
|
ecosystem_service_type: "生态系统服务类型", |
|
|
|
management_control_requirement: "管控要求", |
|
|
|
management_control_requirement: "管控要求", |
|
|
|
|
|
|
|
area_source_mj: "图斑面积", |
|
|
|
area_m2: "图斑面积", |
|
|
|
area_m2: "图斑面积", |
|
|
|
original_area_m2: "原始面积", |
|
|
|
original_area_m2: "原始面积", |
|
|
|
adjusted_area_m2: "调整面积", |
|
|
|
adjusted_area_m2: "调整面积", |
|
|
|
@ -669,6 +670,7 @@ const patchAreaFieldKeys = new Set([ |
|
|
|
"source_area_mu", |
|
|
|
"source_area_mu", |
|
|
|
"area_m2", |
|
|
|
"area_m2", |
|
|
|
"acreage", |
|
|
|
"acreage", |
|
|
|
|
|
|
|
"area_source_mj", |
|
|
|
"original_area_m2", |
|
|
|
"original_area_m2", |
|
|
|
"adjusted_area_m2", |
|
|
|
"adjusted_area_m2", |
|
|
|
"mj", |
|
|
|
"mj", |
|
|
|
@ -683,6 +685,7 @@ const patchAreaFieldKeys = new Set([ |
|
|
|
const townshipNamesByLength = [...hongyuanTownshipDisplayOrder].sort((a, b) => b.length - a.length) |
|
|
|
const townshipNamesByLength = [...hongyuanTownshipDisplayOrder].sort((a, b) => b.length - a.length) |
|
|
|
|
|
|
|
|
|
|
|
const propsData = computed(() => props.feature?.properties || {}) |
|
|
|
const propsData = computed(() => props.feature?.properties || {}) |
|
|
|
|
|
|
|
const featureGeometry = computed(() => props.feature?.feature?.geometry || props.feature?.geometry || null) |
|
|
|
const externalDisplayRows = computed(() => |
|
|
|
const externalDisplayRows = computed(() => |
|
|
|
(Array.isArray(props.rows) ? props.rows : []) |
|
|
|
(Array.isArray(props.rows) ? props.rows : []) |
|
|
|
.map((row, index) => ({ |
|
|
|
.map((row, index) => ({ |
|
|
|
@ -742,6 +745,10 @@ const displayRows = computed(() => { |
|
|
|
used.add(row.sourceKey) |
|
|
|
used.add(row.sourceKey) |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
const areaLabel = getTopicAreaLabel(activeTopicKey.value) |
|
|
|
|
|
|
|
if (!isArtificialGrassland.value && !isEngineeringSuitabilityFeature.value && !rows.some((row) => row.label === areaLabel || isGenericPatchAreaLabel(row.label))) { |
|
|
|
|
|
|
|
addStaticRow(rows, used, areaLabel, formatGeometryArea(featureGeometry.value), "geometry-area") |
|
|
|
|
|
|
|
} |
|
|
|
if (useCompactGrassland) return rows.slice(0, 10) |
|
|
|
if (useCompactGrassland) return rows.slice(0, 10) |
|
|
|
Object.entries(propsData.value).forEach(([key, value]) => { |
|
|
|
Object.entries(propsData.value).forEach(([key, value]) => { |
|
|
|
if (used.has(key) || shouldHideFallbackField(key, value)) return |
|
|
|
if (used.has(key) || shouldHideFallbackField(key, value)) return |
|
|
|
@ -858,6 +865,17 @@ function getRowPriority(row, index) { |
|
|
|
return 150 + index |
|
|
|
return 150 + index |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function addStaticRow(rows, used, label, value, sourceKey) { |
|
|
|
|
|
|
|
if (!hasValue(value) || rows.some((row) => row.label === label || row.value === value)) return |
|
|
|
|
|
|
|
rows.push({ |
|
|
|
|
|
|
|
key: `static-${sourceKey}`, |
|
|
|
|
|
|
|
sourceKey, |
|
|
|
|
|
|
|
label, |
|
|
|
|
|
|
|
value, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
used.add(sourceKey) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function resolveDisplayLabel(label, keys = []) { |
|
|
|
function resolveDisplayLabel(label, keys = []) { |
|
|
|
if (activeTopicKey.value === "ecological" && isEcologicalScopeFeature.value && isEcologicalAreaLabel(label, keys)) { |
|
|
|
if (activeTopicKey.value === "ecological" && isEcologicalScopeFeature.value && isEcologicalAreaLabel(label, keys)) { |
|
|
|
return "图斑面积" |
|
|
|
return "图斑面积" |
|
|
|
@ -921,6 +939,7 @@ function formatValue(key, value) { |
|
|
|
if (patchAreaFieldKeys.has(key) && number === 0) return "" |
|
|
|
if (patchAreaFieldKeys.has(key) && number === 0) return "" |
|
|
|
if (number === 0 && zeroHiddenKeys.has(key)) return "" |
|
|
|
if (number === 0 && zeroHiddenKeys.has(key)) return "" |
|
|
|
const formatted = Number.isInteger(number) ? `${number}` : `${Number(number.toFixed(2))}` |
|
|
|
const formatted = Number.isInteger(number) ? `${number}` : `${Number(number.toFixed(2))}` |
|
|
|
|
|
|
|
if (key === "area_source_mj") return `${formatAreaWanMu(number * 15)} 万亩` |
|
|
|
if (activeTopicKey.value === "ecological" && isEcologicalScopeFeature.value && ["area_mu", "acreage", "mj"].includes(key)) return `${formatAreaWanMu(number)} 万亩` |
|
|
|
if (activeTopicKey.value === "ecological" && isEcologicalScopeFeature.value && ["area_mu", "acreage", "mj"].includes(key)) return `${formatAreaWanMu(number)} 万亩` |
|
|
|
if (activeTopicKey.value === "ecological" && isEcologicalScopeFeature.value && ["area_m2", "original_area_m2", "adjusted_area_m2"].includes(key)) return `${formatAreaWanMu(number / 666.6667)} 万亩` |
|
|
|
if (activeTopicKey.value === "ecological" && isEcologicalScopeFeature.value && ["area_m2", "original_area_m2", "adjusted_area_m2"].includes(key)) return `${formatAreaWanMu(number / 666.6667)} 万亩` |
|
|
|
if (["xbmj", "tbdlmj", "geomj", "area_square_meter"].includes(key)) return `${formatAreaMu(number / 666.6667)} 亩` |
|
|
|
if (["xbmj", "tbdlmj", "geomj", "area_square_meter"].includes(key)) return `${formatAreaMu(number / 666.6667)} 亩` |
|
|
|
@ -1080,6 +1099,49 @@ function isUnmappedCodeField(key, value) { |
|
|
|
].includes(key) |
|
|
|
].includes(key) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatGeometryArea(geometry) { |
|
|
|
|
|
|
|
const squareMeters = getGeometryAreaSquareMeters(geometry) |
|
|
|
|
|
|
|
if (!squareMeters) return "" |
|
|
|
|
|
|
|
const mu = squareMeters / 666.6667 |
|
|
|
|
|
|
|
if (activeTopicKey.value === "ecological" && isEcologicalScopeFeature.value) return `${formatAreaWanMu(mu)} 万亩` |
|
|
|
|
|
|
|
return `${formatAreaMu(mu)} 亩` |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function getGeometryAreaSquareMeters(geometry) { |
|
|
|
|
|
|
|
if (!geometry?.coordinates) return 0 |
|
|
|
|
|
|
|
if (geometry.type === "Polygon") return getPolygonAreaSquareMeters(geometry.coordinates) |
|
|
|
|
|
|
|
if (geometry.type === "MultiPolygon") { |
|
|
|
|
|
|
|
return geometry.coordinates.reduce((sum, polygon) => sum + getPolygonAreaSquareMeters(polygon), 0) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return 0 |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function getPolygonAreaSquareMeters(rings = []) { |
|
|
|
|
|
|
|
if (!rings.length) return 0 |
|
|
|
|
|
|
|
const [outer, ...holes] = rings |
|
|
|
|
|
|
|
const outerArea = Math.abs(getRingAreaSquareMeters(outer)) |
|
|
|
|
|
|
|
const holesArea = holes.reduce((sum, ring) => sum + Math.abs(getRingAreaSquareMeters(ring)), 0) |
|
|
|
|
|
|
|
return Math.max(0, outerArea - holesArea) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function getRingAreaSquareMeters(ring = []) { |
|
|
|
|
|
|
|
if (ring.length < 3) return 0 |
|
|
|
|
|
|
|
const averageLat = ring.reduce((sum, point) => sum + Number(point?.[1] || 0), 0) / ring.length |
|
|
|
|
|
|
|
const metersPerDegree = 111320 |
|
|
|
|
|
|
|
const xScale = metersPerDegree * Math.cos((averageLat * Math.PI) / 180) |
|
|
|
|
|
|
|
let area = 0 |
|
|
|
|
|
|
|
for (let index = 0; index < ring.length; index++) { |
|
|
|
|
|
|
|
const current = ring[index] |
|
|
|
|
|
|
|
const next = ring[(index + 1) % ring.length] |
|
|
|
|
|
|
|
const x1 = Number(current?.[0] || 0) * xScale |
|
|
|
|
|
|
|
const y1 = Number(current?.[1] || 0) * metersPerDegree |
|
|
|
|
|
|
|
const x2 = Number(next?.[0] || 0) * xScale |
|
|
|
|
|
|
|
const y2 = Number(next?.[1] || 0) * metersPerDegree |
|
|
|
|
|
|
|
area += x1 * y2 - x2 * y1 |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return area / 2 |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function normalizeFieldLabel(key) { |
|
|
|
function normalizeFieldLabel(key) { |
|
|
|
return String(key) |
|
|
|
return String(key) |
|
|
|
.replace(/_/g, " ") |
|
|
|
.replace(/_/g, " ") |
|
|
|
|