簡體   English   中英

從 geojson 保存 postgis 幾何類型

[英]Save postgis geometry type from geojson

我在 Laravel Blade 視圖中有一個Lealfet地圖,用戶可以在其中繪制形狀和標記。 這些功能注冊在一個GeoJson對象中,我將其字符串化並插入到一個名為“geojson”的隱藏textarea ,以在表單中將其提交給服務器。

問題是我想使用ST_GeomFromGeoJSON()函數將此數據保存為我的 PostgreSQL 數據庫中的geometry類型,但我無法讓它工作。

這是我現在嘗試的:

$site = new Site;
$data = $request->all();
unset($data['geojson']);

foreach($data as $key=>$d)
{
   $site->$key = $d;
}

$geojson = json_decode($request->geojson);
$site->save();

DB::update('update posha_sites set geom = ST_GeomFromGeoJSON(?)
      WHERE num_site = ?
      AND city_id = ?',
   [$geojson, $request->num_site, $city_id->id]
);

現在我正在保存所有數據,然后嘗試插入geospatial數據,因為我不知道如何在保存其余數據的同時使用原始查詢。

當我這樣做時,我收到此錯誤:

類 stdClass 的對象無法轉換為字符串


編輯

這是 posha_sites 表的整個遷移:

public function up()
{
    Schema::create('posha_sites', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->bigInteger('num_site');
        $table->string('type', 50)->nullable();
        $table->mediumText('adresse')->nullable();
        $table->string('cartes_anciennes')->nullable();
        $table->string('carte_topo')->nullable();
        $table->mediumText('cadastre_remembre')->nullable();
        $table->mediumText('cadastre_moderne')->nullable();
        $table->mediumText('cadastre_ancien')->nullable();
        $table->string('lieu_dit')->nullable();
        $table->mediumText('nature_parcelles')->nullable();
        $table->mediumText('conditions_acces')->nullable();
        $table->string('situation_administrative')->nullable();
        $table->string('altitude')->nullable();
        $table->string('relief')->nullable();
        $table->mediumText('hydrographie')->nullable();
        $table->string('geologie')->nullable();
        $table->string('vestiges_periode')->nullable();
        $table->mediumText('vestiges_nature')->nullable();
        $table->mediumText('vestiges_conservation')->nullable();
        $table->longText('plans_documents_figures')->nullable();
        $table->longText('sources_manuscrites')->nullable();
        $table->longText('sources_imprimees')->nullable();
        $table->longText('renseignement_oral')->nullable();
        $table->longText('bibliographie')->nullable();
        $table->longText('histoire')->nullable();
        $table->longText('historiographie')->nullable();
        $table->longText('description_histoire_monumentale')->nullable();
        $table->geometrycollection('geom')->nullable();
        $table->string('last_author')->nullable();
        $table->integer('tree_id')->unsigned()->nullable();
        $table->integer('parent_id')->unsigned()->nullable();
        $table->integer('city_id')->unsigned();
        $table->timestamps();
    });
}

函數ST_GeomFromGeoJSON()實際上期待一個字符串,所以我沒有解碼我的$geojson變量:

$geojson = $request->geojson;

代替:

$geojson = json_decode($request->geojson);

但我仍然收到一個錯誤:

SQLSTATE[XX000]:內部錯誤:

7 錯誤:GeoJson 表示無效(SQL:更新 posha_sites set geom = ST_GeomFromGeoJSON({"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry": {"type":"Point","coordinates":[-0.229114,44.564488]}}]}) WHERE num_site = 248 AND city_id = 5)

然而,我在一個在線 geojson 驗證器中測試了我的 geojson,它似乎是正確的。

假設您至少有 PostgreSQL 9.3 版,您可以使用一些 JSON 函數和運算符來提取 ST_GeomFromGeoJSON 所需的 GeoJSON 規范的相關部分,以創建幾何。

嘗試以下操作,您可以在其中替換頂部的 JSON:

WITH data AS (SELECT '{ "type": "FeatureCollection",
    "features": [
      { "type": "Feature",
        "geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
        "properties": {"prop0": "value0"}
        },
      { "type": "Feature",
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
            ]
          },
        "properties": {
          "prop0": "value0",
          "prop1": 0.0
          }
        },
      { "type": "Feature",
         "geometry": {
           "type": "Polygon",
           "coordinates": [
             [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
               [100.0, 1.0], [100.0, 0.0] ]
             ]
         },
         "properties": {
           "prop0": "value0",
           "prop1": {"this": "that"}
           }
         }
       ]
     }'::json AS fc)

SELECT
  row_number() OVER () AS gid,
  ST_AsText(ST_GeomFromGeoJSON(feat->>'geometry')) AS geom,
  feat->'properties' AS properties
FROM (
  SELECT json_array_elements(fc->'features') AS feat
  FROM data
) AS f;

查找三個幾何圖形。 geom 列有幾何對象,gid 是特征編號。 ST_AsText 函數顯示每個幾何體的 WKT 等效值。 我還包括可以為每個幾何定義的屬性或屬性,如規范中所示。

 gid |                   geom                   |              properties
-----+------------------------------------------+--------------------------------------
   1 | POINT(102 0.5)                           | {"prop0": "value0"}
   2 | LINESTRING(102 0,103 1,104 0,105 1)      | {                                   +
     |                                          |           "prop0": "value0",        +
     |                                          |           "prop1": 0.0              +
     |                                          |           }
   3 | POLYGON((100 0,101 0,101 1,100 1,100 0)) | {                                   +
     |                                          |            "prop0": "value0",       +
     |                                          |            "prop1": {"this": "that"}+
     |                                          |            }
(3 rows)

您應該使用 ST_SetSRID 為幾何分配一個 SRID。

或者,如果您只需要一個單一的異構 GEOMETRYCOLLECTION,您可以像這樣使其緊湊:

SELECT ST_AsText(ST_Collect(ST_GeomFromGeoJSON(feat->>'geometry')))
FROM (
  SELECT json_array_elements('{ ... put JSON here ... }'::json->'features') AS feat
) AS f;

GEOMETRYCOLLECTION(POINT(2565453.18267219 -3835048.65976031),LINESTRING(2727584.72197102 -3713449.19424187,2732476.69178127 -3992291.47342619),POLYGON((2442627.90254053 -3705499.95430853,2425506.00820465 -3886502.83728783,2555143.20817631 -3910962.68633909,2442627.90254053 -3705499.95430853)))

另請參閱Postgres OnLine Journal 中的使用 JSON 和 PostGIS 函數創建 GeoJSON 要素集合,其作用正好相反。

現代 PostgreSQL + PostGIS 接受JSONB及其函數,這是這項工作最佳數據類型,因為ST_GeomFromGeoJSON函數(也接受 JSONB)只接受純幾何圖形,而不是最流行的 GeoJSON 對象,即Feature 或 FeatureCollection

小例子:

WITH json_load AS (
 SELECT $${
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
 }$$::JSONB j
)

SELECT 
   j->'type' AS type,
   ST_GeomFromGeoJSON(j->'geometry') geom,
   j->'properties' AS props
FROM json_load;

筆記。 在服務器端,在json_load部分,您可以使用pg_read_file('/tmp/myFile.geojson')::jsonb讀取文件。 之前使用chmod 666 /tmp/myFile.geojson類的東西。 可以通過jsonb_array_elements函數分解幾何的 GeoJSON 集合。

來源

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM