【问题标题】:How to update/insert to table with Leaflet.draw and CartoDB如何使用 Leaflet.draw 和 CartoDB 更新/插入表格
【发布时间】:2016-09-01 13:39:12
【问题描述】:

我正在尝试使用 Leaflet 和 CartoDB 创建一个 Web 应用程序。我正在尝试使用 this tutorial 将数据读取和写入公共 CartoDB 表。

本教程解释了如何使用安全定义器来完成此操作。无论出于何种原因,我在应用程序中使用 leaflet.draw 创建的功能都没有插入到我的表格中。我仍然是编码新手,不确定如何在我的代码中实际调用 SQL 查询,但我尝试复制示例源代码并且执行时没有任何运气。

目标是允许用户在地图上创建和编辑他们的点,并将这些点保存到 CartoDB 中的众包数据库中。

我的项目的代码可以在这里查看:https://github.com/zrobby/crowdsource-storymap

我在执行时遇到困难的特定 SQL 查询如下所示,来自上面链接的教程。

    DROP FUNCTION IF EXISTS leaflet_upsert_usercomments(int[], text[]);

    -- Returns a set of op,cartodb_id values where op means:
    --  deleted: -1
    --  updated: 0
    --  inserted: 1

    CREATE OR REPLACE FUNCTION leaflet_upsert_usercomments(
    cartodb_ids integer[],
    geojsons text[])
    RETURNS TABLE(op int, cartodb_id int)

    LANGUAGE plpgsql SECURITY DEFINER
    RETURNS NULL ON NULL INPUT
    AS $$
    DECLARE
    sql text;
    BEGIN

    sql := 'WITH n(cartodb_id,the_geom) AS (VALUES ';

    -- Iterate over the values
    FOR i in 1 .. array_upper(geojsons, 1)
    LOOP
    IF i > 1 THEN sql := sql || ','; END IF;
    sql :=sql || '('||cartodb_ids[i]||','
            || 'ST_SetSRID(ST_GeomFromGeoJSON(NULLIF('''|| geojsons[i] ||''','''')),4326))';
    END LOOP;

    sql := sql || '), do_update AS ('
      || 'UPDATE leaflet_data p '
      || 'SET the_geom=n.the_geom FROM n WHERE p.cartodb_id = n.cartodb_id '
      || 'AND n.the_geom IS NOT NULL '
      || 'RETURNING p.cartodb_id ), do_delete AS ('
      || 'DELETE FROM leaflet_data p WHERE p.cartodb_id IN ('
      || 'SELECT n.cartodb_id FROM n WHERE cartodb_id >= 0 AND '
      || ' n.the_geom IS NULL ) RETURNING p.cartodb_id ), do_insert AS ('
      || 'INSERT INTO leaflet_data (the_geom)'
      || 'SELECT n.the_geom FROM n WHERE n.cartodb_id < 0 AND '
      || ' n.the_geom IS NOT NULL RETURNING cartodb_id ) '
      || 'SELECT 0,cartodb_id FROM do_update UNION ALL '
      || 'SELECT 1,cartodb_id FROM do_insert UNION ALL '
      || 'SELECT -1,cartodb_id FROM do_delete';

    RAISE DEBUG '%', sql;

    RETURN QUERY EXECUTE sql;

    END;
    $$;

    -- Grant access to the public user
    GRANT EXECUTE ON FUNCTION leaflet_upsert_usercomments(integer[],text[]) TO publicuser;

【问题讨论】:

标签: javascript sql leaflet gis cartodb


【解决方案1】:

我之前的回答太老套了,很快就会被弃用。

执行此操作的正确方法是使用 SECURITY DEFINER 设置一个函数,该函数以函数的所有者权限运行 INSERT 查询。

在这里查看 --> https://gist.github.com/ernesmb/beb25f539f8ff38bbd891e6d114ea7f4

希望对你有帮助!

【讨论】:

  • 完美运行!谢谢!!
【解决方案2】:

可能有一种更简单的方法,即为正在使用的表(或列)授予特定权限,而不是创建复杂的安全定义器函数。

由于您只是尝试添加点,因此您可以使用类似于此示例中使用的内容:http://bl.ocks.org/iriberri/7d84ed35ef0b5e80555d

那是前端应用程序部分。为了授予对表足够的权限,您应该从 CARTO 编辑器的 SQL 面板或通过 SQL API 运行以下 SQL。

GRANT INSERT (column1, column2, ...) ON tableName TO publicuser;

GRANT USAGE ON SEQUENCE tableName_cartodb_id_seq_0 TO publicuser;

如果有任何错误,您可以从开发工具中的网络选项卡进行调试,sql 调用将返回错误描述。

授予权限后,您应该能够从前端运行 INSERT 查询,而无需验证您的呼叫。 请注意风险。

【讨论】:

  • 埃内斯托,谢谢您的回复!我没有考虑过安全定义器的替代方法,但是您的方法对我的应用程序的简单性很有意义。我会尽快跟进。
【解决方案3】:

我不熟悉“安全定义器”,但可能有另一种方法,以防其他人有兴趣编辑使用 WFS 事务协议 (WFS-T) 的功能

在 OpenLayers 中使用 WFS-T 的示例: http://dev.openlayers.org/examples/wfs-protocol-transactions.html

在传单中使用 WFS-T 的示例:https://georepublic.info/en/blog/2012/leaflet-example-with-wfs-t/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多