Developer Discussions

Discuss topics with other Hexagon Geospatial Power Portfolio developers and experts to get the most out of our products.
Showing results for 
Search instead for 
Do you mean 
Reply
Highlighted
Contributor
Posts: 39
Registered: ‎11-02-2017
Accepted Solution

How to create a Spatial Filter along a multi-point line

Hello,

 

I am trying to find all crossings between a line of about 20 points and a database of contours which is very large. The problem is that it takes a really long time and usually runs out of resources in the process. I don't need to compare the whole contour database just locally where the path is crossing it. So, I was trying to apply a spatial filter to the database before finding the crossings but there is no examples online. How do I apply a spatial filter to a large recordset about a multipoint line? Could somebody give me an idea of how to do it?

 

This is my example code which runs out of resources and takes forever to run:

 

'********* CREATE LINE RECORD SET *****************
Dim tmpPipe As PClient.OriginatingPipe
Dim lnRS As PClient.GRecordset
_connection.CreateOriginatingPipe(tmpPipe)
tmpPipe.Table = Common.CommonConstants.PathLineFeatureName
tmpPipe.Filter = Common.CommonConstants.LineIndexString & " >= " & CStr(startPtIndex) & " AND " & Common.CommonConstants.LineIndexString & " <= " & CStr(lastPtIndex)

lnRS = tmpPipe.OutputRecordset
If lnRS Is Nothing Then Exit Function
If lnRS.BOF And lnRS.EOF Then Exit Function

tmpPipe = Nothing

'********* CREATE CONTOUR RECORD SET *****************
bathConnection.CreateOriginatingPipe(tmpPipe)
tmpPipe.Table = bathClass.GetTableName
bRec = tmpPipe.OutputRecordset

If bRec Is Nothing Then Exit Function
If bRec.BOF And bRec.EOF Then Exit Function

Dim sqp As PPipe.SpatialIntersectionPipe

'********* SEARCH FOR CROSSINGS *****************
sqp = CreateObject("Geomedia.SpatialIntersectionPipe")

sqp.LeftRecordset = bRec
sqp.RightRecordset = lnRS

sqp.LeftGeometryFieldName = bathyGeomFldName
sqp.RightGeometryFieldName = LineGeometryField
sqp.SpatialOperator = PPipe.SQConstants.gmsqOverlap

sqp.OutputGeometryFieldName = OverlapDerivedGeom
sqp.OutputStatusFieldName = "SIP_Status"

'**** This takes a really long time and usually runs out of resources!! ****
If Not (sqp.EOF And sqp.BOF) Then
End If

Many thanks!!!

 

 

Highlighted
Regular Contributor
Posts: 226
Registered: ‎05-25-2016

Re: How to create a Spatial Filter along a multi-point line

Hi adrianj

 

The OriginatingPipe object has the property SpatialFilter where you can set a Geometry BLOB as spatial filter. See the (on- or offline) documentation of this property.

 

Best regards,

hesrah

Highlighted
Contributor
Posts: 39
Registered: ‎11-02-2017

Re: How to create a Spatial Filter along a multi-point line

Hi Hesrah,

 

Thank you for the message. Unfortunately, there appears to be very little information about how to set up a Geometry BLOB as a spatial filter. That is my whole problem. Do you happen to have any example code, or can point me in the direction of where I can find something useful? 

 

I would really like to generate a spatial filter around my multipoint line of perhaps a fixed width. Is it possible to generate such as BLOB, or does it have to be a rectangle?

 

Many thanks for your help

 

Adrian

 

Highlighted
Contributor
Posts: 39
Registered: ‎11-02-2017

Re: How to create a Spatial Filter along a multi-point line

Hello,

 

Few people write a follow-up to their question when they get an answer which often makes these online forums useless, so here is the solution that works for me, in case it will help anybody else who is looking for something similar!!

 

I can use a SpatialSubsetPipe. Here is an example piece of code:

 

		
'********* CREATE LINE RECORD SET *****************
Dim tmpPipe As PClient.OriginatingPipe
Dim lnRS As PClient.GRecordset
_connection.CreateOriginatingPipe(tmpPipe)
tmpPipe.Table = Common.CommonConstants.PathLineFeatureName
tmpPipe.Filter = Common.CommonConstants.LineIndexString & " >= " & CStr(startPtIndex) & " AND " & Common.CommonConstants.LineIndexString & " <= " & CStr(lastPtIndex)
 
