简体   繁体   中英

GeoProvider and Gem for RoR project

I have a project in Ruby on Rails

I wonder what is the best geolocation/map provider today for money/functionality, whether there is a free limited functionality provider.

What is the best gem to use for RoR project?

For general mapping, there isn't a great gem. Instead look into the Google Maps API and use Javascript to create the maps. As Philip said, the geocoder gem is great for handling address lookup, distances and nearbys. However, it doesn't have a map portion built into the gem. Instead, you can create a migration to your model that needs the geolocation and use the geocoder gem to get the exact longitude and latitude. However, that would be as far as that gem would take you as far as simple plotting on a map. With your coordinates stored in your database, you can then use Javascript and Google Maps API to display the map with markers.

https://developers.google.com/maps/documentation/javascript/tutorial

Their documentation is really good and helped me get the necessary maps and markers on my rails app. You can also sign up for a free api key which will give you 25k requests per day for the map access. Business accounts allow for 100k requests per day.

Here is an example where I used the Google Maps API to display the current location of a person and the nearest markers of items in my database.

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=<%= google_maps_api_key %>&sensor=false"></script>
<body onload="start_location()">
<script type="text/javascript">
    function start_location() {
        var myLatlng = new google.maps.LatLng(0,0);
        var markersArray = [];
        var markersWorkGroupArray = [];
        var work_groups_list = [];
        var mapOptions = {
          center: myLatlng,
          zoom: 16,
          zoomControl: false,
          scaleControl: false,
          streetViewControl: false,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
        <% @work_groups = @company.work_groups.where("address IS NOT NUL") %>
        <% @work_groups.each do |work_group| %>
            <% if work_group.address.present?%>
            var temp_map = new google.maps.LatLng(<%= work_group.latitude %>,<%= work_group.longitude %>)
            addWorkGroupCircle(temp_map, <%= @company.miles / 0.000621371 %>);
            var temp_work_group = {
                wg_name: "<%= work_group.name %>",
                wg_latitude: <%= work_group.latitude %>,
                wg_longitude: <%= work_group.longitude %>
                };
            work_groups_list.push(temp_work_group);
        <% end %><% end %>

        navigator.geolocation.watchPosition(getCoor, errorCoor, {maximumAge:1000, enableHighAccuracy:true});

        function getCoor(position) {
                var myLatlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
                document.getElementById('gps').innerHTML = "<p><a href='/<%= @company.company_shortname %>.dashboard' class='btn btn-block btn-primary'>return to login</a></p><p>Accuracy: " + position.coords.accuracy + "m<br>Location Found: "+Math.round (position.coords.latitude * 10000) / 10000+" "+Math.round (position.coords.longitude * 10000) / 10000 + "</p>";
                deleteOverlays();
                addCircle(myLatlng, position.coords.accuracy);
                addMarker(myLatlng);
                map.setCenter(myLatlng);
                document.getElementById('work_groups').innerHTML = work_groups_list[0].wg_name;
                var temp_array = [];
                var temp_string = "";
                for (i in work_groups_list) {
                    var temp_distance = calculate_distance(work_groups_list[i].wg_latitude,work_groups_list[i].wg_longitude,position.coords.latitude,position.coords.longitude);
                    temp_array.push({
                        wg_distance: temp_distance, 
                        wg_name: work_groups_list[i].wg_name
                    });
                }
                temp_array.sort(function(a,b){return a.wg_distance - b.wg_distance});
                for (i in temp_array.slice(0,4)) {
                    temp_string = temp_string + temp_array[i].wg_name + ": " + temp_array[i].wg_distance + " miles<br>";
                }
                document.getElementById('work_groups').innerHTML = temp_string;
        };
        function errorCoor(position) {
        };

        function addMarker(location) {
          var marker = new google.maps.Marker({
            position: location,
            map: map,
            title: 'You are here'
          });
          markersArray.push(marker);
        }   

        function addCircle(location,size) {
        var milesOptions = {
              strokeColor: '#00FF00',
              strokeOpacity: 0.3,
              strokeWeight: 2,
              fillColor: '#00FF00',
              fillOpacity: 0.15,
              map: map,
              center: location,
              radius: size
            };

            var milesCircle = new google.maps.Circle(milesOptions);
            markersArray.push(milesCircle);
        }   

        function addWorkGroupCircle(location,size) {
        var milesWorkGroupOptions = {
              strokeColor: '#0000FF',
              strokeOpacity: 0.3,
              strokeWeight: 2,
              fillColor: '#0000FF',
              fillOpacity: 0.15,
              map: map,
              center: location,
              radius: size
            };

            var milesWorkGroupCircle = new google.maps.Circle(milesWorkGroupOptions);
            markersWorkGroupArray.push(milesWorkGroupCircle);
        }   

        function deleteOverlays() {
          if (markersArray) {
            for (i in markersArray) {
              markersArray[i].setMap(null);
            }
            markersArray.length = 0;
          }
        }   

        Number.prototype.toRad = function() {
           return this * Math.PI / 180;
        }
        function calculate_distance(lat1, lon1, lat2, lon2) {
            var R = 6371;
            var x1 = lat2-lat1;
            var dLat = x1.toRad();  
            var x2 = lon2-lon1;
            var dLon = x2.toRad();  
            var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
                            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * 
                            Math.sin(dLon/2) * Math.sin(dLon/2);  
            var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
            var d = R * c;
            return (d * 0.6214).toFixed(3);
        } 



    }
</script>
<div id="map_canvas" style="width:100%;height:300px;">Loading map...</div>
<div id="gps"></div>
<div id="work_groups" class="well small-well"></div>
</body>

If you're looking to geocode addresses, I'd recommend the geocoder gem.

https://github.com/alexreisner/geocoder

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM