iOS Question problem with polygon

enrfortin

Member
Licensed User
hi i have a problem with polygons,

i have this rare polygon
WhatsApp Image 2022-08-23 at 8.36.41 PM.jpeg

and i need know if i tocuh inside or outside of the polygon
in the most cases works


WhatsApp Image 2022-08-23 at 8.36.42 PM.jpeg
WhatsApp Image 2022-08-23 at 8.36.41 PM (1).jpeg



but if i touch (inner the polygone) in "barrio las palomas", "colonia ruben dario", "lomas del tepayac"

WhatsApp Image 2022-08-23 at 8.36.42 PM (1).jpeg
WhatsApp Image 2022-08-23 at 8.36.43 PM.jpeg


say in out on polygon area i tried in b4a and the same case,
if i make another polygon in other area i dont have this problem,
attach the code i using.


code:
Private Sub AddMap
    gmap.Initialize("gmap", ApiKey)
    Panel1.AddView(gmap, 0, 0, Panel1.Width, Main.pl)
    'gmap.MapType = gmap.MAP_TYPE_TERRAIN
    gmap.GetUiSettings.CompassEnabled = True
    'gmap.GetUiSettings.MyLocationButtonEnabled = True
    gmap.MyLocationEnabled = True
    
    'add three markers
    Dim m As Marker = gmap.AddMarker(40, 30, "test")
    m.Snippet = "Marker 1"
    m.Opacity = 0.5
    m = gmap.AddMarker2(42, 30, "Marker 2", Colors.Green)
'    gmap.AddMarker3(30, 30, "marker3", LoadBitmap(File.DirAssets, "up76.png"))
    gmap.AddMarker3(30, 30, "marker3", CreateBitmap("L1"))
    gextra.Initialize(gmap)
    gextra.SetGroundAnchor(m, 0.5, 0.5)
    'gextra.MapStyle(File.ReadString(File.DirAssets, "style.json"))
    Dim no As NativeObject = gmap
    no.SetField("selectedMarker", m)
    m.Draggable = True
'   
    'gmap.AddMarker3(20, 20, "ddd", LoadBitmap(File.DirAssets, "up76.png"))
'    'change the camera position
    Dim c As CameraPosition
    'c.Initialize(14.06669638968808, -87.17147916555405, 1)
    c.Initialize2(14.06669638968808, -87.17147916555405, 12, 315, 45)
    'c.Initialize2(32, 35, 2, 315, 45)
    gmap.AnimateCamera(c)
