MouseClick to Geometry

Topics: General Topics
Aug 16, 2006 at 11:24 AM
Is there a way to figure out witch shape is clicked when you click with the mouse on the mapImage control or is there an event that I can handle when the mouse moves over as shape?

this is what I tried but is doesn't seem to work.

code
Private Sub MapImage1_MouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MapImage1.MouseClick
If map IsNot Nothing Then
Dim point As SharpMap.Geometries.Point
point = map.ImageToWorld(New PointF(e.X, e.Y))
Dim prov As New SharpMap.Data.Providers.ShapeFile("map\4PPCmultivlak.shp", True)
For Each ge As SharpMap.Geometries.Geometry In prov.GetGeometriesInView(map.Envelope)
If point.Within(ge) Then
MessageBox.Show(layer.DataSource.GetFeature(ge.SRID)("PC4").ToString())
End If
Next

End If
End Sub
/code

I get a exception that I can't read from a closed datasource.

Kind regards,

Taipan
Developer
Aug 16, 2006 at 12:27 PM
Before calling prov.GetGeometriesInView be sure to call prov.Open() and remember to call .Close() when you are done.
Developer
Aug 16, 2006 at 12:28 PM
oh by the way... the relation-model is not complete in SharpMap, so calling .WithIn() will throw an exception in most cases.
Aug 16, 2006 at 1:24 PM
Thatone i found out myzelf :-)

I used the following code to get it all done:

first I applyed a Costom theme

Dim itheme As New SharpMap.Rendering.Thematics.CustomTheme(AddressOf getpostcodestyle)
Dim defaultstyle As New SharpMap.Styles.VectorStyle()
defaultstyle.Fill = Brushes.LightGray
itheme.DefaultStyle = defaultstyle
layer.Theme = itheme

In the getpostcodestyle function I store all geometry as a key in an hashtable with the information I need.

Private geometry As New Hashtable()

Private Function getpostcodestyle(ByVal row As SharpMap.Data.FeatureDataRow) As SharpMap.Styles.VectorStyle

geometry.Add(row.Geometry, row("PC4"))
Return Nothing
End Function


No the magic happens. In the onmouseclick event of the picturebox I get the world point from the map and use the point in polygon algorithm from http://alienryderflex.com/polygon/

Private Sub PictureBox1_MouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseClick
If map IsNot Nothing Then

Try


Dim point As SharpMap.Geometries.Point
point = map.ImageToWorld(New PointF(e.X, e.Y))

For Each ge As SharpMap.Geometries.Geometry In geometry.Keys
If TypeOf ge Is MultiPolygon Then
Dim p As MultiPolygon = DirectCast(ge, MultiPolygon)
For Each p1 As Polygon In p.Polygons
If pointinpolygon(p1, point) Then
MessageBox.Show(geometry(ge).ToString())
Exit Sub
End If
Next
ElseIf TypeOf ge Is Polygon Then
If pointinpolygon(DirectCast(ge, Polygon), point) Then
MessageBox.Show(geometry(ge).ToString())
Exit Sub
End If
End If
Next
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End If
End Sub

And the algorithm:

Private Function pointinpolygon(ByVal poly As Polygon, ByVal point As SharpMap.Geometries.Point) As Boolean
Dim polySides As Integer = poly.ExteriorRing.NumPoints
Dim ver As List(Of SharpMap.Geometries.Point) = poly.ExteriorRing.Vertices
Dim oddNodes As Boolean = False


Dim i, j As Integer
j = 0
For i = 0 To polySides - 1
j += 1
If j = polySides Then
j = 0
End If
If ((ver(i).Y < point.Y) And (ver(j).Y >= point.Y)) Or ((ver(j).Y < point.Y) And (ver(i).Y >= point.Y)) Then
If ver(i).X + (point.Y - ver(i).Y) / (ver(j).Y - ver(i).Y) * (ver(j).X - ver(i).X) < point.X Then
oddNodes = Not oddNodes
End If
End If
Next
Return oddNodes
End Function

I don't know if this functionality is already buildin but this solution works for me.
Sep 14, 2006 at 10:57 AM
"Point-In-Polygon Algorithm " that's what i am looking for~~~
i use the ExecuteIntersectionQuery method to get the unique polygone i clicked, but it it return much more than expected,so i have to find a "Point-In-Polygon Algorithm " to filter them:)
Sep 25, 2006 at 4:41 PM
Hello,

I am new to SharpMap, but i have developped my own mapServer for one of my client. Here is the code I to know if a point is inside a polygon or not :

//in this function the word this, make reference tio a polygon object
public Inside(Point myShape)
{
int Counter = 0;
Point P1;
Point P2;
double xinters;


P1 = this.Points.Item(this.Points.Count - 1);
for (int i = 0; i < this.Points.Count; i++)
{
P2 = this.Points.Item(i);
if (myShape.Y >= Math.Min(P1.Y, P2.Y))
{
if (myShape.Y <= Math.Max(P1.Y, P2.Y))
{
if (myShape.X <= Math.Max(P1.X, P2.X))
{
if (P1.Y != P2.Y)
{
xinters = (myShape.Y - P1.Y) * (P2.X - P1.X) / (P2.Y - P1.Y) + P1.X;
if ((P1.X == P2.X) || (myShape.X <= xinters))
{
Counter++;
}
}
}
}
}
P1 = P2;
}

if (Counter % 2 == 0)
return false; ////insidePolygon = OUTSIDE
else
return true; ////insidePolygon = inside
}

If you need the touch function let me know

Gaetan
Jun 28, 2008 at 7:04 AM

hi ggingras

This is neoo.You have done a good job.I am facing a problem to show information of a polygon or go to different page when user click on it on webpage.Could u please help me .I am using 

sharpmap v0.9 and shapfile.

Tanks in advance

 

Developer
Jul 2, 2008 at 3:22 AM
you should use function FindGeoNearPoint(....). You can find it here: http://www.codeplex.com/SharpMap/Thread/View.aspx?ThreadId=25449
Nov 30, 2008 at 5:29 AM
Hi, mrTaipan
There is no Polygon as a Data type in VB.Net. What is this data type you used in "Private Function pointinpolygon(ByVal poly As Polygon, ByVal point As SharpMap.Geometries.Point) As Boolean" ?

Thanks
Coordinator
Nov 30, 2008 at 8:48 PM
Hi nemesis52, mrTaipan is referring to SharpMap.Geometries.Polygon hth jd