~ihabunek/triglav

e3cee55bf60246840efd0c8c7181a588472a4961 — Ivan Habunek 11 months ago 9406672
Add maps with stops
M assets/js/routes.js => assets/js/routes.js +20 -7
@@ 1,11 1,24 @@
import "leaflet/dist/leaflet.css"
import { Map, TileLayer } from "leaflet"
import "leaflet/dist/leaflet.css";
import { Map, TileLayer, Marker, Icon, FeatureGroup } from "leaflet";

const map = new Map("routes-map").setView([45.8, 16], 10)
const map = new Map("routes-map").setView([45.8, 16], 10);

const tilesUrl = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
const attribution = '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
const tiles = new TileLayer(tilesUrl, { attribution })
const tilesUrl = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
const attribution =
  '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors';
const tiles = new TileLayer(tilesUrl, { attribution });

tiles.addTo(map)
tiles.addTo(map);

const stops = JSON.parse(document.getElementById("stops-json").innerHTML);
const icon = new Icon({ iconUrl: "/images/stop.svg", iconSize: [14, 14] })

const markers = []
for (const stop of stops) {
  const marker = new Marker(stop, { icon: icon, title: stop.name })
  markers.push(marker)
}

const group = new FeatureGroup(markers)
group.addTo(map)
map.fitBounds(group.getBounds())

A assets/static/images/stop.svg => assets/static/images/stop.svg +6 -0
@@ 0,0 1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Adapted from Font Awesome https://fontawesome.com/license -->
<svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 512 512" version="1.1">
  <circle cx="256" cy="256" r="256" fill="blue" />
  <path fill="#ffffff" d="m 415.83471,167.81533 h -5.51154 v -33.06925 c 0,-30.86464 -68.34312,-55.11542 -154.32317,-55.11542 -85.98005,0 -154.32317,24.25078 -154.32317,55.11542 v 33.06925 h -5.511545 c -9.128491,0 -16.534625,7.39924 -16.534625,16.53462 v 55.11542 c 0,9.1285 7.406134,16.53463 16.534625,16.53463 h 5.511545 v 110.23084 c 0,12.17361 9.87255,22.04616 22.04616,22.04616 v 22.04617 c 0,12.17361 9.87256,22.04617 22.04617,22.04617 h 22.04617 c 12.17362,0 22.04617,-9.87256 22.04617,-22.04617 V 388.277 h 132.277 v 22.04617 c 0,12.17361 9.87255,22.04617 22.04616,22.04617 h 22.04618 c 12.17361,0 22.04616,-9.87256 22.04616,-22.04617 V 388.277 h 4.40923 c 11.02309,0 17.63694,-8.81847 17.63694,-17.63693 V 256 h 5.51154 c 9.12849,0 16.53463,-7.40613 16.53463,-16.53463 v -55.11542 c 0,-9.13538 -7.40614,-16.53462 -16.53463,-16.53462 z M 189.8615,129.23453 c 0,-3.04512 2.46641,-5.51154 5.51154,-5.51154 h 121.25392 c 3.04512,0 5.51154,2.46642 5.51154,5.51154 v 11.02309 c 0,3.04513 -2.46642,5.51154 -5.51154,5.51154 H 195.37304 c -3.04513,0 -5.51154,-2.46641 -5.51154,-5.51154 z m -33.06925,225.97322 c -12.17363,0 -22.04617,-9.87255 -22.04617,-22.04617 0,-12.17362 9.87254,-22.04616 22.04617,-22.04616 12.17362,0 22.04616,9.87254 22.04616,22.04616 0,12.17362 -9.87254,22.04617 -22.04616,22.04617 z m 88.18466,-77.16159 h -77.16158 c -12.17362,0 -22.04617,-9.87254 -22.04617,-22.04616 v -66.1385 c 0,-12.17362 9.87255,-22.04617 22.04617,-22.04617 h 77.16158 z m 22.04618,0 V 167.81533 h 77.16157 c 12.17362,0 22.04618,9.87255 22.04618,22.04617 V 256 c 0,12.17362 -9.87256,22.04616 -22.04618,22.04616 z m 88.18466,77.16159 c -12.17362,0 -22.04617,-9.87255 -22.04617,-22.04617 0,-12.17362 9.87255,-22.04616 22.04617,-22.04616 12.17362,0 22.04617,9.87254 22.04617,22.04616 0,12.17362 -9.87255,22.04617 -22.04617,22.04617 z" />
</svg>

