# EditUpdateShape problem

**URL:** <https://mapwindow.discourse.group/t/editupdateshape-problem/1073>\
**Category:** MapWinGIS\
**Created:** [August 19, 2021, 3:51pm UTC](https://mapwindow.discourse.group/t/editupdateshape-problem/1073 "2021-08-19T15:51:30Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jTati](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@jTati](https://mapwindow.discourse.group/u/jTati)\
**Post date:** [August 19, 2021, 3:51pm UTC](https://mapwindow.discourse.group/t/editupdateshape-problem/1073/1 "2021-08-19T15:51:30Z")

</div>

Hi,

I’ve developed an ms access based application. In this application i create a new shapefile with “handmade” polygon objects, via three routines: one creates the shapefile on disk, - Shapefiletype POLYGON, one creates the polygon objects and one that loops through a table, gathers all affected records, and adds new records to the shapefile with the objects of routine 2.  
This works perfectly, - i can load that shapefile in MapWinGis-OCX and in QGis, - no problem here.

Now i want to add a routine to update the shape-Object of specific Shapefile-Records.  
For this i open the previously generated shapefile from disk, startEdtingShapes(true) → returns true, create a new polygon object with the same routine used to create the shapefile and use the .EditUpdateShape-Method to update the shape-object.

The EditUpdateShape-Method does not throw an error when updating the shape-object, and in this routine there is already a buildin check if the shapetypes of file and new object match, - but when i call shapefile.save() or .stopeditngshapes(true,true) to save the changes this way the error message i get is:  
Shape type is incompatible with the shapefile type.

i took the source code of the current release version, created my own debug version and debuged this behaviour in vs 2019.  
When .EditUpdateShape is entered the newShape-object gets passed correctly and is of type POLYGON with parts, points and a boundary, but when stopeditingshapes is called the routine VerifyMemShapes tells me for this updated shapeindex, that the object stored there is not present any  
longer (no parts, no points, no extend, random numbers vor \_shapeType) and so that routine fails.  
The shapefile is disk based, and since the application can write / create that file, it’s obviously no rights-problem.  
I tried it with fastmode on and off, no changes here.

I’m a bit lost here and happy about any idea that might help.

Cheers  
Stefan

---

<div class="post-metadata">

**Author:** ![jerryfaust](https://yyz2.discourse-cdn.com/free1/user_avatar/mapwindow.discourse.group/jerryfaust/32/378_2.png) [@jerryfaust](https://mapwindow.discourse.group/u/jerryfaust)\
**Post date:** [August 20, 2021, 6:23am UTC](https://mapwindow.discourse.group/t/editupdateshape-problem/1073/2 "2021-08-20T06:23:37Z")

</div>

Hello Stefan.

I may or may not be able to reproduce this without your specific code, but we can start with a question.

Here’s the code leading up to the specific error you are seeing:

```
	shp->get_ShapeType(&shapetype);
	// MWGIS-91
	bool areEqualTypes = shapetype == _shpfiletype;
	if (!areEqualTypes){
		areEqualTypes = ShapeUtility::Convert2D(shapetype) == ShapeUtility::Convert2D(_shpfiletype);
	}
	shp->get_NumPoints(&numPoints);
	shp->get_NumParts(&numParts);

	if (shapetype != SHP_NULLSHAPE && !areEqualTypes)
	{	
		ErrorMessage(tkINCOMPATIBLE_SHAPE_TYPE);
		return FALSE;
	}

```

So, presuming that you are falling into the error where `areEqualTypes` = false, what type is showing for your `shapeType` following the call to `get_ShapeType`?

And it sounds like you’re also saying that `numPoints` and `numParts` are zero?

Could you post the code that creates the shape?

Thank you.  
Jerry.

---

<div class="post-metadata">

**Author:** ![pmeems](https://yyz2.discourse-cdn.com/free1/user_avatar/mapwindow.discourse.group/pmeems/32/9_2.png) [@pmeems](https://mapwindow.discourse.group/u/pmeems)\
**Post date:** [January 5, 2022, 1:49pm UTC](https://mapwindow.discourse.group/t/editupdateshape-problem/1073/3 "2022-01-05T13:49:04Z")

</div>

@jTati Are you still having this issue?

---

<div class="post-metadata">

**Author:** ![jTati](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@jTati](https://mapwindow.discourse.group/u/jTati)\
**Post date:** [January 6, 2022, 8:06am UTC](https://mapwindow.discourse.group/t/editupdateshape-problem/1073/4 "2022-01-06T08:06:30Z")

</div>

Hello Paul,

Jerry and i figured out, that the ocx has some problems when dealing with Shapefile records that contain empty Shapes, = ShapeType == SHP\_NULLSHAPE.  
When ShapeFile.FastMode is turned on, and a shapefile gets saved, these records get corrupted, and the ShapeFile.HasInvalidShapes returns TRUE afterwards.  
Additionally, - and i’m a bit astonished that Jerry didn’t incorporate these changes, i found out, that the Shape-Validation-Functions in the code, do not handle SHP\_NULLSHAPE-Type-Objects correctly.

If you look at the Function “ValidateBasics” in the File Shape.cpp, a Shape-Object gets marked invalid when generally:

```auto
if (_shp->get_PointCount() == 0)
{
        errMsg = "Shape hasn't got points";
        failedCheck = NoPoints;
        return false;
}

```

…but this is always true for a SHP\_NULLSHAPE-Object.  
I changed this code for my personal usage to:

```auto
ShpfileType shptype = ShapeUtility::Convert2D(_shp->get_ShapeType());
   
    if ((_shp->get_PointCount() == 0) && (shptype != SHP_NULLSHAPE))
    {
        errMsg = "Shape hasn't got points";
        failedCheck = NoPoints;
        return false;
    }

```

→ that makes more sense from my point of view.

In the same file, right below this function, the function “get\_IsValid” is defined and there is also a flaw:  
Every Shape of any Shape-Type gets checked if valid, but you don’t have to do that for an  
object of SHP\_NULLSHAPE, so i changed that function to:

```auto
// *************************************************************
// get_IsValid   
// *************************************************************
// Checking validity of the geometry
STDMETHODIMP CShape::get_IsValid(VARIANT_BOOL* retval)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState())
        * retval = VARIANT_FALSE;

    ShpfileType shptype = ShapeUtility::Convert2D(_shp->get_ShapeType());

    if (shptype != SHP_NULLSHAPE)
    {
        ShapeValidityCheck validityCheck;
        if (!ValidateBasics(validityCheck, _isValidReason)) {
            return S_OK;
        }

        // -----------------------------------------------
        // check through GEOS (common for both modes)
        // -----------------------------------------------
        GEOSGeom hGeosGeom = GeosConverter::ShapeToGeom(this);
        if (hGeosGeom == NULL)
        {
            _isValidReason = "Failed to convert to GEOS geometry";
            return S_OK;
        }

        if (!GeosHelper::IsValid(hGeosGeom))
        {
            char* buffer = GeosHelper::IsValidReason(hGeosGeom);
            _isValidReason = buffer;
            GeosHelper::Free(buffer);
        }
        else
        {
            *retval = VARIANT_TRUE;
        }
        GeosHelper::DestroyGeometry(hGeosGeom);
    }
    else
    {
        *retval = VARIANT_TRUE;
    }
   
    return S_OK;
}
---------------------

```

In the Function “WriteShp” in the Source-File ShapeFile\_ReadWrite.cpp  
you can find the problem with SHP\_NULLSHAPE records (somewhere around line 1265):

In the original code, this write operation fails with SHP\_NULLSHAPE-records,  
because the calculation of the number of nodes fails and leads to an error:

```auto
        // disk based mode
            // disk-based + fast data (probably a bit faster procedure can be devised)
            // in-memory mode (COM points)
            ShpfileType shptype = wrapper->get_ShapeType();
            ShpfileType shptype2D = wrapper->get_ShapeType2D();
            numPoints = wrapper->get_PointCount();
            numParts = wrapper->get_PartCount();

            //Write the Record
            if( shptype2D == SHP_NULLSHAPE )
            {
                int ishptype = shptype;
                fwrite(&shptype, sizeof(int), 1, shp);
            }

```

so i changed it to this, so that these calculations only take place,  
if the shape is not of type SHP\_NULLSHAPE:

```auto
        // disk based mode
            // disk-based + fast data (probably a bit faster procedure can be devised)
            // in-memory mode (COM points)
            ShpfileType shptype = wrapper->get_ShapeType();
            ShpfileType shptype2D = wrapper->get_ShapeType2D();

            if ( shptype != SHP_NULLSHAPE )
            {
                numPoints = wrapper->get_PointCount();
                numParts = wrapper->get_PartCount();
            }

            //Write the Record
            if( shptype == SHP_NULLSHAPE || shptype2D == SHP_NULLSHAPE )
            {
                int ishptype = shptype;
                fwrite(&shptype, sizeof(int), 1, shp);
            }

```

With these modifications and FastMode = off, I had no problems since.

thanks and have a nice day  
Stefan

---

<div class="post-metadata">

**Author:** ![pmeems](https://yyz2.discourse-cdn.com/free1/user_avatar/mapwindow.discourse.group/pmeems/32/9_2.png) [@pmeems](https://mapwindow.discourse.group/u/pmeems)\
**Post date:** [January 10, 2022, 9:16am UTC](https://mapwindow.discourse.group/t/editupdateshape-problem/1073/5 "2022-01-10T09:16:30Z")

</div>

Thanks Stefan,

Your changes look fine. But I’m not a C++ developer 😉

Can you make a pull request against the development branch?  
Then I will ask @jerryfaust to review it and if it is OK we will merge your changes.

---

<div class="post-metadata">

**Author:** ![jTati](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@jTati](https://mapwindow.discourse.group/u/jTati)\
**Post date:** [January 10, 2022, 9:55am UTC](https://mapwindow.discourse.group/t/editupdateshape-problem/1073/6 "2022-01-10T09:55:05Z")

</div>

Hi Paul,

if someone can explain to me, how to create a pull request, i would like to do so.

Cheers

---

<div class="post-metadata">

**Author:** ![pmeems](https://yyz2.discourse-cdn.com/free1/user_avatar/mapwindow.discourse.group/pmeems/32/9_2.png) [@pmeems](https://mapwindow.discourse.group/u/pmeems)\
**Post date:** [January 10, 2022, 11:07am UTC](https://mapwindow.discourse.group/t/editupdateshape-problem/1073/7 "2022-01-10T11:07:51Z")

</div>

Does this document help: [Creating an issue or pull request - GitHub Docs](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/working-with-your-remote-repository-on-github-or-github-enterprise/creating-an-issue-or-pull-request)
