Can not save layer to geojson

env:
.net 9 win11
aspose.gis 25.3

q1:can not save layer to geojson

var path =   "CreateFileGdbDataset_out.gdb";

using (var dataset = Dataset.Create(path, Drivers.FileGdb))
{
    using (var layer = dataset.CreateLayer("layer_1", SpatialReferenceSystem.CreateFromEpsg(4490)))
    {
        layer.Attributes.Add(new FeatureAttribute("value", AttributeDataType.Integer));

        for (int i = 0; i < 10; ++i)
        {
            var feature = layer.ConstructFeature();
            feature.SetValue("value", i);
            feature.Geometry = new Point(i, i);
            layer.Add(feature);
        }

       layer.SaveTo("xx.json", Drivers.GeoJson); // throw System.InvalidOperationException:“The layer does not support read access.”
    }
}

q2: a workaround is change code to next , but the output json no ‘id’ , is it fixed in GISNET-1287 Handle the “id” field of a GeoJSON Feature ?

  var path =   "CreateFileGdbDataset_out.gdb";

  using (var dataset = Dataset.Create(path, Drivers.FileGdb))
  {
      Console.WriteLine(dataset.LayersCount); // 0

      using (var layer = dataset.CreateLayer("layer_1", SpatialReferenceSystem.CreateFromEpsg(4490)))
      {
          layer.Attributes.Add(new FeatureAttribute("value", AttributeDataType.Integer));

          for (int i = 0; i < 10; ++i)
          {
              var feature = layer.ConstructFeature();
              feature.SetValue("value", i);
              feature.Geometry = new Point(i, i);
              layer.Add(feature);
          }

         //layer.SaveTo("xx2.json", Drivers.GeoJson);
      }

      using (var layer = dataset.OpenLayerAt(0))
      {
          layer.SaveTo("xx2.json", Drivers.GeoJson);
      }
}

@lsl

To address the issue of saving a layer to GeoJSON, it appears that you are encountering an InvalidOperationException stating that “The layer does not support read access.” This typically occurs when trying to save a layer that hasn’t been properly opened for reading.

In your first code snippet, you are attempting to save the layer immediately after creating it. However, the layer must be opened for reading before you can save it. The workaround you provided in your second snippet is correct; you first create the layer, add features to it, and then open the layer for reading before saving it to GeoJSON.

Here’s a refined version of your code that should work:

var path = "CreateFileGdbDataset_out.gdb";

using (var dataset = Dataset.Create(path, Drivers.FileGdb))
{
    using (var layer = dataset.CreateLayer("layer_1", SpatialReferenceSystem.CreateFromEpsg(4490)))
    {
        layer.Attributes.Add(new FeatureAttribute("value", AttributeDataType.Integer));

        for (int i = 0; i < 10; ++i)
        {
            var feature = layer.ConstructFeature();
            feature.SetValue("value", i);
            feature.Geometry = new Point(i, i);
            layer.Add(feature);
        }
    }

    // Open the layer for reading and save to GeoJSON
    using (var layer = dataset.OpenLayerAt(0))
    {
        layer.SaveTo("output.json", Drivers.GeoJson);
    }
}

Regarding the second part of your question about the ‘id’ field in the output JSON, it has been noted that the library keeps all attributes, including the ID, in the property list of the GeoJSON feature. If a feature has a commonly used identifier, it should be included as a member of the feature object with the name “id”. A ticket (GISNET-1287) has been created to address this issue, and it has been confirmed that a fix was included in a later release of the library. Therefore, if you are using a version of Aspose.GIS for .NET that is 22.1 or later, the handling of the ‘id’ field should be improved.

For more details on converting to GeoJSON, you can refer to the official documentation here.

If you have any further questions or need additional assistance, feel free to ask!

Sources:
[1]: How convert one layer in gdb or one feature to geojson

@lsl
The team will text you back after the investigation. We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): GISNET-1807

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

Hi, @lsl