A lib/triglav/schemas/zet/stop.ex => lib/triglav/schemas/zet/stop.ex +19 -0
@@ 0,0 1,19 @@
defmodule Triglav.Schemas.Zet.Stop do
  use Ecto.Schema

  @primary_key false
  @schema_prefix :zet

  schema "stops" do
    field :id, :string, source: :stop_id
    field :code, :string, source: :stop_code
    field :name, :string, source: :stop_name
    field :desc, :string, source: :stop_desc
    field :lat, :float, source: :stop_lat
    field :lon, :float, source: :stop_lon
    field :zone_id, :string
    field :url, :string, source: :stop_url
    field :location_type, :integer
    field :parent_station, :string
  end
end

A lib/triglav/schemas/zet/stop_time.ex => lib/triglav/schemas/zet/stop_time.ex +18 -0
@@ 0,0 1,18 @@
defmodule Triglav.Schemas.Zet.StopTime do
  use Ecto.Schema

  @primary_key false
  @schema_prefix :zet

  schema "stop_times" do
    field :trip_id, :string
    field :arrival_time, :map
    field :departure_time, :map
    field :stop_id, :string
    field :stop_sequence, :integer
    field :stop_headsign, :string
    field :pickup_type, :integer
    field :drop_off_type, :integer
    field :shape_dist_traveled, :float
  end
end

M lib/triglav/schemas/zet/trip.ex => lib/triglav/schemas/zet/trip.ex +3 -9
@@ 5,19 5,13 @@ defmodule Triglav.Schemas.Zet.Trip do
  @schema_prefix :zet

  schema "trips" do
    field :id, :string, primary_key: true
    field :id, :string, source: :trip_id, primary_key: true
    field :headsign, :string, source: :trip_headsign
    field :short_name, :string, source: :trip_short_name
    field :route_id, :string
    field :service_id, :string
    field :trip_headsign, :string
    field :direction_id, :integer
    field :block_id, :string
    field :shape_id, :string
    field :trip_short_name, :string
    field :wheelchair_accessible, :integer
    field :direction, :string
    field :schd_trip_id, :string
    field :trip_type, :string
    field :exceptional, :integer
    field :bikes_allowed, :integer
  end
end

M lib/triglav/zet/gtfs.ex => lib/triglav/zet/gtfs.ex +15 -2
@@ 18,7 18,7 @@ defmodule Triglav.Zet.Gtfs do
    |> Triglav.Repo.one!()
  end

  def fetch_distinct_trips(route_id) do
  def fetch_distinct_trips(%Zet.Route{} = route) do
    Repo.select!(
      """
        WITH trips AS (


@@ 39,7 39,20 @@ defmodule Triglav.Zet.Gtfs do
        GROUP BY 1, 2
        ORDER BY 1 ASC, 3 DESC;
      """,
      [route_id]
      [route.id]
    )
  end

  def fetch_distinct_stops(%Zet.Route{} = route) do
    from(t in Zet.Trip,
      where: t.route_id == ^route.id,
      join: st in Zet.StopTime,
      on: st.trip_id == t.id,
      join: s in Zet.Stop,
      on: s.id == st.stop_id,
      select: s,
      distinct: true
    )
    |> Repo.all()
  end
end

M lib/triglav_web/controllers/zet/routes_controller.ex => lib/triglav_web/controllers/zet/routes_controller.ex +5 -4
@@ 48,17 48,18 @@ defmodule TriglavWeb.Zet.RoutesController do
      Validator.validate_route(route, relations, ways)
      |> group_errors_by_relation()

    trips =
      Gtfs.fetch_distinct_trips(route.id)
      |> Enum.group_by(& &1["direction_id"])
    trips = Gtfs.fetch_distinct_trips(route) |> Enum.group_by(& &1["direction_id"])
    stops = Gtfs.fetch_distinct_stops(route) |> Enum.map(&Map.take(&1, [:id, :name, :lat, :lon]))

    render(conn, "detail.html",
      conn: conn,
      route: route,
      relations: relations,
      hierarchy: hierarchy,
      errors: errors,
      rel_errors: rel_errors,
      trips: trips
      trips: trips,
      stops: stops
    )
  end


M lib/triglav_web/templates/zet/routes/detail.html.eex => lib/triglav_web/templates/zet/routes/detail.html.eex +4 -2
@@ 7,6 7,10 @@
  }
</style>

<script id="stops-json" type="application/json">
  <%= @stops|> Jason.encode!() |> raw() %>
</script>

<main role="main" class="container-wide">
  <h1>#<%= @route.id %>: <%= @route.long_name %></h1>



@@ 55,8 59,6 @@
  <p>Routes extracted from GTFS data published by ZET.
  All distinct routes are shown along with the number of trips along this route. </p>

  <%= inspect(@stops) %>

  <div id="routes-map"></div>

  <%= for {direction_id, trips} <- @trips do %>