|
@@ -614,7 +614,7 @@ import '@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css';
|
|
|
import * as turf from '@turf/turf';
|
|
|
import SettingPage from './SettingPage.vue';
|
|
|
import wkt from 'terraformer-wkt-parser';
|
|
|
-import Proj from "proj4leaflet";
|
|
|
+import Proj from 'proj4leaflet';
|
|
|
const showLayerControl = ref(false);
|
|
|
const showLegend = ref(false);
|
|
|
const pageRef = ref();
|
|
@@ -1660,6 +1660,111 @@ const updateXzxs = () => {
|
|
|
};
|
|
|
const initLineChart = () => {
|
|
|
const myChart = echarts.init(document.getElementById('chart'));
|
|
|
+
|
|
|
+ // 对x轴年份和y轴数据做升序排序
|
|
|
+ let xData = form.value.chartData.xData.map(Number); // 转为数字,防止字符串排序错乱
|
|
|
+ let yData = form.value.chartData.yData;
|
|
|
+ // 组合成对象数组
|
|
|
+ let arr = xData.map((year, idx) => ({ year, value: yData[idx] }));
|
|
|
+ // 按年份升序排序
|
|
|
+ arr.sort((a, b) => a.year - b.year);
|
|
|
+ // 拆分回x和y
|
|
|
+ let sortedYears = arr.map((item) => item.year.toString());
|
|
|
+ let sortedPrices = arr.map((item) => item.value);
|
|
|
+
|
|
|
+ // 新增:判断是否有2025,分段画线
|
|
|
+ const idx2025 = sortedYears.indexOf('2025');
|
|
|
+ let series = [];
|
|
|
+ if (idx2025 > 0) {
|
|
|
+ // 前面正常线
|
|
|
+ series.push({
|
|
|
+ data: sortedPrices.slice(0, idx2025),
|
|
|
+ type: 'line',
|
|
|
+ lineStyle: { color: '#FF8537' },
|
|
|
+ label: { show: true, position: 'top', color: '#FF8537', fontSize: 14 },
|
|
|
+ symbol: 'circle',
|
|
|
+ symbolSize: 8,
|
|
|
+ // x轴数据对应
|
|
|
+ xAxisIndex: 0,
|
|
|
+ yAxisIndex: 0,
|
|
|
+ });
|
|
|
+ // 2024-2025虚线
|
|
|
+ series.push({
|
|
|
+ data: [sortedPrices[idx2025 - 1], sortedPrices[idx2025]],
|
|
|
+ type: 'line',
|
|
|
+ lineStyle: { color: '#FF8537', type: 'dashed' },
|
|
|
+ label: { show: true, position: 'top', color: '#FF8537', fontSize: 14 },
|
|
|
+ symbol: 'circle',
|
|
|
+ symbolSize: 8,
|
|
|
+ xAxisIndex: 0,
|
|
|
+ yAxisIndex: 0,
|
|
|
+ // 只显示2024和2025的x轴
|
|
|
+ // 通过自定义x轴数据实现
|
|
|
+ // 但ECharts会自动对齐x轴,需用dataset或补齐数据
|
|
|
+ // 这里用x轴数据覆盖
|
|
|
+ encode: { x: [idx2025 - 1, idx2025], y: [0, 1] },
|
|
|
+ });
|
|
|
+ // 重新设置x轴,防止虚线段错位
|
|
|
+ var option = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item'
|
|
|
+ },
|
|
|
+ color: '#FF8537',
|
|
|
+ grid: {
|
|
|
+ top: '15%',
|
|
|
+ bottom: '20%',
|
|
|
+ left: '15%',
|
|
|
+ right: '10%'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ data: sortedYears,
|
|
|
+ axisTick: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ color: '#333',
|
|
|
+ rotate: -45
|
|
|
+ }
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ axisLabel: {
|
|
|
+ color: '#999'
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ color: '#E9EBF4'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ // 前面实线
|
|
|
+ {
|
|
|
+ data: sortedPrices.slice(0, idx2025),
|
|
|
+ type: 'line',
|
|
|
+ lineStyle: { color: '#FF8537' },
|
|
|
+ label: { show: true, position: 'top', color: '#FF8537', fontSize: 14 },
|
|
|
+ symbol: 'circle',
|
|
|
+ symbolSize: 8,
|
|
|
+ },
|
|
|
+ // 2024-2025虚线
|
|
|
+ {
|
|
|
+ data: [null, ...Array(idx2025 - 2).fill(null), sortedPrices[idx2025 - 1], sortedPrices[idx2025]],
|
|
|
+ type: 'line',
|
|
|
+ lineStyle: { color: '#FF8537', type: 'dashed' },
|
|
|
+ label: { show: true, position: 'top', color: '#FF8537', fontSize: 14 },
|
|
|
+ symbol: 'circle',
|
|
|
+ symbolSize: 8,
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ myChart.setOption(option);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 没有2025,正常线
|
|
|
var option = {
|
|
|
tooltip: {
|
|
|
trigger: 'item'
|
|
@@ -1673,7 +1778,7 @@ const initLineChart = () => {
|
|
|
},
|
|
|
xAxis: {
|
|
|
type: 'category',
|
|
|
- data: form.value.chartData.xData,
|
|
|
+ data: sortedYears,
|
|
|
axisTick: {
|
|
|
show: false
|
|
|
},
|
|
@@ -1696,8 +1801,12 @@ const initLineChart = () => {
|
|
|
},
|
|
|
series: [
|
|
|
{
|
|
|
- data: form.value.chartData.yData,
|
|
|
- type: 'line'
|
|
|
+ data: sortedPrices,
|
|
|
+ type: 'line',
|
|
|
+ lineStyle: { color: '#FF8537' },
|
|
|
+ label: { show: true, position: 'top', color: '#FF8537', fontSize: 14 },
|
|
|
+ symbol: 'circle',
|
|
|
+ symbolSize: 8,
|
|
|
}
|
|
|
]
|
|
|
};
|
|
@@ -1743,6 +1852,19 @@ const getNewLineData = () => {
|
|
|
xData: form.value.xData,
|
|
|
yData: yData
|
|
|
};
|
|
|
+ // 新增:如果选择的年份是2025年,xData和yData中加入2025和预测价格
|
|
|
+ if (form.value.formItem.year == '2025' || form.value.formItem.year == 2025) {
|
|
|
+ const predictYear = '2025';
|
|
|
+ const predictPrice =
|
|
|
+ form.value.result && form.value.result.pred_result
|
|
|
+ ? (form.value.result.pred_result * 10000).toFixed(2)
|
|
|
+ : '';
|
|
|
+ // 如果xData中没有2025,则添加
|
|
|
+ if (!form.value.xData.includes(predictYear)) {
|
|
|
+ form.value.xData.push(predictYear);
|
|
|
+ yData.push(predictPrice);
|
|
|
+ }
|
|
|
+ }
|
|
|
nextTick(() => {
|
|
|
initLineChart();
|
|
|
});
|
|
@@ -2005,16 +2127,14 @@ const resetLandPanel = () => {
|
|
|
};
|
|
|
//供地geoserver
|
|
|
const queryGDByGeoServerFeature = (geo) => {
|
|
|
-
|
|
|
const currentYear = new Date().getFullYear();
|
|
|
const preYear = currentYear - form.value.formItem.cksj;
|
|
|
var start = preYear + '-01-01';
|
|
|
var end = currentYear + '-12-31';
|
|
|
|
|
|
-
|
|
|
// 1. 构造 GML Polygon
|
|
|
const rings = geo.rings[0];
|
|
|
- const posList = rings.map(pt => pt.join(' ')).join(' ');
|
|
|
+ const posList = rings.map((pt) => pt.join(' ')).join(' ');
|
|
|
|
|
|
// 2. 构造 XML Filter
|
|
|
const tdytmc = form.value.formItem.tdyt;
|
|
@@ -2075,72 +2195,73 @@ const queryGDByGeoServerFeature = (geo) => {
|
|
|
} else if (!/outputFormat=/.test(url)) {
|
|
|
url += '&outputFormat=application%2Fjson';
|
|
|
}
|
|
|
- axios.post(url, xml, {
|
|
|
- headers: {
|
|
|
- 'Content-Type': 'text/xml'
|
|
|
- },
|
|
|
- transformRequest: [(data) => data]
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- const data = res.data;
|
|
|
+ axios
|
|
|
+ .post(url, xml, {
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'text/xml'
|
|
|
+ },
|
|
|
+ transformRequest: [(data) => data]
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ const data = res.data;
|
|
|
if (!data.features || data.features.length < 1) {
|
|
|
- message.info('未叠加到符合条件的供地数据');
|
|
|
+ message.info('未叠加到符合条件的供地数据');
|
|
|
if (markersLayers) markersLayers.clearLayers();
|
|
|
- form.value.formItem.ycdj = '';
|
|
|
- return;
|
|
|
- }
|
|
|
+ form.value.formItem.ycdj = '';
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
// 调用 algorithm 进行后续处理
|
|
|
- var attrs = [];
|
|
|
- var origGeo = arcgisToGeoJSON(geo);
|
|
|
- var center = turf.center(origGeo);
|
|
|
- let pt = center.geometry.coordinates;
|
|
|
- var orign = { geojson: origGeo, center: pt };
|
|
|
+ var attrs = [];
|
|
|
+ var origGeo = arcgisToGeoJSON(geo);
|
|
|
+ var center = turf.center(origGeo);
|
|
|
+ let pt = center.geometry.coordinates;
|
|
|
+ var orign = { geojson: origGeo, center: pt };
|
|
|
|
|
|
- data.features.forEach((item) => {
|
|
|
- var geojson = item.geometry;
|
|
|
- if (geojson.geometries) {
|
|
|
- geojson.geometries.forEach((it) => {
|
|
|
- try {
|
|
|
- var interGeo = turf.intersect(origGeo, it);
|
|
|
- if (interGeo) {
|
|
|
- var area = turf.area(turf.getGeom(interGeo)).toFixed(2);
|
|
|
- attrs.push({
|
|
|
- area: area,
|
|
|
- attributes: item.properties,
|
|
|
- geo: interGeo,
|
|
|
- center: turf.center(it).geometry.coordinates
|
|
|
+ data.features.forEach((item) => {
|
|
|
+ var geojson = item.geometry;
|
|
|
+ if (geojson.geometries) {
|
|
|
+ geojson.geometries.forEach((it) => {
|
|
|
+ try {
|
|
|
+ var interGeo = turf.intersect(origGeo, it);
|
|
|
+ if (interGeo) {
|
|
|
+ var area = turf.area(turf.getGeom(interGeo)).toFixed(2);
|
|
|
+ attrs.push({
|
|
|
+ area: area,
|
|
|
+ attributes: item.properties,
|
|
|
+ geo: interGeo,
|
|
|
+ center: turf.center(it).geometry.coordinates
|
|
|
});
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
console.error(e);
|
|
|
- }
|
|
|
- });
|
|
|
- } else {
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
try {
|
|
|
- var interGeo = turf.intersect(origGeo, geojson);
|
|
|
- if (interGeo) {
|
|
|
- var area = turf.area(turf.getGeom(interGeo)).toFixed(2);
|
|
|
- attrs.push({
|
|
|
- area: area,
|
|
|
- attributes: item.properties,
|
|
|
- geo: interGeo,
|
|
|
- center: turf.center(geojson).geometry.coordinates
|
|
|
+ var interGeo = turf.intersect(origGeo, geojson);
|
|
|
+ if (interGeo) {
|
|
|
+ var area = turf.area(turf.getGeom(interGeo)).toFixed(2);
|
|
|
+ attrs.push({
|
|
|
+ area: area,
|
|
|
+ attributes: item.properties,
|
|
|
+ geo: interGeo,
|
|
|
+ center: turf.center(geojson).geometry.coordinates
|
|
|
});
|
|
|
}
|
|
|
} catch (e) {
|
|
|
console.error(e);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- });
|
|
|
+ });
|
|
|
|
|
|
//克里金插值
|
|
|
- algorithm(orign, attrs);
|
|
|
+ algorithm(orign, attrs);
|
|
|
})
|
|
|
- .catch(error => {
|
|
|
+ .catch((error) => {
|
|
|
message.error('供地数据查询失败');
|
|
|
console.error(error);
|
|
|
- });
|
|
|
+ });
|
|
|
};
|
|
|
const queryGDByGeoServerFeature1 = (geo) => {
|
|
|
var cksj = null;
|
|
@@ -2213,13 +2334,13 @@ const queryGDByGeoServerFeature1 = (geo) => {
|
|
|
}
|
|
|
});
|
|
|
} else {
|
|
|
- var origGeo = arcgisToGeoJSON(geo);
|
|
|
- var center = turf.center(geojson);
|
|
|
- let pt = center.geometry.coordinates;
|
|
|
- var interGeo = turf.intersect(origGeo, geojson);
|
|
|
- if (interGeo) {
|
|
|
- var area = turf.area(turf.getGeom(interGeo)).toFixed(2);
|
|
|
- console.log(area);
|
|
|
+ var origGeo = arcgisToGeoJSON(geo);
|
|
|
+ var center = turf.center(geojson);
|
|
|
+ let pt = center.geometry.coordinates;
|
|
|
+ var interGeo = turf.intersect(origGeo, geojson);
|
|
|
+ if (interGeo) {
|
|
|
+ var area = turf.area(turf.getGeom(interGeo)).toFixed(2);
|
|
|
+ console.log(area);
|
|
|
attrs.push({ area: area, attributes: item.properties, geo: interGeo, center: pt });
|
|
|
}
|
|
|
}
|
|
@@ -2561,12 +2682,12 @@ const handleAnalysisData = (data) => {
|
|
|
for (var i = 0; i < item.result.length; i++) {
|
|
|
var t = item.result[i];
|
|
|
if (t.unit == 'km') {
|
|
|
- if (t.center && t.center.indexOf(',') > -1) {
|
|
|
- zgdFlag = true;
|
|
|
- var pt = [];
|
|
|
- pt.push(t.center.split(',')[0]);
|
|
|
- pt.push(t.center.split(',')[1]);
|
|
|
- attrs.push({ attributes: t, center: pt });
|
|
|
+ if (t.center && t.center.indexOf(',') > -1) {
|
|
|
+ zgdFlag = true;
|
|
|
+ var pt = [];
|
|
|
+ pt.push(t.center.split(',')[0]);
|
|
|
+ pt.push(t.center.split(',')[1]);
|
|
|
+ attrs.push({ attributes: t, center: pt });
|
|
|
}
|
|
|
}
|
|
|
}
|