In my Ionic 2 application, I'm able to see my current location on the map, but how can I add the location (longtitude and latitude) to Firebase?
initMap(): Promise<any> {
this.mapInitialised = true;
return new Promise((resolve) => {
Geolocation.getCurrentPosition().then((position) => {
let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
//let latLng = new google.maps.LatLng(40.713744, -74.009056);
let mapOptions = {
center: latLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement, mapOptions);
resolve(true);
google.maps.event.addListener(this.map, 'click', (event) => {
this.clearMarkers();
let geocoder = new google.maps.Geocoder;
let infowindow = new google.maps.InfoWindow;
let distanceToYou = this.getDistanceBetweenPoints(
event.latLng,
position,
'miles'
).toFixed(2);
this.geocodeLatLng(event.latLng,geocoder,infowindow,distanceToYou);
});
});
});
}
I'm able to get the current position of me and if I double click the map I can see the distance between me and the marker.
Yes it's possible. But since double clicking a map zooms it, i'll use press. But it would be better if you set a button on a info window with a "save location" text or something like this to call the saving function.
YOUR HTML
<div #mapID (press)="saveLocation()">
YOUR .TS
import * as firebase from 'firebase';
public lat;
public long;
initMap(): Promise<any> {
this.mapInitialised = true;
return new Promise((resolve) => {
Geolocation.getCurrentPosition().then((position) => {
this.lat = position.coords.latitude;
this.long = position.coords.longitude;
// YOUR CODE CONTINUES HERE...
});
});
});
saveLocation(){
firebase.database().ref('PATH/YOU/WANT/TO/SAVE').update({
lat: this.lat,
long: this.long
}).then(res =>{
// THE LOCATION IS SAVED, DO YOUR STUFF
})
}
Like this you can save you location, use update() instead of set() so you don't subscribe other data.
If you want to retrieve that data just use firebase.database().ref('PATH/YOU'VE/SAVED').once('value', snapshot =>{ // CODE });
Hope it helps
Related
I am creating a map to track user position, i am using #geolocation plugin and showing map using:
<script src="https://maps.googleapis.com/maps/api/js?key=API_KEYscript>
Currently marker is being displayed and on watchposition marker is placing multiple times and isn’t removing last placed marker.
import { Component, ViewChild, ElementRef } from '#angular/core';
import { Geolocation, GeolocationOptions, Geoposition, PositionError } from '#ionic-native/geolocation';
declare var google;
#Component({
selector: 'app-tab1',
templateUrl: 'tab1.page.html',
styleUrls: ['tab1.page.scss']
})
export class Tab1Page {
geolocation = Geolocation;
options: GeolocationOptions;
currentPos: Geoposition;
#ViewChild('map', { static: false }) mapElement: ElementRef;
map: any;
constructor() { }
ionViewDidEnter() {
this.getUserPosition();
}
getUserPosition() {
this.options = {
enableHighAccuracy: false
};
//get location
this.geolocation.getCurrentPosition(this.options).then((pos: Geoposition) => {
this.currentPos = pos;
console.log(pos);
//add map
let latLng = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
let mapOptions = {
center: latLng,
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
this.addMarker(latLng);
}, (err: PositionError) => {
console.log("error : " + err.message);
})
let subscription = this.geolocation.watchPosition().subscribe(position =>{
let userPosition = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
this.addMarker(userPosition);
})
}
addMarker(position) {
let marker = new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
position: position
});
let content = "<p>This is your current position !</p>";
let infoWindow = new google.maps.InfoWindow({
content: content
});
google.maps.event.addListener(marker, 'click', () => {
infoWindow.open(this.map, marker);
});
}
}
I want to remove last marker before placing another one.
Thank you.
I use an Array to create a couple of markers in my leaflet map for Photos with Geolocations which works fine:
for (var p of ArrayofData) {
var lat = p.lat;
var lon = p.lon;
var markerLocation = new L.LatLng(lat, lon);
var marker = new L.Marker(markerLocation,{
draggable: 'true',
id: p.Filename
});
mymap.addLayer(marker);
}
to enable users to change their photo location I need them to drag those markers around and then I can read the new location:
marker.on('dragend', function (e) {
// Get position of dropped marker
var latLng = e.target.getLatLng();
console.log ("id:"+e.target.options.id);
console.log ("NewLocation:"+latLng);
});
As all of my markers have the same constructor it seems as if this script only works with the last marker. All others are draggable but do not give back any feedback when released.
Does anybody know, how I can access all of them?
You can do that by adding those drag event handlers inside your for loop.
for (var p of data) {
var lat = p.lat;
var lon = p.lon;
var markerLocation = new L.LatLng(lat, lon);
var marker = new L.Marker(markerLocation,{
draggable: 'true',
id: p.Filename
});
map.addLayer(marker);
marker.on('dragend', function (e) {
// Get position of dropped marker
var latLng = e.target.getLatLng();
console.log ("id:"+e.target.options.id);
console.log ("NewLocation:"+latLng);
});
}
Also I highly recommend that you keep track of your markers by adding them to an array.
var markers = [];
for (var p of data) {
var lat = p.lat;
var lon = p.lon;
var markerLocation = new L.LatLng(lat, lon);
var marker = new L.Marker(markerLocation,{
draggable: 'true',
id: p.Filename
});
map.addLayer(marker);
marker.on('dragend', function (e) {
// Get position of dropped marker
var latLng = e.target.getLatLng();
console.log ("id:"+e.target.options.id);
console.log ("NewLocation:"+latLng);
});
markers.push(marker);
}
Demo
I have used JavaScript SDK to display map.
It's working on the browser but when I open it on dev app, the page shows the blank page.
ionViewDidLoad(){
this.loadMap();
}
loadMap(){
this.geolocation.getCurrentPosition().then((position) => {
let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
let mapOptions = {
center: latLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
}, (err) => {
console.log(err);
});
}
Try to add locationOption
let locationOptions = { timeout: 30000, enableHighAccuracy: true };
and pass to getCurrentPosition like this
this.geolocation.getCurrentPosition(locationOptions).then((position) => {
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.
I have list of markers that want to render in the map, but I want it one by one. In first click I want to make new marker. Then when I click to another location, I want my marker to just move to the new latLng not to create another marker. Here is my code:
function (licon, coord, data) {
var self = jQuery(this);
var map = self.data("map");
var latlng = new L.LatLng(coord[0], coord[1]);
//Create Marker
if (licon) {
var leafIcon = L.icon(licon);
console.log(typeof (marker));
if (typeof (marker) === 'undefined') {
var marker = L.marker(latlng, {
icon: leafIcon,
"markerData": data,
draggable: true
});
} else {
console.log('not undefined');
map.removeLayer(marker);
marker = L.marker(latlng, {
icon: leafIcon,
"markerData": data,
draggable: true
});
}
} else {
var marker = L.marker(latlng, {
"markerData": data,
draggable: true
});
}
marker.addTo(map);
return marker;
}
A quick example of the result: http://jsfiddle.net/ve2huzxw/43/
var currentMarker;
map.on("click", function (event) {
if (currentMarker) {
currentMarker.setLatLng(event.latlng);
return;
}
currentMarker = L.marker(event.latlng, {
draggable: true
}).addTo(map).on("click", function () {
event.originalEvent.stopPropagation();
});
});
document.getElementById("done").addEventListener("click", function () {
currentMarker = null;
});
You can also add a smooth transition to show the marker moving to the new position:
if (currentMarker) {
currentMarker._icon.style.transition = "transform 0.3s ease-out";
currentMarker._shadow.style.transition = "transform 0.3s ease-out";
currentMarker.setLatLng(event.latlng);
setTimeout(function () {
currentMarker._icon.style.transition = null;
currentMarker._shadow.style.transition = null;
}, 300);
return;
}
a slightly more consolidated solution some years later.
var currentMarker;
map2.on('click', function(e) {
if (currentMarker){
currentMarker.setLatLng(e.latlng)
} else {
currentMarker = new L.marker(e.latlng).addTo(map2);
};
//console.log('lat, lon: ', e.latlng.lat, e.latlng.lng);
});
leaflet now defaults to smoothly dragging the point over to the new coords.