Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identify both sequential and hierarchical relationships between road events and other entities #118

Merged
merged 14 commits into from
Sep 1, 2020

Conversation

DeraldDudley
Copy link
Collaborator

@DeraldDudley DeraldDudley commented Jul 23, 2020

Reference Issue #108

In WZDx v2.0 the specification currently uses the road_events subidentifier field as to relate road events to another entity, such as a project or district. However, the field does not explicitly describe how linked features are related. Replacing subidentifier with a relationship object, inspired by the "relation" object used in JSCalendar, will enable identifying both sequential and hierarchical relationships between road events and other entities. For example, a relationship can be used to link multiple road events to a common "parent", such as a project or phase, or identify a sequence of road events.

1. Add relationships data table

Identify both sequential and hierarchical relationships between road events and other entities. For example, a relationship can be used to link multiple road events to a common "parent", such as a project or phase, or identify a sequence of road events.

Relationships show up on the feed as as a relationship property on the road_events feature properties. A road event can have one relationship object, but multiple relationships, as the value for each relationship field (e.g. parents) is an array.

relationships

optional

Identify both sequential and hierarchical relationships between road events and other entities. For example, a relationship can be used to link multiple road events to a common "parent", such as a project or phase, or identify a sequence of road events.

Relationships show up on the feed as as a relationship property on the road_events feature properties.

Table Structure

Data Name Data Type Description Conformance Notes
relationship_id ID Identifies the relationship record Required Primary key
road_event_id ID Identifies the road event to which a relationship applies. Required Foreign key to road_events table
relationship_type Enumeration; Text
  • first
  • next
  • parents
  • children
Characterizes the type of relationship between the road event feature and linked object Required
  • The first and next types define sequential relationships
  • The parents and children types define hierarchical relationships
related_id Text Primary key of the linked feature or object Required May contain a singula ID or an array of IDs separated by commas.

Changes to the feed structure

The subidentifier field is removed and a new relationship field is added to the road event feature "properties".

Examples

Hierarchical Example

  • In the example below, the first road event feature ("road_event_id": "1") is the parent of the second, third, and fourth features ("road_event_id": "2", "road_event_id": "3", "road_event_id": "4"). A non-road event, "project-1", is the parent of all of the road events.
  • Note the relationship in the first feature ("road_event_id": "1") can be left blank. The children can point to the parent with the same effect, or visa versa.
{
  "road_event_feed_info": {},
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "road_event_id": "1",
        "relationship": {
          "parents": ["project-1"],
          "children": ["2", "3", "4"]
         }
         ...
      },
      "geometry": {
        "type": "LineString",
        "coordinates": []
      }
    },
    {
      "type": "Feature",
      "properties": {
        "road_event_id": "2",
        "relationship": {
          "parents": ["1", "project-1"]
        }
      },
        "geometry": {
          "type": "LineString",
          "coordinates": []
      }
    },
    {
      "type": "Feature",
      "properties": {
        "road_event_id": "3",
        "relationship": {
          "parents": ["1", "project-1"]
        }
      },
      "geometry": {
        "type": "LineString",
        "coordinates": []
      }
    },
    {
      "type": "Feature",
      "properties": {
        "road_event_id": "4",
        "relationship": {
          "parents": ["1", "project-1"]
        }
      },
      "geometry": {
        "type": "LineString",
        "coordinates": []
      }
    }
  ]
}

Sequential Example

  • The example below shows how to relate and order road event features.
  • The first road event feature ("road_event_id": "1") begins the sequence and identifies the second feature ("road_event_id": "2") as next in the sequence.
  • The second feature identifies the first feature ("road_event_id": "1") as the beginning of the sequence and the third feature ("road_event_id": "3") as next in the sequence.
  • The third feature identifies the first feature ("road_event_id": "1") as the beginning of the sequence and the fourth feature ("road_event_id": "4") as next in the sequence.
  • The fourth feature identifies the first feature ("road_event_id": "1") as the beginning of the sequence.
{
  "road_event_feed_info": {},
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "road_event_id": "1",
        "relationship": {
          "first": ["1"],
          "next": ["2"]
        }
      },
      "geometry": {
        "type": "LineString",
        "coordinates": []
      }
    },
    {
      "type": "Feature",
      "properties": {
        "road_event_id": "2",
        "relationship":  {
          "first": ["1"],
          "next": ["3"]
        }
      },
        "geometry": {
          "type": "LineString",
          "coordinates": []
      }
    },
    {
      "type": "Feature",
      "properties": {
        "road_event_id": "3",
        "relationship":  {
          "first": ["1"],
          "next": ["4"]
         }
      },
      "geometry": {
        "type": "LineString",
        "coordinates": []
      }
    },
    {
      "type": "Feature",
      "properties": {
        "road_event_id": "4",
        "relationship":  {
          "first": ["1"]
        }
      },
      "geometry": {
        "type": "LineString",
        "coordinates": []
      }
    }
  ]
}

