def sortLocations(locations):
    """ Sort the locations by ranking:
            1.  all on-axis points
            2.  all off-axis points which project onto on-axis points
                these would be involved in master to master interpolations
                necessary for patching. Projecting off-axis masters have
                at least one coordinate in common with an on-axis master.
            3.  non-projecting off-axis points, 'wild' off axis points
                These would be involved in projecting limits and need to be patched.
    """
    onAxis = []
    onAxisValues = {}
    offAxis = []
    offAxis_projecting = []
    offAxis_wild = []
    # first get the on-axis points
    for l in locations:
        if l.isOrigin():
            continue
        if l.isOnAxis():
            onAxis.append(l)
            for axis in l.keys():
                if axis not in onAxisValues:
                    onAxisValues[axis] = []
                onAxisValues[axis].append(l[axis])
        else:
            offAxis.append(l)
    for l in offAxis:
        ok = False
        for axis in l.keys():
            if axis not in onAxisValues:
                continue
            if l[axis] in onAxisValues[axis]:
                ok = True
        if ok:
            offAxis_projecting.append(l)
        else:
            offAxis_wild.append(l)
    return onAxis, offAxis_projecting, offAxis_wild
Sort the locations by ranking:
            1.  all on-axis points
            2.  all off-axis points which project onto on-axis points
                these would be involved in master to master interpolations
                necessary for patching. Projecting off-axis masters have
                at least one coordinate in common with an on-axis master.
            3.  non-projecting off-axis points, 'wild' off axis points
                These would be involved in projecting limits and need to be patched.