1. 程式人生 > 其它 >基於GIS的國土空間規劃平臺建設

基於GIS的國土空間規劃平臺建設

本期介紹基於地理資訊平臺的國土空間規劃平臺的規劃輔助編制應用。在梳理國土空間規劃科學流程的基礎上,將規劃編制各關鍵環節資訊化、工具化、智慧化;充分發揮清華同衡大資料與智慧模型相結合的定量評估、精準預測的資料優勢與模型優勢,提升國土空間規劃編制的精準性、科學性。

國土空間規劃編制包括明晰規劃思路、統一規劃基礎、開展基礎評價、繪製規劃底圖、編制空間規劃等主要任務。在統一規劃基礎資訊前提下,開展資源環境承載能力評價和國土空間開發適宜性評價,劃定“三區三線”,形成規劃底圖;結合國家、區域及城市發展戰略,制定規劃目標,在規劃實施評估的基礎上,進行要素配置,併疊加規劃底圖,形成空間佈局方案,完成規劃成果編制。規劃輔助編制應用針對以上各任務,提供智慧化的分析模組。

國土空間規劃編制流程

模組1

規劃基礎資訊資料處理

國土空間規劃編制需要統一的規劃基礎資訊資料支撐。但目前規劃基礎資訊資料種類多樣、來源不一,面臨基準座標、資料格式、時空精度不統一等問題。規劃基礎資訊資料處理模組,建立國土空間規劃資料儲存、資料治理與資料使用規則;支援圖表、文字、空間向量、柵格、海量高時空精度社會大資料等各型別資料的儲存、載入與展示;提供座標轉換、格式轉換、時空精度轉換等功能,為國土空間規劃提供統一的規劃基礎資訊資料。

國土空間規劃基礎資訊資料目錄

模組2

“雙評價”

資源環境承載能力評價和國土空間開發適宜性評價(簡稱“雙評價”)是開展國土空間規劃編制的前提和基礎。

其中,資源環境承載能力評價是指在土地資源、水資源、海洋資源、環境、生態、災害等單項資源環境要素評價的基礎上,開展生態功能、農業功能、城鎮功能導向的資源環境承載能力整合評價。

國土空間開發適宜性評價以資源環境承載能力評價結果為基礎,劃定生態保護、農業生產、城鎮建設適宜性分割槽。結合“雙評價”結果,進行資源環境秉賦特徵、問題與風險識別、潛力分析、情景分析等綜合分析。

“雙評價”模組以《資源環境承載能力和國土空間開發適宜性評價技術指南》為依據,為每項資源環境要素單項評價、整合評價提供資料處理、要素分級、閾值率定、優化修正、空間分析、統計圖表等功能,實現智慧化的評價分析、成果核驗和輸出。

“雙評價”流程

​“雙評價”模組介面

模組3

“三區三線”劃定

“三區三線”作為空間規劃底圖的載體,是指在“雙評價”的基礎上,科學有序統籌佈局生態、農業、城鎮等功能空間,劃定生態保護紅線、永久基本農田、城鎮開發邊界等空間管控邊界。

“三區三線”劃定模組在綜合考慮底線保護要求(永久基本農田、各類自然保護地、重點生態功能區、生態環境敏感區和脆弱區保護等)和社會經濟發展要素(經濟社會發展、產業佈局、人口集聚趨勢等)基礎上,科學測算城鎮、農業、生態三類空間比例和開發強度指標。

參照生態紅線、城鎮開發邊界等劃定指南,梳理生態保護要素,開展生態功能重要性評價、生態敏感性評價,劃定生態保護紅線;基於城鎮發展現狀研究、城鎮發展定位和目標分析、城鎮發展規模預測、城鎮空間格局研究等,劃定城鎮開發邊界;通過永久基本農田現狀分析、佔補平衡分析等,劃定永久基本農田保護線。統籌“雙評價”結果、三條控制線位置,初步劃定生態、農業、城鎮適宜空間。

“三區三線”劃定模組提供邊界初劃的基本流程及分析工具,以及衝突檢測、方案協調等功能,實現“三區三線”智慧劃定、成果檢驗和輸出。

“三區三線”劃定流程

“三區三線”劃定模組介面

