On Fri, May 13, 2011 at 9:09 PM, Richard Quadling <rquadl...@gmail.com>wrote:

> On 12 May 2011 21:41, Ben Appleton <apple...@google.com> wrote:
> >
> > On May 13, 2011 2:37 AM, "Richard Quadling" <rquadl...@gmail.com> wrote:
> >>
> >> On 12 May 2011 14:12, Ben Appleton <apple...@google.com> wrote:
> >> > It sounds like you have a polygon containment forest: a collection of
> >> > rooted
> >> > trees whose roots are outer polygons, children are polygonal holes,
> >> > grand-children are polygonal islands inside holes, etc. You can
> >> > certainly
> >> > represent containment in JavaScript, but it's not necessary for
> >> > rendering.
> >> > Therefore the Google Maps API does not represent containment.
> >> >
> >> > There is an unfortunate caveat. Many browsers use Canvas to render
> >> > vector
> >> > graphics, and Canvas requires that outer vs inner polygons have
> opposite
> >> > orientations - it implements only "zero-winding fill". For example, if
> >> > your
> >> > outer boundary is clockwise, your holes must be counter-clockwise,
> >> > islands
> >> > within holes must be clockwise, and so on. If you need to determine
> the
> >> > orientation of a polygon you can use the geometry library's
> >> > computeSignedArea method
> >> >
> >> > (
> http://code.google.com/apis/maps/documentation/javascript/reference.html#spherical
> ).
> >> > You can then traverse your containment tree to ensure that outer vs
> >> > inner
> >> > polygons have opposite sign, reversing polygonal loops to negate their
> >> > sign
> >> > where necessary.
> >> >
> >> > Incidentally the geometry library also has a method to encode
> >> > polylines/polygons in the same format as you reference, but compiled
> so
> >> > it
> >> > loads faster.
> >> >
> >> > So I suggest: use google.maps.Polygon to visualize your polygons, but
> >> > wrap
> >> > it in another class or datastructure to represent your containment
> >> > forest.
> >> > To visualize simply add the google.maps.Polygon to the map. When
> >> > constructing queries to your server, consult your wrapper class /
> >> > datastructure to determine which polygonal loops are outside vs
> inside.
> >> > Optionally, also switch to using the compiled poly encoder in the
> >> > geometry
> >> > library.
> >> >
> >> > Hope that helps
> >> > Ben
> >> >
> >>
> >> Thanks for that.
> >>
> >> encodePath only allows for a single path, not a set of paths. I'm
> >> simply concatenating them with | (pipe). And splitting and decoding
> >> them in PHP.  How do I access the compiled encoder. I'm currently
> >> using google.maps.geometry.encoding.encodePath()
> >
> > Oh great, you're already using it. I thought you meant you were using an
> > older JavaScript poly encoder that had not been compiled.
> >
> >> Very useful. -ve values from computeSignedArea() relate to the outer
> >> polygons and +ve values to the inner ones.
> >
> > That's right.
> >
> >> I think the final piece for me now is to determine from 2 polygons if
> >> one is completely within the other.
> >
> > I thought you already had this structure. Else, how are you currently
> > generating KML and WKT queries as you mention?
> >
> > Cheers
> > Ben
> >
>
> I'm still in building/designing/learning/playing phase of the
> development. Essentially proving to myself and the team that what we
> want to do is possible. I'm working things out manually.
>
> In the last test (test 5) I create a map, added a simple polygon and
> send the encoded path to PHP to decode and turn into WTK for SQL to
> get the pins to pass back to the map for displaying.
>
> For a single polygon (I've used 2 sliders to allow different number of
> points and radius) this is working fine. I have to use a polygon as
> whilst I'm only playing with regular ones, the final view of the app
> will be to have complex boundaries.
>
> The next test was to add the exclusion polygon. That's where I'm at
> now. Though I'm still playing I know that the users will need to be
> able to define these complex areas.
>
>
> The purpose of the tool is to allow our call centre staff to display
> the location of a LGV (Large Goods Vehicle) breakdown and, based upon
> the contract (essentially who owns or is hiring the vehicle) provide a
> ranking of the most appropriate maintenance engineers, nearest to the
> breakdown. We have nearly 1,000 service depots in the UK. Each depot
> covers an area. Sometimes just as a 30 mile radius, others cover a
> specific county, or part of it. Others don't go inside a circular
> motorway/ring road, etc. All different. Some will travel over
> bridges/ferries/etc. Or have any sort of boundary/exclusion.
>

