automatic geolocation in ruby - ruby-on-rails

I jus started learn ruby on rails and currently I am creating my first rails app. And I ran into some problems. In my app, I would like to get user's position (latitude, longitude). So I can put the button "find me" and return user's locations. But I would like to load my page and show my position (latitude, longitude), don't press any buttons. And then use lat and lng in my controllers. How can I do this?

Add the below script in your view page.You may go ahead and modify this as needed as to show/customise messages and buttons.Remember to have a dedicated div with id="map-canvas" to show you map on the page.
I have used geocomplete.js to show map and allow user to enter places from search box .You may remove the scripts using geocomplete if not needed.
<script type="text/javascript">
// Enable the visual refresh
// google.maps.visualRefresh = true;
var map;
var mapOptions = {
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
var infowindow = new google.maps.InfoWindow({
map: map,
position: pos,
content: '<p>You are here!</p>'
});
map.setCenter(pos);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
}//initialize ends
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = '<p>Unable to find the current location</p>';
} else {
var content = '<p Your browser doesn\'t support geolocation.</p>';
}
var options = {
map: map,
zoom: 5,
position: new google.maps.LatLng(60, 105),
content: content
};
var marker = new google.maps.Marker({
position: new google.maps.LatLng(60, 105),
map: map,
animation: google.maps.Animation.DROP,
title: 'Sorry,we were unable to find your location'
});
marker.setAnimation(google.maps.Animation.BOUNCE);
var infowindow = new google.maps.InfoWindow(options);
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
infowindow.open(map,marker);
map.setCenter(options.position);
}//handleNoGeolocation ends
//load the page and execute above scripts
$(document).ready(function(){
$('#map-canvas').html("<p class='text-center text-alert'>Loading map...</p>").show(3000);
//load the map after 2 seconds
setTimeout('initialize()', 3000);
// $("#geocomplete").geocomplete({
// map: ".map-canvas-guest"
// });
//you may use this or remove this section using geocomplete.js if not needed.
$("#geocomplete").geocomplete();
$("#geocomplete").geocomplete(mapOptions).bind("geocode:result", function(event, result){
console.log(result.formatted_address);
//use this user entered address and you may call ajax here as well
})
})//document ends
</script>

Related

iOS - Google Maps Places onclick conflicts with map onclick

I have a project created with ionic. In here I have a Google Map with a places search box.
I have included the Google Map library like so:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=SOMEKEY&libraries=places" defer></script>
Now in my TypeScript code I have the following
// init the google map
initMap() {
var centerOfMap;
var draggableMarker = false;
this.mapHasBeenInitialized = true;
this.isStaticLocation = false;
centerOfMap = new google.maps.LatLng(this.locationService.gpsLat, this.locationService.gpsLong);
draggableMarker = true;
var options = {
center: centerOfMap,
zoom: 11,
fullscreenControl: false,
disableDefaultUI: true, // dont allow default zoom/sattelite/street view
gestureHandline: 'cooperative' // disable moving map with one finger
};
this.map = new google.maps.Map(this.googleMap.nativeElement, options);
this.marker = new google.maps.Marker({
position: centerOfMap,
map: this.map,
draggable: draggableMarker
});
if(!this.isStaticLocation) {
var searchBox = new google.maps.places.SearchBox(this.googleInput.nativeElement);
// add the searchbar to the google map
this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.googleInput.nativeElement);
// Bias the SearchBox results towards current map's viewport
this.map.addListener('bounds-changed', () => {
searchBox.setBounds(this.map.getBounds());
});
searchBox.addListener('places_changed', () => {
var places = searchBox.getPlaces();
if(places.length == 0) {
return;
}
var bounds = new google.maps.LatLngBounds();
places.forEach(place => {
if(!place.geometry) {
console.log("returned place contains no geometry");
return;
}
this.setMarkerLocation(place);
if(place.geometry.viewport) {
bounds.union(place.geometry.viewport);
} else {
bounds.extends(place.geometry.location);
}
});
this.map.fitBounds(bounds);
});
}
if(draggableMarker) {
google.maps.event.addListener(this.marker, 'dragend', (event)=>{
this.getMarkerLocation();
});
}
google.maps.event.addListener(this.map, 'click', (event: any)=> {
var clickedLocation = event.latLng;
this.marker.setPosition(clickedLocation);
this.getMarkerLocation();
});
// neccessary for reload. Made async to trick loading process
setTimeout(()=> {
google.maps.event.trigger(this.googleMap.nativeElement, 'resize');
this.map.setCenter(centerOfMap);
}, 100);
}
// function to set the location marker on a different spot
setMarkerLocation(place: any) {
this.marker.setMap(null);
this.marker = new google.maps.Marker({
position: place.geometry.location,
map: this.map,
draggable: true
});
this.getMarkerLocation();
}
getMarkerLocation() {
var currLoc = this.marker.getPosition();
this.locationService.setGoogleMapsLocation(currLoc.lat(), currLoc.lng());
this.locationChanged = true;
}
And this code works like a charm in the browser and on Android. Basically what the code does is whenever someone taps on the map, the marker position changes to their tap location.
When a person searches for a Place, the places dropdown will show over the map. On android, when you tap a place in this dropdown, the marker will go to the selected place (f.e. australia).
On iOS however, the marker will position itself on the location where the person tapped and will totally ignore the tap on the place dropdown.
So when I'm in Europe and I type in 'Australia' and select 'Australia' from my dropdown, on Android I'll go to australia but on iOS I'll stay somewhere in Europe wherever the dropdown was positioned.