'   
'   
    gextra.SetMarkerRotation(m, 45)
    Dim ne, sw As LatLng
    'ne.Initialize(20, 20)
    'sw.Initialize(00, 00)
    Dim bounds As Object = gextra.CreateBounds(ne, sw)
    gextra.AddGroundOverlay(bounds, LoadBitmap(File.DirAssets, "up76_2.png"))
    gextra.SetSelectedMarker(m)
    ''    'add a polyline
    'zona norte
    pl = gmap.AddPolyline
    Dim l1, l2, l3, l4, l5, l6, l7,l8,l9,l10,l11,l12,l13,l14,l15,l16,l17,l18,l19,l20,l21,l22,l23,l24,l25,l26,l27,l28,l29,l30,l31,l32,l33,l34,l35,l36,l37,l38,l39,l40,l41,l42,l43,l44,l45 As LatLng
    l1.Initialize(14.10641, -87.18509)
    l2.Initialize(14.10477, -87.1803)
    l3.Initialize(14.1018, -87.17325)
    l4.Initialize(14.09861, -87.17669)
    l5.Initialize(14.09157, -87.16767)
    l6.Initialize(14.08954, -87.15815)
    l7.Initialize(14.08288, -87.1591)
    l8.Initialize(14.06841, -87.17158)
    l9.Initialize(14.07028, -87.17483)
    l10.Initialize(14.0713, -87.17765)
    l11.Initialize(14.07089, -87.18096)
    l12.Initialize(14.06748, -87.18909)
    l13.Initialize(14.07139, -87.1895)
    l14.Initialize(14.07074, -87.21288)
    l15.Initialize(14.06887, -87.21421)
    l16.Initialize(14.06225, -87.21816)
    l17.Initialize(14.04424, -87.21783)
    l18.Initialize(14.04794, -87.21323)
    l19.Initialize(14.0454, -87.21147)
    l20.Initialize(14.04921, -87.21151)
    l21.Initialize(14.05081, -87.20607)
    l22.Initialize(14.04778, -87.19796)
    l23.Initialize(14.0464, -87.1913)
    l24.Initialize(14.04494, -87.18766)
    l25.Initialize(14.04728, -87.18251)
    l26.Initialize(14.04207, -87.17736)
    l27.Initialize(14.03529, -87.20774)
    l28.Initialize(14.03685, -87.22522)
    l29.Initialize(14.03243, -87.22951)
    l30.Initialize(14.04557, -87.25051)
    l31.Initialize(14.04291, -87.26305)
    l32.Initialize(14.04798, -87.26468)
    l33.Initialize(14.04994, -87.25455)
    l34.Initialize(14.05757, -87.25687)
    l35.Initialize(14.0609, -87.24391)
    l36.Initialize(14.06215, -87.23662)
    l37.Initialize(14.06057, -87.22898)
    l38.Initialize(14.0625, -87.22047)
    l39.Initialize(14.06766, -87.21794)
    l40.Initialize(14.07224, -87.21368)
    l41.Initialize(14.07449, -87.21276)
    l42.Initialize(14.08923, -87.20517)
    l43.Initialize(14.10263, -87.20147)
    l44.Initialize(14.10354, -87.19821)
    l45.Initialize(14.10363, -87.19392)
    
    

    
    
    pl.Points = Array(l1, l2, l3, l4, l5, l6, l7,l8,l9,l10,l11,l12,l13,l14,l15,l16,l17,l18,l19,l20,l21,l22,l23,l24,l25,l26,l27,l28,l29,l30,l31,l32,l33,l34,l35,l36,l37,l38,l39,l40,l41,l42,l43,l44,l45,l1)
    gextra.ZoomToPoints(pl.Points)
    pl.Width = 5
    pl.Color = Colors.red
    
    polxa.Initialize
    polya.Initialize
    polxa.AddAll(Array As String ("14.10641","14.10477","14.1018","14.09861","14.09157","14.08954","14.08288","14.06841","14.07028","14.0713","14.07089","14.06748","14.07139","14.07074","14.06887","14.06225","14.04424","14.04794","14.0454","14.04921","14.05081","14.04778","14.0464", "14.04494","14.04728","14.04207","14.03529","14.03685","14.03243","14.04557","14.04291","14.04798","14.04994","14.05757","14.0609","14.06215","14.06057","14.0625","14.06766","14.07224","14.07449","14.08923","14.10263","14.10354","14.10363"))
    polya.AddAll(Array As String ("-87.18509","-87.1803","-87.17325","-87.17669","-87.16767","-87.15815","-87.1591","-87.17158","-87.17483","-87.17765","-87.18096","-87.18909","-87.1895","-87.21288","-87.21421","-87.21816","-87.21783","-87.21323","-87.21147","-87.21151","-87.20607","-87.19796","-87.1913","-87.18766","-87.18251","-87.17736","-87.20774","-87.22522","-87.22951","-87.25051","-87.26305","-87.26468","-87.25455","-87.25687","-87.24391","-87.23662","-87.22898","-87.22047","-87.21794","-87.21368","-87.21276","-87.20517","-87.20147","-87.19821","-87.19392"))
    'zona sur

    End Sub




Sub gmap_LongClick (Point As LatLng)
    Log(Point)
End Sub



Sub gmap_InfoWindowClick (SelectedMarker As Marker)
    Log("InfoWinsow clicked: " & SelectedMarker)
    
End Sub

Sub FindInZone( polx As List, poly As List, x As Double, y As Double) As Boolean
    ' polx = list of lats for polygon
    ' poly = list of lons for polygon
    ' y = lon to test
    ' x = lat to test

    Dim x1, y1, x2, y2, D As Double
    Dim i, ni As Int
 
    ni = 0
    x1 = polx.Get(0)
    y1 = poly.Get(0)
    For i = 0 To polx.Size -1
        If i < polx.Size Then
            x2 = polx.Get(i)
            y2 = poly.Get(i)
        Else
            x2 = polx.Get(0)     ' checks the last line
            y2 = poly.Get(0)
        End If
  
  
        If y >= Min(y1, y2) Then
            If y <= Max(y1, y2) Then
                If x <= Max(x1, x2) Then
                    If (x = x1 And y = y1) Or (x = x1 And x = x2) Then ' checks vertices and vertical lines
                        Return True
                    End If
                    If y1 <> y2 Then
                        D = (y - y1) * (x2 - x1) / (y2 - y1) + x1
                        If x1 = x2 Or x <= D Then
                            ni = ni + 1
                        End If
                    End If
                End If
            End If
        End If
        x1 = x2
        y1 = y2
    Next

    If ni Mod 2 = 0 Then
        Return False
    Else
        Return True
    End If
End Sub




Sub gmap_Click (Point As LatLng)
    Dim bounds As Object = gextra.GetVisibleBounds
    Dim ne_sw() As LatLng = gextra.GetBoundsNE_SW(bounds)
    Log(ne_sw(0))
    Log(ne_sw(1))
    

    If FindInZone(polxa,polya,Point.Latitude,Point.Longitude)=True   Then
        Log("dentro del poligono")
        hd.ToastMessageShow("dentro del poligono zona",False)   