模組4

要素配置及空間佈局

圍繞底線約束、綠色發展、城鄉融合、區域協同、以人為本、品質提升等發展要求,重點解決要素配置問題。通過高時空精度大資料和靈活的專業模型,進行自然資源、生態環境、人口、產業、交通、基礎設施等要素現狀評估與發展預測模擬,為各類要素定類別、定規模、定位置、定關係,提供科學量化支撐。

<html>
<head>
  <meta charset="utf-8" />
  <meta
    name="viewport"
    content="initial-scale=1,maximum-scale=1,user-scalable=no"
  />

<title>Point clustering - advanced configuration | Sample | ArcGIS API for JavaScript 4.19</title>

<link rel="stylesheet" href="https://js.arcgis.com/4.19/esri/themes/dark/main.css" />
<script src="https://js.arcgis.com/4.19/"></script>

<style>
  html, body, #viewDiv {
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
  }
  #infoDiv {
    padding: 10px;
    width: 275px;
  }
  #sliderValue{
    font-weight: bolder;
  }
  #legendDiv{
    width: 260px;
  }
  #description{
    padding: 10px 0 10px 0;
  }
</style>

<script>
  require([
    "esri/Map",
    "esri/views/MapView",
    "esri/layers/FeatureLayer",
    "esri/widgets/Legend",
    "esri/widgets/Slider",
    "esri/widgets/Expand"
  ], (Map, MapView, FeatureLayer, Legend, Slider, Expand
  ) => {
    // Configure clustering on the layer with a
    // popupTemplate displaying the predominant
    // fuel type of the power plants in the cluster

    const clusterLabelThreshold = 1500;

    const haloColor = "#373837";
    const color = "#f0f0f0";

    const clusterConfig = {
      type: "cluster",
      popupTemplate: {
        title: "Cluster summary",
        content: [
          {
            type: "text",
            text: `
            This cluster represents <b>{cluster_count}</b> power plants with an average capacity of <b>{cluster_avg_capacity_mw} megawatts</b>.
             The power plants in this cluster produce a total of <b>{expression/total-mw} megawatts</b> of power.`
          },
          {
            type: "text",
            text: "Most power plants in this cluster generate power from <b>{cluster_type_fuel1}</b>."
          }
        ],
        fieldInfos: [{
          fieldName: "cluster_count",
          format: {
            places: 0,
            digitSeparator: true
          }
        }, {
          fieldName: "cluster_avg_capacity_mw",
          format: {
            places: 2,
            digitSeparator: true
          }
        }, {
          fieldName: "expression/total-mw",
          format: {
            places: 0,
            digitSeparator: true
          }
        }],
        expressionInfos: [{
          name: "total-mw",
          title: "total megawatts",
          expression: "$feature.cluster_avg_capacity_mw * $feature.cluster_count"
        }]
      },
      // larger radii look better with multiple label classes
      // smaller radii looks better visually
      clusterRadius: "120px",
      labelsVisible: true,
      labelingInfo: [{
        symbol: {
          type: "text",
          haloColor,
          haloSize: "1px",
          color,
          font: {
            family: "Noto Sans",
            size: "11px"
          },
          xoffset: 0,
          yoffset: "-15px",
        },
        labelPlacement: "center-center",
        labelExpressionInfo: {
          expression: "Text($feature.cluster_count, '#,### plants')"
        },
        where: `cluster_avg_capacity_mw > ${clusterLabelThreshold}`
      }, {
        symbol: {
          type: "text",
          haloColor,
          haloSize: "2px",
          color,
          font: {
            weight: "bold",
            family: "Noto Sans",
            size: "18px"
          },
          xoffset: 0,
          yoffset: 0
        },
        labelPlacement: "center-center",
        labelExpressionInfo: {
          expression: "$feature.cluster_type_fuel1"
        },
        where: `cluster_avg_capacity_mw > ${clusterLabelThreshold}`
      }, {
        symbol: {
          type: "text",
          haloColor,
          haloSize: "1px",
          color,
          font: {
            weight: "bold",
            family: "Noto Sans",
            size: "12px"
          },
          xoffset: 0,
          yoffset: "15px"
        },
        deconflictionStrategy: "none",
        labelPlacement: "center-center",
        labelExpressionInfo: {
          expression: `
          var value = $feature.cluster_avg_capacity_mw;
          var num = Count(Text(Round(value)));

          Decode(num,
            4, Text(value / Pow(10, 3), "##.0k"),
            5, Text(value / Pow(10, 3), "##k"),
            6, Text(value / Pow(10, 3), "##k"),
            7, Text(value / Pow(10, 6), "##.0m"),
            Text(value, "#,###")
          );
          `
        },
        where: `cluster_avg_capacity_mw > ${clusterLabelThreshold}`
      }, {
        symbol: {
          type: "text",
          haloColor,
          haloSize: "1px",
          color,
          font: {
            family: "Noto Sans",
            size: "11px"
          },
          xoffset: 0,
          yoffset: "-15px",
        },
        labelPlacement: "above-right",
        labelExpressionInfo: {
          expression: "Text($feature.cluster_count, '#,### plants')"
        },
        where: `cluster_avg_capacity_mw <= ${clusterLabelThreshold}`
      }, {
        symbol: {
          type: "text",
          haloColor,
          haloSize: "2px",
          color,
          font: {
            weight: "bold",
            family: "Noto Sans",
            size: "18px"
          }
        },
        labelPlacement: "above-right",
        labelExpressionInfo: {
          expression: "$feature.cluster_type_fuel1"
        },
        where: `cluster_avg_capacity_mw <= ${clusterLabelThreshold}`
      },  {
        symbol: {
          type: "text",
          haloColor,
          haloSize: "1px",
          color,
          font: {
            weight: "bold",
            family: "Noto Sans",
            size: "12px"
          },
          xoffset: 0,
          yoffset: 0
        },
        labelPlacement: "center-center",
        labelExpressionInfo: {
          expression: `
          var value = $feature.cluster_avg_capacity_mw;
          var num = Count(Text(Round(value)));

          Decode(num,
            4, Text(value / Pow(10, 3), "##.0k"),
            5, Text(value / Pow(10, 3), "##k"),
            6, Text(value / Pow(10, 3), "##k"),
            7, Text(value / Pow(10, 6), "##.0m"),
            Text(value, "#,###")
          );
          `
        },
        where: `cluster_avg_capacity_mw <= ${clusterLabelThreshold}`
      }]
    };

    const layer = new FeatureLayer({
      portalItem: {
        id: "eb54b44c65b846cca12914b87b315169"
      },
      featureReduction: clusterConfig,
      popupEnabled: true,
      labelsVisible: true,
      labelingInfo: [{
        symbol: {
          type: "text",
          haloColor,
          haloSize: "1px",
          color,
          font: {
            family: "Noto Sans",
            size: "11px"
          },
          xoffset: 0,
          yoffset: "-15px",
        },
        labelPlacement: "center-center",
        labelExpressionInfo: {
          expression: "$feature.name"
        },
        where: `capacity_mw > ${clusterLabelThreshold}`
      }, {
        symbol: {
          type: "text",
          haloColor,
          haloSize: "2px",
          color,
          font: {
            weight: "bold",
            family: "Noto Sans",
            size: "18px"
          },
          xoffset: 0,
          yoffset: 0
        },
        labelPlacement: "center-center",
        labelExpressionInfo: {
          expression: "$feature.fuel1"
        },
        where: `capacity_mw > ${clusterLabelThreshold}`
      }, {
        symbol: {
          type: "text",
          haloColor,
          haloSize: "1px",
          color,
          font: {
            weight: "bold",
            family: "Noto Sans",
            size: "12px"
          },
          xoffset: 0,
          yoffset: "15px"
        },
        labelPlacement: "center-center",
        labelExpressionInfo: {
          expression: `
          var value = $feature.capacity_mw;
          var num = Count(Text(Round(value)));

          Decode(num,
            4, Text(value / Pow(10, 3), "##.0k"),
            5, Text(value / Pow(10, 3), "##k"),
            6, Text(value / Pow(10, 3), "##k"),
            7, Text(value / Pow(10, 6), "##.0m"),
            Text(value, "#,###")
          );
          `
        },
        where: `capacity_mw > ${clusterLabelThreshold}`
      }, {
        symbol: {
          type: "text",
          haloColor,
          haloSize: "1px",
          color,
          font: {
            family: "Noto Sans",
            size: "11px"
          },
          xoffset: 0,
          yoffset: "-15px",
        },
        labelPlacement: "above-right",
        labelExpressionInfo: {
          expression: "$feature.name"
        },
        where: `capacity_mw <= ${clusterLabelThreshold}`
      }, {
        symbol: {
          type: "text",
          haloColor,
          haloSize: "2px",
          color,
          font: {
            weight: "bold",
            family: "Noto Sans",
            size: "18px"
          }
        },
        labelPlacement: "above-right",
        labelExpressionInfo: {
          expression: "$feature.fuel1"
        },
        where: `capacity_mw <= ${clusterLabelThreshold}`
      }, {
        symbol: {
          type: "text",
          haloColor,
          haloSize: "1px",
          color,
          font: {
            weight: "bold",
            family: "Noto Sans",
            size: "12px"
          },
          xoffset: 0,
          yoffset: 0
        },
        labelPlacement: "center-center",
        labelExpressionInfo: {
          expression: `
          var value = $feature.cluster_avg_capacity_mw;
          var num = Count(Text(Round(value)));

          Decode(num,
            4, Text(value / Pow(10, 3), "##.0k"),
            5, Text(value / Pow(10, 3), "##k"),
            6, Text(value / Pow(10, 3), "##k"),
            7, Text(value / Pow(10, 6), "##.0m"),
            Text(value, "#,###")
          );
          `
        },
        where: `cluster_avg_capacity_mw <= ${clusterLabelThreshold}`
      }]
    });

    const map = new Map({
      basemap: {
        portalItem: {
          id: "8d91bd39e873417ea21673e0fee87604"
        }
      },
      layers: [layer]
    });

    const view = new MapView({
      container: "viewDiv",
      map: map,
      extent: {
        spatialReference: {
          latestWkid: 3857,
          wkid: 102100
        },
        xmin: -42087672,
        ymin: 4108613,
        xmax: -36095009,
        ymax: 8340167
      }
    });

    layer.when().then(() =>{
      const renderer = layer.renderer.clone();
      renderer.visualVariables = [{
        type: "size",
        field: "capacity_mw",
        legendOptions: {
          title: "Capacity (MW)"
        },
        minSize: "24px",
        maxSize: "100px",
        minDataValue: 1,
        maxDataValue: 5000
      }];
      layer.renderer = renderer;
    });

    const legend = new Legend({
      view: view,
      container: "legendDiv"
    });

    const infoDiv = document.getElementById("infoDiv");
    view.ui.add(
      new Expand({
        view: view,
        content: infoDiv,
        expandIconClass: "esri-icon-layer-list",
        expanded: true
      }),
      "top-right"
    );

    view.whenLayerView(layer).then((layerView) => {
      const field = "capacity_mw";

      const slider = new Slider({
        min: 0,
        max: 2000,
        values: [0],
        container: document.getElementById("sliderDiv"),
        visibleElements: {
          rangeLabels: true
        },
        precision: 0
      });

      const sliderValue = document.getElementById("sliderValue");

      // filter features by power plant capacity when the user
      // drags the slider thumb. If clustering is enabled,
      // clusters will recompute and render based on the number
      // and type of features that satisfy the filter where clause

      slider.on(["thumb-change", "thumb-drag"], (event) => {
        sliderValue.innerText = event.value;
        layerView.filter = {
          where: field + " >= " + event.value
        };
      });
    });
  });
</script>

</head>

<body>
  <div id="viewDiv"></div>
  <div id="infoDiv" class="esri-widget">
    <div id="description">
      Show power plants with at least <span id="sliderValue">0</span> megawatts of capacity
    </div>
    <div id="sliderContainer">
      <div id="sliderDiv"></div>
    </div>
    <div id="legendDiv"></div>
  </div>
</body>

</html>

同時,根據規劃目標導向,統籌協調空間佈局安排,將各要素在空間規劃底圖上進行有機疊加,形成空間佈局方案,為國土空間用途管制提供依據。

要素配置和空間佈局流程