problem with spatial queries

2929
11
02-09-2011 10:02 AM
LisaT
by
Occasional Contributor III
Hi,
My company just changed my computer and my program is now having problems performing spatial queries.  Old computer had 9.3sp1 and new computer has 9.3.1.  I am intersecting a point with lines and returning a selectionset.  On the old computer, I might get a selectionset of 2 features.  On the new computer I will get 1.  The program is a COM tool using ArcObjects in ArcMap.  I still have access to my old computer, so I have been able to test THE SAME program on both computers and check my debug output for features returned.  Any ideas on what could be going on?  Snap tolerance in ArcMap is set the same...anything else I should check?

Another tidbit is that if I run debug/compile the program on the new computer then I cannot download using an .msi on a 3rd computer without having these issues.  However, If I compile the SAME program on my old computer & download on the same 3rd computer, no problems! ALL esri dependencies are removed from the references because I am assuming that the user has ArcMap and the needed dlls.  THE 3rd COMPUTER HAS 9.3sp1.

Any help would be appreciated.  In addition, it seems that there is not as much traffic in these forums since the new format was introduced...anyone have suggestions to another forum where I may ask questions?
0 Kudos
11 Replies
NeilClemmons
Regular Contributor III
Sounds like a spatial reference issue.  If your code that performs the spatial query is not accounting for differences in coordinate systems then you may get incorrect query results.  An example of how this can happen is this:  your map's coordinate system is different than that of the layer you're querying.  Your code takes an envelope sketched by the user as the query geometry.  That envelope will have the same coordinate system as the map so if you don't project that envelope into the layer's coordinate system you may get incorrect results.

As for deploying to other computers - you can only deploy to computers that are running the same version of ArcGIS (including service pack) as the computer on which you compiled the code.  In some cases (but not all) you can deploy to computers that are running a higher version.
0 Kudos
LisaT
by
Occasional Contributor III
Thanks for your quick response!
OK, I have changed the point to "snaptospatialreference" of the layer I am querying, which seems to help a lot.  However, I am still having a bit of the issue.  It seems that when the selectionset does not have a line, it is because the point does not intersect a vertex on the line.  I need to be able to pull all lines that the point intersects, even if there is not currently a vertex there!  My code will actually split the line at that point...but I need to get the line first!

Here is the code:
            ISpatialFilter pSelSetFilter = new SpatialFilterClass();
            pSelSetFilter.Geometry = myPoint;
            pSelSetFilter.GeometryField = "SHAPE";
            pSelSetFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

            ISelectionSet pSelSet = lineFeatureClass.Select(pSelSetFilter, esriSelectionType.esriSelectionTypeIDSet, esriSelectionOption.esriSelectionOptionNormal, pWSOut);

Anything that I need to do differently??  

Also, for a little more background, the point is actually the "fromPoint" of a line.  I have the lines snapping to line, vertex, and end.  So, the "fromPoint" should be snapped to the line I am trying to get.  When I zoom in, I do not see any gap between the line endpoint (frompoint) and the line it is touching (the one I am trying to get).
0 Kudos
NeilClemmons
Regular Contributor III
Using a point as a selection geometry is not your best bet.  If you were selecting polygons then it wouldn't be much of a problem but to select lines or points the point coordinates must match exactly or nothing will be returned.  For instance, if the coords of your point are 1.0, 1.0 and the nearest point on the line you're trying to select has coords 1.00000001, 1.00000001 then it won't select it because those points aren't the same.  Try using a small tolerance to buffer your point and use the resulting buffer polygon as your search geometry.  I would recommend using ArcMap's selection tolerance to buffer your point.  You can use ITopologicalOperator to buffer the point and use IMxDocument.SearchTolerance to get your buffer radius.  Note that SearchTolerance returns a value in map units, so if the map units differ from the units specified by the query layer's coordinate system you'll need to convert (use IUnitConverter interface).
0 Kudos
LisaT
by
Occasional Contributor III
Looks like this is working so far!  I'll keep testing and will post if I encounter any more problems.  The only thing different was that I had to create an IPointCollection = new MultiPointClass() and add the point in order to cast it to a topologicaloperator.

