Drawing and Spatial Filtering

This page demonstrates drawing shapes on the map and perform a spatial search for features within the drawn area. Click the "Draw" () button to draw a freehand area of interest.


Here is the server-side code to check if a point is within the polygon drawn on the map.


  ''' <summary>
  ''' Retrieve list of points of interest for a given geometry boundary.
  ''' </summary>
  ''' <param name="geometry"></param>
  ''' <returns></returns>
  ''' <remarks></remarks>
  <WebMethod>
  Public Shared Function GetPointsOfInterest(ByVal geometry As FeatureGeometry) As List(Of PointOfInterest)
    Dim points As New List(Of PointOfInterest)

    ' Coordinates contains an array of XY values
    Dim coordinates As Object() = geometry.coordinates(0)

    Dim dc As New Controllers.PointsOfInterestController()
    Dim dt As DataTable = dc.GetPOIData()

    Dim nwLng As Double = Double.MinValue, seLng As Double = Double.MinValue, nwLat As Double = Double.MinValue, seLat As Double = Double.MinValue

    ' Get bounding box of polygon to use for quick filtering
    For i As Integer = 0 To coordinates.Length - 1
      Dim lng As Double = coordinates(i)(0)
      Dim lat As Double = coordinates(i)(1)

      If nwLng = Double.MinValue OrElse nwLng > lng Then nwLng = lng
      If nwLat = Double.MinValue OrElse nwLat < lat Then nwLat = lat
      If seLng = Double.MinValue OrElse seLng < lng Then seLng = lng
      If seLat = Double.MinValue OrElse seLat > lat Then seLat = lat
    Next


    ' Find rows within polygon extent
    Dim filterExpression As String = String.Format("X >= {0} AND X <= {1} AND Y <= {2} AND Y >= {3}", nwLng, seLng, nwLat, seLat)
    Dim matchRows As DataRow() = dt.Select(filterExpression)

    For Each row As DataRow In matchRows
      Dim pt As Double() = {row("X"), row("Y")}

      If isPointInPoly(coordinates, pt) Then

        Dim point As New PointOfInterest()
        point.ID = row("ID")
        point.Name = row("NAME")
        point.Category = row("CATEGORY")
        point.Color = row("COLOR")
        point.Lat = row("Y")
        point.Lng = row("X")

        points.Add(point)

      End If
    Next

    dt.Dispose()
    dc.Dispose()

    Return points
  End Function
    
  ''' <summary>
  ''' See if point is inside of polygon
  ''' </summary>
  ''' <param name="pts">Polygon coordinates XY array</param>
  ''' <param name="pt">Point XY array</param>
  ''' <returns></returns>
  ''' <remarks></remarks>
  Private Shared Function isPointInPoly(ByVal pts As Object(), ByVal pt As Double()) As Boolean
    Dim isInside As Boolean = False

    Dim nvert As Integer = pts.Length
    Dim testy As Double = pt(1), testx As Double = pt(0)
    Dim i As Integer = 0, j As Integer = nvert - 1

    For i = 0 To nvert - 1

      If (((pts(i)(1) > testy) <> (pts(j)(1) > testy)) AndAlso _
          (testx < (pts(j)(0) - pts(i)(0)) * (testy - pts(i)(1)) / (pts(j)(1) - pts(i)(1)) + pts(i)(0))) Then
        isInside = Not isInside
      End If

      j = i

    Next

    Return isInside
  End Function