I am using 'jquery-ui-map' for an android app. My emulator is Google API Level 13 version 3.2. My Javascript code is :
$('#gps_map').live("pageshow", function() {
$('#map_canvas_2').gmap('refresh');
$('#map_canvas_2').gmap('getCurrentPosition', function(position, status) {
if ( status === 'OK' ) {
var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude)
$('#map_canvas_2').gmap('get', 'map').panTo(latlng);
$('#map_canvas_2').gmap('search', { 'location': latlng }, function(results, status) {
if ( status === 'OK' ) {
$('#from').val(results[0].formatted_address);
}
});
} else {
alert('Unable to get current position');
}
});});
This code always fails to get location. I can't see the GPS icon in the emulator. I tried setting all possible permissions, tried setting the latlong coordinates with geo fix method but nothing works. Is there ANY way by which geo location can work on android ?
Finally found the answer to this.
$('#map_canvas').gmap('getCurrentPosition', function(pos, status) {
if (status === "OK") {
var latLng = new google.maps.LatLng(pos.coords.latitude,pos.coords.longitude);
$('#map_canvas').gmap('option', 'center', latLng);
} else {
// error msg
}
}, { timeout: 10000, enableHighAccuracy: true} );
Adding a longer timout in options, like shown above fixes the issue. The example shows a long timeout: 10 seconds.
Related
I am trying to add google maps to my vuejs application following this tutorial here: https://markus.oberlehner.net/blog/using-the-google-maps-api-with-vue/
I have a div with id="maps" as well as ref="mapsection". I tried binding maps instance with the div with both document.getElementById as well as this.ref but I get the null/undefined error. Can someone please advise what I am doing wrong? I see the div created when I go I to inspect mode.
I have tried both of the following where "mapsection" is the ref and "map" is the id for the div.
const map = new google.maps.Map(this.refs.mapsection);
const map = new google.maps.Map(document.getElementById('map'));
View code:
<el-row>
<div ref="mapsection" id="map" style="width:100%;height:400px">
</div>
</el-row>
Script code:
async mounted() {
try {
console.log(document.getElementById('map')); //returns null
const google = await gmapsInit();
const geocoder = new google.maps.Geocoder();
const map = new google.maps.Map(document.getElementById('map')); //tried this.refs.mapsection as well.
const locations = [{
position: {
lat: 48.160910,
lng: 16.383330
}
}]
geocoder.geocode({ address: 'Austria' }, (results, status) => {
if (status !== 'OK' || !results[0]) {
throw new Error(status);
}
map.setCenter(results[0].geometry.location);
map.fitBounds(results[0].geometry.viewport);
const markers = locations.map(x => new google.maps.Marker({ ...x, map }));
});
} catch (error) {
console.error(error);
}
}
Errors I am getting:
with this.refs.mapsection > TypeError: Cannot read property 'mapsection' of undefined
with document.getElementById('maps') > TypeError: Cannot read property 'firstChild' of null
The referenced tutorial does not use el-row. Your problem has nothing to do with google maps.
To debug try one of these approaches.
put all of mounted in an async $nextTick to ensure render.
move your code out of el-row, el-table, etc, and into a div to isolate the issue.
refs in loops is often an array, so when you finally get this working, it is something to consider.
I've been doing mobile part of my project after "completing" the web part. I'm using google map api. I have coded following:
function codeAddress() {
var image = 'images/tickmark1.png';
var address = document.getElementById('address').value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var markerZad = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: "NEW TASK",
icon: image
});
document.getElementById('latitude').value =results[0].geometry.location.nb.toPrecision(9);
document.getElementById('longitude').value=results[0].geometry.location.ob.toPrecision(9);
document.getElementById('adrs').value=document.getElementById('address').value;
document.getElementById('latit').value =results[0].geometry.location.nb.toPrecision(9);
document.getElementById('longit').value=results[0].geometry.location.ob.toPrecision(9);
alert("Ustalono wspolrzedne nowego zadania. Wybierz pracownika \n (PPM usuwa znacznik)");
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
google.maps.event.addListener(markerZad, 'click', function() {
alert("Nowe zadanie: \n"+ address + "\n"+"Wybierz pracownika \n (PPM usuwa znacznik)");
map.setZoom(14);
map.setCenter(this.getPosition());
});
google.maps.event.addListener(markerZad, 'rightclick', function() {
markerZad.setMap(null);
document.getElementById('latitude').value =0;
document.getElementById('longitude').value=0;
document.getElementById('adrs').value=0;
document.getElementById('latit').value =0;
document.getElementById('longit').value=0;
document.getElementById('ajdideva').value="X";
document.getElementById('iddev').value=0;
document.getElementById('baton').disabled=true;
alert("Usunieto znacznik. Wpisz inny adres.");
});
});
}
Let's leave behind the level of this code. I'm sure it's a bad one. But the thing is...it used to work for me like few days ago. Now it doesn't. And yes, I haven't touched it since then... I figured out myself, that the problem causes "results". I get status==OK, then it places a marker in a correct spot, and then...nothing happens. I mean my inputs in html file don't get their values changed and +listeners aren't working. When I changed "results[0]." etc to simple string, it worked, that's why I think that there's a problem with results[0]. Any suggestions please?
Don't access undocumented properties like e.g. results[0].geometry.location.nb . The names of these properties may(and will) change. To access the values of these properties use the documented methods, e.g. lat() to access the latitude of a LatLng-instance:
document.getElementById('latitude').value
= results[0].geometry.location.lat().toPrecision(9);
Here is the code :
var map = new google.maps.Map(document.getElementById("map_canvas"), $scope.map_options);
var dirService= new google.maps.DirectionsService();
var dirRenderer= new google.maps.DirectionsRenderer()
var dirContainer=document.getElementById('dir-container');
var showDirections = function(dirResult, dirStatus) {
if (dirStatus != google.maps.DirectionsStatus.OK) {
alert('Directions failed: ' + dirStatus);
return;
}
// Show directions
dirRenderer.setMap(map);
dirRenderer.setDirections(dirResult);
dirRenderer.setPanel(dirContainer);
};
dirService.route( {origin: '158 cours tolstoi, villeurbanne',
destination: '8 cours andré philip, villeurbanne',
travelMode: google.maps.DirectionsTravelMode.DRIVING,
provideRouteAlternatives: true }
, showDirections);
I would like to catch the event of selecting another route between the route displaying in the dirContainer.
The alternatives route are displaying in the dirContainer and because provideRouteAlternatives: true.
The event
google.maps.event.addListener(dirRenderer, 'directions_changed',
function() {
alert('a');
});
is not fired when you change the alternative route.
In advance thanks.
UPDATE
from this post in the v3 API group
There is no event. There is a feature request to add that to the API:
https://code.google.com/p/gmaps-api-issues/issues/detail?id=3565
There should be a routeIndex_changed event, but that doesn't seem to work (and isn't documented). routeindex_changed does work, but I don't see it in the documentation.
http://www.geocodezip.com/v3_SO_simpleMap_directions_changed.html
Here is the event :
google.maps.event.addListener(dirRenderer, 'routeindex_changed',
function() {
alert(dirRenderer.getRouteIndex());
});
Two questions here, but they're related. Is there a way to make the centerMapOnUser() action smooth? I have a marker that denotes my location, and it's draggable.
// watch for marker movement, and update location accordingly
function updateUserLocation(latLng) {
var revGeo = new google.maps.Geocoder();
revGeo.geocode({'latLng': latLng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
$('#loc').html(results[1].formatted_address);
}
} else {
alert("Geocoder failed due to: " + status);
}
});
Gmaps.map.userLocation = latLng;
Gmaps.map.centerMapOnUser();
lat = latLng.lat();
lng = latLng.lng();
}
This is very abrupt, and almost disorienting, though. I was wondering if anyone knew of a way to make it a smooth transition.
Side question. Sometimes the map shows 1 marker, sometimes it shows 26 (A-Z). If it's only 1, the zoom level is set to max. I disabled auto_zoom and added this function:
function zoom() {
if (Gmaps.map.markers.length == 1) {
//only one marker, choose the zoom level you expect
Gmaps.map.serviceObject.setZoom(16);
}
else{
//more than one marker, let's auto_zoom
Gmaps.map.map_options.auto_zoom = true;
Gmaps.map.adjustMapToBounds();
}
}
Checking the console, Gmaps.map.markers always returns 0, whether there are 0, 1, or several markers. Markers get added initially, though, and even added later on through the replaceMarkers() function, so everything seems to be configured proper.
I am using Google geocoder for lat and lon and my question is, is there a way you can find out zipcode with latitude and longitude?
It's good to note that Google Maps has a new version since this solultion was presented.
Reference: https://developers.google.com/maps/documentation/geocoding/?csw=1#ReverseGeocoding
Here's an updated example for Google Maps v3. It makes use of the Address Components that JIssak mentions above. I should note that there is no fallback. If it fails to find a zip code, it does nothing. This may or may not be important to your script.
var latlng = new google.maps.LatLng(p.coords.latitude, p.coords.longitude);
geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
for (j = 0; j < results[0].address_components.length; j++) {
if (results[0].address_components[j].types[0] == 'postal_code')
alert("Zip Code: " + results[0].address_components[j].short_name);
}
}
} else {
alert("Geocoder failed due to: " + status);
}
});
I think what you are looking for is the address_components[] in the results array. Maybe something like this would work, just typing the below so it might have errors in it but I think you will get the idea.
http://code.google.com/apis/maps/documentation/geocoding/#Results
function (request, response) {
geocoder.geocode({ 'address': request.term, 'latLng': centLatLng, 'region': 'US' }, function (results, status) {
response($.map(results, function (item) {
return {
item.address_components.postal_code;//This is what you want to look at
}
}
[Removed non-working solution for google - see #hblackorby's solution.]
Here's a version that uses openstreetmap.org, much simpler than google's api - coffeescript, then javascript:
getZip = (cb) ->
# try to populate zip from geolocation/google geocode api
if document.location.protocol == 'http:' && navigator.geolocation?
navigator.geolocation.getCurrentPosition (pos) ->
coords = pos.coords
url = "http://nominatim.openstreetmap.org/reverse?format=json&lat=#{ coords.latitude }&lon=#{ coords.longitude }&addressdetails=1"
$.ajax({
url: url,
dataType: 'jsonp',
jsonp: 'json_callback',
cache: true,
}).success (data) ->
cb(data.address.postcode)
Here's the compiled javascript:
getZip = function(cb) {
if (document.location.protocol === 'http:' && (navigator.geolocation != null)) {
return navigator.geolocation.getCurrentPosition(function(pos) {
var coords, url;
coords = pos.coords;
url = "http://nominatim.openstreetmap.org/reverse?format=json&lat=" + coords.latitude + "&lon=" + coords.longitude + "&addressdetails=1";
return $.ajax({
url: url,
dataType: 'jsonp',
jsonp: 'json_callback',
cache: true
}).success(function(data) {
return cb(data.address.postcode);
});
});
}
};
Use it like this:
getZip(function(zipcode){ console.log("zip code found:" + zipcode); });
Yahoo's PlaceFinder API provides a good wat to lookup location data by lat/lng:
http://developer.yahoo.com/geo/placefinder/
Here's an example url that they use:
http://where.yahooapis.com/geocode?q=38.898717,+-77.035974&gflags=R
It would seem so:
Source: Google Maps API Service
Geocoding is the process of converting addresses (like "1600
Amphitheatre Parkway, Mountain View, CA") into geographic coordinates
(like latitude 37.423021 and longitude -122.083739), which you can use
to place markers or position the map. The Google Geocoding API
provides a direct way to access a geocoder via an HTTP request.
Additionally, the service allows you to perform the converse operation
(turning coordinates into addresses); this process is known as
"reverse geocoding."
You should also check out this documentation which has some sample code:
Reverse Geocoding
I made a generic function to look for the type that you want. Not always the address_component has zipcode, country, etc and if they do not always are in the same index. Sometimes your array is lenght 8, 6 or whatever. I did it in Typescript, just change a few things to make it vanilla JS.
getPlaceTypeValue(addressComponents: Places[], type: string): string {
let value = null;
for (const [i] of addressComponents.entries()) {
if (addressComponents[i].types.includes(type)) {
value = addressComponents[i].long_name;
break;
}
}
return value;
}
OR
getPlaceTypeValue(addressComponents: any[], type: string): string {
return (addressComponents.find(({ types }) => types.includes(type)) || {}).long_name || null;
}
Example of usage:
this.placesService.getPlaceTypeValue(address.address_components, 'postal_code');
this.placesService.getPlaceTypeValue(address.address_components, 'country');