Why panning google map updates angularjs scope var? - angularjs

Kind of an odd question/hard to find an answer. I'm relatively new to using angularjs and have a problem i'm confused about.
I've set up a google map using http://angular-ui.github.io/angular-google-maps/#!/ and have an issue.
So i have a $scope.homeBase where i am setting a lat & long for the owners 'Home Base', i want to use that location to set the on load map center, & a pin to show the location. So in my mind cool, set the one var and use it in both locations. Wrong.
So this works on load, but every time i pan the map, i guess it re-sets the map center location, which in turn binds to the map marker and sends the marker to the middle of the screen, on every pan.
Is there anyway to have the two not bound? or have separate vars? without them bound?
i thought a simple 'var homebase' would remove binding and not update the var. instead of using scope but it still binds?
This perhaps is a newb question but i appreciate any pointing in proper direction.
Thanks again
here's my code.
// uiGmapGoogleMapApi is a promise, The "then" callback function provides a maps object.
uiGmapGoogleMapApi.then(function() {
// Setting homebase coords, these will come from firebase
$scope.homeBase = { latitude: -34.18405, longitude: 150.71319 };
// Set default map.
$scope.map = {
center: $scope.homeBase,
pan: true,
zoom: 14,
events: {
click: function(){
}
}
};
// Set homebase marker.
$scope.homebaseMarker = {
id: 0,
coords: $scope.homeBase,
options: { draggable: false },
};
});

I was able to set the center on page load via
angular.copy(var)

Related

Changing animateCamera pitch and zoom properties dynamically doesn't work

Changing animateCamera pitch and zoom properties dynamically with useState doesn't work
onLayout={() => {
map.current.animateCamera({
center: { latitude: location?.coords?.latitude, longitude: location?.coords?.longitude },
zoom: zoomLevel,
heading: 50,
pitch: pitchLevel,
altitude: 5,
})
}}
I find that onlayout doesn't quite work with transformations.
So here's all of the undocumented or buggy behavior I've encountered with onLayout and .measure so far:
onLayout doesn't get called in some conditions (seemingly when an element is moved by a parent resizing)
the measure returns undefined on android unless there's an onLayout or collapsible: false on the view
onLayout doesn't take transforms into account, it returns the "internal" size of the view not the size displayed on the screen
onLayout doesn't fire for animations of transforms (which is pretty much all animations since only transforms and opacity can use native driver) -- that's this issue
measure returns different values for width and height than onLayout. It returns scaled values if any parent is scaled as opposed to the raw values. Docs suggest the opposite.
onLayout Will return wrong/random values during component mount in some (maybe all?) cases if the view or any parent is being animated.
It's because layout process is not involved in transformations at all. Actually Animated can't change any properties that can change layout of the component tree.
I find this approach https://reactnative.dev/docs/direct-manipulation
I will give a snippet if I find solution
I think you should use hook (useEffect) for animating Map to then region. In my case i was getting new locations from GoogleAutoPlaces
api . i am receiving latlng object in coordinate variable. here you
can add coordinate variable as dependency and when your location
will change it will automatically animate the map to the new
location. useEffect(() => { mapref?.current?.animateToRegion(coordinate, 1000); }, [coordinate]);
solution was:
ref={(current) => (map.current = current)}
onUserLocationChange={() => {
map.current.animateCamera({
center: {
latitude: locationUpdate?.coords?.latitude,
longitude: locationUpdate?.coords?.longitude,
},
zoom: 16,
heading: Math.round(headingRef.current),
pitch: 90,
altitude: Math.round(altitudeRef.current),
useNativeDriver: true,
});
}}
although to even enhance react native performance you can set this in useCallback hook and call it from that like:
onUserLocationChange={animateCameraUseCallback}

Is it possible to display mapbox coordinates inside a dynamic url?

I'm working on a mapbox app and I need to make a dynamic URL to reflect mapbox info like lat, long and zoom level.
ex: /?city=London&zoom=1&lat=30&lng=140. On page load map should be centred and zoomed accordingly. How to read/write page URL?
Just activate the hash : true in the Map initial settings
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/outdoors-v11',
center: [128, 47],
zoom: 16.5,
pitch: 60,
hash: true // just add this
});
It’s not the same param names but you’ll have the same information

How to get lat lang of top left and bottom right of map when zoomed

I am trying to get top left and right bottom of the Map which i am displaying. And i am trying to get this particular data in zoom event, but somehow this.map is becoming undefined and breaking the application
this.map.on('zoomend', function (layer) {
console.log("zoom",layer.target._zoom)
console.log("getbounds", this.map.getBounds());
});
Below i am providing the componentDidMount, here only i am defining zoom event, which working fine if i simply console.
componentDidMount() {
/* We are loading the map here whether or not load has loaded */
this.map = L.map('map', {
center: [50, 10],
zoom: 3,
minZoom: 2,
maxZoom: 11,
zoomControl: false,
attributionControl: false,
scrollwheel: false,
legends: true,
infoControl: false,
});
console.log("getbounds", this.map.getBounds()); //WORKING BUT JUST ONCE, when this component mounts.
this.map.on('zoomend', function (layer,a) {
console.log("zoom",layer.target._zoom)
console.log("zoom",layer)
console.log("a",a)
console.log("getbounds", this.map.getBounds()); // NOT WORKING, this.map GETS UNDEFINED which is obvious also.
});
/* Giving zoom control a different place in UI */
L.control.zoom({ position: 'topright' }).addTo(this.map);
L.control.scale({ position: "topright" }).addTo(this.map);
/* Selecting and showing styles for the map */
L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
}).addTo(this.map);
}
Just change this part of your code bro
this.map.on('zoomend', (layer,a) => {
console.log("zoom",layer.target._zoom)
console.log("zoom",layer)
console.log("a",a)
console.log("getbounds", this.map.getBounds()); // NOT WORKING, this.map GETS UNDEFINED which is obvious also.
});
The reason why your code did not work is you were using simple function as a callback which need to bind to use this.
Solution: Use arrow function

Marker not updating coordinates in Google Maps for AngularJS

I am using Google Maps for AngularJS and have the following Jade code:
#map_canvas
google-map(center='map.center', zoom='map.zoom', draggable='true', options='options', events='map.events')
marker(coords='marker.coords', options='marker.options', idkey='marker.id')
In my angular controller I have:
$scope.map = {center: {latitude: 42.2405, longitude: -8.7207 }, zoom: 12, events: {
click: function (map, eventName, args) {
$scope.marker.coords.latitude = args[0].latLng.lat();
$scope.marker.coords.longitude = args[0].latLng.lng();
console.log($scope.marker);
}
}
}
$scope.marker = {
id: 0,
coords: {
latitude: 42.2405, longitude: -8.7207
},
options: { draggable: true }
}
What I am trying is to update the marker location with every click.
At console.log($scope.marker); I can see that my marker does print the updated coordinates value but the red pin does not move on the map.
I can't figure what I am doing wrong.
EDIT:
The marker does move to the new location after I resize the map, so I figured it is a matter of the map no refreshing when marker location changes. Should this be reported as a bug? Anything I can do to solve it?
Finally! After reading a bit on $apply() here and here and finding solutions like this one where it mentions to:
wrap your callback body into $scope.$apply(function () { ... });. Remember
that your event is coming from "non-Angular" world.
I found this other post where it just adds $scope.$apply(); to the end of the click function.
This last solution was the only one working for me.
I've posted all the process cause I consider it interesting to learn about $apply().

Google Maps infoWindow without marker?

According to the documention a marker is optional with an infoWindow, so how is this achieved please? I have tried infowindow.open(map) and infowindow.open(map,null) but both produce nothing.
If the position is set, there is no problem showing the info window
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: {lat: 55.6761, lng: 12.5683},
mapTypeId: google.maps.MapTypeId.TERRAIN
});
var infowindow = new google.maps.InfoWindow({
content: "Copenhagen"
});
infowindow.setPosition({lat: 55.6761, lng: 12.5683});
infowindow.open(map);
}
infowindow.open(map) makes no sense since you need to specify the position where the infowindow should open, also it has a tapered stem which specifies the location where it should point.
According to the documentation of Infowindows- InfoWindows may be attached to either Marker objects (in which case their position is based on the marker's location) or on the map itself at a specified LatLng.
So if you donot want the marker to open the infowindow, use the map click event-
var iwindow= new google.maps.InfoWindow;
google.maps.event.addListener(map,'click',function(event)
{
iwindow.setContent(event.latLng.lat()+","+event.latLng.lng());
iwindow.open(map,this);
iwindow.open(map,this);
});
And to close a InfowWindow- infowindow.setMap(null);
Hope that cleared your doubts.
Since the api has changed, it is not possible to set position on info window any more. the solution i found is to add a marker to the map with visibility false:
this.map.addMarker({
position: {
'lat': sites[0].latitude,
'lng': sites[0].longitude
},
// setting visible false since the icon will be the poi icon
visible: false
}).then((marker: Marker) => {
this.htmInfoWindow.open(marker);
});

Resources