One of the aspects of the project I'm working on needs to have
polygons created and written in a specific order. The first point in
the polygon draw order must be the bottom left and the polygon must be
drawn clockwise.
What I'm trying to do is to input existing polygons (all of them are
square, with only 4 points in lat/long so far), deconstruct the
polygon to points, reorder the points then redraw the polygons.
Wow, that was a bit more challenging than I expected when I started connecting the dots. The orientation is simple (Orienter) but if there's a simple path for re-ordering the coordinates to start at the lower-left corner I'd like to know about it.
Basic workflow:
- Calculate bounding box of the polygon and extract the lower-left coordinate - Decompose the polygon into four points (hint, polygons have five vertices) associated with their parent polygon ID - Use Pythagorean theorem to calculate distance of each of the points from the lower-left coordinate - Use StatisicsCalculator to determine shortest distance for each polygon ID. - Using a FeatureMerger on a copy of the points, determine which point ID has the shortest distance for each PolygonID - Merge the new starting Point ID back onto all of the points - Offset each point's position in the line by the new starting position - Re-compose the polygons - Join the new polygons back to the attributes of the old polygons
One of the aspects of the project I'm working on needs to have polygons created and written in a specific order. The first point in the polygon draw order must be the bottom left and the polygon must be drawn clockwise.
What I'm trying to do is to input existing polygons (all of them are square, with only 4 points in lat/long so far), deconstruct the polygon to points, reorder the points then redraw the polygons.
Well, that attachment didn't work too well in Google Groups. Bloody Outlook webmail.
Try this instead.
Jason
From: Jason Birch Subject: RE: [fme] Reordering polygon vertices
Wow, that was a bit more challenging than I expected when I started connecting the dots. The orientation is simple (Orienter) but if there's a simple path for re-ordering the coordinates to start at the lower-left corner I'd like to know about it.
- use CoordinateConcatenator to get positions
- AttributeSplitter to get a list of positions
- ListExploder to get 1 feature per position with countid
- StatisticsCalculator (Group by polygon_Id)to find minx and miny
- Tester to pick this feature and its countid (we're back to 1 feature
now)
- AttributeSplitter again to get coordinatelist again
- loop through coordinate list starting with id incrementing upwards
2DPointAdder for each position
wrap around when overflow starting with 0
... until all positions processed
- Orientor to get it clockwise
Remarks:
1) This cries for TCL script ...
2) I have no FME usable at the moment (my PC is reinstalled)
hope I didn't get lost throughout the simulation ;-)
Michael
On Apr 25, 10:18 pm, "Jason Birch" <Jason.Bi...@nanaimo.ca> wrote:
> Wow, that was a bit more challenging than I expected when I started connecting the dots. The orientation is simple (Orienter) but if there's a simple path for re-ordering the coordinates to start at the lower-left corner I'd like to know about it.
Heh. Looks like it might work, but I'm not sure that it's all that much simpler than my solution.
One thing that is important though is that you can't determine the lower-left coordinate using minx/miny. Even in a basic rotated box, one point will have minx and another will have miny. I chose to use distance from the lower left of the bounding box; I wonder if there's an easier way of calculating this. Maybe creating a point for the bounding box LL and then using a neighbour finder to get the closest node on the polygon :)
- use CoordinateConcatenator to get positions - AttributeSplitter to get a list of positions - ListExploder to get 1 feature per position with countid - StatisticsCalculator (Group by polygon_Id)to find minx and miny - Tester to pick this feature and its countid (we're back to 1 feature now) - AttributeSplitter again to get coordinatelist again - loop through coordinate list starting with id incrementing upwards 2DPointAdder for each position wrap around when overflow starting with 0 ... until all positions processed - Orientor to get it clockwise
Remarks: 1) This cries for TCL script ... 2) I have no FME usable at the moment (my PC is reinstalled) hope I didn't get lost throughout the simulation ;-)
Too much detail! Much too hard. Surely with all the power in the
transformers you don't have to bit twiddle?
The capability of FME should be used on whole features if possible.
Surely faster and more reliable than workbench scripts on lists.
There are several constraints that allow an easier solution such as 4
points as a rectangle?
My first thought was to look for a transformer that reordered points
in a polygon.
Orientor is a useful start.
What about ConvexHullReplacer? It does almost exactly what is required
but the convention is Upper Left and Anticlockwise for the start of
the polygon.
Perhaps that would be good enough?
If not, then all that remains to be done for a 4 point poly is to
adjust the start of the polygon by one vertex to the lower left.
VertexSnipper is supposed to work on a polygon but the help **lies**
about that, it only works on lines. Edit request?
Never mind, a quick GeometryCoercer, keep the second point, add it
back on the end with 2dPointAdder and Orientor fixes it up.
Almost a one liner if upper left will do, otherwise 6 simple
transformers.
...now how do you attach the workspace to a reply in google groups?
reorder_poly_kimo.fmw
On Apr 26, 12:48 pm, "Jason Birch" <Jason.Bi...@nanaimo.ca> wrote:
> Heh. Looks like it might work, but I'm not sure that it's all that much simpler than my solution.
> One thing that is important though is that you can't determine the lower-left coordinate using minx/miny. Even in a basic rotated box, one point will have minx and another will have miny. I chose to use distance from the lower left of the bounding box; I wonder if there's an easier way of calculating this. Maybe creating a point for the bounding box LL and then using a neighbour finder to get the closest node on the polygon :)
> - use CoordinateConcatenator to get positions
> - AttributeSplitter to get a list of positions
> - ListExploder to get 1 feature per position with countid
> - StatisticsCalculator (Group by polygon_Id)to find minx and miny
> - Tester to pick this feature and its countid (we're back to 1 feature
> now)
> - AttributeSplitter again to get coordinatelist again
> - loop through coordinate list starting with id incrementing upwards
> 2DPointAdder for each position
> wrap around when overflow starting with 0
> ... until all positions processed
> - Orientor to get it clockwise
> Remarks:
> 1) This cries for TCL script ...
> 2) I have no FME usable at the moment (my PC is reinstalled)
> hope I didn't get lost throughout the simulation ;-)
Sctweedy,
One way to tackle this is to use MS Excel - then FME.
Look in the "Files" area (Link in orange panel at right) for the
spreadsheet - polys_from_coords.xls that I've uploaded for you.
(how do you actually attach files to posts - I don't see a button for
it ???)
...
Dump your old poly coords out of your GIS (along with an old ID if you
have one) to txt or dbf etc (or xls).
...
Then process all your data in MS Excel.
Finally rebuild polys in FME.
(Attached spreadsheet can be used to help build polys from coords
using a GIS program eg ArcView or FME).
...
Don't forget to repeat lower South West corner coords to close poly.
Hope this helps
Regards
Howard L'
On Apr 25, 2:19 pm, sctweedy <sctwe...@nrcan.gc.ca> wrote:
> One of the aspects of the project I'm working on needs to have
> polygons created and written in a specific order. The first point in
> the polygon draw order must be the bottom left and the polygon must be
> drawn clockwise.
> What I'm trying to do is to input existing polygons (all of them are
> square, with only 4 points in lat/long so far), deconstruct the
> polygon to points, reorder the points then redraw the polygons.
Another thought,
You may not have to export your original poly coords at all.
Are the coords in some sort of regular pattern ???
(eg map sheet corner coordinates)
You might be able to set the coords of the corners up in Excel without
exporting your original points at all.
Get Excel to pick the pattern up ie use Auto - Fill to help complete
your spreadsheet.
Then, once Spreadsheet set up, get FME to convert coords to polys as
per my previous post.
...
Hope this helps
Regards
Howard L'
On Apr 25, 2:19 pm, sctweedy <sctwe...@nrcan.gc.ca> wrote:
> One of the aspects of the project I'm working on needs to have
> polygons created and written in a specific order. The first point in
> the polygon draw order must be the bottom left and the polygon must be
> drawn clockwise.
> What I'm trying to do is to input existing polygons (all of them are
> square, with only 4 points in lat/long so far), deconstruct the
> polygon to points, reorder the points then redraw the polygons.
I was working under the assumption that the sctweedy's "so far" meant that I couldn't count on the polygons remaining as simple squares.
I wouldn't have come up with anything as elegant as your solution even if I had accepted these constraints though; use of the ConvexHullReplacer was a great call.
I'd agree with full-feature processing being faster, but I've found lists to be entirely reliable and one of the parts of FME that I like most.
The only way that I know of to "attach" to Google Groups is to use the email interface instead of the web interface.
I got the idea from an example previously seen in the Python Cookbook
for computing convex hulls. It discusses finding the lowest point and
sorting into clockwise order using Graham's Scan Algorithm. I had
initially thought of calling a Python script using this code, or using
the logic in a list handler, but it was quite complicated for an
apparently simple problem, and not really in the spirit of using
transformers and FME. I am sure that list handling is robust, but
this problem puts a lot of skill back on the scripter to implement
properly. This algorithm would be able cope with the general case to
answer the original question completely.
Routine from Python Cookbook Ed 2 chapter 18.17 p 686. Actually it's
not Graham's Scan (1972) at all
It is really Andrew's Monotone Chain Algorithm (1979), but never mind,
I tested it and it worked after debugging.
http://en.wikipedia.org/wiki/Graham_scan for a graphical explanation
I understand how an expert can do "anything" once you have a list of
coordinates, but I consider if I have to get down to that detail as a
'spatial language failure' either because I have not been able to
express the problem in terms of the 'spatial language' available in
FME or there is not yet a 'verb' (transformer) to handle the concept.
It's Dale's team's job to implement Graham's Algorithm. I want
spatial feature manipulation to become more SQL-like where you specify
the result without having to code the implementation. That is what I
find fascinating about transformers and topology.
On Apr 27, 6:53 am, "Jason Birch" <Jason.Bi...@nanaimo.ca> wrote:
> I was working under the assumption that the sctweedy's "so far" meant that I couldn't count on the polygons remaining as simple squares.
> I wouldn't have come up with anything as elegant as your solution even if I had accepted these constraints though; use of the ConvexHullReplacer was a great call.
> I'd agree with full-feature processing being faster, but I've found lists to be entirely reliable and one of the parts of FME that I like most.
> The only way that I know of to "attach" to Google Groups is to use the email interface instead of the web interface.
Wow, that's been a great weekend discussion!
May I dare to add another idea?
1) The corner problem: I have posted a way to find a polygon's
"corner" in coordinate system representation earlier, see
http://groups.google.com/group/fmetalk/browse_thread/thread/c172d5e96... (I hope I got the link right, the message was "Extract NE cornder of
polygon", "3 Jan. 2007 by Hans van der Maarel", but you don't need to
follow it, I'll explain it here too).
The basic idea is to rotate the polygon by 45 degrees, so you can
easily find all the points that are closest to a 45 degree axis ...
which is a good representation of the corner point even for a general
polygon. The closest points are simply obtained as min / max
operations. Of course, the rotation is not really done with the data,
it is simply accomplished by an addition or subtraction of a point's
coordinates, in your case:
The SW corner is simply the point with minimal x(i)+y(i), where i is
the index of all points of that polygon.
2) The rotation problem:
You have to find out the point index of the (new) first point. Then
you can reorder the points by a modulo operation on the point indices.
This approach will work for any polygons, not only squares.
Implementation can be done in several ways. The easiest would
certainly be to do it within a TCL or python script: Extract all
coordinates of the polygon except the last one (this would be present
twice) into an array. Calculate x(i)+y(i) and find the minimum of
these values. Then you have the list index of the first (at the same
time last) point. Now run a loop for all list indices starting from
that index with modulo by the number of points, running till that
index is reached again. Or you do two loops, one from i to the number
of points -1, the other one from 0 to i.
With transformers you would have to do a lot more operations, of
course.
Maybe that helps,
Wolfgang
On 27 Apr., 01:14, kimo <k...@ollivier.co.nz> wrote:
> I got the idea from an example previously seen in the Python Cookbook
> for computing convex hulls. It discusses finding the lowest point and
> sorting into clockwise order using Graham's Scan Algorithm. I had
> initially thought of calling a Python script using this code, or using
> the logic in a list handler, but it was quite complicated for an
> apparently simple problem, and not really in the spirit of using
> transformers and FME. I am sure that list handling is robust, but
> this problem puts a lot of skill back on the scripter to implement
> properly. This algorithm would be able cope with the general case to
> answer the original question completely.
> Routine from Python Cookbook Ed 2 chapter 18.17 p 686. Actually it's
> not Graham's Scan (1972) at all
> It is really Andrew's Monotone Chain Algorithm (1979), but never mind,
> I tested it and it worked after debugging.http://en.wikipedia.org/wiki/Graham_scanfor a graphical explanation
> I understand how an expert can do "anything" once you have a list of
> coordinates, but I consider if I have to get down to that detail as a
> 'spatial language failure' either because I have not been able to
> express the problem in terms of the 'spatial language' available in
> FME or there is not yet a 'verb' (transformer) to handle the concept.
> It's Dale's team's job to implement Graham's Algorithm. I want
> spatial feature manipulation to become more SQL-like where you specify
> the result without having to code the implementation. That is what I
> find fascinating about transformers and topology.
> On Apr 27, 6:53 am, "Jason Birch" <Jason.Bi...@nanaimo.ca> wrote:
> > That's a good solution.
> > I was working under the assumption that the sctweedy's "so far" meant that I couldn't count on the polygons remaining as simple squares.
> > I wouldn't have come up with anything as elegant as your solution even if I had accepted these constraints though; use of the ConvexHullReplacer was a great call.
> > I'd agree with full-feature processing being faster, but I've found lists to be entirely reliable and one of the parts of FME that I like most.
> > The only way that I know of to "attach" to Google Groups is to use the email interface instead of the web interface.