Else
        Log("fuera de los poligonos")
        hd.ToastMessageShow("fuera de los poligonos",False)
    End If
    

    
End Sub

Thanks,
Regards!
 
Solution
I made a small test program with your coordinates to verify the calculation in Sub FindInZone.
The calculation is OK !

So the problem is somewhere else.
Therefore I checked further and I suspect that the problem is here:
If FindInZone(polxa,polya,Point.Latitude,Point.Longitude)=True
It should be:
If FindInZone(polxa,polya,Point.Longitude,Point.Latitude)=True
You should invert Latitude and Longitude.
X = Longitude
Y = Latitude

Attached my test program.

roumei

Active Member
Licensed User
I don't understand your algorithm for the point-in-polygon check but there seems to be problem with it. Try this:
B4X:
Sub FindInZone( polx As List, poly As List, x As Double, y As Double) As Boolean
    Dim piX, piY, pjX, pjY As Double
    Dim result As Boolean = False
    Dim j As Int = polx.Size - 1
    For i = 0 To polx.Size - 1
        piX = polx.Get(i)
        piY = poly.Get(i)
        pjX = polx.Get(j)
        pjY = poly.Get(j)
        If piY < Y And pjY >= Y Or pjY < Y And piY >= Y Then
            If piX + (Y - piY) / (pjY - piY) * (pjX - piX) < X Then
                result = Not(result)
            End If
        End If
        j = i
    Next
    Return result
End Sub
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I made a small test program with your coordinates to verify the calculation in Sub FindInZone.
The calculation is OK !

So the problem is somewhere else.
Therefore I checked further and I suspect that the problem is here:
If FindInZone(polxa,polya,Point.Latitude,Point.Longitude)=True
It should be:
If FindInZone(polxa,polya,Point.Longitude,Point.Latitude)=True
You should invert Latitude and Longitude.
X = Longitude
Y = Latitude

Attached my test program.
 

Attachments

  • TestPointInPolygon.zip
    10.5 KB · Views: 134
Upvote 1
Solution

enrfortin

Member
Licensed User
I made a small test program with your coordinates to verify the calculation in Sub FindInZone.
The calculation is OK !

So the problem is somewhere else.
Therefore I checked further and I suspect that the problem is here:
If FindInZone(polxa,polya,Point.Latitude,Point.Longitude)=True
It should be:
If FindInZone(polxa,polya,Point.Longitude,Point.Latitude)=True
You should invert Latitude and Longitude.
X = Longitude
Y = Latitude

Attached my test program.

thank you very much for taking your time to solve this question, changing latitude for long in the original project and it doesn't work, but I'm testing your project and it works perfect, I'll use it as a reference, regards.
 
Upvote 0

enrfortin

Member
Licensed User
I don't understand your algorithm for the point-in-polygon check but there seems to be problem with it. Try this:
B4X:
Sub FindInZone( polx As List, poly As List, x As Double, y As Double) As Boolean
    Dim piX, piY, pjX, pjY As Double
    Dim result As Boolean = False
    Dim j As Int = polx.Size - 1
    For i = 0 To polx.Size - 1
        piX = polx.Get(i)
        piY = poly.Get(i)
        pjX = polx.Get(j)
        pjY = poly.Get(j)
        If piY < Y And pjY >= Y Or pjY < Y And piY >= Y Then
            If piX + (Y - piY) / (pjY - piY) * (pjX - piX) < X Then
                result = Not(result)
            End If
        End If
        j = i
    Next
    Return result
End Sub
without results.
 
Upvote 0

enrfortin

Member
Licensed User
Have you checked the values of Point in Sub gmap_Click (Point As LatLng) ?
Put a breakpoint in there to see what happens.
1661436311627.png

yes, they are the correct values, that is, the expected ones
first its for gmap_CameraChange (Position As CameraPosition) (red)
white gmap_click
 
Upvote 0

enrfortin

Member
Licensed User
i change
I made a small test program with your coordinates to verify the calculation in Sub FindInZone.
The calculation is OK !

So the problem is somewhere else.
Therefore I checked further and I suspect that the problem is here:
If FindInZone(polxa,polya,Point.Latitude,Point.Longitude)=True
It should be:
If FindInZone(polxa,polya,Point.Longitude,Point.Latitude)=True
You should invert Latitude and Longitude.
X = Longitude
Y = Latitude

Attached my test program.
I changed in the function FindInZone polx, poly from the list type to the double type
and declared as it is in the example you sent me
Dim n = 45 As Int
Dim px(n) As Double
Dim py(n) As Double
and initialize InitPolygone1 and works perfect!
i think maybe
the problem was the floating point of the coordinate I see that in the function it is divided by 2 and if the mod is 0 it takes it outside the polygon
Perhaps in those specific points that condition was met but being able to evaluate more decimals does not
(is what I think),
Thank you very much for answering and solving this.
 
Upvote 0
Top