@DeraldDudley DeraldDudley changed the base branch from master to v3.0 July 23, 2020 18:37
@j-d-b j-d-b changed the title V3 relationship object Identify relationship between road events using the "Relationship" object from JSCalendar Jul 24, 2020
@DeraldDudley DeraldDudley marked this pull request as ready for review July 25, 2020 01:49
@j-d-b
Copy link
Collaborator

j-d-b commented Aug 7, 2020

@j-d-b
Copy link
Collaborator

j-d-b commented Aug 7, 2020

FYI this is called the "relation" object in JSCalendar, not "relationship". Not sure we need to follow that but wanted to make sure it was clear.

@j-d-b j-d-b changed the title Identify relationship between road events using the "Relationship" object from JSCalendar Identify relationship between road events using the "Relation" object from JSCalendar Aug 7, 2020
@j-d-b
Copy link
Collaborator

j-d-b commented Aug 7, 2020

@DeraldDudley I read through the JSCalendar Relation section 1.4.10 several times and it's still not completely clear to me, however I don't believe how this implementation proposes its usage matches up with the definition in JSCalendar. Specifically, since we don't care about types in WZDx, the only property on the relation object is relation. JSCalendar allows a "set of relation objects".

  • relation: "String[Boolean]" (optional, default: empty Object)
    Describes how the linked object is related to the linking object. The relation is defined as a set of relation types. If empty, the relationship between the two objects is unspecified.

I was wondering what the "String[Boolean]" part meant, and earlier up in the document it describes how types are defined:

"A[B]" - A JSON object where the keys are all of type "A", and the values are all of type "B".

That means an example of the relation object is

{
    "relation": {
        "first": true
    }
}

