如何使用 Leaflet.draw 和 CartoDB update/insert 到 table
How to update/insert to table with Leaflet.draw and CartoDB
我正在尝试使用 Leaflet 和 CartoDB 创建一个 Web 应用程序。我正在尝试使用 this tutorial 将数据读取和写入 public CartoDB table。
本教程解释了如何使用安全定义器来完成此操作。无论出于何种原因,我在我的应用程序中使用 leaflet.draw 创建的功能都没有插入到我的 table 中。我对编码还是个新手,不确定 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;
可能有更简单的方法,向正在使用的 table(或列)授予特定权限,而不是创建复杂的安全定义器函数。
因为您只是想添加点数,所以您可以使用类似于本例中使用的东西:http://bl.ocks.org/iriberri/7d84ed35ef0b5e80555d
这是前端应用程序部分。为了向您的 table 授予足够的权限,您应该 运行 以下 SQL,从 CARTO 编辑器的 SQL 面板,或通过 SQL API。
GRANT INSERT (column1, column2, ...) ON tableName TO publicuser;
GRANT USAGE ON SEQUENCE tableName_cartodb_id_seq_0 TO publicuser;
如果出现任何错误,您可以从开发工具中的网络选项卡进行调试,sql 调用将 return 错误描述。
授予权限后,您应该能够 运行 从前端插入查询而无需对您的调用进行身份验证。
请注意风险。
我之前的回答太老套了,很快就会被弃用。
执行此操作的正确方法是使用 SECURITY DEFINER 设置一个函数,该函数以函数的所有者权限运行 INSERT 查询。
在这里查看 --> https://gist.github.com/ernesmb/beb25f539f8ff38bbd891e6d114ea7f4
希望对您有所帮助!
我不熟悉 'security definer' 但可能还有另一种方法,以防其他人有兴趣编辑使用 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/
我正在尝试使用 Leaflet 和 CartoDB 创建一个 Web 应用程序。我正在尝试使用 this tutorial 将数据读取和写入 public CartoDB table。
本教程解释了如何使用安全定义器来完成此操作。无论出于何种原因,我在我的应用程序中使用 leaflet.draw 创建的功能都没有插入到我的 table 中。我对编码还是个新手,不确定 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;
可能有更简单的方法,向正在使用的 table(或列)授予特定权限,而不是创建复杂的安全定义器函数。
因为您只是想添加点数,所以您可以使用类似于本例中使用的东西:http://bl.ocks.org/iriberri/7d84ed35ef0b5e80555d
这是前端应用程序部分。为了向您的 table 授予足够的权限,您应该 运行 以下 SQL,从 CARTO 编辑器的 SQL 面板,或通过 SQL API。
GRANT INSERT (column1, column2, ...) ON tableName TO publicuser;
GRANT USAGE ON SEQUENCE tableName_cartodb_id_seq_0 TO publicuser;
如果出现任何错误,您可以从开发工具中的网络选项卡进行调试,sql 调用将 return 错误描述。
授予权限后,您应该能够 运行 从前端插入查询而无需对您的调用进行身份验证。 请注意风险。
我之前的回答太老套了,很快就会被弃用。
执行此操作的正确方法是使用 SECURITY DEFINER 设置一个函数,该函数以函数的所有者权限运行 INSERT 查询。
在这里查看 --> https://gist.github.com/ernesmb/beb25f539f8ff38bbd891e6d114ea7f4
希望对您有所帮助!
我不熟悉 'security definer' 但可能还有另一种方法,以防其他人有兴趣编辑使用 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/