Syntax FACTORY_DEF DonutFactory [FACTORY_NAME ] [INPUT FEATURE_TYPE [ ]* []*]* [DROP_HOLES [(YES|NO)]] [TAG_HOLES [(YES|NO)]] [MODE (QUICK|COMPLETE)] [BREAK_BEFORE_FIELD_CHANGE []+] [BREAK_AFTER_FIELD_CHANGE []+] [FLUSH_BEFORE_CURRENT_WHEN ] [FLUSH_AFTER_CURRENT_WHEN ] [FME_GEOMETRY_HANDLING [(YES|NO)]] [SPLIT_INPUT_DONUTS [(YES|NO)]] [HOLE_LIST {}] [LIST_ATTRS_TO_INCLUDE []* ] [LIST_ATTRS_TO_INCLUDE_MODE (ALL|SELECTED)] [GROUP_BY []+]* [FLUSH_WHEN_GROUPS_CHANGE (Yes|No)] [MERGE_INCOMING_ATTR [(YES|NO)]] [ATTR_ACCUM_MODE ] [ATTR_CONFLICT_RES ] [INCOMING_ATTR_PREFIX ] [OUTPUT (DONUT|LINE|PIP|POINT|POLYGON|REJECTED) FEATURE_TYPE [ ]* []*]* Overview This factory takes a series of features and joins them together based on spatial enclosure. Only features with polygon, donut polygon, or point geometry are processed by the factory. If a linear feature is found, then it is output according to the OUTPUT LINE clause. Once all input features have been collected, the factory produces an internal spatial ordering of all components. If there are attributes specified by the GROUP_BY clause, joins will only be performed on features within the same group. If FLUSH_WHEN_GROUPS_CHANGE is set to Yes, the factory will only perform joins on the current group, and change the current group every time a feature from a different group is encountered. The factory assumes that all input is topologically clean and that areas do not overlap. If the DROP_HOLES directive is set to yes, any polygons enclosed within another polygon will be deleted. Holes of holes are kept. If DROP_HOLES is set to no, then all polygons will be output. DROP_HOLES drops the hole polygon, leaving a hole-shaped void in place of the hole polygon. If DROP_HOLES is not specified, yes is assumed. If the TAG_HOLES directive is set to yes, any polygons enclosed within another polygon will have the attribute tagged_hole added to them with a value of yes. If the TAG_HOLES directive is set to no, any features not enclosed will have a value of no in the tagged_hole attribute when they exit. If TAG_HOLES is not specified, yes is assumed. If SPLIT_INPUT_DONUTS is specified, then donuts that are input to the factory will be split into their component rings before the donut-building algorithm is executed. If this directive is absent, then the behavior is undefined when there exist input donut features; in most cases such features will be output unmodified. If HOLE_LIST is given, then a list will be created on each output feature, containing an element for each input feature which became a hole on that geometry, in order of appearance. The optional LIST_ATTRS_TO_INCLUDE_MODE will specify if ALL attributes should be added to a list, or if only the SELECTED attributes (specified with the LIST_ATTRS_TO_INCLUDE clause) should be added to the list. If this value is not specified, it defaults to ALL. If the FLUSH_BEFORE_CURRENT_WHEN directive is specified, the factory performs the test defined by this clause every time it receives an input feature. If the result of the test is true, then the factory flushes out all stored features via the OUTPUT clauses before processing the input feature. If the result is false, the feature is processed and the factory is not flushed. The FLUSH_AFTER_CURRENT_WHEN tag operates identically except the factory is flushed after the current input feature processed instead of before. The is one of <, >, =, !=, >=, <=. The may be a literal constant, an attribute name preceded by the value-of operator (&), or an attribute value function. If it is an attribute value function, the function is executed on the current feature and the result will be used for the test. The example FLUSH_BEFORE_CURRENT_WHEN and FLUSH_AFTER_CURRENT_ WHEN clauses include: FLUSH_BEFORE_CURRENT_WHEN @Area() < 100 FLUSH_AFTER_CURRENT_WHEN &numLanes > 2 FLUSH_BEFORE_CURRENT_WHEN "Joe" = "Jerry" At run-time, the DonutFactory decides to invoke numeric comparisons or string comparisons, as greater than and less than, that have different meanings depending on the type of the operands. If both arguments may be converted to numbers, then numeric comparisons are used, otherwise string comparisons are used. The factory performs the following steps each time it is flushed, or once the last feature is input to the factory: 1. First, the factory determines the nesting of all input polygons. 2. At the conclusion of this operation, all polygons and donut polygons have been identified. 3. If there are no points input into the factory, then it is done and the polygons are output by the OUTPUT clauses tagged with POLYGON and DONUT. 4. When a donut polygon is created, the DonutFactory ensures that there are no holes that share a common edge by combining abutting holes together into a single hole. 5. If points are also input into the factory, the DonutFactory will then match points to the polygon and donut polygons determined in Step 1 above. Points are matched to the polygons that enclose them. At most, one point will be matched to any polygon. 6. Any polygons found to contain a point have the point's attributes and coordinates merged with their own. 7. The resulting features are then output with the PIP-tagged OUTPUT clause. 8. Points, polygons, and donut polygons not matched are output through the POINT, POLYGON, and DONUT output clauses respectively. The current set of features is also output whenever any of the following cases is true: The values of any of the BREAK_BEFORE_FIELD_CHANGE fields change from one feature to the next. When this occurs, the newly received input feature is not part of the set of features that is output; rather, it is part of the next set of features for which donuts are being constructed. The values of any of the BREAK_AFTER_FIELD_CHANGE fields change from one feature to the next. When this occurs, the newly received input feature is part of the set of features output. If the MERGE_INCOMING_ATTR is YES, then any conflicts between features with same attributes are to be resolved. The ATTR_ACCUM_MODE's value is the way of resolving the conflicts and its possible values are: HANDLE_CONFLICT, PREFIX_INCOMING and INCOMING_ONLY. If HANDLE_CONFLICT is chosen, we need to provide ATTR_CONFLICT_RES, and its possible values are: ORIGINAL_IF_CONFLICT and INCOMING_IF_CONFLICT. If PREFIX_INCOMING, we need to provide prefix with INCOMING_ATTR_PREFIX. Assumptions The DonutFactory assumes that the model is topologically clean and that no polygons within a group intersect. It is further assumed that each point is only in one polygon, and that each polygon has only one point. Output Tags The DonutFactory supports the following output tags. DONUT All donut polygons that were successfully constructed but contained no points. LINE All line objects sent into the model. The geometry of these features is unchanged. PIP All Point-In-Polygon (PIP) features. The geometry of these features consists of a polygon or donut polygon and an inner point. The point's attributes are merged with the polygon's. POINT All point features that weren't found to be in any polygon. POLYGON All polygon features that don't contain any holes or an inside point. REJECTED All features with not enough vertices or zero area. Note that features of wrong type are not outputted to this tag. TO BE RESOLVED Added MODE clause to syntax, but not documented.