Dynamically load Google Maps Markers with gmaps4rails
Here is how I did it, I only replace the markers after the user finishes panning or zooming, if you require different behavior then use a different event listener:
In your view (index.html.erb):
<%= gmaps({ "map_options" => { "zoom" => 15,
"auto_adjust" => false,
"detect_location" => true,
"center_on_user" => true }}, false, true) %>
At the bottom of your view add:
<script type="text/javascript" charset="utf-8">
function gmaps4rails_callback() {
google.maps.event.addListener(Gmaps4Rails.map, 'idle', function () {
var bounds = Gmaps4Rails.map.getBounds();
drawItems(bounds);
});
}
</script>
In application.js (using jQuery):
function drawItems(theBounds) {
var url = '/venues.json/?sw_y=' + theBounds.getSouthWest().lng() +
'&sw_x=' + theBounds.getSouthWest().lat() +
'&ne_y=' + theBounds.getNorthEast().lng() +
'&ne_x=' + theBounds.getNorthEast().lat();
$.get(url, function(newItemData) {
Gmaps4Rails.replace_markers(newItemData);
});
}
venues_controller#index:
def index
# Only pull venues within the visible bounds of the map
if (params[:sw_y] && params[:sw_x] && params[:ne_y] && params[:ne_x])
bounds = [ [params[:sw_x].to_f, params[:sw_y].to_f],
[params[:ne_x].to_f, params[:ne_y].to_f] ]
@venues_within_bounds = Venue.within_bounds(bounds)
else
@venues_within_bounds = Venue.all
end
respond_to do |format|
format.html # index.html.erb
format.json {
@data = @venues_within_bounds.collect {|v| {
:longitude => v.longitude,
:latitude => v.latitude,
:picture => v.marker_picture,
:title => v.marker_title
}
render :json => @data
}
end
end
Venue.rb model (using mongodb and mongoid):
def self.within_bounds(bounds)
self.where(:location.within => {"$box" => bounds })
end
gmaps4rails - update dynamically the markers from the database on the map without refresh the page
<script>
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%=raw @hash.to_json %>);
handler.bounds.extendWith(markers);
$( document ).ready(function() {
setInterval(function(){
$(function () {
$.ajax({
type:"GET",
url:"/path_to_controller_action",
dataType:"json",
data: {some_id:1},
success:function(result){
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
handler.removeMarkers(markers);
}
markers = [];
markers = handler.addMarkers(result);
handler.bounds.extendWith(markers);
}
})
});
}, 10000);
handler.fitMapToBounds();
handler.getMap().setZoom(17);
});
});
</script>
replace the markers with x intervel using ajax thats worked for me.
Show markers on google maps dynamically -Rails 3.2
well after struggling with jquery arrays
and json
,i was able to find this best solution...this is working in all scenarios and all i need is to handle empty and null conditions,which i already did and its working the way i needed.HOPE THIS HELPS SOMEONE
my controller
def show_nearby_locations
@nearbys = Place.near("#{params[:address]}", 5,:order => "distance",:units => :km)
@nearbys.first(10)
end
in my view file
<%= javascript_tag do%>
window.nearbys= <%=raw @nearbys.to_json %>;
<%end%>
this is my script inside view
function initialize() {
var map;
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: 'roadmap'
};
// Display a map on the page
map = new google.maps.Map(document.getElementById("map-canvas-guest"), mapOptions);
map.setTilt(45);
var markers=[];
var infoWindowContent=[];
$.each(nearbys, function(index) {
console.log( data[0][index].latitude,data[0][index].longitude );
markers.push([nearbys[index]['title'], nearbys[index]['latitude'],nearbys[index]['longitude']]);
infoWindowContent.push(['<div class="info_content" >' +
'<h3 style="color: rgb(<%= rand(0..200)%>,<%= rand(0..200)%> ,<%= rand(0..200)%>);">'+nearbys[index]['title']+'</h3>' +'</br>'+
'<p>'+nearbys[index]['about']+'</p>' +
'</div>']);
});
// Display multiple markers on a map
var infoWindow = new google.maps.InfoWindow(), marker, i;
// Loop through our array of markers & place each one on the map
for( i = 0; i < markers.length; i++ ) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
// Automatically center the map fitting all markers on the screen
map.fitBounds(bounds);
}
// Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
this.setZoom(14);
google.maps.event.removeListener(boundsListener);
});
}//initialize ends
ReplaceMarkers with gmaps4rails using javascript
You should simply use:
JSON.parse(string)
Since result from .js isn't automatically converted to an object.
Different Markers in Google Maps with gmaps4rails
Building on apneadivings answer, two possibly shorter ways come to mind:
Generic:
def gmaps4rails_marker_picture
{
"picture" => self.image_path, # image_path column has to contain something like '/assets/my_pic.jpg'.
"width" => 32, #beware to resize your pictures properly
"height" => 32 #beware to resize your pictures properly
}
end
In this case, we reuse the category column as the name for the picture:
def gmaps4rails_marker_picture
{
"picture" => "/images/" + self.category + ".png",
"width" => 32, #beware to resize your pictures properly
"height" => 32 #beware to resize your pictures properly
}
end
The only thing missing now, is a way to use sprites. But thats probably impossible.
Google Map API Marker add dynamic lable in Ruby On Rails
Step 1:
create a coffee file, name it gmaps4rails_builder.coffee
:
class @CustomMarkerBuilder extends Gmaps.Google.Builders.Marker
create_marker: ->
options = _.extend @marker_options(), @rich_marker_options()
@serviceObject = new RichMarker options
rich_marker_options: ->
marker = document.createElement("div")
marker.setAttribute('class', 'custom_marker_content')
marker.innerHTML = this.args.custom_marker
{ content: marker }
Step2:
in your view:
<script src='//google-maps-utility-library-v3.googlecode.com/svn/trunk/richmarker/src/richmarker-compiled.js' type='text/javascript'></script>
<script type="text/javascript">
var handler = Gmaps.build("Google", builders: { Marker: CustomMarkerBuilder } )
handler.buildMap({ internal: id: "map" }, function(){
var markers = handler.addMarkers(<%=raw @hash.to_json %>);
});
</script>
Step3:
In your controller:
@hash = Gmaps4rails.build_markers(@noiseDevices) do |noiseDevice, marker|
marker.lat noiseDevice.latitude
marker.lng noiseDevice.longitude
marker.json({
custom_marker: "marker html here"
})
end
gmaps4rails dynamic load question
You should declare the json as safe or render it raw:
Gmaps4Rails(<%=raw @markers %>);
Jumping markers on Google maps
Its a feature to prevent overlapping. Its documented in the code here.
You can customise or remove the behaviour, example:
handler = Gmaps.build('Google', { markers: { maxRandomDistance: null } });
adding and updating markers after map has loaded, using Gmaps4rails v2
Check the doc here
You can do:
var markers = handler.addMarkers(json_array)
var marker = handler.addMarker(json)
handler.removeMarkers(markers)
handler.removeMarker(marker)
If you read the source you'll see it handles the clusterer for you.
Related Topics
Why Do People Say That Ruby Is Slow
How to Build a Rubygems Mirror Server
How to Map/Collect with Index in Ruby
Tell Ruby Program to Wait Some Amount of Time
How to Invoke an Instance Method on a Ruby Module Without Including It
Rvm Is Not a Function, Selecting Rubies with 'Rvm Use ...' Will Not Work
Typing 'Rails Console' Doesn't Start
Why Does Ruby Have Trueclass and Falseclass Instead of a Single Boolean Class
Ruby on Rails "Invalid Byte Sequence in Utf-8" Due to Bot
Routing Nested Resources in Rails 3
How to Know What Is Not Thread-Safe in Ruby
Can Rails Migrations Be Used to Convert Data
Getting Rid of Ruby Gems That Won't Die
Rails: How to Use Dependent: :Destroy in Rails