How to write <script> in $scope style - ionic-framework

I'm implementing google map into my ionic app, and I have a script in my index.html, which, will only allow the map works in the index.html.
But I need my map in my templates file route.html instead, so I believe I should move the script in the index.html to the specific controller.js file, but things here are written in $scope style, can anyone tell me how could I wrote the style into $scope style?
And why actually things won't works in the route.html as the same code is used?
<div id="map"></div>
Here's my script in my index.html:
<script>
function initMap() {
var uluru = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: uluru
});
var marker = new google.maps.Marker({
position: uluru,
map: map
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=APIKEY&callback=initMap">
</script>
And my controller in the controller.js
.controller('RouteCtrl', function($scope, $ionicLoading) {
$scope.mapCreated = function(map) {
$scope.map = map;
};
$scope.centerOnMe = function () {
console.log("Centering");
if (!$scope.map) {
return;
}
$scope.loading = $ionicLoading.show({
content: 'Getting current location...',
showBackdrop: false
});
navigator.geolocation.getCurrentPosition(function (pos) {
console.log('Got pos', pos);
$scope.map.setCenter(new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude));
$scope.loading.hide();
}, function (error) {
alert('Unable to get location: ' + error.message);
});
}
})

There 2 ways to solve your problem :
Change your script to angular method in controller or create a service , like:
var marker = new google.maps.Marker({
map: $scope.map,
animation: google.maps.Animation.DROP,
position: latLng
});
var infoWindow = new google.maps.InfoWindow({
content: "Here I am!"
});
google.maps.event.addListener(marker, 'click', function () {
infoWindow.open($scope.map, marker);
});
Change it to jquery in controller, but it not recommend because it will break to purpose of angular usage in ionic:
var map = new google.maps.Map($("#map"), {
zoom: 4,
center: uluru
});

Related

How to stop cursor flickering over mapbox marker icons?

How do I stop cursor flickering over my Mapbox icons? Here is the live site where you can see the problem when hovering over the marker icons: https://rustic-waters-group.thesparksite.com/lakes/
Here is my code:
mapboxgl.accessToken = 'pk.eyJ1IjoiZG1pdHJpbWFydGluIiwiYSI6ImNreHRobHRmcjVqM3cydmt5NWkxdWNibTcifQ.CuN5Dwc963TW-BKRcowxBA';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/dmitrimartin/ckxtj5aur4fvv15mrhmihala8',
center: [-89.2, 44.33],
zoom: 9.2
});
map.on('load', () => {
const popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
map.on('mouseenter', 'lakes', (event) => {
map.getCanvas().style.cursor = 'pointer';
const features = map.queryRenderedFeatures(event.point, {
layers: ['lakes']
});
if (event.features.length === 0) return;
popup.setLngLat(features[0].geometry.coordinates);
popup.setHTML('<h3 class="lake-popup">' + features[0].properties.title + '</h3>');
popup.setMaxWidth("calc(100vw - 40px);");
popup.addTo(map);
});
map.on('mouseleave', 'lakes', () => {
map.getCanvas().style.cursor = '';
popup.remove();
});
map.on('click', 'lakes', (event) => {
const features = map.queryRenderedFeatures(event.point, {
layers: ['lakes']
});
if (event.features.length === 0) return;
window.location.href = ('/lakes/' + features[0].properties.url + '/');
});
document.getElementById("lakes-header").onmouseover = function() {
MyMouseOver();
};
function MyMouseOver() {
document.getElementById("wrapper").style.display = "none";
document.getElementById("lakes-header").style.display = "none";
}
});
The issue stems from the popup box on top of the layer and can be fixed by adding the CSS property 'cursor-events: none' to the popup. That should stop the flickering and shouldn't interfere with the layers.

Bing Maps pushpin icon issues

