0

我在 Ruby on Rails 中有一个项目

我想知道今天对于金钱/功能来说最好的地理位置/地图提供商是什么,是否有免费的有限功能提供商。

用于 RoR 项目的最佳 gem 是什么?

4

2 回答 2

1

对于一般映射,没有一个很好的宝石。而是查看 Google Maps API 并使用 Javascript 来创建地图。正如 Philip 所说,geocodergem 非常适合处理地址查找、距离和附近。但是,它没有内置到 gem 中的地图部分。相反,您可以创建一个迁移到需要地理定位的模型并使用地理编码器 gem 来获取准确的经度和纬度。但是,只要该宝石可以带您在地图上进行简单绘图即可。将坐标存储在数据库中后,您可以使用 Javascript 和 Google Maps API 显示带有标记的地图。

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

他们的文档非常好,帮助我在我的 rails 应用程序上获得了必要的地图和标记。您还可以注册一个免费的 api 密钥,每天可以为您提供 25k 次地图访问请求。企业帐户每天允许 10 万个请求。

这是一个示例,我使用 Google Maps API 来显示一个人的当前位置以及我的数据库中最近的项目标记。

<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>
于 2013-10-01T21:06:18.380 回答
0

如果您要对地址进行地理编码,我建议您使用地理编码器 gem。

https://github.com/alexreisner/geocoder

于 2013-10-01T20:58:38.930 回答