I am using Gmaps4rails gem. I could show markers without Infowindow, but after adding Infowindow in the controller, any markers do not appear. As the following, the Infowindow is rendered with partial.
What should I change the code? Thank you in advance.
clinics_controller.rb
#hash = Gmaps4rails.build_markers(#clinics) do |clinic, marker|
marker.lat clinic.latitude
marker.lng clinic.longitude
marker.json({:id => clinic.id})
marker.picture ({
"url" => "/images/red-dot.png",
"width" => 32,
"height" => 32
})
marker.infowindow render_to_string(partial: "map_infowindow", locals: {clinic: clinic})
end
_map_infowindow.html.erb
<h3><%= clinic.name %></h3>
Javascript
<script type="text/javascript" charset="utf-8">
handler = Gmaps.build('Google');
handler.buildMap({
provider: {
zoom: 15,
center: {lat: 35.765, lng: 139.62}
},
internal: {id: 'map'}},
function(){
markers = handler.addMarkers(<%= raw #hash.to_json %>);
}
);
</script>
Related
on my search page I have a google map with markers for each 'job'. I have made the map default to zoom level 2, where the markers cluster correctly, but as soon as I pass zoom level 5, clustering stops working. I have searched and haven't found any information on this.
Search page map javascript:
<script type="text/javascript">
var mapStyle = [{"featureType":"administrative","elementType":"all","stylers":[{"visibility":"on"},{"lightness":33}]},{"featureType":"landscape","elementType":"all","stylers":[{"color":"#f2e5d4"}]},{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#c5dac6"}]},{"featureType":"poi.park","elementType":"labels","stylers":[{"visibility":"on"},{"lightness":20}]},{"featureType":"road","elementType":"all","stylers":[{"lightness":20}]},{"featureType":"road.highway","elementType":"geometry","stylers":[{"color":"#c5c6c6"}]},{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#e4d7c6"}]},{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#fbfaf7"}]},{"featureType":"water","elementType":"all","stylers":[{"visibility":"on"},{"color":"#acbcc9"}]}];
var handler = Gmaps.build('Google');
handler.buildMap({
provider: {
styles: mapStyle,
minZoom: 2,
maxZoom: 18,
center: new google.maps.LatLng(20.68177501, -103.3514794)
},
internal: {id: 'map'}},
function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
</script>
Jobs controller:
def index
if params[:search].present?
#q = Gig.near(params[:search], 200, :order => 'distance' ).ransack(params[:q])
#gigs = #q.result(distinct: true)
#hash = Gmaps4rails.build_markers(#gigs) do |gig, marker|
marker.lat gig.latitude
marker.lng gig.longitude
marker.title gig.title
end
else
#q = Gig.ransack(params[:q])
#gigs = #q.result(distinct: true)
#hash = Gmaps4rails.build_markers(#gigs) do |gig, marker|
marker.lat gig.latitude
marker.lng gig.longitude
marker.title gig.title
end
end
end
Any insight into this would be great, thanks.
Relevant code lives here.
Here is where you can customize the behavior.
So you can adpat the maxZoom level :
var handler = Gmaps.build('Google', {
markers: {
clusterer: {
maxZoom: 8,
gridSize: 50
}
}
});
How can I enable clustering so instead of showing markers it is clustered? For example: https://www.police.uk/metropolitan/00BK17N/crime/
users_controller
class UsersController < ApplicationController
def index
#users = User.all
#hash = Gmaps4rails.build_markers(#users) do |user, marker|
marker.lat user.latitude
marker.lng user.longitude
marker.infowindow user.description
end
end
end
index.html.erb
<div id="map-container">
<div id="map-canvas"></div>
</div>
<script>
$(document).ready(function(){
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map-canvas'}}, function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>)
handler.bounds.extendWith(markers);
handler.fitMapToBounds(markers);
if(navigator.geolocation)
navigator.geolocation.getCurrentPosition;
});
});
</script>
Appreciate your help guys
Did you try this?
https://github.com/apneadiving/Google-Maps-for-Rails/wiki/Markers#displaying-your-markers
Simply passing do_clustering => true should enable it. It's false by default.
Example:
<%= gmaps("markers" => { "data" => #markers, "options" => { "do_clustering" => true } }) %>
Users can post 'notices' and these are displayed in users/show.html.erb in their 'notice feed'. Each notice has a :latitude and a :longitude and an associated marker on a google map.
I'm trying to make the marker change colour when the user hovers over the notice in the feed. I've given the marker the same id as the notice with marker.json({ id: notice.id }). In the notice partial, each notice is uniquely identified by its id: <li id="notice-<%= notice.id %>">. The problem is accessing 'markers' from within the notice partial. I want to use the code markers[<%= notice.id %>] but how do I pass 'markers' from the show javascript to the partial javascript?
Alternatively, I could do it all inside the show javascript, but the problems remains: how would I access the notice id from within the show javascript?
Users_controller.rb:
def show
#notice = #character.notices.build
#notice_feed_items = current_user.notice_feed.paginate(page: params[:notices_page])
#hash = Gmaps4rails.build_markers(#notice_feed_items) do |notice, marker|
marker.lat notice.latitude
marker.lng notice.longitude
marker.infowindow notice.content
marker.json({ id: notice.id })
end
redirect_to root_url and return unless #user.activated
end
users/show/html.erb:
<% if #notice_feed_items.any? %>
<ol class="posts">
<%= render #notice_feed_items %>
</ol>
<%= will_paginate #notice_feed_items, param_name: 'notices_page' %>
<% end %>
<script type="text/javascript">
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
map = handler.getMap();
var update_timeout = null;
google.maps.event.addListener(map, 'click', function(event){
update_timeout = setTimeout(function(){
placeMarker(event.latLng);
fillInForm(event.latLng);
document.getElementById("dropfield").focus();
}, 300);
});
google.maps.event.addListener(map, 'dblclick', function(event) {
clearTimeout(update_timeout);
});
});
function placeMarker(latLng) {
var marker = new google.maps.Marker({
position: latLng,
map: map,
draggable: false
});
}
function fillInForm(latLng) {
$('#notice_latitude').val(latLng.lat());
$('#notice_longitude').val(latLng.lng());
}
</script>
_notice.html.erb:
<li id="notice-<%= notice.id %>">
.
.
.
</li>
<script type="text/javascript">
document.getElementById("notice-<%= notice.id %>").onmouseover=function(){
markers[<%= notice.id %>].setIcon("markers/blue_MarkerA.png");
}
document.getElementById("notice-<%= notice.id %>").onmouseout=function(){
markers[<%= notice.id %>].setIcon("markers/yellow_MarkerA.png");
}
</script>
EDIT:
I'm trying to solve the problem by doing it all in show.html.erb with the following code, using grep:
<script type="text/javascript">
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
map = handler.getMap();
var update_timeout = null;
google.maps.event.addListener(map, 'click', function(event){
update_timeout = setTimeout(function(){
placeMarker(event.latLng);
fillInForm(event.latLng);
document.getElementById("dropfield").focus();
}, 300);
});
google.maps.event.addListener(map, 'dblclick', function(event) {
clearTimeout(update_timeout);
});
});
function placeMarker(latLng) {
var marker = new google.maps.Marker({
position: latLng,
map: map,
draggable: false
});
}
function fillInForm(latLng) {
$('#notice_latitude').val(latLng.lat());
$('#notice_longitude').val(latLng.lng());
}
$("#notice_list li").on('mouseenter', function(){
var id = $(this).attr('id');
$.grep(markers, function(m){return m.id == id;})[0].setIcon("markers/blue_MarkerA.png");
}).on('mouseleave', function(){
var id=$(this).attr('id');
$.grep(markers, function(m){return m.id == id;})[0].setIcon("markers/yellow_MarkerA.png");
});
</script>
... but it isn't working. I think the problem is that trying to access the id of each marker in markers with m.id isn't working. I tried to get it to print out markers[0].id but nothing happened, it seems you can't access the marker id with markers[0].id?! (I checked markers.length wasn't zero. It wasn't - the map is full of markers).
So, how do you access the id of an element of markers if markers[0].id doesn't work??
marker haven't id attribute. To have a reference of each marker you could use the index of the markers array (adding markers one per one).
# pseudocode
<% #notice_feed_items.each do |item| %>
markers[<%= item.id %>] = handler.addMarker(<%=raw item.to_json %>);
<% end %>
I'm trying to dynamically update the markers on a google map using gmaps4rails (i.e. with an AJAX call back). I'm finding the documentation for gmaps4rails very scattered and unclear.
I've successfully been able to display markers on a map using the build_markers method (as per the video tutorial v2).
My controller code:
# GET /telemetry_recordings
def index
#telemetry_recordings = TelemetryRecording.all
#hash = Gmaps4rails.build_markers(#telemetry_recordings) do |telemetry_recording, marker|
marker.lat telemetry_recording.latitude
marker.lng telemetry_recording.longitude
marker.title telemetry_recording.delivery_unit.driver.full_name
marker.infowindow telemetry_recording.delivery_unit.driver.full_name
end
end
My view code:
<script type="text/javascript">
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
</script>
Now, to implement a dynamic update, I've added the following script to my view:
<script type="text/javascript">
jQuery(function($) {
$('body').on('click', '#replace_markers', function(){
$.getJSON("/telemetry_recordings", function(data){
Gmaps.map.replaceMarkers(data);
});
});
});
</script>
As well as a button:
<button id="replace_markers">Refresh</button>
And, I've added the following code to my controller:
respond_to :json, :html
# GET /telemetry_recordings
def index
#json = TelemetryRecording.all.to_gmaps4rails
respond_with #json
end
Note: TelemetryRecording class has 3 attributes: latitude (float), longitude (float) and location_time (DateTime)
This results in the following error:
undefined method `to_gmaps4rails' for #<TelemetryRecording::ActiveRecord_Relation:0x55dee78>
As per the documentation, I've installed the gmaps4rails gem, added //= require underscore and
//= require gmaps/google to my application.js file, and included the following scripts in my view:
<script src="//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js" type="text/javascript"></script>
<script src="//maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=geometry" type="text/javascript"></script>
Am I using to_gmaps4rails correctly here? (my understanding is that it converts an object with latitude/longitude attributes to an array of markers, e.g. [{"lat":"x", "lng":"y"}, {"lat":"x", "lng":"y"}]. Why is it undefined?
You're using code from v1.x and 2.x.
to_gmaps4rails has been removed from the code base. So your first shot was ok:
def index
#hash = Gmaps4rails.build_markers(TelemetryRecording.all) do |telemetry_recording, marker|
marker.lat telemetry_recording.latitude
marker.lng telemetry_recording.longitude
marker.title telemetry_recording.delivery_unit.driver.full_name
marker.infowindow telemetry_recording.delivery_unit.driver.full_name
end
respond_with #hash
end
and in the js
<script type="text/javascript">
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
var markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
$('body').on('click', '#replace_markers', function(){
$.getJSON("/telemetry_recordings", function(newMarkers){
handler.removeMarkers(markers); // to remove previous markers
markers = handler.addMarkers(newMarkers);
});
});
});
});
</script>
I can't figure out how to display the sidebar for google map on my rails app.
It's been a while and i can't find any sources on that subject. The v2 of the gem changed a lot and i'm not skilled enaught.
This is my code:
view:
<div style='width: 800px;'>
<div id="map" style='width: 800px; height: 400px;'></div>
</div>
<div id='markers_list'></div>
<script type="text/javascript">
$(document).ready(function(){
var raw_markers = <%=raw #hash.to_json %>;
var gmaps_markers;
function createSidebarLi(property_json) {
return ("<li><a>" + property.titre + " - " + property.address + "<\/a></li>");
};
function bindLiToMarker($li, marker){
$li.click(function(){
marker.panTo(); //to pan to the marker
google.maps.event.trigger(marker.getServiceObject(), "click"); // to open infowindow
});
};
function createSidebar(){
for (var i=0;i<raw_markers.length;i++){
var $li = $( createSidebarLi(raw_markers[i]) );
$li.appendTo($('#markers_list'));
bindLiToMarker($li, gmaps_markers[i]);
}
};
handler = Gmaps.build('Google', {markers: { maxRandomDistance: 1} });
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(raw_markers);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
createSidebar();
});
});
google.maps.event.addListener(marker, 'mouseout', function(){
infowindow.open(marker.get('map'), marker);
});
</script>
controller:
def index
#properties = Property.all
#hash = Gmaps4rails.build_markers(#properties) do |property, marker|
marker.lat property.latitude
marker.lng property.longitude
marker.infowindow property.titre
end
end
Can somebody help me ?
You made several mistakes, variable names etc...
I made you a working plunkr here.
If you need documentation, check here.
To pass additional info in the json:
#hash = Gmaps4rails.build_markers(#properties) do |property, marker|
marker.lat property.latitude
marker.lng property.longitude
marker.infowindow property.titre
marker.json({ titre: property.marker, address: property. address})
end