I have a custom set of icons I'm setting various pins too. When the mouse hovers over them I'd like to bring them to the front and change the style to a different icon.
I use this code to create the pin. OnHover I see the new push pin and on mouseout it returns to how it was. However, it has transparent areas and I can see parts of the non-hover pushpin below it when hovering.
For bringing it to the forefront have tried changing the zIndex value and as far as I can tell it does nothing.
Do I need to refresh the map or something?
Feels like there is something I'm missing.
function createImagePin(location, obj)
{
var smallPin = getSmallPin(obj);
var pin = new Microsoft.Maps.Pushpin(location, {
icon: smallPin.data,
visible: true,
anchor: new Microsoft.Maps.Point(smallPin.width / 2, smallPin.height / 2) //Align center of pushpin with location.
});
pin.dataTarget = obj;
Microsoft.Maps.Events.addHandler(pin, 'mouseover', function (e)
{
if(e.targetType === 'pushpin')
{
var largePin = getLargePin(e.target.dataTarget);
e.target.setOptions({ icon: largePin.data, anchor: new Microsoft.Maps.Point(largePin.width/2,largePin.height/2) });
}
});
Microsoft.Maps.Events.addHandler(pin, 'mouseout', function (e)
{
if (e.targetType === 'pushpin')
{
var smallPin = getSmallPin(e.target.dataTarget);
e.target.setOptions({ icon: smallPin.data, anchor: new Microsoft.Maps.Point(smallPin.width/2,smallPin.height/2) });
}
});
return pin;
}
Currently shapes do no support zIndexing due to performance issues, but there are plans to add support for this. You can however use two layers for your data, the first to store your main data, and the second to display the hovered data. Below is a code sample that demonstrates hovering a pushpin, changing its style and displaying it above all other shapes on the map. When you mouse out the style goes back to what it was and the pushpin goes back to the main layer.
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script type='text/javascript' src='https://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
<script type='text/javascript'>
var map;
var defaultColor = 'blue';
var hoverColor = 'red';
var mouseDownColor = 'purple';
function GetMap()
{
map = new Microsoft.Maps.Map('#myMap', {
credentials: 'YourBingMapsKey'
});
var layer = new Microsoft.Maps.Layer();
map.layers.insert(layer);
var hoverLayer = new Microsoft.Maps.Layer();
map.layers.insert(hoverLayer);
//Add some random pushpins to fill the map and cover our hoverable main pushpin.
var pushpins = Microsoft.Maps.TestDataGenerator.getPushpins(300, map.getBounds());
layer.add(pushpins);
//Create our hoverable pushpin.
var pin = new Microsoft.Maps.Pushpin(map.getCenter(), {
color: defaultColor
});
layer.add(pin);
Microsoft.Maps.Events.addHandler(pin, 'mouseover', function (e) {
e.target.setOptions({ color: hoverColor });
//Move pin to hover layer.
layer.remove(pin);
hoverLayer.add(pin);
});
Microsoft.Maps.Events.addHandler(pin, 'mousedown', function (e) {
e.target.setOptions({ color: mouseDownColor });
});
Microsoft.Maps.Events.addHandler(pin, 'mouseout', function (e) {
e.target.setOptions({ color: defaultColor });
//Move pin to main layer.
hoverLayer.remove(pin);
layer.add(pin);
});
}
</script>
</head>
<body>
<div id="myMap" style="position:relative;width:600px;height:400px;"></div>
</body>
</html>
You can try this code sample out here: http://bingmapsv8samples.azurewebsites.net/#Pushpin_HoverStyle

Google Markers with dynamic data for Ionic Modal

