首页 > 解决方案 > Javascript变量到Python

问题描述

我正在使用 Django 在本地工作,并使用 Leaflet 创建了一个地图模板。在做了一些研究之后,我发现您可以让用户单击地图以创建标记,然后按下按钮(导出)以下载用户创建的每个图形或标记的 geoJSON。

我想要做的不是下载geoJSON,而是将其存储在数据库中(可能在本地)。我不精通 JavaScript,所以我真的很困惑。

这是地图代码

<!DOCTYPE html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />

        <script>
            L_NO_TOUCH = false;
            L_DISABLE_3D = false;
        </script>

    <script src="https://cdn.jsdelivr.net/npm/leaflet@1.5.1/dist/leaflet.js"></script>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.5.1/dist/leaflet.css"/>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"/>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css"/>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Leaflet.awesome-markers/2.0.2/leaflet.awesome-markers.css"/>
    <link rel="stylesheet" href="https://rawcdn.githack.com/python-visualization/folium/master/folium/templates/leaflet.awesome.rotate.css"/>
    <style>html, body {width: 100%;height: 100%;margin: 0;padding: 0;}</style>
    <style>#map {position:absolute;top:0;bottom:0;right:0;left:0;}</style>

            <meta name="viewport" content="width=device-width,
                initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
            <style>
                #map_a3375e0d166f4ec89fd79df498d1f8b8 {
                    position: relative;
                    width: 100.0%;
                    height: 100.0%;
                    left: 0.0%;
                    top: 0.0%;
                }
            </style>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.css"/>

            <style>
                #export {
                    position: absolute;
                    top: 5px;
                    right: 10px;
                    z-index: 999;
                    background: white;
                    color: black;
                    padding: 6px;
                    border-radius: 4px;
                    font-family: 'Helvetica Neue';
                    cursor: pointer;
                    font-size: 12px;
                    text-decoration: none;
                    top: 90px;
                }
            </style>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.css"/>
</head>
<body>

            <div class="folium-map" id="map_a3375e0d166f4ec89fd79df498d1f8b8" ></div>

    <a href='#' id='export'>Continue</a>
</body>
<script>

            var map_a3375e0d166f4ec89fd79df498d1f8b8 = L.map(
                "map_a3375e0d166f4ec89fd79df498d1f8b8",
                {
                    center: [46.8527, -121.7649],
                    crs: L.CRS.EPSG3857,
                    zoom: 13,
                    zoomControl: true,
                    preferCanvas: false,
                }
            );





            var tile_layer_0cce79173c4743718c558aeea7872020 = L.tileLayer(
                "https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg",
                {"attribution": "Map tiles by \u003ca href=\"http://stamen.com\"\u003eStamen Design\u003c/a\u003e, under \u003ca href=\"http://creativecommons.org/licenses/by/3.0\"\u003eCC BY 3.0\u003c/a\u003e. Data by \u0026copy; \u003ca href=\"http://openstreetmap.org\"\u003eOpenStreetMap\u003c/a\u003e, under \u003ca href=\"http://creativecommons.org/licenses/by-sa/3.0\"\u003eCC BY SA\u003c/a\u003e.", "detectRetina": false, "maxNativeZoom": 18, "maxZoom": 18, "minZoom": 0, "noWrap": false, "opacity": 1, "subdomains": "abc", "tms": false}
            ).addTo(map_a3375e0d166f4ec89fd79df498d1f8b8);


            var options = {
              position: "topleft",
              draw: {"polyline": {"allowIntersection": false}},
              edit: {"poly": {"allowIntersection": false}},
            }
            // FeatureGroup is to store editable layers.
            var drawnItems = new L.featureGroup().addTo(
                map_a3375e0d166f4ec89fd79df498d1f8b8
            );
            options.edit.featureGroup = drawnItems;
            var draw_control_ca0cd7071ba049ccb3dafbbf098f2b38 = new L.Control.Draw(
                options
            ).addTo( map_a3375e0d166f4ec89fd79df498d1f8b8 );
            map_a3375e0d166f4ec89fd79df498d1f8b8.on(L.Draw.Event.CREATED, function(e) {
                var layer = e.layer,
                    type = e.layerType;
                var coords = JSON.stringify(layer.toGeoJSON());
                layer.on('click', function() {
                    alert(coords);
                    console.log(coords);
                });
                drawnItems.addLayer(layer);
             });
            map_a3375e0d166f4ec89fd79df498d1f8b8.on('draw:created', function(e) {
                drawnItems.addLayer(e.layer);
            });

            document.getElementById('export').onclick = function(e) {
                var data = drawnItems.toGeoJSON();
                var convertedData = 'text/json;charset=utf-8,'
                    + encodeURIComponent(JSON.stringify(data));
                document.getElementById('export').setAttribute(
                    'href', 'data:' + convertedData
                );
                document.getElementById('export').setAttribute(
                    'download', "my_data.geojson"
                );
            }


</script>

我知道这是我必须改变的部分

            document.getElementById('export').onclick = function(e) {
                var data = drawnItems.toGeoJSON();
                var convertedData = 'text/json;charset=utf-8,'
                    + encodeURIComponent(JSON.stringify(data));
                document.getElementById('export').setAttribute(
                    'href', 'data:' + convertedData
                );
                document.getElementById('export').setAttribute(
                    'download', "my_data.geojson"
                );
            }

谁能给我一些关于如何实现我想要的方向/教程?

标签: javascriptpythondjango-formsleaflet

解决方案


我强烈推荐fetch API。它非常接近一个简单的网络请求!

您的代码可能如下所示:

        // async function here allows you to use "await" keyword.
        document.getElementById('export').onclick = async function(e) {

            var data = drawnItems.toGeoJSON();

            // make the request:
            var rsp = await fetch("path/to/server/upload/url", {
                method: "POST",
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(data),
            });

            console.log("server responded with: ", await rsp.json());
        }

编辑:您的问题的答案很大程度上取决于您使用的数据库技术。一些数据库服务器拥有一个 HTTP API,允许您fetch直接访问它们,例如CouchDB,但这非常罕见,即使在使用 Couch 时也是如此(出于安全原因,浏览器中的 JavaScript 具有非常有限的 IO 选项)。

这是(迄今为止)最常见的解决此问题的方法:

  1. 将 geoJSON 从浏览器发送到服务器(上面的代码示例)

  2. 服务器将 JSON 保存到数据库

您已经声明您正在使用 Django。这就是#2 中的服务器技术。

在服务器上,您将采用的路径是:

  1. 在你放置你的 URL 端点处创建一个Django 路由path/to/server/upload/url
  2. 在路由的 python 函数中,您将数据保存到连接到 Django 的数据库中。

在 Django 中,数据库交互通常通过Django 的 ORM完成,但此时您可以使用任何您想要的方法。

上面的代码向您展示了如何将 geoJSON 数据从浏览器 JS 获取到您的 Django 服务器,以便您可以将其保存到数据库中。


推荐阅读