简体   繁体   English

从 geojson 保存 postgis 几何类型

[英]Save postgis geometry type from geojson

I have a Lealfet map in a Laravel Blade view where the user can draw shapes and markers.我在 Laravel Blade 视图中有一个Lealfet地图,用户可以在其中绘制形状和标记。 These features are registered in a GeoJson object, that I stringify and insert in a hidden textarea with name "geojson" to submit it to the server, within a form.这些功能注册在一个GeoJson对象中,我将其字符串化并插入到一个名为“geojson”的隐藏textarea ,以在表单中将其提交给服务器。

The problem is that I want to save this data as geometry type in my PostgreSQL database, using the PostGis ST_GeomFromGeoJSON() function, but I can't get it to work.问题是我想使用ST_GeomFromGeoJSON()函数将此数据保存为我的 PostgreSQL 数据库中的geometry类型,但我无法让它工作。

Here is what I tried for now:这是我现在尝试的:

$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]
);

Right now I am saving all my data and then trying to insert the geospatial data, as I don't know how I could use a raw query while saving the rest of my data.现在我正在保存所有数据,然后尝试插入geospatial数据,因为我不知道如何在保存其余数据的同时使用原始查询。

When I do that I am getting this error:当我这样做时,我收到此错误:

Object of class stdClass could not be converted to string类 stdClass 的对象无法转换为字符串


EDIT编辑

Here is the whole migration for the posha_sites table:这是 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();
    });
}

The function ST_GeomFromGeoJSON() is in fact expecting a string so I didn't decode my $geojson variable:函数ST_GeomFromGeoJSON()实际上期待一个字符串,所以我没有解码我的$geojson变量:

$geojson = $request->geojson;

instead of:代替:

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

But I still get an error:但我仍然收到一个错误:

SQLSTATE[XX000]: Internal error: SQLSTATE[XX000]:内部错误:

7 ERROR: invalid GeoJson representation (SQL: update 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) 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)

Yet I tested my geojson in an online geojson validator and it seems correct.然而,我在一个在线 geojson 验证器中测试了我的 geojson,它似乎是正确的。

Assuming you have at least PostgreSQL version 9.3, you can use a few JSON functions and operators to extract the relevant parts of the GeoJSON specification required by ST_GeomFromGeoJSON to create geometries.假设您至少有 PostgreSQL 9.3 版,您可以使用一些 JSON 函数和运算符来提取 ST_GeomFromGeoJSON 所需的 GeoJSON 规范的相关部分,以创建几何。

Try the following, where you can replace the JSON in the top part:尝试以下操作,您可以在其中替换顶部的 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;

Finds three geometries.查找三个几何图形。 The geom column has the geometry object, and the gid is the feature number. geom 列有几何对象,gid 是特征编号。 The ST_AsText function shows the WKT equivalent of each geometry. ST_AsText 函数显示每个几何体的 WKT 等效值。 I've also included the properties or attributes that can be defined for each geometry, as is shown in the specification.我还包括可以为每个几何定义的属性或属性,如规范中所示。

 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)

You should assign an SRID for the geometry, using ST_SetSRID.您应该使用 ST_SetSRID 为几何分配一个 SRID。

Or if you simply need a single heterogeneous GEOMETRYCOLLECTION, you can make it compact like this:或者,如果您只需要一个单一的异构 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)))

See also Creating GeoJSON Feature Collections with JSON and PostGIS functions from the Postgres OnLine Journal , which does the opposite.另请参阅Postgres OnLine Journal 中的使用 JSON 和 PostGIS 函数创建 GeoJSON 要素集合,其作用正好相反。

Modern PostgreSQL + PostGIS accepts JSONB and its functions , the best datatype for this job , because the ST_GeomFromGeoJSON function (that accepts also JSONB) only accepts pure geometries, not the most popular GeoJSON object, the Feature or FeatureCollection .现代 PostgreSQL + PostGIS 接受JSONB及其函数,这是这项工作最佳数据类型,因为ST_GeomFromGeoJSON函数(也接受 JSONB)只接受纯几何图形,而不是最流行的 GeoJSON 对象,即Feature 或 FeatureCollection

SMALL EXAMPLE:小例子:

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;

Note.笔记。 At server-side, in the json_load part, you can use pg_read_file('/tmp/myFile.geojson')::jsonb to read files.在服务器端,在json_load部分,您可以使用pg_read_file('/tmp/myFile.geojson')::jsonb读取文件。 Use something like chmod 666 /tmp/myFile.geojson before.之前使用chmod 666 /tmp/myFile.geojson类的东西。 A GeoJSON collenction of geometries can be exploded by jsonb_array_elements function.可以通过jsonb_array_elements函数分解几何的 GeoJSON 集合。

( Source ) 来源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM