【问题标题】:How can I save a map in PostgreSQL?如何在 PostgreSQL 中保存地图?
【发布时间】:2020-06-25 22:28:30
【问题描述】:

我目前正在开发用于制作地质图的应用程序。我的后端使用 Ruby on Rails,前端使用 React,数据库使用 Postgres。我正在使用 React Leaflet 来显示地图(将 Leaflet.js 抽象为 React 组件)。我从 OpenTopoMap 获取地图。这个应用程序是非商业的,我已经检查了他们的使用条款,以确保我没有违反。

我希望用户能够查看地图并能够在其上添加点和绘制多边形(我已经知道如何做这部分)。 一旦他们在地图上画完,我希望他们能够保存地图,并添加他们所做的任何添加。然后他们应该能够稍后重新打开并修改它。

我发现保存地图的唯一方法是保存为 .png,这意味着重新打开时无法对其进行编辑。

只要在重新打开地图时显示正确的地图区域,只保存点/多边形并在用户重新打开地图时重新渲染它们是一个可接受的解决方案,但我不确定我会怎么做存储这些数据。一个用户可以拥有许多地图,因此仅适用于单个地图实例的解决方案在这种情况下将不起作用。

我知道我在这里所描述的只是复制了许多其他地图应用程序的功能。一旦弄清楚这部分,我计划添加专门用于制作地质图的广泛功能。我没有在这里描述该功能,因为它与我当前的问题无关。

如何将地图以允许在重新打开时进行编辑的格式保存到 PostgreSQL?

【问题讨论】:

    标签: ruby-on-rails postgresql leaflet openstreetmap react-leaflet


    【解决方案1】:

    不要用一些 JSON 列怪物来重新发明轮子,而是看看 PostGIS。它是 Postgres 的扩展,添加了点、线和多边形等地理空间数据类型。它还允许您编写地理空间数据库查询,例如测试点是否在多边形中或邻近搜索。

    对于 Rails,the activerecord-postgis-adapter gem 添加了这些数据库类型:

    • :geometry -- 任何几何类型
    • :st_point -- 点数据
    • :line_string -- LineString 数据
    • :st_polygon -- 多边形数据
    • :geometry_collection -- 任何集合类型
    • :multi_point -- 积分集合
    • :multi_line_string -- LineStrings 的集合
    • :multi_polygon -- 多边形集合

    这为创建具有地理空间属性的模型提供了基础。它不是一根魔杖,可以让您将带有涂鸦的地图填充到 Postgres 中并获得可编辑的内容,并且需要在研究和实施方面付出巨大努力。

    【讨论】:

    • 我在一个应用程序中使用了它,该应用程序使用地理围栏在用户靠近绘制的多边形时通知用户。效果很好
    【解决方案2】:

    我同时使用leaflet 和leaflet.draw 来保存geoJSON 以绘制多边形或放置标记,并将其保存到数据库中名为coords 的字段中。这里有一个很好的例子:https://github.com/jeremygradisher/mapping-leaflet

    归结为使用 leaflet.draw 绘制坐标,然后将数据保存在您需要的地方。这是leaflet.draw:http://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html

    这里我使用leaflet.draw 在地图上进行绘制,然后我将数据字符串化并将其添加到要保存在数据库中的字段中。

    <script>
    // Initialize the FeatureGroup to store editable layers
    var drawnItems = new L.FeatureGroup();
    map.addLayer(drawnItems);
    
    
    // Initialize and alter the draw control and pass it the FeatureGroup of editable layers
    var drawControl = new L.Control.Draw({
        draw: {
            //These options make up the root object that is used when initializing the Leaflet.draw control.
            position: 'topleft',
            polygon: {
                allowIntersection: false,
                drawError: {color: '#00dd00', timeout: 1000
                },
                shapeOptions: {color: '#00dd00', weight: 1}, showArea: true},
            polyline:  false,
            rectangle:  {shapeOptions: {color: '#00dd00',weight: 1}},circle: false},
        edit: {featureGroup: drawnItems}
    });
    map.addControl(drawControl);
    
    
    //draw:created - Triggered when a new vector or marker has been created.
    map.on('draw:created', function (e) {
        var type = e.layerType,
            layer = e.layer;
    
        var shape = layer.toGeoJSON();
    var shape_for_db = JSON.stringify(shape);
    
        drawnItems.addLayer(layer);
        //trying some things here
    
        //enter in field to save to the database
        document.getElementById('area_coords').value = shape_for_db;
    });
    

    【讨论】:

      【解决方案3】:

      据我了解,您希望将复杂的对象保存到数据库中。用户可以在地图上绘制线条,可以绘制多边形等。也许使用 jsonb 对象来解决这个问题可能是您的解决方案。基本上它将一个 JSON 格式的字段保存到数据库中。

      一个示例 jsonb 对象可以是这样的。

      {
        "data": {
          "type": "user_map",
          "attributes": {
            "user_id": "1",
            "drawings": {
              "points": [],
              "lines": {},
              "polygons": {}
            }
          }
        }
      }
      

      您可以在用户模型上使用has_many :maps 将这些信息保留在用户或单独的模型上。

      可以帮助您的链接:

      Example 1

      Example 2

      【讨论】:

        【解决方案4】:

        我建议不要考虑地图(空间数据的渲染),而是考虑数据(具有属性的点/线/多边形)。您可以将每个用户数据保存在表中,可能还有另一个 map_config 表来保存地图边界框、名称等。

        在您的应用中,一旦您对用户进行了身份验证,您就可以访问其地图配置(让他选择要显示的那个)和相关数据。然后,您可以直接在 Leaflet、Open Layers(或其他)中使用原始矢量数据显示地图,或者您可以通过地理服务器(Geoserver、Mapserver 等)将其作为 wms 图像或 wfs 可编辑矢量数据提供服务。您可以将显示区域缩放或限制为保存在地图配置中的区域。

        【讨论】:

          猜你喜欢
          • 2017-08-10
          • 2017-10-30
          • 2015-05-09
          • 1970-01-01
          • 2021-05-29
          • 1970-01-01
          • 2019-12-26
          • 1970-01-01
          • 2013-02-09
          相关资源
          最近更新 更多