I am new to hybrid mobile app creation. And my use case is very simple. I have a single ionic modal using template html.
What I want is populating the same ionic template with different values based on some records data. Basically it is a google map and on click on any of the markers, the same template should open with different values based on the marker.
My controller code -
.controller('MyLocationCtrl', function(
$scope,
$stateParams,
force,
$cordovaGeolocation,
$ionicModal,
GoogleMapService,
ForceService,
$q
) {
console.log('this is in my location page');
var currentPosition = GoogleMapService.getCurrentLocation();
var restaurantModal = $ionicModal.fromTemplateUrl('templates/bottom-sheet.html', {
scope: $scope,
viewType: 'bottom-sheet',
animation: 'slide-in-up'
});
var allContacts = ForceService.getAllContactsWithGeo();
var promises = [];
promises.push(currentPosition);
promises.push(allContacts);
promises.push(restaurantModal);
var allMarkers = [];
var allContactDetails = [];
currentPosition.then(
function(position) {
console.log('position data -->', position);
var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapOptions = {
center: latLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
$scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);
var bounds = new google.maps.LatLngBounds();
allContacts.then(
function(contacts) {
console.log('contacts final -->', contacts);
for (var i=0; i<contacts.records.length; i++) {
var contact = contacts.records[i];
console.log('single contact -->', contact.MailingLatitude, contact.MailingLongitude);
var contactlatLng = new google.maps.LatLng(contact.MailingLatitude, contact.MailingLongitude);
var contactInfo = {};
//contactInfo.marker = {};
var marker = new google.maps.Marker({
map: $scope.map,
animation: google.maps.Animation.DROP,
position: contactlatLng
});
contactInfo.marker = marker;
contactInfo.recordDetails = contact;
allMarkers.push(marker);
allContactDetails.push(contactInfo);
// Set boundary for markers in map
bounds.extend(contactlatLng);
}
// Fit map based on markers
$scope.map.fitBounds(bounds);
}
);
// google.maps.event.addListenerOnce($scope.map, 'idle', function(){
// });
},
function(error) {
console.log("Could not get location" + error);
}
);
// Add listener for marker pop up once all promises resolved
$q.all(promises).then(
function(values) {
console.log('first -->', values[0]);
console.log('second -->', values[1]);
console.log('third -->', values[2]);
var detailModal = values[2];
$scope.modal = detailModal;
for (var i=0; i<allContactDetails.length; i++) {
allContactDetails[i].marker.addListener('click', function() {
console.log('helllos from marker');
console.log('all contactInfo -->', allContactDetails[i].recordDetails.Name);
$scope.contactName = allContactDetails[i].recordDetails.Name;
detailModal.show();
});
}
}
);
})
Front end template code -
<script id="templates/bottom-sheet.html" type="text/ng-template">
<ion-bottom-sheet-view>
<ion-header-bar align-title="left">
<h1 class="title">New Particle</h1>
<button class="button button-icon icon ion-android-close" ng-click="modal.hide()"></button>
{{contactName}}
</ion-header-bar>
</ion-bottom-sheet-view>
</script>
Now the modal opens properly when i click on the google marker, but I am not sure how to pass dynamic data to the pop modal.
Since you are doing this :
var restaurantModal = $ionicModal.fromTemplateUrl('templates/bottom-sheet.html', {
scope: $scope,
viewType: 'bottom-sheet',
animation: 'slide-in-up'
});
Your modal can access to the scope of your controller.
So if you declare any variable in your controller it will be accessible through the modal.

Bing cluster need to display tooltip & popup