about q1:
Current implementation make changes to GDB file on dispose. So we can make several actions and save it at once in file. It works this way to make better performance.
In you example above ‘SaveTo’ function works as converter from File Gdb to GeoJson format and make copy all attributes and features. For this we need to read file but layer created this way ‘dataset.CreateLayer’ does not support read access.

about q2:
I reproduced it. Seem for ‘SaveTo’ function it does not work properly.
Btw we have options ‘AutoId’ which has ‘none’ value by default.
It should work as you need with this code:
var options = new GeoJsonOptions
{
AutoId = AutoIds.Number
};
using (var layer = dataset.OpenLayerAt(0))
{
layer.SaveTo(“xx2.json”, Drivers.GeoJson, new SavingOptions() {DriverOptions=options });
}

But before need make small fix. It will be in next release.

q1:I understand your explanation about q1, but saving it directly is more intuitive for developer, and sometimes we don’t need to save it in place, just like when editing Word or Excel, we can directly modify and save to a new file use a template file

in my option, fields can be passed in when creating the layer, Id and geometry are just one of AttributeDataType,
next are the definitions of field types in ArcGIS

  [Guid("4CA2D959-5A38-11D2-AABD-00C04FA37585")]
  public enum esriFieldType
  {
    /// <summary>Short Integer.</summary>
    esriFieldTypeSmallInteger,
    /// <summary>Long Integer.</summary>
    esriFieldTypeInteger,
    /// <summary>Single-precision floating-point number.</summary>
    esriFieldTypeSingle,
    /// <summary>Double-precision floating-point number.</summary>
    esriFieldTypeDouble,
    /// <summary>Character string.</summary>
    esriFieldTypeString,
    /// <summary>Date.</summary>
    esriFieldTypeDate,
    /// <summary>Long Integer representing an object identifier.</summary>
    esriFieldTypeOID,
    /// <summary>Geometry.</summary>
    esriFieldTypeGeometry,
    /// <summary>Binary Large Object.</summary>
    esriFieldTypeBlob,
    /// <summary>Raster.</summary>
    esriFieldTypeRaster,
    /// <summary>Globally Unique Identifier.</summary>
    esriFieldTypeGUID,
    /// <summary>Esri Global ID.</summary>
    esriFieldTypeGlobalID,
    /// <summary>XML Document.</summary>
    esriFieldTypeXML,
  }

q2: I am wondering if the ‘feature’ class can add an Id property like arcgis?

@lsl

Right now GeoJson file in your example above has ‘OBJECTID’ (instead of ‘id’) property which was generated by FileGdb dataset. Is this property not enough? Do you want to generate ‘Id’ property with the same value like ‘OBJECTID’?

The ‘id’ referred to here is not a field called ‘id’, but rather the primary key of the database,In GDB, it is usually called objectid , in shapefiles, it is often called fid , but in reality, you can create it with any name you want

Geojson add ID attribute outside to avoid the issue of different field names

https://www.rfc-editor.org/rfc/rfc7946#section-3.2

 If a Feature has a commonly used identifier, that identifier
      SHOULD be included as a member of the Feature object with the name
      "id", and the value of this member is either a JSON string or
      number.

@lsl
Thanks, I understand.
During make copy all attributes i will add new ‘Id’ attribute if it not exists.

@lsl

about q1:
Just in case you can try to use InMemory layer. It works fine for code below

var layer = Drivers.InMemory.CreateLayer();
layer.Attributes.Add(new FeatureAttribute(“value”, AttributeDataType.Integer));
for (int i = 0; i < 10; ++i)
{
var feature = layer.ConstructFeature();
feature.SetValue(“value”, i);
feature.Geometry = new Point(i, i);
layer.Add(feature);
}
layer.SaveTo(GetTempName(“.json”), Drivers.GeoJson);

about q2:
We made fix for this. It will be in next release.

ok
please look Different Geometrytype create by arcgis and aspose
The core of this problem is to create a layer without ZM (It is optional for ZM when creating in ArcGIS.)

Thanks,
I will check it right now