Add more markers to markerCluster without removing previous

I build a map and add markers. When I'm calling AJAX , Some more records are coming from db and updating the location to map without reloading the map. But the problem is it is making new cluster for new records.
Here is code :
var marker, i;
var markers=[]
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
icon: locations[i][4]
});
google.maps.event.addListener(marker, 'mouseover', (function (marker, i) {
return function () {
infowindow.setContent("<img src="+locations[i][5]+" width='100%'><br> <strong>"+locations[i][0]+"</strong>");
infowindow.open(map, marker);
}
})(marker, i));
// assuming you also want to hide the infowindow when user mouses-out
marker.addListener('mouseout', function() {
infowindow.close();
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent("<img src="+locations[i][5]+" width='100%'><br> <strong>"+locations[i][0]+"</strong>");
infowindow.open(map, marker);
}
})(marker, i));
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers,{
imagePath: 'https://cdn.rawgit.com/googlemaps/js-marker-clusterer/gh-pages/images/m'
});
You can Add markers
var markers = []
var marker = new google.maps.Marker({position: center});
markers.push(marker);
markerClusterer.addMarkers(markers);
Note that here I have added only one.
You can remove all markers
markerClusterer.clearMarkers();
markers = [];
Note that for tidiness I have also unset the markers array here.
you can go through
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/docs/reference.html

Drag and update location - how to do this?

