I have written a system for plotting cargo units GPS positions (through GSM SMS) on a map, but now I want to add some features to the system. For instance, if a unit hasn't reached zone x withing given timelimit, I'll generate an alert.

So, letting the customers define theese zones on the map requires a fair amount of map-event coding, which I've zero experience of. Why not ask if any of you guys have some sample code for this purpouse to share, right ! ;-) Rectangle areas is sufficient in my case.

Much apprechiated...

/Smuts

SoulSolutions

Usually with tracking applications these alerts are generated server side as the data streams in from the unit (or sometimes the units themselves do it). Rectangles are simple you just check the location is greater then the small values, larger then the big ones:

If point.Latitude >= _bottomright.Latitude _

AndAlso point.Latitude <= _topleft.Latitude _

AndAlso point.Longitude >= _topleft.Longitude _

AndAlso point.Longitude <= _bottomright.Longitude Then

But why stop there, have a search for determining a point is within a polygon, the best method is to draw a line in one direction and count the intersections, even is outside, odd is inside.

For performance I usually store a maximum rectangle for complex polgons and do the above check first.

Dim crossings As Integer = 0

'for each point in the geofence except the last one

For x As Integer = 0 To (points.Count - 2)

If LineIntersects(points(x), points(x + 1), point) Then

crossings += 1

End If

Next

'finnaly do the last point with the first point to finish off the geofence

If LineIntersects(points(points.Count - 1), points(0), point) Then

crossings += 1

End If

'if crossings is even then it is outside, odd inside.

If crossings Mod 2 = 0 Then

Return False

Else

Return True

End If

'start, finish are the points on the geofence edge

'point is the current location

Private Function LineIntersects(ByVal start As VELatLong, ByVal finish As VELatLong, ByVal point As VELatLong) As Boolean

Dim a1 As Double = finish.Longitude - start.Longitude

Dim b2 As Double = point.Latitude - 90

Dim denom As Double = a1 * b2

If denom = 0 Then 'will never cross so shortcut.

Return False

Else

Dim b1 As Double = start.Latitude - finish.Latitude

Dim c1 As Double = finish.Latitude * start.Longitude - start.Latitude * finish.Longitude

Dim c2 As Double = 90 * point.Longitude - point.Latitude * point.Longitude

Dim x As Double = Math.Round((b1 * c2 - b2 * c1) / denom, 8) 'round to 8 decimal places to ensure 0.9999999999999999999999999 becomes 1

Dim y As Double = Math.Round((0 - a1 * c2) / denom, 8)

'round to 8 decimal places to ensure a match

start.Latitude = Math.Round(start.Latitude, 8)

start.Longitude = Math.Round(start.Longitude, 8)

finish.Latitude = Math.Round(finish.Latitude, 8)

finish.Longitude = Math.Round(finish.Longitude, 8)

'TODO: refactor this - must be a simpler way rather then 9 compares

If ((x >= start.Latitude OrElse x >= finish.Latitude) AndAlso (x <= finish.Latitude OrElse x <= start.Latitude)) _

AndAlso ((y >= start.Longitude OrElse y >= finish.Longitude) AndAlso (y <= finish.Longitude OrElse y <= start.Longitude)) _

AndAlso x > point.Latitude Then

Return True

Else

Return (False)

End If

End If

End Function

John.

Smuts

Thanks John,

Yes the alerts will be generated on server-side.

I was looking for code samples on how to retrieve the zones from user input on the map, and then use this info when checking the data.

When the user draws a rectangle on the map, I want to save the coordinates as Zone x.

Smuts

SoulSolutions

Yeah well currently we don't get the nice drawing tools from maps.live.com but we do get the basics and maybe soemthing a little better around the corner with V5.

Cool i just used the snippet in another post:

map.AttachEvent("onclick", onclick);

function onclick(e)

{

//do your logic here

// use:

// e.view.LatLong.Latitude

// e.view.LatLong.Longitude

}

So attach to the onclick event when you to start drawing, i also change the mouse cursor:

document.getElementById("mymap").childNodes[0].style.cursor = "crosshair";

And build an array of points, at the same time you draw a polyline.

Check this out from the wiki:

http://www.viavirtualearth.com/Wiki/DrawPolygon.ashx

John.

Smuts

Perfect! Just what I was looking for, thanks for excelent help, John.

/Smuts

Noble Bell

I have a set of points saved in an array. (I wrote this in JavaScript). My question is how can I save that point array to a file on the server so that I can use it elsewhere

Thanks in advance,

nb

SoulSolutions

looks like you have a couple of answers on your new thread:

http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1479931&SiteID=1&mode=1

John.

Smuts

Sorry if I missed a basic geography school class, but...

If I wan't to check if a point is within a polygon, how would drawing a line help me By making the line very short (as a point), or what

/Smuts

bhowden

The basic idea is if you are testing a point to see if it is inside a polygon or not, you generate a line from the point out to infinity (say to the East). You then walk around the line segments that make up your polygon looking for line crosses with your line. If you have an even number of line crosses (or zero) your point is outside the polygon. If it is odd, you are inside the polygon. Works for just about any combination of islands in lakes in your polygon (ie holes within holes) and loop back arms on your polyon. As spatial tests go, it is pretty fast (order n) and pretty easy to code. Seems a bit cumbersome at first but you get used to the pain....

Brian

Smuts

Hi again John,

I'm having a little trouble converting the Wiki sample you mention (DrawPolygon) to API V5. It's the 'contextMenu' eventcode in the sample (moved to the new onclick rightmouseButton event section). Something in the creation of the polygon runtime-errors on me, dunno whath though. Any ideas

Smuts