Hello, I edited an empty shapefile using ShapefileFeatureTable.
However, when I checked the shapefile in QGIS, no geometry was displayed, even though the shapefile actually contains a polygon.
It looks like ShapefileFeatureTable does not update the extent of the shapefile, is that correct?
Here is the output of ogrinfo:
$ ogrinfo -al -so test.shp
INFO: Open of `test.shp'
using driver `ESRI Shapefile' successful.
Layer name: test
Metadata:
DBF_DATE_LAST_UPDATE=2025-12-17
Geometry: Polygon
Feature Count: 1
Extent: (0.000000, 0.000000) - (0.000000, 0.000000)
...
$ ogrinfo -al test.shp
INFO: Open of `test.shp'
using driver `ESRI Shapefile' successful.
Layer name: test
Metadata:
DBF_DATE_LAST_UPDATE=2025-12-17
Geometry: Polygon
Feature Count: 1
Extent: (0.000000, 0.000000) - (0.000000, 0.000000)
...
OGRFeature(test):0
level (Integer64) = 3
POLYGON ((139.757125 35.671236,139.757125 35.691236,
139.777125 35.691236,139.777125 35.671236,
139.757125 35.671236))
Solved! Go to Solution.
It appears that some tools, including ArcGIS Pro and Google Earth, are able to read a shapefile with an incorrect extent, whereas QGIS fails to do so.
I would be hesitant to conclude that Google Earth Pro and ArcGIS Pro are working despite reading an incorrect extent. Examining your shapefile in both applications indicates that the extent is being updated to the expected values, and the polygon is rendering. I can also see (after setting some breakpoints in your code using Visual Studio), that the extent of the table is updated after calling AddFeatureAsync. I have also verified that running the program again and reading from the modified shapefile that the table that is created has the expected extent.
Is this a QGIS-side issue?
Given that your code works in 3 separate instances (including one non-Esri application), I have to conclude that this is an issue with QGIS, or perhaps OGR, as that is the "provider" for QGIS. Other shapefiles seem to work fine with QGIS, so at a glance it seems as though QGIS, or OGR, is incapable of reading the updated extent of the shapefile table. This is unfortunately the limit of my expertise, as I am not in a position to know how QGIS reads and interprets shapefiles.
Hi there! This was determined to be a bug in the ArcGIS Maps SDK. This issue will be fixed with the release of the next major version of ArcGIS Maps SDK. In the meantime, the following workarounds exist that will resolve the issue:
1) After creating a feature layer from the shapefile feature table, adding it to a map, and rendering that map, updating features will correctly adjust the extent.
2) If there is no intention or ability to render the data, then copying the existing feature into a new feature, changing the new feature's geometry, deleting the old feature, then finally adding the new feature to the table, (essentially a roundabout way to update a feature) will correctly adjust the extent of the table.
Thank you for the reply.
I'll go with approach 2) ,as I am writing a command line tool to export a shapefile.
If I want to create a shafile containing two polygons , is the following procedure correct?
(1)Read empty shapefile with openasync
(2)Add the first polygon with CreateFeature
(3)Copy the polygon with CreateFeature ,edit it with UpdateFeatureAsync, and delete the original with DeleteFeatureAsync
(4)Add the second polygon with CreateFeature
CreateFeature is a synchronous method that creates a new feature in memory, and will not write to the shapefile's table. In order to write a feature to the shapefile, you will need to call AddFeatureAsync. So for your use case, it sounds like the following would be sufficient:
1) Read in the empty shapefile
2) Create a Feature using the overload of CreateFeature, with the polygon as the Geometry
3) Add the new Feature to the Shapefile with AddFeatureAsync
4) Repeat for each Polygon
Alternatively, instead of calling AddFeatureAsync after you create each new feature, you could add all the newly created features to a collection, and then add them all at once by calling AddFeaturesAsync.
The bug I mentioned in my first response is specific to UpdateFeatureAsync, AddFeatureAsync will correctly adjust the extent of the table if the added feature's geometry exceeds the extent of the table.
If you find that you need to change the geometry of a Feature that already exists in the table, and you are concerned that the change to the geometry will exceed the table's extent, then you will need to use the workaround I described for the time being.
Thank you for your quick reply.
I tried using AddFeatureAsync , but the extent wasn't updated.
$ ogrinfo -al -geom=YES empty_polygon.shp
INFO: Open of `empty_polygon.shp'
using driver `ESRI Shapefile' successful.
Layer name: empty_polygon
Metadata:
DBF_DATE_LAST_UPDATE=2026-01-01
Geometry: Polygon
Feature Count: 1
Extent: (0.000000, 0.000000) - (0.000000, 0.000000)
Layer SRS WKT:
GEOGCRS["WGS 84",
DATUM["World Geodetic System 1984",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
CS[ellipsoidal,2],
AXIS["latitude",north,
ORDER[1],
ANGLEUNIT["degree",0.0174532925199433]],
AXIS["longitude",east,
ORDER[2],
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4326]]
Data axis to CRS axis mapping: 2,1
level: Real (21.6)
OGRFeature(empty_polygon):0
level (Real) = 3.000000
POLYGON ((139.757125 35.671236,139.757125 35.691236,139.777125 35.691236,139.777125 35.671236,139.757125 35.671236))
My code was below. (I also pushed the full code to github )
Any ideas what I might be doing wrong?
class Program
{
static async Task Main()
{
var baseDir = AppContext.BaseDirectory;
var shpPath = Path.Combine(baseDir, "data", "empty_polygon.shp");
var sr = SpatialReferences.Wgs84;
//near tokyo station
double centerLon = 139.767125;
double centerLat = 35.681236;
double offset1 = 0.01; // ~1.1 km
var points = new PointCollection(sr)
{
new MapPoint(centerLon - offset1, centerLat - offset1, sr),
new MapPoint(centerLon + offset1, centerLat - offset1, sr),
new MapPoint(centerLon + offset1, centerLat + offset1, sr),
new MapPoint(centerLon - offset1, centerLat + offset1, sr),
new MapPoint(centerLon - offset1, centerLat - offset1, sr)
};
var poly1 = new Polygon(points);
//
var attrs = new Dictionary<string, object>
{
["level"] = (float)3
};
await ShapeHandler.AddPolygonFeatureAsync(shpPath, poly1, attrs);
} public static async Task AddPolygonFeatureAsync(string shapefilePath, Polygon polygon, IDictionary<string, object>? attributes = null)
{
if (string.IsNullOrWhiteSpace(shapefilePath))
throw new ArgumentException("shapefilePath is required", nameof(shapefilePath));
var table = new ShapefileFeatureTable(shapefilePath);
Console.WriteLine(table);
await table.LoadAsync().ConfigureAwait(false);
var feature = table.CreateFeature();
//SpatialReference sr = table.SpatialReference ?? SpatialReferences.Wgs84;
feature.Geometry = polygon;
if (attributes != null)
{
foreach (var kv in attributes)
{
if (feature.Attributes.ContainsKey(kv.Key))
{
Console.WriteLine(kv);
feature.Attributes[kv.Key] = kv.Value;
}
}
}
await table.AddFeatureAsync(feature).ConfigureAwait(false);
Console.WriteLine("add feature");
Console.WriteLine(table.GetField("level").FieldType);
table.Close();
}
I ran the program you uploaded to GitHub. It appears to be working as expected. I was able to see a polygon over Tokyo and the extent was updated to match (this was observed using ArcGIS Pro, see image below). I noticed your Hello.csproj file included these lines
<!-- Copy shapefile components from the data folder to output and publish directories -->
<ItemGroup>
<None Include="data\**\*.shp" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
<None Include="data\**\*.dbf" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
<None Include="data\**\*.shx" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
<None Include="data\**\*.prj" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
<None Include="data\**\*.cpg" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
</ItemGroup>
It would be good to confirm you are inspecting the correct files. The original shapefiles you included inside your Data folder are not actually the ones being modified by your program. I was only able to see shapefile updates after looking at the path contained within shpPath. For me, the file path looked like \MyArcSample-master\bin\Debug\net9.0\data\empty_polygon.shp, not MyArcSample-master\data\empty_polygon.shp.
Hope this helps!
@RossMcguyerI appreciate you checking my code.
I also checked the file at \bin\Debug\net9.0\data\empty_polygon.shp.
The polygon itself was saved correctly, but the extent was not updated, as shown below.
ogrinfo -al -geom=YES empty_polygon.shp
INFO: Open of `empty_polygon.shp'
using driver `ESRI Shapefile' successful.
Layer name: empty_polygon
Metadata:
DBF_DATE_LAST_UPDATE=2026-01-01
Geometry: Polygon
Feature Count: 1
Extent: (0.000000, 0.000000) - (0.000000, 0.000000)
(****************some lines omitted**********************************)
OGRFeature(empty_polygon):0
level (Real) = 3.000000
POLYGON ((139.757125 35.671236,139.757125 35.691236,139.777125 35.691236,139.777125 35.671236,139.757125 35.671236))It appears that some tools, including ArcGIS Pro and Google Earth, are able to read a shapefile with an incorrect extent, whereas QGIS fails to do so.
Is this a QGIS-side issue?
It appears that some tools, including ArcGIS Pro and Google Earth, are able to read a shapefile with an incorrect extent, whereas QGIS fails to do so.
I would be hesitant to conclude that Google Earth Pro and ArcGIS Pro are working despite reading an incorrect extent. Examining your shapefile in both applications indicates that the extent is being updated to the expected values, and the polygon is rendering. I can also see (after setting some breakpoints in your code using Visual Studio), that the extent of the table is updated after calling AddFeatureAsync. I have also verified that running the program again and reading from the modified shapefile that the table that is created has the expected extent.
Is this a QGIS-side issue?
Given that your code works in 3 separate instances (including one non-Esri application), I have to conclude that this is an issue with QGIS, or perhaps OGR, as that is the "provider" for QGIS. Other shapefiles seem to work fine with QGIS, so at a glance it seems as though QGIS, or OGR, is incapable of reading the updated extent of the shapefile table. This is unfortunately the limit of my expertise, as I am not in a position to know how QGIS reads and interprets shapefiles.
The issue is due to the fact that the .shx index sidecar file of the provided zipped ESRI Shapefile layer is malformed, according to the ESRI Shapefile Technical Description; in fact, the extent stored in its header section is 0,0 - 0,0:
Offset(d) 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 00000032 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ............................ 00000064 00 00 00 00
ogrinfo reports the extent information contained in the header section of the .shx file.
See a more detailed answer at https://gis.stackexchange.com/a/499601/107272.