calvinmetcalf / shapefile-js

Convert a Shapefile to GeoJSON. Not many caveats.
http://calvinmetcalf.github.io/shapefile-js/
715 stars 228 forks source link

RangeError when parsing shapefile containing single line #159

Closed edsnowden closed 2 years ago

edsnowden commented 3 years ago

I have a shapefile created using esri/shp-write (attached). The shapefile contains a polyline and appears to be valid insofar as I can upload it to https://mygeodata.cloud/converter/ and view it on a map.

However, when I feed the zip file to shpjs it reports a RangeError during ParseShp.getRow(). From my limited debugging it seems there's an out-by-four somewhere: it's at offset 244 of a 252-byte buffer and expects a further 12 bytes.

Unfortunately my knowledge of the format is minimal so I can't tell whether this is an issue in the code that wrote the shapefile, or something in shpjs. The problem seems to be limited to lines: shpjs is happy with shapefiles created in the same way containing a single point or a single polygon.

I'll keep digging but I thought I'd sling this up here, if nothing else it could end up as one of your test suite cases.

T8Th4_6n.zip

calvinmetcalf commented 3 years ago

ok i'll take a look

calvinmetcalf commented 3 years ago

do you mind if I include the shapefile as a test in the repo?

edsnowden commented 3 years ago

Go for it - it's not real data anyway. Thanks for looking into it.

edsnowden commented 3 years ago

I've built the propperly-parse-nulls branch and while it now succeeds, it produces GeoJSON with two incomplete features:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "bbox": [
          -64.64355468750001,
          45.79816953017265,
          -61.09497070312501,
          46.78501604269256
        ],
        "type": "LineString",
        "coordinates": [
          [ -64.64355468750001, 46.7248003746672  ],
          [ -64.18212890625001, 46.29381556233369 ],
          [ -62.369384765625014, 45.79816953017265 ],
          [ -61.36962890625001, 46.4605655457854 ],
          [ -61.09497070312501, 46.78501604269256 ]
        ]
      },
      "properties": {
        "name": "1974.1004"
      }
    },
    {
      "type": "Feature",
      "geometry": null,
      "properties": undefined
    },
    {
      "type": "Feature",
      "geometry": null,
      "properties": undefined
    }
  ],
  "fileName": "export/POLYLINE"
}

Does the Shapefile really seem to contain three shapes? If so I'll file a bug with esri/shp-write.

For reference, here is the GeoJSON that was passed into the esri/shp-write code to produce the Shapefile. The id has been lost (I'm guessing on export rather than import) and shpjs has added a bbox, which is fine, and a fileName which is also fine.

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [ -64.643554687500014, 46.724800374667197 ],
          [ -64.182128906250014, 46.293815562333691 ],
          [ -62.369384765625007, 45.79816953017265 ],
          [ -61.369628906250007, 46.4605655457854 ],
          [ -61.094970703125007, 46.785016042692561 ]
        ]
      },
      "id":"O1022",
      "properties": {
        "name": "1974.1004"
      }
    }
  ]
}
calvinmetcalf commented 3 years ago

yes there are two null geometries present in the shapefile for a total of 3 features which was why we were throwing an error since I hadn't tested two null geometries in a row or a null geometry in the last position.

edsnowden commented 3 years ago

Thanks. I've reported this and also amended my code that consumes the shpjs GeoJSON to ignore features where the geometry property is null.