lnRS = tmpPipe.OutputRecordset
If lnRS Is Nothing Then Exit Function
If lnRS.BOF And lnRS.EOF Then Exit Function
 
tmpPipe = Nothing
 
'********* CREATE CONTOUR RECORD SET *****************
bathConnection.CreateOriginatingPipe(tmpPipe)
tmpPipe.Table = bathClass.GetTableName
bRec = tmpPipe.OutputRecordset
 
If bRec Is Nothing Then Exit Function
If bRec.BOF And bRec.EOF Then Exit Function
 
Dim sqp As PPipe.SpatialIntersectionPipe
 
'****************************************************
'*****************NEW CODE START*********************
'****************************************************
lnRS.MoveFirst() 'Needed to reset the cache if you have used the recordset
bRec.MoveFirst()

Dim SSPobj As PPipe.SpatialSubsetPipe
Dim fRS As PClient.GRecordset
SSPobj = CreateObject("Geomedia.SpatialSubsetPipe")
SSPobj.InputRecordset = bRec
SSPobj.InputGeometryFieldName = bathyGeomFldName
SSPobj.FilterRecordset = lnRS
SSPobj.FilterGeometryFieldName = Common.CommonConstants.LineGeometryField
SSPobj.SpatialOperator = PPipe.SQConstants.gmsqTouches
SSPobj.OutputStatusFieldName = "output"

fRS = SSPobj.OutputRecordset
If fRS Is Nothing Then
End If
If fRS.BOF And fRS.EOF Then
End If
'****************************************************
'******************NEW CODE END**********************
'****************************************************
 
'********* SEARCH FOR CROSSINGS *********************
'** THIS CODE IS KIND OF REDUNDANT BECAUSE THE FILTERING
'** ABOVE DOES THE SAME THING!
sqp = CreateObject("Geomedia.SpatialIntersectionPipe")
 
sqp.LeftRecordset = fRS
sqp.RightRecordset = lnRS
 
sqp.LeftGeometryFieldName = bathyGeomFldName
sqp.RightGeometryFieldName = LineGeometryField
sqp.SpatialOperator = PPipe.SQConstants.gmsqOverlap
 
sqp.OutputGeometryFieldName = OverlapDerivedGeom
sqp.OutputStatusFieldName = "SIP_Status"
 
'**** This takes a really long time and usually runs out of resources!! ****
If Not (sqp.EOF And sqp.BOF) Then
End If

 

 

Highlighted
Regular Contributor
Posts: 226
Registered: ‎05-25-2016

Re: How to create a Spatial Filter along a multi-point line

[ Edited ]

Hi adrianj,

 

to your question above and to make this forum even more useful Cat Wink

 

Both approaches works. The main difference is the form in which your spatial filter geometry enters the process.

 

Use an OriginatingPipe object if you have one single geometry value (from one (1) record or created by code).

Use a SpatialSubsetPipe if you just have a RecordSet object for your spatial filter geometry.

 

Here are the steps to create a single geometry value by code, and use it for the SpatialFilter property of an OriginatingPipe object:

  1. Create the geometry object. You can use every type of geometry (you find a list of geometry types here: https://hgdsupport.hexagongeospatial.com/API/GeoMedia/Building%20on%20the%20GeoMedia%20Engine/#geome...).
  2. Fill the geometry object with values (points etc., depends on the geometry object type).
  3. Convert the geometry object in a geometry BLOB: Use the method GeometryToStorage of the GeometryStorage object.
  4. Assign the BLOB to the SpatialFilter property of the OriginatingPipe object. And set the SpatialOperator Property of the OriginatingPipe object as you need.

I guess, this version is more performant as the SpatialSubsetPipe (but never know with GeoMedia Cat LOL). But, if your spatial filter geometry already stored in a data table, it's easier to use a SpatialSubsetPipe object.

 

Notice: You can transform each approach into the other. Merge all geometries from the RecordSet object to one single geometry value which you can use as BLOB (use a MergePipe object). Or for the other direction, store the Geometry BLOB in a RecordSet object (you can do this with an "in-memory-recordset"; is a bit awkward but works).

 

Regards,

hesrah