首页 > 解决方案 > pg-promise 错误地将多面体插入到 postgis 数据库中

问题描述

所以我使用 pg-promise 将多个 geojson MultiPolygons 插入到 postgis 数据库中。插入数据库工作正常,但对于数据库中的某些行,我得到一个奇怪的行为,即单元格填充了两行。第一行一些加载消息,第二行是实际的 geom 对象,更奇怪的是它从 geojson 转换为 postgis geom。

function createBorder(pathToJSON, table) {
  fs.readFile(pathToJSON,
    {encoding: 'UTF-8'},
    (err, data) => {

    let geoJSON = JSON.parse(data);
    geoJSON.features.forEach(f => {
      f.geometry.crs = {
        type: 'name',
        properties: {
          name: 'EPSG:4326'
        }
      }
      db.none('INSERT INTO nyc_borders(geom)\
        VALUES (ST_GeomFromGeoJSON(${geoJSON}))', {
        geoJSON: f.geometry
      })
      .then((d) => {
        console.log(f.geometry);
      })
      .catch(error => {
        console.log("ERROR: ", error);
      })
    });
  });
}
createBorder('./data/community_districts.geojson');

我缩短了 geoJSON 输出,它基本上是从opendata门户 Geojson 下载的来自 nyc 的社区区边界:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "shape_leng": "51549.5578986",
        "boro_cd": "311",
        "shape_area": "103177785.347"
      },
      "geometry": {
        "type": "MultiPolygon",
        "coordinates": [
          [
            [
              [
                -73.97348373564797,
                40.61137106069874
              ],
              [
                -73.97303089190211,
                40.6090051063008
              ],
              [
                -73.97299433938896,
                40.60881414180224
              ]
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "shape_leng": "65821.875617",
        "boro_cd": "313",
        "shape_area": "88195686.2688"
      },
      "geometry": {
        "type": "MultiPolygon",
        "coordinates": [
          [
            [
              [
                -73.96720294103956,
                40.573326317397424
              ],
              [
                -73.96738975478877,
                40.573258999904446
              ],
              [
                -73.9674356779313,
                40.57320896967127
              ],
              [
                -73.96736390080571,
                40.57304456895217
              ],
              [
                -73.98372152615246,
                40.59582107821707
              ]
            ]
          ]
        ]
      }
    }
  ]
}

我的数据库中的一些图片:

一个单元格内包含两行的行的数据库表

扩大一个单元格以更好地查看实际的拖链

所以我真的被卡住了,因为我不知道如何开始调试,单次插入确实可以工作,而且 geojson 对象的转换看起来也很好。我实际上无法弄清楚是谁造成了这种错误行为。

标签: javascriptpostgresqlgispostgispg-promise

解决方案


通过使用自定义类型格式化,您可以完全控制pg-promise如何格式化数据。

例如,如果你有一个array[][2](如图所示的点),你可以像这样转换它们:

const toGeometry = g => ({ /* g = array[][2] (points) */
    rawType: true,
    toPostgres: a => {
        const points = a.map(p => pgp.as.format('$1 $2', p));
        return 'ST_GeomFromText(\'LINESTRING(' + points.join() + ')\')';
    }
});

然后您可以传入toGeometry(f.geometry)以应用您的自定义格式。

另请参阅:ST_GeomFromText


推荐阅读