将GeoJSON中的PostGIS几何类型保存

3
我在Laravel Blade视图中有一个Lealfet地图,用户可以在上面绘制形状和标记。这些功能都在一个GeoJson对象中注册,我将其字符串化并插入具有名称“geojson”的隐藏textarea中以便在表单内提交到服务器。
问题是,我想使用PostGis ST_GeomFromGeoJSON()函数将此数据保存为数据库中的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]
);

目前,我正在保存所有数据,然后尝试插入地理空间数据,因为我不知道在保存其余数据时如何使用原始查询。

这样做时,我会遇到以下错误:

无法将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变量:

"ST_GeomFromGeoJSON()"函数需要接收一个字符串参数,因此我没有对$geojson变量进行解码处理:

$geojson = $request->geojson;

替代方案:

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

但是我仍然遇到错误:

SQLSTATE [XX000]:内部错误:

7 ERROR:无效的GeoJson表示(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)

但是我在在线GeoJson验证器中测试了我的geojson,看起来是正确的。

翻译结果仅供参考,如有不准确之处请以原文为准。

posha_sites表的迁移是什么样子? - stokoe0990
我编辑了我的帖子。 - Skery
你的迁移出现了错误。数据类型是驼峰式命名的。你需要使用 "geometryCollection" 而不是 "geometrycollection"。(虽然可能有错,最好先检查一下)。 - stokoe0990
这对你有帮助吗?https://dba.stackexchange.com/a/227581 - stokoe0990
2个回答

3

假设您至少有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要素集合的教程,该教程与本文相反。


0

现代的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集合拆分开来。
来源

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接