I'm trying to follow the information on your wiki, stackExchange, etc to make this work.
The idea is to create a new location for the user. The app displays a map, put a marker on the 0,0 location and then the user drag this marker to any place and the form is updated with the new lat and log. Seems trivial and there's doc in the wiki, but I could not make it work.
I'm using gem version 2.1.2 and Rails 4.1. I had success showing maps, markers, etc, but I cannot make the callback and others functions to work. I'm using this doc to try: https://github.com/apneadiving/Google-Maps-for-Rails/wiki/Javascript-goodies#drop-a-marker-and-update-fields-attribute-in-a-form
Follow my view code:
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(
[
{
"lat": 0,
"lng": 0,
draggable: true
}
]
);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
// Callback function
var markersArray = [];
var marker = handler.getMap().markers[0];
if (marker) {
// Move existing marker when editing a previously stored location
google.maps.event.addListener(marker.serviceObject, 'dragend', function() {
updateFormLocation(this.getPosition());
});
}
// On click, clear markers, place a new one, update coordinates in the form
google.maps.event.addListener(handler.getMap().serviceObject, 'click', function(event) {
clearOverlays();
placeMarker(event.latLng);
updateFormLocation(event.latLng);
});
});
// Other functions
// Update form attributes with given coordinates
function updateFormLocation(latLng) {
$('#centre_latitude').val(latLng.lat());
$('#centre_longitude').val(latLng.lng());
$('#centre_gmaps_zoom').val(handler.getMap().serviceObject.getZoom());
}
// Add a marker with an open infowindow
function placeMarker(latLng) {
var marker = new google.maps.Marker({
position: latLng,
map: handler.getMap().serviceObject,
draggable: true
});
markersArray.push(marker);
// Set and open infowindow
var infowindow = new google.maps.InfoWindow({
content: '<div class="popup"><h2>Awesome!</h2><p>Drag me and adjust the zoom level.</p>'
});
infowindow.open(handler.getMap().serviceObject, marker);
// Listen to drag & drop
google.maps.event.addListener(marker, 'dragend', function() {
updateFormLocation(this.getPosition());
});
}
// Removes the overlays from the map, including the ones loaded with the map itself
function clearOverlays() {
for (var i = 0; i < markersArray.length; i++ ) {
markersArray[i].setMap(null);
}
markersArray.length = 0;
for (var i = 0; i < handler.getMap().markers.length; i++ ) {
handler.getMap().clearMarker(handler.getMap().markers[i]);
}
}
Then I get an error:
TypeError: undefined is not an object (evaluating 'handler.getMap().markers[0]')
Also, the marker is not draggable...
Is there any complete example of how to do this?
Thanks all!
There are many errors in your code. Hard to explain one by one.
Here is a solution suggestion.
Basically when you use
handler.getMap()
its already a google maps object, so dont do:
handler.getMap().serviceObject
I think I found a solution. Follows the code
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(
[
{
"lat": 0,
"lng": 0,
}
]
,{ draggable: true}
);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
// Move existing marker
google.maps.event.addListener(markers[0].serviceObject, 'dragend', function() {
updateFormLocation(this.getPosition());
});
});
// Update form attributes with given coordinates
function updateFormLocation(latLng) {
$('#latitude').val(latLng.lat());
$('#longitude').val(latLng.lng());
}
Now the marker is draggable and I can update the correct field in the form.
Any other approaches are welcome.

Google Maps JS API v3 not Geolocating with Phonegap iOS 3.5.0 and jQuery Mobile