Need to display marker bunch(cluster) title on bing map.
And I want to display tooltip#hover and popup#click with cluster is there any option to display with map.
I have tried usign following code (but there is no tooltip and popup on click):
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: 'Your Bing Maps Key'
});
var pushpin = new Microsoft.Maps.Pushpin(map.getCenter(), null);
var layer = new Microsoft.Maps.Layer();
layer.add(pushpin);
map.layers.insert(layer);
thanks
You can use the infobox class to do this. As luck would have it I was just putting together sample to do this. Here you go:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script type='text/javascript'
src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap'
async defer></script>
<script type='text/javascript'>
var map, infobox, tooltip;
var tooltipTemplate = '<div style="background-color:white;height:20px;width:150px;padding:5px;text-align:center"><b>{title}</b></div>';
function GetMap() {
map = new Microsoft.Maps.Map('#myMap', {
credentials: Your Bing Maps Key'
});
//Create a second infobox to use as a tooltip when hovering.
tooltip = new Microsoft.Maps.Infobox(map.getCenter(), {
visible: false,
showPointer: false,
showCloseButton: false,
offset: new Microsoft.Maps.Point(-75, 10)
});
tooltip.setMap(map);
//Create an infobox at the center of the map but don't show it.
infobox = new Microsoft.Maps.Infobox(map.getCenter(), {
visible: false
});
//Assign the infobox to a map instance.
infobox.setMap(map);
//Create random locations in the map bounds.
var randomLocations = Microsoft.Maps.TestDataGenerator.getLocations(5, map.getBounds());
for (var i = 0; i < randomLocations.length; i++) {
var pin = new Microsoft.Maps.Pushpin(randomLocations[i]);
//Store some metadata with the pushpin.
pin.metadata = {
title: 'Pin ' + i,
description: 'Discription for pin' + i
};
//Add a click event handler to the pushpin.
Microsoft.Maps.Events.addHandler(pin, 'click', pushpinClicked);
Microsoft.Maps.Events.addHandler(pin, 'mouseover', pushpinHovered);
Microsoft.Maps.Events.addHandler(pin, 'mouseout', closeTooltip);
//Add pushpin to the map.
map.entities.push(pin);
}
}
function pushpinClicked(e) {
//Hide the tooltip
closeTooltip();
//Make sure the infobox has metadata to display.
if (e.target.metadata) {
//Set the infobox options with the metadata of the pushpin.
infobox.setOptions({
location: e.target.getLocation(),
title: e.target.metadata.title,
description: e.target.metadata.description,
visible: true
});
}
}
function pushpinHovered(e) {
//Hide the infobox
infobox.setOptions({ visible: false });
//Make sure the infobox has metadata to display.
if (e.target.metadata) {
//Set the infobox options with the metadata of the pushpin.
tooltip.setOptions({
location: e.target.getLocation(),
htmlContent: tooltipTemplate.replace('{title}', e.target.metadata.title),
visible: true
});
}
}
function closeTooltip() {
tooltip.setOptions({
htmlContent: ' ',
visible: false
});
}
</script>
</head>
<body>
<div id="myMap" style="position:relative;width:600px;height:400px;"></div>
</body>
</html>

Leaflet Markercluster - tooltip on hover issue

I'm a newbie of javascript, trying to build an interactive map online, where some events should be triggered by clicking on markers and some just by hovering them.
Managed to have the click part working, but, because of Markercluster plugin, I'm not sure where to use onEachFeature function for having the tooltip opened by hover a single marker.
Anyone please can tell me what I'm doing wrong?
var geoJsonFeature = {
type: 'FeatureCollection',
features:
[
{
type: 'Feature',
properties: {
title: 'Title',
page: 'some.html',
'marker-color': '#000000',
zoom: 7
},
geometry: {
type: 'Point',
coordinates: [12.583745,55.6750803]
}
},
...
};
// access to mapbox api
L.mapbox.accessToken ='...';
var map = L.mapbox.map('map', 'example1234').setView([34, -37], 3);
function getTitle(marker) {
return marker.feature.properties.title;
};
function getPage(marker) {
return marker.feature.properties.page;
};
var markerGroup = new L.MarkerClusterGroup({showCoverageOnHover:false});
var geoJsonLayer = L.geoJson(geoJsonFeature, {
onEachFeature: function (feature, layer) {
var popupContent = getTitle(marker);
layer.bindPopup(popupContent);
}
});
markerGroup.addLayer(geoJsonLayer);
map.addLayer(markerGroup);
markerGroup.on('click', function(ev) {
var marker = ev.layer;
marker.on('click', function(ev) {
if(map.getZoom() > marker.feature.properties.zoom) {
map.setView(ev.latlng, map.getZoom());
}
else {
map.setView(ev.latlng, marker.feature.properties.zoom);
}
});
});
});
geoJsonLayer.on('mouseover', function(e) {
e.layer.openPopup();
});
geoJsonLayer.on('mouseout', function(e) {
e.layer.closePopup();
});
You need to use the onEachFeature option to get the individual markers and bind handlers to the mouseover and mouseout events:
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.title);
layer.on("mouseover", function () {
layer.openPopup();
});
layer.on("mouseout", function () {
layer.closePopup();
});
}
Here's a working example on Plunker: http://plnkr.co/edit/hfjOWv3uCBFawDGqR3Ue?p=preview
Note: i'm not using ClusterMarker in this example but it should work just fine when using ClusterMarker