and as a set (I'm assuming that means array, but it's not as clear as I'd like):

"fieldUsingRelationObject": [
    {
        "relation": {
            "first": true,
            "parent": true
        }
    },
    {
        "relation": {
            "next": false
        }
    }
]

Seems slightly useless in this context, but maybe I'm missing something. Either way I don't think using the relation object like JSCalendar proposes it will be relevant to WZDx.

Regardless, I'm largely ok with the proposal in this PR but think there is a need to clarify/restrict the relationship property on the road event to either an array or an object, not allowing both as in the examples in the PR text. Note the proposed file changes only allow an array, but also calls the field relationships (note the s), which if it's an array makes sense.

Rather than an array for the property itself, though, another option would be to allow arrays for the values of each of the keys (first, next, etc.) on the object. I believe this would capture the same functionality and would avoid unnecessary flexibility in splitting relations (example of that below) and ease parsing (e.g. wouldn't have to aggregate all the objects in the relationships array to find all the relations of a given type [e.g. "parent"]).

With the relationship field as an object and the values for each key as arrays, the JSON would then look like this:

{
    ...road event details
    "relationship": {
        "first": ["rd-event-1"],
        "parent": ["proj-10-s", "phase-2"]
    }
}

An an example of multiple ways to split relations if relationship(s) is an array, that would be avoided if an object (as in the above):

way 1
{
    ... road event details
    "relationships": [
        {
            "first": "rd-event-10"
        },
        {
            "next": "rd-event-12"
        }
    ]
}

way 2
{
    ... road event details
    "relationships": [
        {
            "first": "rd-event-10"
            "next": "rd-event-12"
        }
    ]
}

Let me know if you have any additional thoughts or a better understanding of the JSCalendar "Relation". I think the idea behind this PR is great and it adds a lot of functionality, but the implementation (files changed) proposed here is not quite clear enough.

@j-d-b j-d-b self-assigned this Aug 10, 2020
@j-d-b j-d-b self-requested a review August 10, 2020 19:19
@j-d-b j-d-b removed their assignment Aug 10, 2020
@DeraldDudley
Copy link
Collaborator Author

@j-d-b Thanks for making this better.

My intent is to partially adopt the JS Calendar "relation" object. The concept of keys describing relationships and values identifying the related objects works for the WZD; It has the added benefit of being more precise than the original "subidentifier" property which only indicated "parental" relationships. Maybe a better title for the PR would be "Identify relationships between road event features by using an object similar to the "Relation" object from JSCalendar."

@DeraldDudley I read through the JSCalendar Relation section 1.4.10 several times and it's still not completely clear to me, however I don't believe how this implementation proposes its usage matches up with the definition in JSCalendar. Specifically, since we don't care about types in WZDx, the only property on the relation object is relation. JSCalendar allows a "set of relation objects".

  • relation: "String[Boolean]" (optional, default: empty Object)
    Describes how the linked object is related to the linking object. The relation is defined as a set of relation types. If empty, the relationship between the two objects is unspecified.

I was wondering what the "String[Boolean]" part meant, and earlier up in the document it describes how types are defined:

"A[B]" - A JSON object where the keys are all of type "A", and the values are all of type "B".

That means an example of the relation object is

{
    "relation": {
        "first": true
    }
}

and as a set (I'm assuming that means array, but it's not as clear as I'd like):

"fieldUsingRelationObject": [
    {
        "relation": {
            "first": true,
            "parent": true
        }
    },
    {
        "relation": {
            "next": false
        }
    }
]

Seems slightly useless in this context, but maybe I'm missing something. Either way I don't think using the relation object like JSCalendar proposes it will be relevant to WZDx.

Regardless, I'm largely ok with the proposal in this PR but think there is a need to clarify/restrict the relationship property on the road event to either an array or an object, not allowing both as in the examples in the PR text. Note the proposed file changes only allow an array, but also calls the field relationships (note the s), which if it's an array makes sense.

Rather than an array for the property itself, though, another option would be to allow arrays for the values of each of the keys (first, next, etc.) on the object. I believe this would capture the same functionality and would avoid unnecessary flexibility in splitting relations (example of that below) and ease parsing (e.g. wouldn't have to aggregate all the objects in the relationships array to find all the relations of a given type [e.g. "parent"]).

With the relationship field as an object and the values for each key as arrays, the JSON would then look like this:

{
    ...road event details
    "relationship": {
        "first": ["rd-event-1"],
        "parent": ["proj-10-s", "phase-2"]
    }
}

An an example of multiple ways to split relations if relationship(s) is an array, that would be avoided if an object (as in the above):

way 1
{
    ... road event details
    "relationships": [
        {
            "first": "rd-event-10"
        },
        {
            "next": "rd-event-12"
        }
    ]
}

way 2
{
    ... road event details
    "relationships": [
        {
            "first": "rd-event-10"
            "next": "rd-event-12"
        }
    ]
}

Let me know if you have any additional thoughts or a better understanding of the JSCalendar "Relation". I think the idea behind this PR is great and it adds a lot of functionality, but the implementation (files changed) proposed here is not quite clear enough.

My intent is to enable an optional collection of key/value pairs which identify and describe relationships among features. I like the method you suggest of allowing arrays for the values of each of the keys.

{
    ...road event details
    "relationships": {
        "first": ["rd-event-1"],
        "next": ["rd-event-3"],
        "parent": ["proj-10-s", "phase-2"]
    }
}

@j-d-b j-d-b removed their request for review August 11, 2020 17:23
@j-d-b j-d-b changed the title Identify relationship between road events using the "Relation" object from JSCalendar Identify both sequential and hierarchical relationships between road events and other entities Aug 11, 2020
@j-d-b
Copy link
Collaborator

j-d-b commented Aug 11, 2020

Finished the changes here and updated the first comment with semantic headers + to reflect the new changes.

Copy link
Contributor

@chuehlien chuehlien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants