angularJS find the location/place name using angular google map - javascript

I want to find the location name which user select on map.
Currently I am getting latitude and longitude both.
But unable to get the location name.
I am using angularJS and angular-google-maps 2.1.5.
Here is the html.
<ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true" options="options" events="map.events">
</ui-gmap-google-map>
JS :
$scope.map = {
center: {
latitude: 21.0000,
longitude: 78.0000
},
zoom: 4,
events: {
click: function(mapModel, eventName, originalEventArgs,ok) {
var e = originalEventArgs[0];
objOneDevice.dev_latitude = e.latLng.lat();
objOneDevice.dev_longitude = e.latLng.lng();
$scope.templatedInfoWindow.show = true;
}
}
};
$scope.options = {
scrollwheel: true
};
Anything is appreciated.

Here what I have done using Reverse geocoding.
$scope.map = {
center: {
latitude: 21.0000,
longitude: 78.0000
},
zoom: 4,
events: {
click: function(mapModel, eventName, originalEventArgs,ok) {
var e = originalEventArgs[0];
var geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(e.latLng.lat(), e.latLng.lng());
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
console.log(results[1].formatted_address); // details address
} else {
console.log('Location not found');
}
} else {
console.log('Geocoder failed due to: ' + status);
}
});
}
}
};

Given Latitude/Longitude object you can map location to approximate address using Google Map API.
You can use the Geocoding API for mapping locations to addresses and addresses to locations.
Geocoder.geocode( { 'latLng': latLngObject }, callbackFn);
Here is the link for Google Map API for Geocoding.

Try these links
https://developers.google.com/maps/documentation/javascript/examples/geocoding-reverse?csw=1
Use the Geocoding API for mapping locations to addresses and addresses to locations. http://code.google.com/apis/maps/documentation/javascript/services.html#Geocoding
Geocoder.geocode( { 'latLng': latLngObject }, callback);
http://wbyoko.co/angularjs/angularjs-google-maps-components.html
Hope it helps!!!

Related

Handling Google Geocode Callback Results to Vue JS Model

Here's my issue... I have two selections for my user, use current location, or use a zip code. When the user selects a zip code I make a call to the Google geocode API and retrieve the central point for that zip code. I want to be able to put these coordinates into my Vue model and then execute a method within Vue called refresh which retrieves some data from my database and calls a function that sets up the map with markers and bounds. Since the callback function is decoupled from the model, I cannot seem to set the Vue properties, nor can I call the method. How do I handle the callback?
Please note that the refresh method works properly when using the selection for current location.
getLocation is called when the user selects "Current Location"
checkZip is called when the user selects "Use Zip Code"
<script>
var app = new Vue({
el: '#app-content',
data: {
locationType: "CurrentLocation",
lat: "",
lng: "",
radiusInMiles: 10,
filters: [],
zipCode: "",
geoError: "",
error: "",
results: []
},
methods: {
getLocation: function () {
this.zipCode = "";
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.storeLocation, this.locationError);
} else {
this.locationType = "ZipLocation";
console.log("Geolocation does not appear to be supported by the browser.");
this.geoError = "Unable to obtain location. Please make sure location services are turned on and try again.";
}
},
storeLocation: function (position) {
this.lat = position.coords.latitude;
this.lng = position.coords.longitude;
this.refresh();
},
locationError: function (err) {
this.locationType = "ZipLocation";
this.results = [];
console.warn(err);
this.geoError = "Unable to obtain location. Please make sure location services are turned on and try again.";
},
refresh: function () {
if (!(this.lat && this.lng && this.radiusInMiles && this.filters)) {
console.log("Location and filters are undefined.");
}
else {
//https://github.com/axios/axios
axios
.post('xyxyxyxyx', {
lat: this.lat,
lng: this.lng,
radiusInMiles: this.radiusInMiles,
filters: this.filters.toString()
})
.then(response => {
this.results = response.data.d;
//Send to map function...
loadMap(this.lat, this.lng, this.results);
})
.catch (error => console.log(error))
}
},
checkZip: function () {
if (this.zipCode.length == 5 && !isNaN(this.zipCode)) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': 'zipcode ' + this.zipCode }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
//Here's my issue...
//How do I store to the model and then call this.refresh
this.lat = results[0].geometry.location.lat();
this.lng = results[0].geometry.location.lng();
this.refresh();
} else {
console.error("Request failed.")
}
});
}
}
}
})
</script>
I was able to get this to work by copying the Vue model into a variable (self).
How can I update a Vue app's or component's property in a promise call back?
checkZip: function () {
if (this.zipCode.length == 5 && !isNaN(this.zipCode)) {
var self = this;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': 'zipcode ' + this.zipCode }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
self.lat = results[0].geometry.location.lat();
self.lng = results[0].geometry.location.lng();
self.refresh();
} else {
console.error("Request failed.")
}
});
}
}

Vue-google-map autocomplete two way binding not working

I am using vue-google-maps, and I have implemented the plugin and it works flawlessly, but there is a small problem ( or maybe I am not able to do it correctly ). When I implemented the autocomplete functionality it works one way. I enter the address and the map points me to the selected place but when I drag the pointer it doesn't update the address in the search field.
I am using Vuejs 2
and vue-google-maps
This is what I am doing:
<template>
<div>
<label>
AutoComplete
<GmapAutocomplete :position.sync="markers[0].position" #keyup.enter="usePlace" #place_changed="setPlace">
</GmapAutocomplete>
<button #click="usePlace">Add</button>
</label>
<br/>
<gmap-map
:center="center"
:zoom="7"
map-type-id="terrain"
style="width: 100%; height: 500px"
>
<gmap-marker
#dragend="updateMaker"
:key="index"
v-for="(m, index) in markers"
:position="m.position"
:clickable="true"
:draggable="true"
#click="center=m.position"
></gmap-marker>
</gmap-map>
</div>
</template>
<script>
export default {
data() {
return {
center: {lat: 10.0, lng: 10.0},
markers: [{
position: {lat: 11.0, lng: 11.0}
}],
place: null,
}
},
description: 'Autocomplete Example (#164)',
methods: {
setPlace(place) {
this.place = place
},
setDescription(description) {
this.description = description;
},
usePlace(place) {
if (this.place) {
var newPostion = {
lat: this.place.geometry.location.lat(),
lng: this.place.geometry.location.lng(),
};
this.center = newPostion;
this.markers[0].position = newPostion;
this.place = null;
}
},
updateMaker: function(event) {
console.log('updateMaker, ', event.latLng.lat());
this.markers[0].position = {
lat: event.latLng.lat(),
lng: event.latLng.lng(),
}
},
}
}
</script>
I'm not sure this is supported. You might have to implement this by yourself.
In your updateMaker() method, you could use google.maps.Geocoder() to find the address name yourself:
updateMaker: function(event) {
const geocoder = new google.maps.Geocoder()
geocoder.geocode({ 'latLng': event.latLng }, (result, status) => {
if (status === google.maps.GeocoderStatus.OK) {
// set the input field value with address:
console.log(result[0].formatted_address)
}
})
}
add 'ref' to your auto complete component like :
<GmapAutocomplete ref="gmapAutocomplete" :position.sync="markers[0].position" #keyup.enter="usePlace" #place_changed="setPlace">
</GmapAutocomplete>
Change updateMarker function to this:
updateMaker: function(event) {
console.log('updateMaker, ', event.latLng.lat());
this.markers[0].position = {
lat: event.latLng.lat(),
lng: event.latLng.lng(),
}
const geocoder = new google.maps.Geocoder()
geocoder.geocode({ 'latLng': event.latLng }, (result, status) => {
if (status === google.maps.GeocoderStatus.OK) {
this.$refs.gmapAutocomplete.$refs.input.value = result[0].formatted_address
}
})
},

Uncaught TypeError: Cannot read property 'apply' of undefined Google Maps

I am using Google Maps to make markers on a map and I am trying to convert addresses to geocodes using the following code:
<script src="https://maps.googleapis.com/maps/api/js?key=&callback=initialize" async defer></script>
<script type="text/javascript">
var map;
function initialize() {
var chamberLocation = {lat: 43, lng: -82};
var geocoder = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 42.9745, lng: -82.4066},
zoom: 14,
styles: [{"featureType":"road","elementType":"geometry","stylers":[{"visibility":"simplified"}]},{"featureType":"road.arterial","stylers":[{"hue":149},{"saturation":-78},{"lightness":0}]},{"featureType":"road.highway","stylers":[{"hue":-31},{"saturation":-40},{"lightness":2.8}]},{"featureType":"poi","elementType":"label","stylers":[{"visibility":"off"}]},{"featureType":"landscape","stylers":[{"hue":163},{"saturation":-26},{"lightness":-1.1}]},{"featureType":"transit","stylers":[{"visibility":"off"}]},{"featureType":"water","stylers":[{"hue":3},{"saturation":-24.24},{"lightness":-38.57}]}],
zoomControl: false,
scaleControl: false,
mapTypeControl: false,
disableDefaultUI: false,
streetViewControl: false,
rotateControl: false,
scrollwheel: false,
draggable: false
});
codeAddress(geocoder, map);
}
function codeAddress(geocoder, map) {
var address = 'place';
geocoder.geocode({ 'address' : address }), function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
console.log('This didnt work' + status);
}
};
}
</script>
Whenever I do this I get an error saying Uncaught TypeError: Cannot read property 'apply' of undefined
What is causing this error? I am unsure as to how to fix this. Do I have to import another google maps api?
The error is a typo. I put the code below and commented //change in places where the typo was at. geocoder.geocode({}, callback) is a function that takes an object and a callback, but you have geocoder.geocode({ 'address' : address }), the typo is the ) it should be geocoder.geocode({ 'address' : address }, function(results, status) { ...
<div id="map" style="width: 320px; height: 480px;"></div>
<script type="text/javascript">
var map;
function initialize() {
// your code
// etc ...
codeAddress(geocoder, map);
}
function codeAddress(geocoder, map) {
var address = 'place';
geocoder.geocode({
'address': address
}, // change
function(results, status) {
if (status == 'OK') { // change
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
// some debug output
console.log("status is: " + status)
console.log("results is: " + JSON.stringify(results[0].geometry.location))
} else {
console.log('This didnt work' + status);
}
});
};
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=initialize"></script>
Today i have also faced the same error while using distance matrix library, what we need to do is simply use the callback function mentioned here https://developers.google.com/maps/documentation/javascript/distancematrix
According to this doc https://developers.google.com/maps/documentation/javascript/examples/distance-matrix#maps_distance_matrix-typescript i was using promises thats when i encounterd the above error
var origin1 = new google.maps.LatLng(55.930385, -3.118425);
var origin2 = 'Greenwich, England';
var destinationA = 'Stockholm, Sweden';
var destinationB = new google.maps.LatLng(50.087692, 14.421150);
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [origin1, origin2],
destinations: [destinationA, destinationB],
travelMode: 'DRIVING',
transitOptions: TransitOptions,
drivingOptions: DrivingOptions,
unitSystem: UnitSystem,
avoidHighways: Boolean,
avoidTolls: Boolean,
}, callback);
function callback(response, status) {
// See Parsing the Results for
// the basics of a callback function.
console.log(status);
console.log(response);
}

Asynchronous execution of a function passed as an argument

I'm facing the following problem. I want to use Google's geocoding service to draw some markers on the map. However, the marker is instantiated before geocoding even finished it's job. drawMarker function will return a Marker with location undefined.
I tried passing the geocoding function as an argument to drawMarker function, and executing it there. I thought that this way I'd achieve synchronous behaviour, which is not the case. Simplified code follows:
drawMarker(i, map, codeAddress, locationsToConvert[i]);
function drawMarker(i, map, func, arg) {
var location = func.apply(this, [arg]);
return new google.maps.Marker({
position: {lat: location.lat, lng: location.lng},
map: map,
html: locations[i][0],
id: i
});
}
function codeAddress(address) {
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
return results[0].geometry.location
}
});
}
What are my solutions, which one's best, perhaps:
using the Promise interface?
doing everything in one function and instantiating Marker in the callback of the geocode service?
other?
You could try getting the address first and calling drawMarker from the callback once you have it. Edited drawMarker to something close to how it would look, I do not have full code so might not be 100% correct.
codeAddress(locationsToConvert[i]);
function drawMarker(i, map, location) {
return new google.maps.Marker({
position: {lat: location.lat, lng: location.lng},
map: map,
html: locations[i][0],
id: i
});
}
function codeAddress(address) {
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
drawMarker(i, map, results[0].geometry.location);
}
});
}
You have to put the drawMarker inside the geocoder callback
function codeAddress(address) {
geocoder.geocode({ 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
drawMarker(map,results[0].geometry.location);
}
});
}
take a look at this -> fiddle for the example
Why not convert the location then call the draw function once it returns?
Something similar to the below example (will change depending on the promise lib you are using) -- also can't promise there aren't any syntax errors in the example.
function geocodeAsync(addressToConvert) {
return new Promise((resolve, reject) => {
geocoder.geocode( {'address': addressToConvert }, (results, status) => {
if (status == google.maps.GeocoderStatus.OK) {
resolve(results[0].geometry.location);
}
else {
reject(status);
}
});
});
}
let loc = locationsToConvert[i];
var promise = geocodeAsync(loc)
promise.then(result => {
let marker = new google.maps.Marker({
position: {lat: result.lat, lng: result.lng},
map: map,
html: loc[0],
id: i
});
// add marker to google maps
})
.catch(err => console.error(err));

Remove Streetview Controls

I'm working on the front-end of an app I had developed and wanting to remove the controls from the Google StreetView embed shown here:
function displayGoogleSV(address_str) {
var geocoder = new google.maps.Geocoder();
var myStreetView = null;
var marker = null;
var address = address_str;
geocoder.geocode({
'address': address
}, function (results, status) {
//alert (results);
if (status == google.maps.GeocoderStatus.OK) {
//alert(results[0].geometry.location);
myStreetView = new google.maps.StreetViewPanorama(document.getElementById("streetview"));
myStreetView.setPosition(results[0].geometry.location);
google.maps.event.addListenerOnce(myStreetView, 'status_changed', function () {
var heading = google.maps.geometry.spherical.computeHeading(myStreetView.getLocation().latLng, results[0].geometry.location);
myStreetView.setPov({
heading: heading,
pitch: 0
});
Where would I stick in the controls seen here: https://developers.google.com/maps/documentation/javascript/examples/streetview-controls
Thanks!
You should disable them by using the link's options in your Street View's options:
/* ... */
myStreetView.setPov({
heading: heading,
pitch: 0
});
var panoOptions = {
addressControlOptions: {
position: google.maps.ControlPosition.BOTTOM_CENTER
},
linksControl: false,
panControl: false,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
},
enableCloseButton: false
};
myStreetView.setOptions( panoOptions );

Categories

Resources