Skip to content

Commit

Permalink
Fixed #741 read and write linestring from and to shapefiles when pImp…
Browse files Browse the repository at this point in the history
…->GetShapeType() != ShapeTypes::ST_Polygon
  • Loading branch information
MaartenHilferink committed Jun 13, 2024
1 parent 0808f56 commit 4f28e56
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 65 deletions.
6 changes: 3 additions & 3 deletions stg/dll/src/gdal/gdal_vect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,16 +507,16 @@ void ReadPointData(typename sequence_traits<PointType>::seq_t data, OGRLayer* la
template <typename PolygonType>
void ReadPolyData(typename sequence_traits<PolygonType>::seq_t dataArray, OGRLayer* layer, SizeT firstIndex, SizeT size, ResourceHandle& readBuffer, GDALDataset* m_hDS)
{
dms_assert(layer);
assert(layer);

DBG_START("ReadPolyData", typeid(PolygonType).name(), true);

DBG_TRACE(("firstIndex %d, size %d", firstIndex, size));

typedef sequence_traits<PolygonType>::container_type dataBufType;
using dataBufType = typename sequence_traits<PolygonType>::container_type;
if (!readBuffer)
{
dms_assert(!firstIndex || !size);
assert(!firstIndex || !size);
readBuffer = makeResource<dataBufType>();
}
dataBufType& data = GetAs<dataBufType>(readBuffer);
Expand Down
38 changes: 8 additions & 30 deletions stg/dll/src/shp/ShpImp.h
Original file line number Diff line number Diff line change
@@ -1,31 +1,10 @@
//<HEADER>
/*
Data & Model Server (DMS) is a server written in C++ for DSS applications.
Version: see srv/dms/rtc/dll/src/RtcVersion.h for version info.
// Copyright (C) 1998-2024 Object Vision b.v.
// License: GNU GPL 3
/////////////////////////////////////////////////////////////////////////////

Copyright (C) 1998-2004 YUSE GSO Object Vision BV.
Documentation on using the Data & Model Server software can be found at:
http://www.ObjectVision.nl/DMS/
See additional guidelines and notes in srv/dms/Readme-srv.txt
This library is free software; you can use, redistribute, and/or
modify it under the terms of the GNU General Public License version 2
(the License) as published by the Free Software Foundation,
provided that this entire header notice and readme-srv.txt is preserved.
See LICENSE.TXT for terms of distribution or look at our web site:
http://www.objectvision.nl/DMS/License.txt
or alternatively at: http://www.gnu.org/copyleft/gpl.html
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details. However, specific warranties might be
granted by an additional written contract for support, assistance and/or development
*/
//</HEADER>
#if defined(_MSC_VER)
#pragma once
#endif

#ifndef _ShpImp_H_
#define _ShpImp_H_
Expand All @@ -51,7 +30,6 @@ granted by an additional written contract for support, assistance and/or develop
// ----------------------------------------------------------------



// To handle ESRI shapefile (*.shp)
// For now only ShapeType = 5 is supported (Polygons)
enum class ShapeTypes {
Expand All @@ -73,13 +51,13 @@ inline bool IsKnownOrNone (ShapeTypes st) { return IsKnown(st) || IsNone(st);
// ESRI type struct for fileheader
#pragma pack(push, 4)

typedef Point<Float64> ShpPoint;
using ShpPoint = Point<Float64>;
std::size_t Read ( ShpPoint& self, FILE * fp);
std::size_t Write(const ShpPoint& self, FILE * fp);


// Used by ShpImp::GetPoints() and ShpImp::AddPoints()
typedef Range<ShpPoint> ShpBox;
using ShpBox = Range<ShpPoint>;

struct ShpHeader
{
Expand Down
76 changes: 44 additions & 32 deletions stg/dll/src/shp/ShpStorageManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ void ReadSequences(AbstrDataObject* ado, UInt32 shpImpFeatureCount, ShpImp* pImp

auto polyData = debug_valcast<DataArray<PolygonType>*>(ado)->GetDataWrite();

dms_assert(polyData.size() == shpImpFeatureCount);
assert(polyData.size() == shpImpFeatureCount);
MG_CHECK(pImp->GetShapeType() != ShapeTypes::ST_Point);

bool mustCloseRings = (pImp->GetShapeType() == ShapeTypes::ST_Polygon);
Expand All @@ -135,14 +135,14 @@ void ReadSequences(AbstrDataObject* ado, UInt32 shpImpFeatureCount, ShpImp* pImp
typename DataArray<PolygonType>::iterator polygonPtr = polyData.begin();
for (UInt32 p=0, n=polyData.size(); p!=n; ++p, ++polygonPtr)
{
UInt32 polygonSize = pImp->ShapeSet_NrPoints(p);
auto polygonSize = pImp->ShapeSet_NrPoints(p);
if (!polygonSize)
{
vector_resize_uninitialized(*polygonPtr, 0);
continue;
}
UInt32 nrExtraParts = pImp->ShapeSet_NrParts(p) - 1;
dms_assert(nrExtraParts < polygonSize); // since there are points, there is at least one part, and parts are not allowed to have less that three or at least one points
assert(nrExtraParts < polygonSize); // since there are points, there is at least one part, and parts are not allowed to have less that three or at least one points

UInt32 nrUnclosedRings = 0;
if (mustCloseRings)
Expand All @@ -154,34 +154,34 @@ void ReadSequences(AbstrDataObject* ado, UInt32 shpImpFeatureCount, ShpImp* pImp

typename sequence_traits<PointType>::pointer
pointData = (*polygonPtr).begin();
if (!nrUnclosedRings)
{
ConstPointIterRange pointRange = pImp->ShapeSet_GetPoints(p);
dms_assert(pointRange.size() == polygonSize);
ConvertResultFunctor<PointType, DPoint, shp_reorder_functor> converter;

pointData = convert_copy(pointRange.begin(), pointRange.end(), pointData, shp_reorder_functor() );
}
else
for (UInt32 partI = 0; partI <= nrExtraParts; ++partI)
{
ConvertResultFunctor<PointType, DPoint, shp_reorder_functor> converter;

for (UInt32 partI=0; partI<=nrExtraParts; ++partI)
ConstPointIterRange pointRange = pImp->ShapeSet_GetPoints(p, partI);
pointData = convert_copy(pointRange.begin(), pointRange.end(), pointData, shp_reorder_functor());
if (mustCloseRings)
{
ConstPointIterRange pointRange = pImp->ShapeSet_GetPoints(p, partI);
pointData = convert_copy(pointRange.begin(), pointRange.end(), pointData, shp_reorder_functor() );
if (!IsRingClosed(pointRange))
*pointData++ = converter( *pointRange.begin() );
*pointData++ = converter(*pointRange.begin());
}
else
{
if (partI < nrExtraParts) // include a multi-linstring separator if another linestring follows
*pointData++ = UNDEFINED_VALUE(PointType);
}

}

// connect extra parts in possible reverse order to origins of previous parts
ConvertResultFunctor<PointType, DPoint, shp_reorder_functor> converter;

for (UInt32 i=0; i<nrExtraParts; ++pointData)
*pointData = converter(
pImp->ShapeSet_GetPoint(p, nrExtraParts - ++i, 0) // i increments here
);
dms_assert(pointData == (*polygonPtr).end());
if (mustCloseRings)
{
for (UInt32 i = 0; i < nrExtraParts; ++pointData)
*pointData = converter(
pImp->ShapeSet_GetPoint(p, nrExtraParts - ++i, 0) // i increments here
);
assert(pointData == (*polygonPtr).end());
}
}
}

Expand All @@ -208,7 +208,7 @@ bool ShpStorageManager::ReadDataItem(StorageMetaInfoPtr smi, AbstrDataObject* bo
const TreeItem* storageHolder = smi->StorageHolder();
AbstrDataItem* adi = smi->CurrWD();

dms_assert(adi->GetDataObjLockCount() < 0); // Write lock is already set.
assert(adi->GetDataObjLockCount() < 0); // Write lock is already set.

ShpImp impl;

Expand Down Expand Up @@ -243,7 +243,7 @@ bool ShpStorageManager::ReadDataItem(StorageMetaInfoPtr smi, AbstrDataObject* bo
}
);
}
dms_assert(borrowedReadResultHolder->GetNrFeaturesNow() == shpImpFeatureCount);
assert(borrowedReadResultHolder->GetNrFeaturesNow() == shpImpFeatureCount);
return true;
}

Expand Down Expand Up @@ -297,10 +297,10 @@ void WriteSequences(const AbstrDataObject* ado, ShpImp* pImp, WeakStr nameStr, c
{
typename DataArrayBase<PolygonType>::const_reference polygon = *polygonIter;

typedef FuncIter<
using func_iter = FuncIter<
typename PolygonArray::const_reference::const_iterator,
ConvertResultFunctor<DPoint, PointType, shp_reorder_functor>
> func_iter;
>;

auto feature = pImp->ShapeSet_PushBackPolygon();
if (pImp->GetShapeType() == ShapeTypes::ST_Polygon)
Expand All @@ -319,12 +319,24 @@ void WriteSequences(const AbstrDataObject* ado, ShpImp* pImp, WeakStr nameStr, c
}
}
else
feature.AddPoints(
func_iter(polygon.begin()),
func_iter(polygon.end ())
);
{
auto linestringIter = polygon.begin();
auto polygonEnd = polygon.end();
while (true)
{
auto linestringEnd = std::find(linestringIter, polygonEnd, UNDEFINED_VALUE(PointType));

feature.AddPoints(
func_iter(linestringIter),
func_iter(linestringEnd)
);
if (linestringEnd == polygonEnd)
break;
linestringIter = ++linestringEnd;
}
}
}
dms_assert(pImp->m_Polygons.size() == nrRecs);
assert(pImp->m_Polygons.size() == nrRecs);

auto wktPrjStr = GetWktProjectionFromValuesUnit(adi);

Expand Down

0 comments on commit 4f28e56

Please sign in to comment.