[英]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 的对象无法转换为字符串
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 集合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.