Syntax FACTORY_DEF ProximityFactory [FACTORY_NAME ] [INPUT (BASE|CANDIDATE) FEATURE_TYPE [ ]* []*]* [SPATIAL_MATCH (CLOSEST |ENVELOPE_INTERSECT)]+ [K_NEAREST [] []] [INSERT_VERTEX_ON_BASE [(YES|NO)]] [TAKE_MEASURES_MODE [(YES|NO)]] [COMPUTE_MEASURES_MODE [(DISCRETE|CONTINUOUS)]] [COMBINE_GEOMETRY] [DISTANCE_ATTR ] [TREAT_POLYGON_AS (LINE|AREA)] [TEST ]+ [TESTED_CANDIDATES_LIST ] [CLOSE_CANDIDATES_LIST ] [LIST_ATTRS_TO_INCLUDE []* ] [LIST_ATTRS_TO_INCLUDE_MODE (ALL|SELECTED)] [GROUP_BY []+]* [FLUSH_WHEN_GROUPS_CHANGE (Yes|No)] [REQUIRE_BASE [(YES|NO)]] [KEY_ATTR ] [REJECT_INVALID_GEOM (Yes|No)] [OUTPUT (MATCHED|UNMATCHED_BASE|UNMATCHED_CANDIDATE|REJECTED) FEATURE_TYPE [ ]* []*]* Overview This factory performs feature matching based on the spatial relationship between features. Either SPATIAL_MATCH or K_NEAREST may be specified. When K_NEAREST [] [] is specified: Detailed behaviour is similar to that of CLOSEST described below. Generally this mode means to find the nearest CANDIDATEs to each BASE. If is also given, then the search will only include candidates up to that distance from each base. Both arguments may be a constant, attr ref, or function. Note that there are two ways to search by . The following two clauses should give the same results, but the first one uses a the "k Nearest Neighbors" algorithm (but with no !) while the second uses an envelope-intersect search followed by filtering: 1. K_NEAREST "" 10 2. CLOSEST 10 When CLOSEST is specified: The factory first stores all BASE features in one set and all CANDIDATE features in another set until it receives all features. After all features have been received, the factory then looks at each BASE feature and finds the closest CANDIDATE feature within distance of the BASE feature. If no CANDIDATE feature is found to be within distance, then the BASE feature will be output via the UNMATCHED_BASE output tag. The units of are those of the input features. may be a constant, attr ref, or function. If a CANDIDATE feature is found, then the factory will add all attributes from the closest CANDIDATE feature to the BASE feature and will send the BASE feature out of the factory via the MATCHED tag. It will also add the distance (in ground units) from the BASE to the CANDIDATE in the attribute distance. If the same attribute exists on the BASE and the CANDIDATE, the BASE feature's attribute value will be overwritten by the value contained in the CANDIDATE's attribute. The coordinates of the closest BASE point and the closest CANDIDATE point are added to the matched BASE feature to the corresponding attributes: closest_base_x, closest_base_y, closest_candidate_x, and closest_candidate_y. The angle between the closest BASE point and the closest CANDIDATE point is also added to the BASE feature on the attribute angle. Finally, the angle from the closest candidate point to its immediate successor within the candidate feature is stored in the attribute candidate_angle. (If the closest candidate point is the last point in the feature, then candidate_angle will contain the angle from the previous point of the candidate feature to the closest candidate point.) Also, it adds an attribute named candidate_label_angle which contains the candidate_angle adjusted such that if a label is created with that angle, it will read from left to right. Once all BASE features have been processed, the factory outputs any CANDIDATE features that have not been matched via the UNMATCHED_CANDIDATE output tag. It is important to note that if a CANDIDATE feature is the closest feature to multiple BASE features, then it will be combined with multiple BASE features. If REQUIRE_BASE is specified, then if no BASE input is given, a warning will be logged and all CANDIDATEs will be output as UNMATCHED_CANDIDATE. Note: If REQUIRE_BASE is not specified, the BASE input clause is optional. In that case, if only CANDIDATEs are supplied to the factory, then they are also used as the BASEs. When considering each feature as a BASE, the feature itself will be ignored as a CANDIDATE; i.e., every feature will not find itself as the closest candidate. When ENVELOPE_INTERSECT is specified, the following is performed: The CANDIDATE features are held until the first BASE feature is encountered. All BASE features other than the first are output via the UNMATCHED_BASE clause. When CONTAINED_IN is specified all candidate features which are CONTAINED_IN the base feature are combined with the base feature. The INTERSECT spatial match: returns all the candidate features that intersect the BASE feature. If the base is a line then all area features which the line passes thru are returned. If the base is an area features then all line area and point features which intersect the interior of the polygon are returned. The attributes of the base feature are added to the output MATCHED candidate feature. Candidate features which are do not intersect the base are output via the UNMATCHED_CANDIDATE clause. In this case you can only have one base feature. Subsequent base features will be output via the UNMATCHED_BASE clause. The TEST clause here specifies the comparison done between the BASE and CANDIDATE features. To refer to BASE attributes, prefix the attributes with "BASE." and to refer to CANDIDATE attributes, use the prefix "CANDIDATE.". Note: If the K_NEAREST clause is in use, unprefixed "angle" and "distance" attributes will be available to use in the test. FOR OLDER INSTANCES OF THE FACTORY (not using the K_NEAREST clause): Just prior to the test being performed, the BASE features have the closest_base_x, closest_base_y, closest_candidate_x, and closest_candidate_y attributes added. Furthermore, an unprefixed angle and distance attribute is available to be used in the test as well. The following example specifies a test which will only allow BASE and CANDIDATE features to be matched when they have the same value in their ID attribute: TEST &BASE.ID = &CANDIDATE.ID When the TESTED_CANDIDATES_LIST clause is specified, an attribute list with the specified name is created and added to the BASE features. This attribute list contains the CANDIDATES information that was tested against the BASE feature. The CANDIDATES information corresponds with the BASE features, which include the attribute distance, angle, closest_base_x, closest_base_y, closest_candidate_x, and closest_candidate_y. Note: Not all CANDIDATEs' attributes will appear in the TESTED_CANDIDATES_LIST. There is a preliminary test whereby the distance between the CANDIDATE's bounding box and the BASE's bounding box is considered. Only features for which this distance is less than or equal to will have their real distance from the base calculated, and these features' attributes will appear in the TESTED_CANDIDATES_LIST. Note 2: The TESTED_CANDIDATES_LIST has no effect when K_NEAREST is the specified algorithm. CLOSE_CANDIDATES_LIST has similar behavior to TESTED_CANDIDATES_LIST. The list that this clause creates will contain the attributes from all candidates within of the BASE in question. The CANDIDATES_LIST clauses also change the way that CANDIDATE feature attributes are copied to the BASE feature. Normally the BASE feature attributes are replaced by all of the CANDIDATE feature attributes. However, if both the BASE and CANDIDATE have an attribute with the same name, then the value of the CANDIDATE attribute replaces the existing BASE attribute value. If either CANDIDATES_LIST clause is specified, then the BASE attributes take precedence, so if both the BASE and CANDIDATE have an attribute with the same name, then the value of the BASE attribute will be preserved. Only new CANDIDATE attributes will be added to the BASE, but all of the CANDIDATE attributes will appear in the requested CANDIDATES_LIST(s). Hint: To get the distance from a given BASE to all CANDIDATE features, use a very large number for and specify CLOSE_CANDIDATES_LIST. 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. The GROUP_BY clause specifies the attributes used to group the base and candidate features. Each group of features is processed through the ProximityFactory independently of other groups. If FLUSH_WHEN_GROUPS_CHANGE is set to Yes, then the factory will process all features in the current group immediately upon encountering a feature from a different group, then switch groups. If no GROUP_BY clause is specified, then all features fall into the same group. Also note that the GROUP_BY clause cannot be used in conjunction with the SPATIAL_MATCH of ENVELOPE_INTERSECT. DISTANCE_ATTR allows the user to specify the attribute name of the distance attribute. This will be removed from manual documentation and the distance attribute name will be fixed with the name of distance. RELATION 1:1 - each base feature is matched to one candidate feature and each candidate feature is matched on only one base feature. RELATION 1:M - each base feature may be matched to multiple candidate feature but the candidate feature may only be associated with one base feature. This is the default if RELATION is not specified. RELATION M:1 - each base feature is matched to one candidate feature but the candidate features may be associated with multiple base features. RELATION M:M - no restriction on how many candidate features the base feature is associated or how many base features the candidate is associated. Currently only 1:M is implemented. The closest candidate is always sent out with all the closest base features it is with. The RELATION CLAUSE is currently not processed. The TAKE_MEASURES_MODE clause specifies if the base should take all measures and z values from the candidate. The COMPUTE_MEASURES_MODE only applies when TAKE_MEASURES_MODE is "YES." It specifies whether the measures should be interpolated (CONTINUOUS), or if they should be taken from the closest true value (DISCRETE). The COMBINE_GEOMETRY clause instructs the factory to combine the geometry of the base and candidate features. It is currently not implemented. The attribute specified by KEY_ATTR will always be copied from Candidate to Base even it exists there already. (Only currently implemented for K_NEAREST mode or when ATTR_ACCUM_MODE is given.) When REJECT_INVALID_GEOM is Yes, the factory will output invalid features to Rejected port. Output Tags The ProximityFactory supports the following output tags. MATCHED The features that result from a successful proximity match. These features have the geometry of the BASE feature with the attributes of the CANDIDATE feature added. If COMBINE_GEOMETRY is specified then the geometry is also copied and the feature becomes an aggregate. When geometry is combned the base feature is always the first part of the feature. Also a few attributes are added upon the base feature: distance_to_candidate, angle (this is the angle between the base to the candidate), candidate_angle (this is the angle between the closest candidate point and the next candidate point, either before or closet candidate point), closest_base_x, closest_base_y, closest_candidate_x, and closest_candidate_y. UNMATCHED_BASE The BASE features for which there is no CANDIDATE feature within . UNMATCHED_CANDIDATE The CANDIDATE features that are not the closest to any BASE feature. REJECTED Any unused features (i.e. extra candidates). TO BE RESOLVED The SPATIAL_MATCH clause has 2 values that are not implemented: INTERSECT and CONTAINED_IN. However, the documentation above provides extensive descriptions of their usage, making it appear as though they are actually implemented. The description for the RELATION clause describes a number of options; however, this clause is not actually implemented and therefore it would be helpful if it was explained which cardinality is actually being used. In one part of the header, it was claimed that: If RELATION is not specified then M:M is assumed and each base will be paired with as many secondaries as possible. and elsewhere: Currently only 1:M is implemented. The closest candidate is always sent out with all the closest base features it is with. The RELATION CLAUSE is currently not processed. The COMBINE_GEOMETRY clause is not implemented. Let's remove this keyword and update the doc to explain the behaviour in its absence (i.e. is there any combining of geometries still?).