~ihabunek/triglav

7cbad225e849bdc6e92053a7a08b6945697ed4e4 — Ivan Habunek 8 months ago c80b8e9
Validate gtfs stop ids populated
3 files changed, 40 insertions(+), 7 deletions(-)

M lib/triglav/schemas/error.ex
M lib/triglav/zet/errors.ex
M lib/triglav/zet/validator.ex
M lib/triglav/schemas/error.ex => lib/triglav/schemas/error.ex +9 -0
@@ 83,6 83,15 @@ defmodule Triglav.Schemas.Error do
      params: %{tags: tags}
    }

  @spec relation_missing_gtfs_stop_ids(Route.t(), Relation.t(), integer()) :: Error.t()
  def relation_missing_gtfs_stop_ids(%Route{} = route, %Relation{} = relation, count),
    do: %__MODULE__{
      key: "relation_missing_gtfs_stop_ids",
      route_id: route.id,
      relation_id: relation.id,
      params: %{count: count}
    }

  @spec invalid_tag_value(Route.t(), Relation.t(), String.t(), String.t(), String.t()) ::
          Error.t()
  def invalid_tag_value(%Route{} = route, %Relation{} = relation, name, actual, expected),

M lib/triglav/zet/errors.ex => lib/triglav/zet/errors.ex +4 -0
@@ 32,6 32,10 @@ defmodule Triglav.Zet.Errors do
    "Unexpected tags: #{Enum.join(tags, ", ")}"
  end

  def render(%Error{key: "relation_missing_gtfs_stop_ids", params: %{"count" => count}}) do
    "Missing gtfs:stop_id tags on #{count} platforms"
  end

  def render(%Error{
        key: "invalid_tag_value",
        params: %{"name" => name, "expected" => expected, "actual" => actual}

M lib/triglav/zet/validator.ex => lib/triglav/zet/validator.ex +27 -7
@@ 13,24 13,30 @@ defmodule Triglav.Zet.Validator do
  def validate_all_routes() do
    routes = Gtfs.list_routes()
    relations = Osmosis.list_public_transport_relations(members: true)
    relation_stop_ids = relations |> Enum.map(& &1.id) |> Osmosis.list_gtfs_stop_ids()
    ways = Osmosis.list_ways(relations) |> Map.new(&{&1.id, &1})

    for route <- routes do
      route_relations = Enum.filter(relations, &(Relation.ref(&1) == route.id))
      validate_route(route, route_relations, ways)
      validate_route(route, route_relations, ways, relation_stop_ids)
    end
    |> List.flatten()
  end

  @spec validate_route(Route.t(), [Relation.t()], %{required(integer) => Way.t()}) :: [Error.t()]
  def validate_route(route, relations, ways) do
  @spec validate_route(
          Route.t(),
          [Relation.t()],
          %{integer() => Way.t()},
          %{integer() => [integer()]}
        ) :: [Error.t()]
  def validate_route(route, relations, ways, relation_stop_ids) do
    [
      validate_has_relations(route, relations),
      validate_has_route_master(route, relations),
      validate_routes_are_contained_in_route_master(route, relations),
      validate_routes_master_route_has_no_unknown_members(route, relations),
      Enum.map(relations, &validate_route_master_relation(route, &1)),
      Enum.map(relations, &validate_route_relation(route, &1, ways))
      Enum.map(relations, &validate_route_relation(route, &1, ways, relation_stop_ids))
    ]
    |> List.flatten()
    |> Enum.filter(& &1)


@@ 120,7 126,8 @@ defmodule Triglav.Zet.Validator do
  defp validate_route_relation(
         %Route{} = route,
         %Relation{tags: %{"type" => "route"}} = relation,
         ways
         ways,
         relation_stop_ids
       ) do
    required_tags = ["type", "route", "ref", "operator", "from", "to", "name"]



@@ 139,11 146,12 @@ defmodule Triglav.Zet.Validator do
      validate_required_tags(route, relation, required_tags),
      validate_allowed_tags(route, relation, allowed_tags),
      validate_tag_values(route, relation, expected_tags),
      validate_continuous_ways(route, relation, ways)
      validate_continuous_ways(route, relation, ways),
      validate_has_gtfs_stop_ids(route, relation, relation_stop_ids)
    ]
  end

  defp validate_route_relation(_, _, _), do: nil
  defp validate_route_relation(_, _, _, _), do: nil

  defp validate_is_ptv2(route, relation) do
    if !Relation.is_ptv2(relation) do


@@ 192,6 200,18 @@ defmodule Triglav.Zet.Validator do
    end)
  end

  defp validate_has_gtfs_stop_ids(route, relation, relation_stop_ids) do
    stop_ids = Map.get(relation_stop_ids, relation.id)

    if is_list(stop_ids) do
      empty_count = Enum.count(stop_ids, &is_nil/1)

      if empty_count > 0 do
        Error.relation_missing_gtfs_stop_ids(route, relation, empty_count)
      end
    end
  end

  #
  # Generic relation validators
  #