[fdo-internals] PATCH: OGR provider fixed to use FDO spatial test,
rather than GEOS
Kenneth Skovhede, GEOGRAF A/S
ks at geograf.dk
Sat May 17 07:35:58 EDT 2008
Attached is a diff agains the trunk version of the OGR provider.
It all works in my tests, but I would appreciate it if someone would
review the changes to see that there are no unintentional memory leaks,
or places where there should be a copy rather than a reference.
--
Regards, Kenneth Skovhede, GEOGRAF A/S
-------------- next part --------------
Index: OgrFdoUtil.cpp
===================================================================
--- OgrFdoUtil.cpp (revision 3962)
+++ OgrFdoUtil.cpp (working copy)
@@ -305,14 +305,11 @@
//This function assumes MapGuide style queries -- either
//an attribute filter or a simple spatial filter or a binary
//combination of the two
-void OgrFdoUtil::ApplyFilter(OGRLayer* layer, FdoFilter* filter, bool* isbbox)
+void OgrFdoUtil::ApplyFilter(OGRLayer* layer, FdoFilter* filter)
{
FdoFilter* spatial = NULL;
FdoFilter* attr = NULL;
- if (isbbox != NULL)
- (*isbbox) = false;
-
//zero out the filters
layer->SetAttributeFilter(NULL);
layer->SetSpatialFilter(NULL);
@@ -372,7 +369,6 @@
envelope->GetMinY(),
envelope->GetMaxX(),
envelope->GetMaxY());
- (*isbbox) = true;
}
}
else if (sc->GetOperation() == FdoSpatialOperations_Intersects)
@@ -612,4 +608,3 @@
return dst.GetLength();
}
-
Index: OgrFdoUtil.h
===================================================================
--- OgrFdoUtil.h (revision 3962)
+++ OgrFdoUtil.h (working copy)
@@ -27,7 +27,7 @@
static FdoClassDefinition* ConvertClass(OGRLayer* layer, FdoIdentifierCollection* requestedProps = NULL);
static void ConvertFeature(FdoPropertyValueCollection* src, OGRFeature* dst, OGRLayer* layer);
- static void ApplyFilter(OGRLayer* layer, FdoFilter* filter, bool* isbbox);
+ static void ApplyFilter(OGRLayer* layer, FdoFilter* filter);
static int Fgf2Wkb(const unsigned char* fgf, unsigned char* wkb);
static int Wkb2Fgf(const unsigned char* wkb, unsigned char* fgf);
Index: OgrProvider.cpp
===================================================================
--- OgrProvider.cpp (revision 3962)
+++ OgrProvider.cpp (working copy)
@@ -25,6 +25,7 @@
#include "OgrProvider.h"
#include "OgrFdoUtil.h"
#include "ProjConverter.h"
+#include "FdoSpatial.h"
#define PROP_NAME_DATASOURCE L"DataSource"
@@ -178,7 +179,7 @@
size_t slen = wcslen(dsw);
if (dsw[slen - 1] == '\\')
- slen--;
+ slen--;
wchar_t* tmp = new wchar_t[slen + 1];
wcsncpy(tmp, dsw, slen);
@@ -412,9 +413,9 @@
OGRLayer* layer = m_poDS->GetLayerByName(mbfc);
- OgrFdoUtil::ApplyFilter(layer, filter, &bbox);
+ OgrFdoUtil::ApplyFilter(layer, filter);
- return new OgrFeatureReader(this, layer, props, bbox);
+ return new OgrFeatureReader(this, layer, props, filter);
}
FdoIDataReader* OgrConnection::SelectAggregates(FdoIdentifier* fcname,
@@ -501,7 +502,7 @@
if (!canDo)
throw FdoCommandException::Create(L"Current OGR connection does not support update of existing features.");
- OgrFdoUtil::ApplyFilter(layer, filter, NULL);
+ OgrFdoUtil::ApplyFilter(layer, filter);
OGRFeature* feature = NULL;
@@ -535,7 +536,7 @@
if (!canDo)
throw FdoCommandException::Create(L"Current OGR connection does not support delete.");
- OgrFdoUtil::ApplyFilter(layer, filter, NULL);
+ OgrFdoUtil::ApplyFilter(layer, filter);
std::vector<long> ids; //list of FIDs of features to delete
@@ -732,7 +733,7 @@
//
//---------------------------------------------------------------------
-OgrFeatureReader::OgrFeatureReader(OgrConnection* connection, OGRLayer* layer, FdoIdentifierCollection* props, bool bboxquery)
+OgrFeatureReader::OgrFeatureReader(OgrConnection* connection, OGRLayer* layer, FdoIdentifierCollection* props, FdoFilter* filter)
{
m_connection = connection;
((FdoIConnection*)m_connection)->AddRef();
@@ -747,7 +748,20 @@
m_fgflen = 64;
m_fgf = new unsigned char[m_fgflen*2];
m_wkb = new unsigned char[m_fgflen];
- m_bboxquery = bboxquery;
+
+ FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
+
+ m_geomFilter = NULL;
+ if (dynamic_cast<FdoSpatialCondition*>(filter))
+ {
+ FdoSpatialCondition* sc = (FdoSpatialCondition*)filter;
+ m_spatialOperation = sc->GetOperation();
+ if (m_spatialOperation != FdoSpatialOperations_EnvelopeIntersects)
+ {
+ FdoPtr<FdoExpression> geomExpr = sc->GetGeometry();
+ m_geomFilter = gf->CreateGeometryFromFgf(((FdoGeometryValue*)(geomExpr.p))->GetGeometry());
+ }
+ }
}
OgrFeatureReader::~OgrFeatureReader()
@@ -757,6 +771,10 @@
((FdoIConnection*)m_connection)->Release();
delete [] m_fgf;
delete [] m_wkb;
+
+ //TODO: Will the smart pointer release itself?
+ /*if (m_geomFilter != NULL)
+ FDO_SAFE_RELEASE(m_geomFilter);*/
}
void OgrFeatureReader::Dispose()
@@ -876,10 +894,8 @@
return FdoByteArray::Create((unsigned char*)ptr, len);
}
-const FdoByte* OgrFeatureReader::GetGeometry(FdoString* propertyName, FdoInt32* len)
+const FdoByte* OgrFeatureReader::GetGeometry(OGRGeometry* geom, FdoInt32* len)
{
- OGRGeometry* geom = m_poFeature->GetGeometryRef();
-
if (geom)
{
size_t wkblen = geom->WkbSize();
@@ -903,6 +919,11 @@
throw FdoException::Create(L"Geometry is null.");
}
+const FdoByte* OgrFeatureReader::GetGeometry(FdoString* propertyName, FdoInt32* len)
+{
+ return this->GetGeometry(m_poFeature->GetGeometryRef(), len);
+}
+
FdoIRaster* OgrFeatureReader::GetRaster(FdoString* propertyName)
{
return NULL;
@@ -919,17 +940,26 @@
m_poFeature = m_poLayer->GetNextFeature();
- //Ugly hack to fix broken providers, with BBOX only testing
- if (!m_bboxquery)
- {
- OGRGeometry* spfilter = m_poLayer->GetSpatialFilter();
- if (spfilter != NULL)
- while (m_poFeature != NULL && m_poFeature->GetGeometryRef() != NULL && !spfilter->Intersects(m_poFeature->GetGeometryRef()))
+ //OGR uses envelope intersection testing only, this breaks tooltips and selection
+ //If the actual selection was not for envelope intersection, the geometry filtering is done here instead
+ if (m_geomFilter != NULL)
+ while (m_poFeature != NULL && m_poFeature->GetGeometryRef() != NULL)
+ {
+ FdoPtr<FdoFgfGeometryFactory> gf = FdoFgfGeometryFactory::GetInstance();
+ FdoInt32 fgfLen;
+ const FdoByte* fgf = this->GetGeometry(m_poFeature->GetGeometryRef(), &fgfLen);
+ FdoPtr<FdoIGeometry> featureGeom = gf->CreateGeometryFromFgf(fgf, fgfLen);
+
+ //call on the geometry utility to evaluate the spatial operation
+ if (FdoSpatialUtility::Evaluate(m_geomFilter, m_spatialOperation, featureGeom))
+ break;
+ else
{
+ //Goto next
OGRFeature::DestroyFeature(m_poFeature);
m_poFeature = m_poLayer->GetNextFeature();
}
- }
+ }
return (m_poFeature != NULL);
}
Index: OgrProvider.h
===================================================================
--- OgrProvider.h (revision 3962)
+++ OgrProvider.h (working copy)
@@ -997,7 +997,7 @@
{
public:
OGR_API OgrFeatureReader(OgrConnection* connection,
- OGRLayer* layer, FdoIdentifierCollection* props, bool bboxquery);
+ OGRLayer* layer, FdoIdentifierCollection* props, FdoFilter* filter);
protected:
OGR_API virtual ~OgrFeatureReader();
@@ -1038,18 +1038,22 @@
virtual FdoDataType GetDataType( FdoString* propertyName );
private:
+
+ virtual const FdoByte* GetGeometry(OGRGeometry* geom, FdoInt32* len);
+
OgrConnection* m_connection;
FdoIdentifierCollection* m_props;
OGRLayer* m_poLayer;
OGRFeature* m_poFeature;
+ FdoPtr<FdoIGeometry> m_geomFilter;
+ FdoSpatialOperations m_spatialOperation;
std::map<long, std::wstring> m_sprops;
unsigned char* m_fgf;
unsigned char* m_wkb;
size_t m_fgflen;
- bool m_bboxquery;
};
Index: OGRProvider.vcproj
===================================================================
--- OGRProvider.vcproj (revision 3962)
+++ OGRProvider.vcproj (working copy)
@@ -61,7 +61,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="fdo.lib fdocommon.lib fdogeometry.lib wsock32.lib gdal_i.lib xerces-c_2D.lib"
+ AdditionalDependencies="fdo.lib fdocommon.lib fdogeometry.lib wsock32.lib gdal_i.lib xerces-c_2D.lib fdospatial.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\Fdo\Unmanaged\lib\win32\Debug;"$(FDOGDAL)\lib\win32\Debug";..\..\Thirdparty\gdal\lib\win32\Debug;"..\..\Thirdparty\apache\xml-xerces\c\Build\Win32\VC8\Debug""
GenerateDebugInformation="true"
@@ -140,7 +140,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="fdo.lib fdocommon.lib fdogeometry.lib wsock32.lib gdal_i.lib xerces-c_2.lib"
+ AdditionalDependencies="fdo.lib fdocommon.lib fdogeometry.lib wsock32.lib gdal_i.lib xerces-c_2.lib fdospatial.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\Fdo\Unmanaged\lib\win32\release;"$(FDOGDAL)\lib\win32\Release";..\..\Thirdparty\gdal\lib\win32\release;"..\..\Thirdparty\apache\xml-xerces\c\Build\Win32\VC8\Release""
GenerateManifest="true"
More information about the fdo-internals
mailing list