Your explanation is excellent. Thank you very much. Do you know of any tools that provide a user with polygon drawing? Something I don't want to have to start from scratch?
A library of useful apps that have been generated using the maps API would be excellent. On 14 May 2011 03:30, Ben Appleton <apple...@google.com> wrote: > > > 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. > -- 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.