
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 1: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 1:28 PM

oh by the way... the relationmodel is not complete in SharpMap, so calling .WithIn() will throw an exception in most cases.



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.



"PointInPolygon 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 "PointInPolygon Algorithm " to filter them:)



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



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 4:22 AM

you should use function FindGeoNearPoint(....). You can find it here:
http://www.codeplex.com/SharpMap/Thread/View.aspx?ThreadId=25449



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 9:48 PM

Hi nemesis52, mrTaipan is referring to SharpMap.Geometries.Polygon hth jd