The Setup
Currently building my phone gap iOS app which includes geolocation in addition to sending the results to a database and getting back nearby locations. Because I am using jQuery Mobile and Phonegap, I was testing on a browser to perfection, geolocation was success and everything returned was as well. On the iOS device, not so much. When sending a set latitude and longitude, everything returned successfully, but when using the google maps geolocation, and eventually the cordova plugin for geolocation, both failed as unable to find my location, even though they are the exact same code, minus the phone gap initializer on the website.
The Code
jQuery
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
$(document).ready(function () {
//Load Google Map & Geolocate
$(document).on("pagecreate", "#game", function () {
// keep as separate function call to allow for DOM to update after a tag
loadGoogleMap();
});
function loadGoogleMap() {
var defaultLatLng = new google.maps.LatLng(34.0983425, -118.3267434); //default location is Hollywood, CA
if (navigator.geolocation) {
function success(pos) {
//set fields for current user latitude and longitude
$("#lat_in").val(pos.coords.latitude);
$("#lon_in").val(pos.coords.longitude);
//location found
drawMap(new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude));
}
function fail(error) {
//try cordova geolocation plugin
function onSuccess(position) {
alert("CDV position success");
//alert(position.coords.latitude);
//alert(position.coords.longitude);
}
function onError(error) {
alert("CDV position error");
//alert("code: " + error.code + "\n" + "message: " + error.message);
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
alert("CDV position fail. Google geolocate fail"); //WHERE THE ERROR IS THROWN. THIS IS ALWAYS THE OUTCOME
//drawMap(defaultLatLng); //Failed to find location. Show default location
}
//Geolocate. Cache location for 5 mins. Timeout after 6 seconds
navigator.geolocation.getCurrentPosition(success, fail, {
maximumAge: 500000,
enableHighAccuracy: true,
timeout: 6000
});
} else {
drawMap(defaultLatLng); //No geolocation support, show default map
}
function drawMap(latlng) {
//Collect Data to Send
var uname = $("#unm_in").val();
var lat = $("#lat_in").val();
var lon = $("#lon_in").val();
var myOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
//update latitude and longitude on DB for logged in user && get nearby users
$.post("PHP_ON_SERVER", {
uname: uname,
lat: lat,
lon: lon
}, function (data) {
$.each(data, function (key, value) {
//Define variables
var allUsrLoc = new google.maps.LatLng(value.lat, value.lon);
var contentString = value.uname;
var mkrImg = "inUsrIcon.png"; //icon for logged in user
var inUserName = value.fname + " " + value.lname;
//if info belongs to current user
if (contentString === uname) {
var marker = new google.maps.Marker({
position: allUsrLoc,
map: map,
title: "Player",
icon: mkrImg
});
//change header to name and points
$("#inUserInfo").text("Hi " + inUserName + " || You have " + value.points + " points");
//disable tag button if not it
if (value.isit === "notit") {
$("#tagBtn").addClass("ui-state-disabled");
}
}
//if not current user and is not it
else if (contentString != uname && value.isit != "it") {
var marker = new google.maps.Marker({
position: allUsrLoc,
map: map,
title: "Player"
});
google.maps.event.addListener(marker, 'click', function () {
//Change selected player hidden field to match marker
$("#unm_sel").val(contentString);
$("#lat_sel").val(value.lat);
$("#lon_sel").val(value.lon);
$("#isit_sel").val(value.isit);
//Change tag button to selected player's username
$("#tagBtn").text("Tag " + contentString);
});
}
//no condition for if not current user and is it. TBD if anything will come
});
}, "json");
} //end drawMap
} // end loadGoogleMap
}
HTML
<div data-role="content" role="main" id="map-canvas">
<!-- Map loads here -->
</div>
Some More to Know
I have been reading up on other related questions, but none of the others do work. Either they say use the plugin, which I am to no avail, or set <access origin="*" /> which I am doing already. In addition, most of the other questions revolve around pre-3.0.0 versions of phone gap, which was its own monster. Also, the map loads, just no markers display. On the DB, the user who's location is being updated is set to (0,0). Lastly, when using geolocation in any other app, the iOS device I test on is successfully finding my location. In addition, I am testing on the same WiFi network as the browser which worked, so anything relating to internally being unable to locate due to network or hardware is ruled out.
If you want to see the working example, just ask.

using http://code.google.com/p/jquery-ui-map/

using jquery-ui-map
here is my code
$(document).ready(function() {$('#map_canvas').gmap({ 'center': new google.maps.LatLng(3.162456,21.09375), 'zoom': 2, 'streetViewControl': false, 'callback':
function() {
$('#map_canvas').gmap('loadHTML', 'microformat', '.importers', function(markerOpts, node, index) {
var clone = $(node);
// We have to add a callback in the addmarker method so we can access the marker just added
var name = $(node).find('.name');
var icon = $(node).find('.icon');
$('#map_canvas').gmap('addMarker', jQuery.extend({ 'title': name.html(), 'icon':new google.maps.MarkerImage(icon.html())}, markerOpts), function(map, marker) {
$(name).click( function() {
$(marker).triggerEvent('click');
return false;
});
}).click(function() {
$('.reveal').removeClass('reveal');
$(this).get(0).map.panTo($(this).get(0).position);
$(clone).toggleClass('reveal');
//need to wait till pan has complete before doing zoom!
});
});
}
});
});
at the moment when you click on a market it pans to its position
what i want to do is also zoomin, i've tried just adding
$(this).get(0).map.setZoom(5, true);
but this means the pan does not work it just jumps straight to the zoom level, how do i get it to fire the $(this).get(0).map.setZoom(5, true); after the panning is done?
thanks in advance
$('#map_canvas').gmap('addMarker').click(function() {
$(this).get(0).map.panTo($(this).get(0).position);
var self = $(this).get(0);
setTimeout(function() { self.map.setCenter(self.position); self.map.setZoom(15); }, 2000);
});
This would be the easy way of setting the zoom after the pan.

Resources