diff options
Diffstat (limited to 'app')
| -rw-r--r-- | app/assets/stylesheets/OpenLayers/custom.sass | 21 | ||||
| -rw-r--r-- | app/helpers/routes_helper.rb | 8 | ||||
| -rw-r--r-- | app/javascript/helpers/routes_map.coffee | 157 | ||||
| -rw-r--r-- | app/javascript/packs/referential_lines/show.js | 10 | ||||
| -rw-r--r-- | app/javascript/packs/routes/show.js | 123 | ||||
| -rw-r--r-- | app/javascript/routes/components/StopPointList.js | 4 | ||||
| -rw-r--r-- | app/views/referential_lines/show.html.slim | 8 |
7 files changed, 207 insertions, 124 deletions
diff --git a/app/assets/stylesheets/OpenLayers/custom.sass b/app/assets/stylesheets/OpenLayers/custom.sass index 7a5b4baf1..5a3612f99 100644 --- a/app/assets/stylesheets/OpenLayers/custom.sass +++ b/app/assets/stylesheets/OpenLayers/custom.sass @@ -2,6 +2,27 @@ .list-group-item & margin-top: 15px + .routes-labels + padding: 0 + display: flex + justify-content: space-between + flex-wrap: wrap + margin: 5px -5px + li + list-style-type: none + flex: 1 0 25% + border: 1px solid $lightgrey + padding: 5px + margin: 5px + border-radius: 5px + cursor: pointer + color: $blue + white-space: nowrap + max-width: 33% + + &:hover + background: $orange + color: white .ol-scale-line background-color: transparent diff --git a/app/helpers/routes_helper.rb b/app/helpers/routes_helper.rb index 4bffa99d4..61714a066 100644 --- a/app/helpers/routes_helper.rb +++ b/app/helpers/routes_helper.rb @@ -19,13 +19,15 @@ module RoutesHelper css end - def route_json_for_edit(route) - route.stop_points.includes(:stop_area).order(:position).map do |stop_point| + def route_json_for_edit(route, serialize: true) + data = route.stop_points.includes(:stop_area).order(:position).map do |stop_point| stop_area_attributes = stop_point.stop_area.attributes.slice("name","city_name", "zip_code", "registration_number", "longitude", "latitude", "area_type", "comment") stop_area_attributes["short_name"] = truncate(stop_area_attributes["name"], :length => 30) || "" stop_point_attributes = stop_point.attributes.slice("for_boarding","for_alighting") stop_area_attributes.merge(stop_point_attributes).merge(stoppoint_id: stop_point.id, stoparea_id: stop_point.stop_area.id).merge(user_objectid: stop_point.stop_area.user_objectid) - end.to_json + end + data = data.to_json if serialize + data end end diff --git a/app/javascript/helpers/routes_map.coffee b/app/javascript/helpers/routes_map.coffee new file mode 100644 index 000000000..85def1390 --- /dev/null +++ b/app/javascript/helpers/routes_map.coffee @@ -0,0 +1,157 @@ +class RoutesMap + constructor: (@target)-> + @initMap() + @area = [] + @seenStopIds = [] + @routes = {} + + initMap: -> + @map = new ol.Map + target: @target, + layers: [ new ol.layer.Tile(source: new ol.source.OSM()) ] + controls: [ new ol.control.ScaleLine(), new ol.control.Zoom(), new ol.control.ZoomSlider() ], + interactions: ol.interaction.defaults(zoom: true) + view: new ol.View() + + addRoutes: (routes)-> + for route in routes + @addRoute route + + addRoute: (route)-> + geoColPts = [] + geoColLns = [] + @routes[route.id] = route if route.id + stops = route.stops || route + geoColEdges = [ + new ol.Feature({ + geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stops[0].longitude), parseFloat(stops[0].latitude)])) + }), + new ol.Feature({ + geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stops[stops.length - 1].longitude), parseFloat(stops[stops.length - 1].latitude)])) + }) + ] + stops.forEach (stop, i) => + if i < stops.length - 1 + geoColLns.push new ol.Feature + geometry: new ol.geom.LineString([ + ol.proj.fromLonLat([parseFloat(stops[i].longitude), parseFloat(stops[i].latitude)]), + ol.proj.fromLonLat([parseFloat(stops[i + 1].longitude), parseFloat(stops[i + 1].latitude)]) + ]) + + geoColPts.push(new ol.Feature({ + geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stop.longitude), parseFloat(stop.latitude)])) + })) + unless @seenStopIds.indexOf(stop.stoparea_id) > 0 + @area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)] + @seenStopIds.push stop.stoparea_id + + vectorPtsLayer = new ol.layer.Vector({ + source: new ol.source.Vector({ + features: geoColPts + }), + style: @defaultStyles(), + zIndex: 2 + }) + route.vectorPtsLayer = vectorPtsLayer if route.id + vectorEdgesLayer = new ol.layer.Vector({ + source: new ol.source.Vector({ + features: geoColEdges + }), + style: @edgeStyles(), + zIndex: 3 + }) + route.vectorEdgesLayer = vectorEdgesLayer if route.id + vectorLnsLayer = new ol.layer.Vector({ + source: new ol.source.Vector({ + features: geoColLns + }), + style: [@lineStyle()], + zIndex: 1 + }) + route.vectorLnsLayer = vectorLnsLayer if route.id + @map.addLayer vectorPtsLayer + @map.addLayer vectorEdgesLayer + @map.addLayer vectorLnsLayer + + lineStyle: (highlighted=false)-> + new ol.style.Style + stroke: new ol.style.Stroke + color: if highlighted then "#ed7f00" else '#007fbb' + width: 3 + + edgeStyles: (highlighted=false)-> + new ol.style.Style + image: new ol.style.Circle + radius: 5 + stroke: new ol.style.Stroke + color: if highlighted then "#ed7f00" else '#007fbb' + width: 2 + fill: new ol.style.Fill + color: if highlighted then "#ed7f00" else '#007fbb' + width: 2 + + defaultStyles: (highlighted=false)-> + new ol.style.Style + image: new ol.style.Circle + radius: 4 + stroke: new ol.style.Stroke + color: if highlighted then "#ed7f00" else '#007fbb' + width: 2 + fill: new ol.style.Fill + color: '#ffffff' + width: 2 + + addRoutesLabels: -> + labelsContainer = $("<ul class='routes-labels'></ul>") + labelsContainer.appendTo $("##{@target}") + @vectorPtsLayer = null + @vectorEdgesLayer = null + @vectorLnsLayer = null + Object.keys(@routes).forEach (id)=> + route = @routes[id] + label = $("<li>#{route.name}</ul>") + label.appendTo labelsContainer + label.mouseleave => + route.vectorPtsLayer.setStyle @defaultStyles(false) + route.vectorEdgesLayer.setStyle @edgeStyles(false) + route.vectorLnsLayer.setStyle @lineStyle(false) + route.vectorPtsLayer.setZIndex 2 + route.vectorEdgesLayer.setZIndex 3 + route.vectorLnsLayer.setZIndex 1 + @fitZoom() + label.mouseenter => + route.vectorPtsLayer.setStyle @defaultStyles(true) + route.vectorEdgesLayer.setStyle @edgeStyles(true) + route.vectorLnsLayer.setStyle @lineStyle(true) + route.vectorPtsLayer.setZIndex 11 + route.vectorEdgesLayer.setZIndex 12 + route.vectorLnsLayer.setZIndex 10 + @fitZoom(route) + + fitZoom: (route)-> + if route + area = [] + route.stops.forEach (stop, i) => + area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)] + else + area = @area + boundaries = ol.extent.applyTransform( + ol.extent.boundingExtent(area), ol.proj.getTransform('EPSG:4326', 'EPSG:3857') + ) + @map.getView().fit boundaries, @map.getSize() + tooCloseToBounds = false + mapBoundaries = @map.getView().calculateExtent @map.getSize() + mapWidth = mapBoundaries[2] - mapBoundaries[0] + mapHeight = mapBoundaries[3] - mapBoundaries[1] + marginSize = 0.1 + heightMargin = marginSize * mapHeight + widthMargin = marginSize * mapWidth + tooCloseToBounds = tooCloseToBounds || (boundaries[0] - mapBoundaries[0]) < widthMargin + tooCloseToBounds = tooCloseToBounds || (mapBoundaries[2] - boundaries[2]) < widthMargin + tooCloseToBounds = tooCloseToBounds || (boundaries[1] - mapBoundaries[1]) < heightMargin + tooCloseToBounds = tooCloseToBounds || (mapBoundaries[3] - boundaries[3]) < heightMargin + if tooCloseToBounds + @map.getView().setZoom(@map.getView().getZoom() - 1) + + +export default RoutesMap diff --git a/app/javascript/packs/referential_lines/show.js b/app/javascript/packs/referential_lines/show.js new file mode 100644 index 000000000..99c5072ef --- /dev/null +++ b/app/javascript/packs/referential_lines/show.js @@ -0,0 +1,10 @@ +import clone from '../../helpers/clone' +import RoutesMap from '../../helpers/routes_map' + +let routes = clone(window, "routes", true) +routes = JSON.parse(decodeURIComponent(routes)) + +var map = new RoutesMap('routes_map') +map.addRoutes(routes) +map.addRoutesLabels() +map.fitZoom() diff --git a/app/javascript/packs/routes/show.js b/app/javascript/packs/routes/show.js index 71777c379..c20de0800 100644 --- a/app/javascript/packs/routes/show.js +++ b/app/javascript/packs/routes/show.js @@ -1,121 +1,8 @@ import clone from '../../helpers/clone' +import RoutesMap from '../../helpers/routes_map' + let route = clone(window, "route", true) route = JSON.parse(decodeURIComponent(route)) - -const geoColPts = [] -const geoColLns = [] -const area = [] -const geoColEdges = [ - new ol.Feature({ - geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(route[0].longitude), parseFloat(route[0].latitude)])) - }), - new ol.Feature({ - geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(route[route.length - 1].longitude), parseFloat(route[route.length - 1].latitude)])) - }) -] -route.forEach(function (stop, i) { - if (i < route.length - 1) { - geoColLns.push(new ol.Feature({ - geometry: new ol.geom.LineString([ - ol.proj.fromLonLat([parseFloat(route[i].longitude), parseFloat(route[i].latitude)]), - ol.proj.fromLonLat([parseFloat(route[i + 1].longitude), parseFloat(route[i + 1].latitude)]) - ]) - })) - } - geoColPts.push(new ol.Feature({ - geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stop.longitude), parseFloat(stop.latitude)])) - })) - area.push([parseFloat(stop.longitude), parseFloat(stop.latitude)]) -}) -var edgeStyles = new ol.style.Style({ - image: new ol.style.Circle(({ - radius: 5, - stroke: new ol.style.Stroke({ - color: '#007fbb', - width: 2 - }), - fill: new ol.style.Fill({ - color: '#007fbb', - width: 2 - }) - })) -}) -var defaultStyles = new ol.style.Style({ - image: new ol.style.Circle(({ - radius: 4, - stroke: new ol.style.Stroke({ - color: '#007fbb', - width: 2 - }), - fill: new ol.style.Fill({ - color: '#ffffff', - width: 2 - }) - })) -}) -var lineStyle = new ol.style.Style({ - stroke: new ol.style.Stroke({ - color: '#007fbb', - width: 3 - }) -}) - -var vectorPtsLayer = new ol.layer.Vector({ - source: new ol.source.Vector({ - features: geoColPts - }), - style: defaultStyles, - zIndex: 2 -}) -var vectorEdgesLayer = new ol.layer.Vector({ - source: new ol.source.Vector({ - features: geoColEdges - }), - style: edgeStyles, - zIndex: 3 -}) -var vectorLnsLayer = new ol.layer.Vector({ - source: new ol.source.Vector({ - features: geoColLns - }), - style: [lineStyle], - zIndex: 1 -}) - -var map = new ol.Map({ - target: 'route_map', - layers: [ - new ol.layer.Tile({ - source: new ol.source.OSM() - }), - vectorPtsLayer, - vectorEdgesLayer, - vectorLnsLayer - ], - controls: [new ol.control.ScaleLine(), new ol.control.Zoom(), new ol.control.ZoomSlider()], - interactions: ol.interaction.defaults({ - zoom: true - }), - view: new ol.View({ - center: ol.proj.fromLonLat([parseFloat(route[0].longitude), parseFloat(route[0].latitude)]), - zoom: 13 - }) -}); -const boundaries = ol.extent.applyTransform( - ol.extent.boundingExtent(area), ol.proj.getTransform('EPSG:4326', 'EPSG:3857') -) -map.getView().fit(boundaries, map.getSize()); -let tooCloseToBounds = false -const mapBoundaries = map.getView().calculateExtent(map.getSize()) -const mapWidth = mapBoundaries[2] - mapBoundaries[0] -const mapHeight = mapBoundaries[3] - mapBoundaries[1] -const marginSize = 0.1 -const heightMargin = marginSize * mapHeight -const widthMargin = marginSize * mapWidth -tooCloseToBounds = tooCloseToBounds || (boundaries[0] - mapBoundaries[0]) < widthMargin -tooCloseToBounds = tooCloseToBounds || (mapBoundaries[2] - boundaries[2]) < widthMargin -tooCloseToBounds = tooCloseToBounds || (boundaries[1] - mapBoundaries[1]) < heightMargin -tooCloseToBounds = tooCloseToBounds || (mapBoundaries[3] - boundaries[3]) < heightMargin -if(tooCloseToBounds){ - map.getView().setZoom(map.getView().getZoom() - 1) -} +var map = new RoutesMap('route_map') +map.addRoute(route) +map.fitZoom() diff --git a/app/javascript/routes/components/StopPointList.js b/app/javascript/routes/components/StopPointList.js index 43a027084..b39fa0c9c 100644 --- a/app/javascript/routes/components/StopPointList.js +++ b/app/javascript/routes/components/StopPointList.js @@ -56,7 +56,7 @@ export default function StopPointList({ stopPoints, onDeleteClick, onMoveUpClick ) } -StopPointList.PropTypes = { +StopPointList.propTypes = { stopPoints: PropTypes.array.isRequired, onDeleteClick: PropTypes.func.isRequired, onMoveUpClick: PropTypes.func.isRequired, @@ -68,4 +68,4 @@ StopPointList.PropTypes = { StopPointList.contextTypes = { I18n: PropTypes.object -}
\ No newline at end of file +} diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim index 02d605d8c..5ea0e31bb 100644 --- a/app/views/referential_lines/show.html.slim +++ b/app/views/referential_lines/show.html.slim @@ -17,7 +17,8 @@ @line.human_attribute_name(:transport_submode) => (@line.transport_submode.present? ? t("enumerize.transport_submode.#{@line.transport_submode}") : '-'), @line.human_attribute_name(:url) => (@line.url ? @line.url : '-'), @line.human_attribute_name(:seasonal) => (@line.seasonal? ? t('true') : t('false')),} - + .col-lg-6.col-md-6.col-sm-12.col-xs-12 + #routes_map.map.mb-lg .row .col-lg-12 .h3 = t('lines.show.routes.title') @@ -79,3 +80,8 @@ .row.mt-xs .col-lg-12 = replacement_msg t('routes.search_no_results') + += javascript_tag do + | window.routes = "#{URI.escape(@routes.map{|r| {name: r.name, id: r.id, stops: route_json_for_edit(r, serialize: false)}}.to_json)}" + += javascript_pack_tag 'referential_lines/show.js' |
