diff options
| author | Marc Florisson | 2014-09-03 17:27:27 +0200 | 
|---|---|---|
| committer | Marc Florisson | 2014-09-03 17:27:27 +0200 | 
| commit | d7cb286c6af0b542ed5c91614424cc4b735053dc (patch) | |
| tree | 690a08c71f9d5b45c0a7c9e0bc360eb12049eb8d | |
| parent | bfa1dcaca136d8bd2733933be1eee651e2cd00d3 (diff) | |
| download | chouette-core-d7cb286c6af0b542ed5c91614424cc4b735053dc.tar.bz2 | |
make geolocation editable on stop_area#new. Mantis 26828
| -rw-r--r-- | app/controllers/stop_areas_controller.rb | 24 | ||||
| -rw-r--r-- | app/maps/stop_area_map.rb | 118 | ||||
| -rw-r--r-- | app/models/referential.rb | 4 | ||||
| -rw-r--r-- | app/views/stop_areas/_form.html.erb | 27 | 
4 files changed, 135 insertions, 38 deletions
diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb index e18f89cab..ab4900ef1 100644 --- a/app/controllers/stop_areas_controller.rb +++ b/app/controllers/stop_areas_controller.rb @@ -42,7 +42,7 @@ class StopAreasController < ChouetteController      @detail_access_links = stop_area.detail_access_link_matrix    end -  def index     +  def index      request.format.kml? ? @per_page = nil : @per_page = 12      @country_codes = referential.stop_areas.collect(&:country_code).compact.uniq      index! do |format| @@ -51,22 +51,28 @@ class StopAreasController < ChouetteController            redirect_to params.merge(:page => 1)          end        } -    end        +    end +  end + +  def new +    @map = StopAreaMap.new( Chouette::StopArea.new).with_helpers(self) +    @map.editable = true +    new!    end    def show      map.editable = false      @access_points = @stop_area.access_points      show! do |format| -      unless stop_area.position or params[:default] or params[:routing]  +      unless stop_area.position or params[:default] or params[:routing]          format.kml { -          render :nothing => true, :status => :not_found  +          render :nothing => true, :status => :not_found          } -         +        end      end    end -   +    def edit      stop_area.position ||= stop_area.default_position @@ -85,9 +91,9 @@ class StopAreasController < ChouetteController        format.json { render :json => referential.stop_areas.collect(&:country_code).compact.uniq.to_json }      end    end -   +    protected -   +    alias_method :stop_area, :resource    def map @@ -96,7 +102,7 @@ class StopAreasController < ChouetteController    def collection      @q = parent.present? ? parent.stop_areas.search(params[:q]) : referential.stop_areas.search(params[:q]) -    @stop_areas ||=  +    @stop_areas ||=        begin          stop_areas = @q.result(:distinct => true).order(:name)          stop_areas = stop_areas.paginate(:page => params[:page], :per_page => @per_page) if @per_page.present? diff --git a/app/maps/stop_area_map.rb b/app/maps/stop_area_map.rb index 3fff4a110..ee0adc0bb 100644 --- a/app/maps/stop_area_map.rb +++ b/app/maps/stop_area_map.rb @@ -10,9 +10,6 @@ class StopAreaMap < ApplicationMap    end    def customize_map(map, page) -      page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => Design::EditStopAreaStyleMap.new(helpers).style_map) -      page << map.add_layer(:edit_stop_area_layer) -        if stop_area.children.present?          page.assign "children_layer", kml_layer(stop_area, { :children => true }, :style_map => Design::StopAreasStyleMap.new(helpers).style_map)          page << map.add_layer(:children_layer) @@ -23,27 +20,106 @@ class StopAreaMap < ApplicationMap          page << map.add_control( hover_control_display_name(:routing_layer) )          page << map.zoom_to_extent(bounds.to_google.to_openlayers) if bounds        else -       -        page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => Design::EditStopAreaStyleMap.new(helpers).style_map) + + +        if stop_area.new_record? +          page << <<EOF +          var createStyleMap = function() { +            var defProp = {strokeColor: "red"}; +            var defProp = {strokeColor: "black", strokeOpacity: 1, strokeWidth: 2, fillColor: "white", fillOpacity: 1}; +            var defStyle = OpenLayers.Util.applyDefaults(defProp, OpenLayers.Feature.Vector.style["default"]); +            return new OpenLayers.StyleMap({'default': defStyle}); +          }; +          var edit_stop_area_layer = new OpenLayers.Layer.Vector( "edit_stop_area_layer", {styleMap: createStyleMap()}); + +EOF +        else +          page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => Design::EditStopAreaStyleMap.new(helpers).style_map) +        end + +          page << <<EOF +          var createAddressStyleMap = function() { +            var defProp = {strokeColor: "black", strokeOpacity: 1, strokeWidth: 2, fillColor: "#86b41d", fillOpacity: 1}; +            var defStyle = OpenLayers.Util.applyDefaults(defProp, OpenLayers.Feature.Vector.style["default"]); +            return new OpenLayers.StyleMap({'default': defStyle, }); +          }; +          var address_layer = new OpenLayers.Layer.Vector( "address_layer", {styleMap: createAddressStyleMap()}); + +          var removeAddress = function() { +            address_layer.destroyFeatures(); +          }; + +          var addAddress = function( lat, lng, name ) { +            var wgs84point = new OpenLayers.Geometry.Point( lat, lng); +            var point = transformedGeometry( wgs84point, "EPSG:4326", "EPSG:900913" ) +            var feature = new OpenLayers.Feature.Vector( point, { name: name}); +            address_layer.addFeatures( [feature]); + +            var bounds = new OpenLayers.Bounds(); +            bounds.extend( feature.geometry.getBounds()); +            for (var x in edit_stop_area_layer.features) { +                bounds.extend( edit_stop_area_layer.features[x].geometry.getBounds()); +            } +            map.zoomToExtent(bounds,true); +          }; +          var transformedGeometry = function( geometry, origin, target ) { +            return geometry.clone().transform( new OpenLayers.Projection( origin ), new OpenLayers.Projection( target )); +          } +EOF +        page << map.add_layer(:address_layer)          page << map.add_layer(:edit_stop_area_layer) -       +          if editable? -          page.assign "referential_projection", projection_type.present? ? projection("EPSG:" + projection_type) : JsVar.new("undefined")   -          # TODO virer ce code inline        +          page.assign "referential_projection", projection_type.present? ? projection("EPSG:" + projection_type) : JsVar.new("undefined") + +          # TODO virer ce code inline            page << <<EOF -          edit_stop_area_layer.events.on({  -                          'afterfeaturemodified': function(event) {  -                            geometry = event.feature.geometry.clone().transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326")); -                            $('#stop_area_coordinates').val(geometry.y.toString()+ ","+ geometry.x.toString()); - -                            if(referential_projection != undefined) -                            { -                              projection_geometry = event.feature.geometry.clone().transform(new OpenLayers.Projection("EPSG:900913"), referential_projection ); -                              $('#stop_area_projection_xy').val(projection_geometry.x.toString()+ ","+ projection_geometry.y.toString());                                                   } -                           } -                        }); + +          var getEventWGS84 = function( event) { +            return transformedGeometry( event.geometry, "EPSG:900913", "EPSG:4326"); +          } +          var getEventProjection = function( event, projCode) { +            return transformedGeometry( event.geometry, "EPSG:900913", projCode); +          } +          var updateStopAreaCoordinates = function( event ) { +            var geometry = getEventWGS84( event ); +            $('#stop_area_coordinates').val( geometry.y.toString()+ ","+ geometry.x.toString()); +          } +          var updateStopAreaProjectionXY = function( event, projCode ) { +            var geometry = getEventProjection( event, projCode); +            $('#stop_area_projection_xy').val( geometry.x.toString()+ ","+ geometry.y.toString()); +          } + +          var drawControl = new OpenLayers.Control.DrawFeature( edit_stop_area_layer, OpenLayers.Handler.Point, +              { featureAdded: function(event) { +              console.log( "featureAdded" ); +                  updateStopAreaCoordinates( event); +                  if( typeof referential_projection !== 'undefined') { +                    updateStopAreaProjectionXY( event, referential_projection.projCode); +                  } +                  this.deactivate(); +                } +              }); + +          var dragControl = new OpenLayers.Control.DragFeature( edit_stop_area_layer, +              { autoActivate: true, +                onComplete: function(event) { +                  updateStopAreaCoordinates( event); +                  if( typeof referential_projection !== 'undefined') { +                    updateStopAreaProjectionXY( event, referential_projection.projCode); +                  } +                }, +              }); +            map.addControl( dragControl); +            map.addControl( drawControl);  EOF -          page << map.add_control(OpenLayers::Control::ModifyFeature.new(:edit_stop_area_layer, :mode => 8, :autoActivate => true)) + +          if stop_area.new_record? +          page << <<EOF +            drawControl.activate(); +EOF +          end +          #page << map.add_control(OpenLayers::Control::ModifyFeature.new(:edit_stop_area_layer, :mode => 8, :autoActivate => true))          elsif stop_area.children.present?            page << map.add_control( hover_control_display_name(:children_layer) ) @@ -52,7 +128,7 @@ EOF        page << map.set_center(center.to_google.to_openlayers, 16, false, true)        end    end -   +    def projection_type      stop_area.referential.projection_type    end diff --git a/app/models/referential.rb b/app/models/referential.rb index f99c65f9f..41d239961 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -41,6 +41,10 @@ class Referential < ActiveRecord::Base      end    end +  def viewbox_left_top_right_bottom +    [  lower_corner.lng, upper_corner.lat, upper_corner.lng, lower_corner.lat ].join(',') +  end +    def human_attribute_name(*args)      self.class.human_attribute_name(*args)    end diff --git a/app/views/stop_areas/_form.html.erb b/app/views/stop_areas/_form.html.erb index e907bd2d8..5a612614b 100644 --- a/app/views/stop_areas/_form.html.erb +++ b/app/views/stop_areas/_form.html.erb @@ -7,12 +7,10 @@        <%= form.input :stop_area_type, :as => :select, :input_html => { :disabled => !@stop_area.new_record? }, :collection => Chouette::StopArea.stop_area_types, :include_blank => false, :member_label => Proc.new { |stop_area_type| t("area_types.label.#{stop_area_type}") }  %>        <div class="location_info">        <h3><%= t("stop_areas.stop_area.localisation") %></h3> -      <% if @stop_area.new_record? %>        <div id="prefetch">          <label><%= t('.geolocalize') %></label>  	      <input class="typeahead form-control input-lg" maxlength="255" type="text" placeholder="<%= t('.address') %>" />        </div> -      <% end %>        <% unless @referential.projection_type_label.empty? %>    	    <%= form.input :projection_xy, :label => t("projection_xy", :projection => @referential.projection_type_label), :input_html => { :title => t("formtastic.titles.stop_area.projection_xy")} %>  	    <% end %> @@ -64,8 +62,11 @@          name += address.house_number+" ";        }        name += address.road+", "; -      if ( address.postalcode) { -        name += address.postalcode+" "; +      if ( address.suburb) { +        name += address.suburb+", "; +      } +      if ( address.postcode) { +        name += address.postcode+" ";        }        if ( address.city) {          name += address.city; @@ -78,13 +79,19 @@        return name;      };      var filtering = function(list) { +      // update map view +      removeAddress(); +        var selection = $.grep( list, function(item) { -          return (item.type == "house" || item.type == "residential") && item.address.road ; +          return (item.type == "house" || item.type == "residential" || +            item.type == "tertiary" || item.type == "primary" || +            item.type == "secondary") && item.address.road ;            });        return $.map( selection, function( d) {            return { postcode: d.address.postcode,                     road: d.address.road,                     lon: d.lon, lat: d.lat, +                   suburb: d.address.suburb,                     city: d.address.city,                     postcode: d.address.postcode,                     the_key: address_display( d.address)}; @@ -100,7 +107,8 @@        },        limit: 10,        remote: { -        url: 'http://nominatim.openstreetmap.org/search?q=%QUERY&format=json&addressdetails=1', +        url: 'http://nominatim.openstreetmap.org/search?q=%QUERY&format=json&addressdetails=1&bounded=1&viewbox='+ +          '<%= @referential.viewbox_left_top_right_bottom %>',          filter: filtering,        }      }); @@ -124,11 +132,14 @@      );      $('.typeahead').on('typeahead:selected', function($e, datum) { -      $('input[name="stop_area[coordinates]"]').val(datum.lat+","+datum.lon); -      $('input[name="stop_area[coordinates]"]').change(); +      // update map view +      addAddress( datum.lon, datum.lat, datum.road); +      // update form fields +      <% if @stop_area.new_record? %>        $('input[name="stop_area[street_name]"]').val(datum.road);        $('input[name="stop_area[zip_code]"]').val(datum.postcode);        $('input[name="stop_area[city_name]"]').val(datum.city); +      <% end %>      })    });  </script>  | 
