03-21-2019 04:24 PM
I am currently using a SpatialSubsetPipe to reduce the size of recordset, but unfortunately in the process of doing that I get an "Out of Resources" error. When I watch the RAM allocated to my program it slowly rises to about 2.6G and then the filtering stops.
How can I prevent this from happening. Since GeoMedia is 32 bit I understand that the memory limitation is going to be 2G or 3G if they use LARGE ADDRESS but is there no internal memory management that can prevent this from occuring?
Many thanks for your help!!
Here is my code:
Dim SSPobj As PPipe.SpatialSubsetPipe Dim fRS As PClient.GRecordset SSPobj = CreateObject("Geomedia.SpatialSubsetPipe") SSPobj.InputRecordset = LargeRecSet SSPobj.InputGeometryFieldName = GeomFieldName SSPobj.FilterRecordset = SmallRecSet SSPobj.FilterGeometryFieldName = LineGeometryField SSPobj.SpatialOperator = PPipe.SQConstants.gmsqTouches SSPobj.OutputStatusFieldName = "output" fRS = SSPobj.OutputRecordset ' ********* RUN OUT OF RESOURCES WHEN PROCESSING HERE ******** If fRS.BOF And fRS.EOF Then End If
Solved! Go to Solution.
03-21-2019 06:27 PM
SpatialSubsetPipe is the pipe behind the Spatial Query command. It does a topological overlay of two recordsets, and that construction of topology has several side effects - it's computationally intense, it uses lots of memory, and it requires all input data to be processed before it can start handing out results.
Your circumstances may allow you to use SpatialFilterPipe instead. It constructs a spatial index for the single geometry value that is used as the spatial filter, and performs rapid comparison of each candidate geometry against that spatial filter with less overall computation, far less memory usage, and each feature/record is processed independently so there's no delay in accessing the first record of the output recordset.
Of course for this alternative to be useful to you, SSP must be able to perform the function you need - if you actually need to compare two recordsets, not just a recordset and a lone geometry, then SFP is what you need for sure. - Hal
03-22-2019 10:37 AM - edited 03-23-2019 05:04 AM
the SpatialFilterPipe does in this case the same as the SpatialFilter property from OriginatingPipe object. So I recommend to choose directly the solution with the OriginatingPipe object, if you use that anyway above (https://community.hexagongeospatial.com/t5/Developer-Discussions/How-to-create-a-Spatial-Filter-alon...). Otherwise you first load all data for the InputRecordset property of the SpatialFilterPipe.
If your recordset from FilterRecordset property (SmallRecSet) has more than one record, merge the geometries with a MergePipe and use this merged geometry as input for the SpatialFilter property. (As noticed in https://community.hexagongeospatial.com/t5/Developer-Discussions/How-to-create-a-Spatial-Filter-alon...)
If you only use the OriginatingPipe object that should be more performant. This approach should load minimal amount of data. But no guarantee that this will not lead in "Out of Resources" ... When this is the case, you should try to iterate trough every single record (or clusters of records). Whether it is possible depends on your process - I don't know which analysis you want to do ... This will not be fast, but doesn't required to much RAM.
03-25-2019 12:18 PM
Thank you Hal, Hesrah for your help!
So I have attempted to implemented a SpatialFilterPipe from the OriginatingPipe, but I am getting 0 results. Can you see what I am doing wrong!?! Many thanks for your help.
Dim PLGeom As New PBasic.PolylineGeometry Dim GSS As PClient.GeometryStorageService = CreateObject("Geomedia.GeometryStorageService") Dim GeomOut As Object Dim pt As PBasic.point For Each point As PathPoint In points pt = New PBasic.point pt.X = point.X pt.Y = point.Y pt.Z = point.Z PLGeom.Points.Add(pt) Next GSS.GeometryToStorage(PLGeom, GeomOut) '********* CREATE CONTOUR RECORD SET ***************** bathConnection.CreateOriginatingPipe(tmpPipe) tmpPipe.Table = ContourTableName tmpPipe.SpatialFilter = GeomOut tmpPipe.GeometryFieldName = "LinearGeometry" tmpPipe.SpatialOperator = PClient.GConstants.gdbTouches bRec = tmpPipe.OutputRecordset '********* RECORDSET IS EMPTY ************************ If bRec Is Nothing Then Exit Function If bRec.BOF And bRec.EOF Then Exit Function
03-25-2019 02:00 PM
I got it to work by creating a specific SpatialFilterPipe and not doing it from the OriginatingPipe. Not sure why this worked and the other way didn't?
Many thanks for your help!!
Dim PLGeom As New PBasic.PolylineGeometry Dim GSS As PClient.GeometryStorageService = CreateObject("Geomedia.GeometryStorageService") Dim GeomOut As Object Dim pt As PBasic.point For Each point As PathPoint In points pt = New PBasic.point pt.X = point.X pt.Y = point.Y pt.Z = point.Z PLGeom.Points.Add(pt) Next GSS.GeometryToStorage(PLGeom, GeomOut) '********* CREATE CONTOUR RECORD SET ***************** bathConnection.CreateOriginatingPipe(tmpPipe) tmpPipe.Table = ContourTableName 'tmpPipe.SpatialFilter = GeomOut 'REMOVED THIS LINE tmpPipe.GeometryFieldName = "LinearGeometry" 'tmpPipe.SpatialOperator = PClient.GConstants.gdbTouches 'REMOVED THIS LINE bRec = tmpPipe.OutputRecordset If bRec Is Nothing Then Exit Function If bRec.BOF And bRec.EOF Then Exit Function '********* CREATE SPATIAL FILTER PIPE ***************** Dim SFPobj As PDBPipe.SpatialFilterPipe SFPobj = CreateObject("Geomedia.SpatialFilterPipe") SFPobj.InputRecordset = bRec SFPobj.SpatialFilter = GeomOut SFPobj.SpatialOperator = PClient.GConstants.gdbTouches SFPobj.InputGeometryFieldName = "LinearGeometry" Dim FinalOutputRs As PClient.GRecordset FinalOutputRs = SFPobj.OutputRecordset
03-26-2019 02:33 AM
can't say, what's exactly the proplem with the OriginatingPipe.
You can try to set the OriginatingPipe properties in a different order. - It's not a programming issue it's a GeoMedia issue ...
E.g. set the GeometryFieldName property before SpatialFilter property. (I guess the SpatialFilter setter executes code that needs to run again after setting the GeometryFieldName property ... dirty internals ...)
03-26-2019 02:48 AM
the idea with OriginatingPipe filter is interesting, the problem is that you cannot use a linear geometry as a spatial filter in Originating pipe. But what you can try is to make a small buffer around your line and use that area as a spatial filter. If you use gdbTouches as the spatial operator, it should select the right geometries for your further analysis. You can create the buffer using BufferPipe object.
03-26-2019 03:50 AM
Ah, I didn't know/remember this restriction for the Spatial Filter property of an OriginatingPipe object.
@ adrianj: If you only want to reduce the amount of data with your polyline and don't need an exact spatial filter, you can pragmatically switch from a PolylineGeometry object to a PolygonGeometry object (don't forget to close the PolygonGeometry: first point == last point). So you don't need a BufferPipe object. But this pragmatic approach depends on the concrete situation of your data ...