This project is read-only.

Intersects method problem

Jul 12, 2012 at 4:38 PM

Dear all

 

I am finding some trouble working with the intersect method to see if a point (coordinate) is inside a polygon shape.

I implemented a code same as described in 

http://dotspatial.codeplex.com/wikipage?title=PointInPolygonCS&referringTitle=Desktop_SampleCode

to create my own "info" tool.

It usually works but it happens in some occasion that it does not get the intersection with the feature I am clicking to.

While I can get the info when using the dotspatial.controls.functionmode.info, in some places of my shapefile I cannot get any information.

The strange thing is that  within the same shape in some part of it I get it working, in others not.

I guess that the dotspatial.controls.functionmode.info uses the same algorithm in the example linked above to get the intersected shape. Am I wrong? Any suggestion?

 

Thank you

Oscar 

Jul 13, 2012 at 9:59 AM
Edited Jul 13, 2012 at 10:40 AM

Also the functionmode.info does not work

I cannot get rid of this problem, in some shapes there are small areas in which the intersects method does not give the correct response

I noticed that after using the open attribute table, the functionmode.info works correctly

Has anyone of you noticed the same problem?

Oscar

Jul 13, 2012 at 8:04 PM
Edited Jul 13, 2012 at 8:09 PM

This is the code I pulled out of MapFunctionIdentify...

                    var gfl = layer as IMapFeatureLayer;
                    if (gfl != null)
                    {
                        if (gfl.DataSet.FeatureType == FeatureType.Polygon)
                        {
                            _frmFeatureIdentifier.Add(gfl, strict);
                        }
                        else
                        {
                            _frmFeatureIdentifier.Add(gfl, tolerant);
                        }
                    }


Then, I looked at FeatureIdentifier.cs inside         public virtual void Add(IFeatureLayer layer, Extent bounds)
There is different treatment based on whether Attributes are populated...
List result = layer.DataSet.Select(bounds); foreach (IFeature feature in result) { DataRow dr = null; if (!layer.DataSet.AttributesPopulated) { int fid; if (feature.ShapeIndex != null) fid = layer.DataSet.ShapeIndices.IndexOf(feature.ShapeIndex); else fid = feature.Fid; using (DataTable dt = layer.DataSet.GetAttributes(fid, 1)) { if ((dt != null) && (dt.Rows.Count > 0)) dr = layer.DataSet.GetAttributes(fid, 1).Rows[0]; } feature.DataRow = dr; } else { dr = feature.DataRow; }
Jul 14, 2012 at 8:19 AM
Edited Jul 14, 2012 at 8:20 AM

Hi Mudnug

thank you for your answer.

However, yesterday, following the instructions at http://alienryderflex.com/polygon/

i made myself a routine for controlling if a point lies within a polygon shape. 

 

    Public Function pointInPolygon(ByVal shape As ShapeRange, ByVal coord As Coordinate) As Boolean
        Dim polysides As Integer
        Dim polyX(), polyY(), x, y As Double
        Dim part As PartRange
        Dim vert As Vertex
        x = coord.X
        y = coord.Y

        polysides = 0
        For Each part In shape.Parts
            polysides = polysides + part.NumVertices
        Next
        Dim i As Integer
        Dim j As Integer = polysides - 1
        ReDim polyX(polysides)
        ReDim polyY(polysides)

        i = 0
        Dim oddNodes As Boolean = False
        Dim nodes As Integer

        If shape.Extent.MaxY >= y And shape.Extent.MinY <= y Then
            For Each part In shape.Parts
                For Each vert In part
                    polyX(i) = vert.X
                    polyY(i) = vert.Y
                    i = i + 1
                Next
            Next

            nodes = 0
            For i = 0 To polysides - 1

                If ((polyY(i) < y And polyY(j) >= y) Or (polyY(j) < y And polyY(i) >= y)) And (polyX(i) <= x Or polyX(j) <= x) Then
                    If (polyX(i) + (y - polyY(i)) / (polyY(j) - polyY(i)) * (polyX(j) - polyX(i)) < x) Then
                        nodes = nodes + 1
                    End If
                End If
                j = i
            Next
            If nodes Mod 2 <> 0 Then
                oddNodes = True
            End If
        End If
        Return oddNodes
    End Function

 

Basically, the trick is to search for intersection between the orizontal line passing by the searching point and the borders of the polygon shape. If the number of intersections occurring either to the left or to the right is odd, then the point is inside the shape, otherwise it lies outside.

In the code above I avoid to make any computation if the shape Y extent is above or below the orizontal line passing by the searching point.

The above routine solved my problem efficiently. I guess it might be computationally demanding if one has to search thousands of points, but for a simple identifier it works fine.

Thank you

Oscar