Android Question CallSub2 Sub not found

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Calling a Public Sub in a class from another class:

B4X:
private Sub touchInShape(aX As Double, aY As Double) As Map
    
    Dim m As Map
    Dim p As TMapPoint = MapUtilities.initPoint(aX, aY)
    Dim tLL As TMapLatLng = PointToLatLng(p)

    m.Initialize

    For Each oKey As Object In fMap.fShapes.Keys
        Dim oItem As Object = fMap.fShapes.Get(oKey)
        If CallSub2(oItem, "PointInShapeX", tLL) Then '<<<<<<<<< error Sub not found here
        'If CallSub2(oItem,"PointInShape", p) Then
            m.Put(oKey, oItem)
        End If
    Next
    Return m
End Sub

This is the code in the other class being called:

B4X:
'return true if type LatLng is in shape
Public Sub PointInShapeX(tLL As TMapLatLng) As Boolean
    
    'to do a quick and simple check first
    Dim BB As TMapBoxLatLng = BoundingBox2(fShape)
    If (tLL.fLat > BB.fLeftTop.fLat) Or (tLL.fLat < BB.fRightBottom.fLat) Or _
        (tLL.fLng > BB.fRightBottom.fLng) Or (tLL.fLng < BB.fLeftTop.fLng) Then
        Return False
    End If
    
'    'http://geomalgorithms.com/a03-_inclusion.html
'    '2012 Dan Sunday
'    '---------------------------------------------

    Dim i As Int
    Dim wn As Int
    Dim iUBound As Int
    Dim tLL1 As TMapLatLng
    Dim tLL2 As TMapLatLng
    
    iUBound = fShape.fLatLng.Size - 1

    For i = 0 To iUBound - 1 '- 1 as we do i + 1
        tLL1 = fShape.fLatLng.Get(i)
        tLL2 = fShape.fLatLng.Get(i + 1)
        If tLL1.flng <= tLL.fLng Then
            If tLL2.flng > tLL.fLng Then
                If IsLeft(tLL1, tLL2, tLL.fLat, tLL.fLng) Then
                    wn = wn + 1
                End If
            End If
        Else
            If tLL2.flng <= tLL.fLng Then
                If IsLeft(tLL1, tLL2, tLL.fLat, tLL.fLng) = False Then
                    wn = wn - 1
                End If
            End If
        End If
    Next
    
    Return wn <> 0
    
End Sub

It compiles fine, but get this error:

cvmap_touchinshape (java line: 1764)
java.lang.Exception: Sub pointinshapex was not found.
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:219)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:1082)
at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:1037)
at b4a.sqlitelight1.cvmap._touchinshape(cvmap.java:1764)
at b4a.sqlitelight1.cvmap._fviewtouch_touch(cvmap.java:813)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
at anywheresoftware.b4a.BA$1.run(BA.java:352)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8633)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1133)

When I call another Sub in the same class that has Public Sub PointInShapeX it all runs fine.
That other Sub is very similar and this is the code of that Sub:

B4X:
'return true if point is in shape
Public Sub PointInShape(aPoint As TMapPoint) As Boolean
    
    'https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html
    
    'to do a quick and simple check first
    Dim r As B4XRect = BoundingBox(fShape)
    If (aPoint.fX < r.left) Or (aPoint.fX > r.Right) Or (aPoint.fY < r.Top) Or (aPoint.fY > r.Bottom) Then
        Return False
    End If

    Dim bInside As Boolean
    Dim i As Int
    Dim j As Int = fShape.fLatLng.size - 1
    
    For i = 0 To fShape.fLatLng.Size - 1
        Dim pti As TMapPoint = fcvMap.LatLngToPoint(fShape.fLatLng.Get(i))
        Dim ptj As TMapPoint = fcvMap.LatLngToPoint(fShape.fLatLng.Get(j))
        If ((pti.fy > aPoint.fY) <> (ptj.fy > aPoint.fY)) And _
            (aPoint.fX < (ptj.fX - pti.fX) * (aPoint.fY - pti.fY) / (ptj.fy - pti.fY) + pti.fX) Then
            bInside = Not(bInside)
        End If
        j = i
    Next
    
    Return bInside
    
End Sub

Can't understand this at all.
Any ideas?

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
After that test, DummyPolygon, I'm not so sure about that.

Try another test: change the name of the "working sub", PointInShape, to something like "NewPointInShape" (and the calls to it).
That errors, Sub not found.
That is what I kind of expected, but then why PointInShape is fine??

RBS
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
This comment may not help but this problem seems to have all the hallmarks of what will turn out to be a simple problem that looks complicated because of a wrong assumption making you look in the wrong place. Either that or you have found a very subtle bug in B4A. Possible but Occam's Law says unlikely. Can you post something that shows the problem?

By the way. I have checked the Java source code in for raiseEvent2 in B4AShared.jar and it means that the Sub name is not found in the hash table of Subs implemented by that class so it looks like it is really not there. Have you carefully checked spellings?
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
If you are sure that you made this last change in the same class you added DummyPolygon to, try changing the packagename at this point.

I think the solution of this problem must be to add the same Sub PointInShape to the clsmapshapecircle class as well.
No need I think to add to the clsMapShapeLine class.
Will try this in a bit.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
This comment may not help but this problem seems to have all the hallmarks of what will turn out to be a simple problem that looks complicated because of a wrong assumption making you look in the wrong place. Either that or you have found a very subtle bug in B4A. Possible but Occam's Law says unlikely. Can you post something that shows the problem?

By the way. I have checked the Java source code in for raiseEvent2 in B4AShared.jar and it means that the Sub name is not found in the hash table of Subs implemented by that class so it looks like it is really not there. Have you carefully checked spellings?
The Sub is definitely in the Polygon class, but not in the circle class or the line class and I think that is the problem.
The question to me is why does it work if I call the Sub PointInShape?

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
It is a very big project and I think I have crux of the problem now.

RBS
Eureka!!
agraham was absolutely right!
clsMapShapeCircle and also clsMapShapeLine do have a Sub called PointInShape!
So, it looks, all I have to do is rename these as well.
Will try that now.
Lesson is, don't do these complex things while watching football.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
C'è una sola soluzione: mandaci il progetto 😄 (use Google translator)
This is how the calling Sub is now and all working perfectly fine.

B4X:
Private Sub touchInShape(aX As Double, aY As Double) As Map
    
    Dim m As Map
    Dim p As TMapPoint = MapUtilities.initPoint(aX, aY)
    
    m.Initialize

    For Each oKey As Object In fMap.fShapes.Keys
        Dim oItem As Object = fMap.fShapes.Get(oKey)
        If oKey = "MapArea" Then
            'this will be a polygon
            Dim tLL As TMapLatLng = PointToLatLng(p)
            If CallSub2(oItem, "PointIn_ShapeX", tLL) Then
                m.Put(oKey, oItem)
            End If
        Else
            'this will be a circle or line
            If CallSub2(oItem, "PointInShape", p) Then
                m.Put(oKey, oItem)
            End If
        End If
    Next

    Return m
    
End Sub

RBS
 
Upvote 0
Top