Thanks for your help!
0 Kudos
LornaMurison
Occasional Contributor
Hi,
Hopefully someone is still watching this thread...

I am having the exact same problem described here. I am trying to split a line fc at a point fc by using an esrispatialrelintersects spatial filter to find all lines intersecting with a point.
It appears that it is skipping over some lines that are a fraction of a millimetre away from intersecting the line. It occurred to me to use some kind of buffer, or tolerance when finding intersecting features, but I could really use some guidance in implementing this in VBA.
Both the feature classes and the data frame are all in the same projection (NAD83 UTM Zone 17N).
I have had a look at the ITopologicalOperator and IMxDocument.SearchTolerance interface/property as Neil suggested but am really at a loss as to how to implement it.

Here is the full code:
Thank-you

Private Sub SplitLineAtPoint_Click()

Dim pEditor As IEditor
Set pEditor = Application.FindExtensionByName("ESRI Object Editor")

If pEditor.EditState <> esriStateEditing Then
    MsgBox ("Start editing your line feature before proceeding...  ALSO - Make sure the lines you are editing are in a different workspace than your intersecting points.")
    Exit Sub
End If

Dim pEL As IEditLayers
Set pEL = pEditor

If pEL.CurrentLayer.FeatureClass.ShapeType <> esriGeometryPolyline Then
    MsgBox ("Target layer must be a line feature.")
    Exit Sub
End If

Dim pMxDoc As IMxDocument
Set pMxDoc = ThisDocument

Dim pMap As IMap
Set pMap = pMxDoc.FocusMap

Dim pPointL As IFeatureLayer
Set pPointL = pMap.Layer(0) 'point layer to split lines with

Dim pLineL As IFeatureLayer
Set pLineL = pMap.Layer(1) 'line layer to be split

Dim pLineFC As IFeatureClass
Set pLineFC = pLineL.FeatureClass

Dim pLineGDS As IGeoDataset
Set pLineGDS = pLineFC

Dim pPointFC As IFeatureClass
Set pPointFC = pPointL.FeatureClass 'point feature class to split lines with

Dim pPointCursor As IFeatureCursor
Set pPointCursor = pPointFC.Search(Nothing, False)

Dim pPointF As IFeature
Set pPointF = pPointCursor.NextFeature 'the point feature to split lines with

Dim pointCount As Integer
pointCount = 1
Debug.Print pointCount
Dim pointFeatureCount As Integer
pointFeatureCount = pPointFC.FeatureCount(Nothing)

Do Until pPointF Is Nothing
    Dim pPoint As IPoint
    Set pPoint = pPointF.Shape
    Dim pSF As ISpatialFilter
    Set pSF = New SpatialFilter

    With pSF
        Set .Geometry = pPoint
        .GeometryField = "Shape"
        .SpatialRel = esriSpatialRelIntersects
    End With
    
    Dim pLineCursor As IFeatureCursor
    Set pLineCursor = pLineFC.Search(pSF, False)
    
    Dim pLineF As IFeature
    Set pLineF = pLineCursor.NextFeature

    Do Until pLineF Is Nothing   ' <---- The problem lines don't get past this point
        Dim pPolyCurve As IPolycurve
        Set pPolyCurve = pLineF.Shape

        Dim pToPoint As IPoint
        Set pToPoint = pPolyCurve.ToPoint 'end point of the line

        Dim pFromPoint As IPoint
        Set pFromPoint = pPolyCurve.FromPoint  'start point of the line

        'Show something in status bar
        Dim pStatus As IStatusBar
        Set pStatus = Application.StatusBar
        pStatus.Message(0) = "Splitting at point:" & pointCount & "     " & ((pointCount / pointFeatureCount) * 100) & "% done"

        If (Round(pFromPoint.X, 6) = Round(pPoint.X, 6) And Round(pFromPoint.Y, 6) = Round(pPoint.Y, 6)) Then  'do nothing
        ElseIf (Round(pToPoint.X, 6) = Round(pPoint.X, 6) And Round(pToPoint.Y, 6) = Round(pPoint.Y, 6)) Then  'do nothing
        Else
            Dim pFeatureEdit As IFeatureEdit
            Set pFeatureEdit = pLineF
            pFeatureEdit.Split pPointF.Shape
            Debug.Print "split at point " & pointCount
        End If
        Set pLineF = pLineCursor.NextFeature
    Loop
    pointCount = pointCount + 1
    Set pPointF = pPointCursor.NextFeature
