~ihabunek/triglav

9ed962974e9931fff77ecf36a3c444ec201065c2 — Ivan Habunek 9 months ago 9a0a35d
Show route relations on map
M assets/js/routes.js => assets/js/routes.js +11 -8
@@ 1,18 1,21 @@
import "leaflet/dist/leaflet.css";
import { Map, TileLayer, Marker, Icon, FeatureGroup } 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 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 });
  '&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 stops = JSON.parse(document.getElementById("stops-json").innerHTML)
const icon = new Icon({ iconUrl: "/images/stop.svg", iconSize: [14, 14] })

const waysGeoJSON = JSON.parse(document.getElementById("ways-geojson").innerHTML)
L.geoJSON(waysGeoJSON).addTo(map)

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

M lib/triglav/schemas/osmosis/way.ex => lib/triglav/schemas/osmosis/way.ex +3 -0
@@ 20,6 20,9 @@ defmodule Triglav.Schemas.Osmosis.Way do
    field :linestring, Geo.PostGIS.Geometry
    field :node_ids, {:array, :integer}, source: :nodes

    # To contain the linestring converted to geojson
    field :geojson, :map, virtual: true

    has_many :way_nodes, WayNode
    has_many :nodes, through: [:way_nodes, :node], references: :id
  end

M lib/triglav/zet/osmosis.ex => lib/triglav/zet/osmosis.ex +14 -4
@@ 29,8 29,10 @@ defmodule Triglav.Zet.Osmosis do
  For a given list of relations returns all included members of the :way variety
  which do not have a role (to skip stations entered as ways).
  """
  @spec list_ways([Relation.t()]) :: Way.t()
  def list_ways(relations) do
  @spec list_ways([Relation.t()], Keyword.t()) :: Way.t()
  def list_ways(relations, opts \\ []) do
    geojson = Keyword.get(opts, :geojson, false)

    ids =
      relations
      |> Enum.map(fn r ->


@@ 40,8 42,16 @@ defmodule Triglav.Zet.Osmosis do
      end)
      |> List.flatten()

    from(w in Way, where: w.id in ^ids)
    |> Repo.all()
    if geojson do
      from(w in Way,
        select: %{w | geojson: fragment("st_asgeojson(?)", w.linestring)},
        where: w.id in ^ids
      )
      |> Repo.all()
    else
      from(w in Way, where: w.id in ^ids)
      |> Repo.all()
    end
  end

  @doc """

M lib/triglav_web/controllers/zet/routes_controller.ex => lib/triglav_web/controllers/zet/routes_controller.ex +29 -1
@@ 53,6 53,8 @@ defmodule TriglavWeb.Zet.RoutesController do
      |> Enum.map(&Map.take(&1, [:id, :name, :lat, :lon]))
      |> Jason.encode!()

    ways_geojson = ways_geojson_feature_collection(relations) |> Jason.encode!(pretty: true)

    render(conn, "detail.html",
      conn: conn,
      route: route,


@@ 61,10 63,36 @@ defmodule TriglavWeb.Zet.RoutesController do
      errors: errors,
      rel_errors: rel_errors,
      trips: trips,
      stops_json: stops_json
      stops_json: stops_json,
      ways_geojson: ways_geojson
    )
  end

  defp ways_geojson_feature_collection(relations) do
    features =
      for {relation, idx} <- Enum.with_index(relations), Relation.is_route(relation) do
        coordinates =
          Osmosis.list_ways(relations, geojson: true)
          |> Enum.map(&(&1.geojson |> Jason.decode!() |> Map.get("coordinates")))

        %{
          type: "Feature",
          properties: %{
            idx: idx
          },
          geometry: %{
            type: "MultiLineString",
            coordinates: coordinates
          }
        }
      end

    %{
      type: "FeatureCollection",
      features: features
    }
  end

  defp match_trips_with_relations(trips, relations, platforms) do
    route_relations = Enum.filter(relations, &Relation.is_route/1)


M lib/triglav_web/templates/zet/routes/detail.html.eex => lib/triglav_web/templates/zet/routes/detail.html.eex +4 -0
@@ 11,6 11,10 @@
  <%= raw(@stops_json) %>
</script>

<script id="ways-geojson" type="application/json">
  <%= raw(@ways_geojson) %>
</script>

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