OK - so for this first step, you only need to display a complex polygon
(such as a polygon with multiple inner and outer boundaries). That should
work fine, so long as exterior vs interior loops wind in opposite
directions.


> The next step in the design is to allow a backoffice user the ability
> to plot out these boundaries. The boundaries will be stored in our SQL
> Server in 2 ways:
>
> 1 - Using the Google Maps encoded form, so when I need to display the
> polygon, I can just supply that to the client app, call the decoder
> and add each path to the polygon.
>

So long as your exterior and interior loops wind in opposite directions, I
believe you can store a google.maps.Polygon as a pipe-separated sequence of
encoded LatLng strings.

2 - As a SQL Server Geography type, so I can use SQL Server to do all
> the intersection and find a list of service providers who cover the
> point of the breakdown and are attributable to the contract for the
> vehicle.
>

For both of these cases you need to distinguish exterior vs interior loops.
In addition, if I understand correctly, for the SQL Server Geography type
you need to represent the polygon containment forest I mentioned earlier -
that is, which polygonal loops contain which other polygonal loops. So when
a backoffice user plots out a boundary, either the UI itself or a
post-processing step must construct the polygon containment forest.

The UI could enforce this, by providing a flow where a backoffice user adds
a "child loop" to an existing loop - to punch a hole in an exterior loop,
for example. Or you could compute this after the fact by testing which loops
lie inside which other loops. For non-intersecting loops, loop A contains
loop B if and only if the first vertex of loop B lies inside loop A. So long
as there are only a handful of loops per polygon this should be fast enough,
otherwise you could use a faster (but more complex) scan-line algorithm.

Obviously, there is more to the front end than just the map, but the
> map is one of the key players. The map will also show any service
> provider that has part of their boundary within the viewport, so, if
> the preferred providers are unable to handle the breakdown (some
> providers are quite small and only have 2 or 3 maintenance staff), the
> user can see that there are other providers in the area who are linked
> to the contract and may be able to help, even though it is outside of
> their boundary. It's all very fluid, but not a total free for all.
> Travelling time for the maintenance people means some driver is
> sitting in their cab waiting and having the stock not being delivered.
> The vast majority of the contracts are delivering perishables and
> delivery times are quite tight.
>
> And I then, on top of all of this, ...
>
> GoogleMaps ...
>
> LatLng(latitude, longiture)
> Polygon orientation of points to create a small closed area : clockwise
>
> WTK (as used by SQL Server)
> POINT(Longitude, Latitude) <<< Reverse
> POLYGON orientation of points to create a small closed area :
> anticlockwise. Otherwise the enclosed area encompasses the whole of
> the earth, except the small part "outside" the boundary.
>
> And to this, the MS SQL native Geography::Point() method uses
> Point(latitude, longitude), the reverse of WTK but matches Google Maps
> API.
>
> Don't you just love standards!
>

Haha, I'm sorry for you. Lat/lng versus lng/lat seems to be a perennial
source of pain in GIS systems.

Cheers
Ben


> --
> Richard Quadling
> Twitter : EE : Zend
> @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY
>
> --
> You received this message because you are subscribed to the Google Groups
> "Google Maps JavaScript API v3" group.
> To post to this group, send email to
> google-maps-js-api-v3@googlegroups.com.
> To unsubscribe from this group, send email to
> google-maps-js-api-v3+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-maps-js-api-v3?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Google Maps JavaScript API v3" group.
To post to this group, send email to google-maps-js-api-v3@googlegroups.com.
To unsubscribe from this group, send email to 
google-maps-js-api-v3+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-maps-js-api-v3?hl=en.

Reply via email to