Loop

MsgBox ("Lines have been split at intersecting points..." & vbNewLine & vbNewLine & "SAVE Your EDITS before closing..")

End Sub
0 Kudos
NeilClemmons
Regular Contributor III
Something like this:

Do Until pPointF Is Nothing
    Dim pPoint As IPoint
    Set pPoint = pPointF.Shape
    Dim topoOp As ITopologicalOperator
    Set topoOp = pPoint
    Dim bufferPoly As IPolygon
    Set bufferPoly = topoOp.Buffer(pMxDoc.SearchTolerance)
    Dim pSF As ISpatialFilter
    Set pSF = New SpatialFilter

    With pSF
        Set .Geometry = bufferPoly
        .GeometryField = "Shape"
        .SpatialRel = esriSpatialRelIntersects
    End With
0 Kudos
LornaMurison
Occasional Contributor
Thank you so much for your quick reply,
The code worked.
But I am now finding another issue. I have been getting "split line will result in zero length polygon" errors and have found that these are happening where the point doesn't intersect with the line.
The code will find all intersecting lines for a point using searchtolerance, and then split all lines that do not have the same start or end point coordinates as the point.
In editor options, I have set the snapping tolerance to 0.01 map units (metres), but have found a point that is trying to split a line that is 2 metres away.
So my question is, where does the searchtolerance value come from?  It tells me it is 5.211... but I don't what the units are, or how pixels come in to play with vector data.

If you could explain this to me it would be highly appreciated.
Thank-you.
0 Kudos
NeilClemmons
Regular Contributor III
The search tolerance is a document property.  You set it in the options dialog (Selection menu->Options) - it affects such things as the Select Features tool, Identify tool, etc.  In many cases it's a good idea to use the search tolerance because it's something the user can change on their own but in your case you probably do want to use a tighter tolerance.  Also, I'm not sure if the snap tolerance will automatically be used when you split your line.  You may have to use IProximityOperator to get the actual point on the line and use that point in your split operation.
0 Kudos
LornaMurison
Occasional Contributor
I'm still not sure where the tolerance comes from, but I have managed, more or less, to get the code to work.
Right now the code loops through all points
loops through all lines intersecting the point within the tolerance (1 pixel)
gets the point on the line closest to the input point (iproximityoperator.returnnearestpoint)
if that point is within 0.001 meters of the line start or end point it gets ignored
else the line gets split
next line
next point

But now all of a sudden Set BufferPoly = pTopoOp.Buffer(pMxDoc.SearchTolerance) is giving my a type mismatch error and I am at a loss as to why.  It was working before and I really don't think anything in the code above that point has been changed.
Any suggestions are much appreciated.
Thanks

Do Until pPointF Is Nothing
    Dim pPoint As IPoint
    Set pPoint = pPointF.Shape
    Dim pTopoOp As ITopologicalOperator
    Set pTopoOp = pPoint
    Dim BufferPoly As esriGeometry.IPolygon
    Set BufferPoly = pTopoOp.Buffer(pMxDoc.SearchTolerance)
...


...I changed it to Set BufferPoly = pTopoOp.Buffer(0.5) and it works
0 Kudos