How to move marker over map in ionic2? - google-maps-api-3

In this code I try to move marker as I change location but it seems something is wrong.marker is not replacing.
declare var google;
#Component({
selector: 'page-page1',
templateUrl: 'page1.html',
providers: [Geolocation]
})
export class Page1 {
#ViewChild('map') mapElement: ElementRef;
map: any;
public marker =[];
public lat;
public lng;
public speed = '0';
public watch: any;
constructor(public navCtrl: NavController, public Geolocation: Geolocation, public zone: NgZone,
){ }
ionViewDidLoad(){
this.loadMap();
this.startTracking();
}
loadMap(){
this.Geolocation.getCurrentPosition().then((position) => {
let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
let mapOptions = {
center: latLng,
zoom: 17,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
this.addMarker();
}, (err) => {
console.log(err);
});
}
startTracking() {
let config = {
desiredAccuracy: 0,
stationaryRadius: 20,
distanceFilter: 10,
debug: true,
interval: 2000
};
let options = {
frequency: 3000,
enableHighAccuracy: true
};
this.watch = this.Geolocation.watchPosition(options).filter((p: any) => p.code === undefined).subscribe((position: Geoposition) => {
this.zone.run(() => {
this.lat = position.coords.latitude;
this.lng = position.coords.longitude;
this.marker[0].lat= position.coords.latitude;
this.marker[0].lng= position.coords.longitude;
this.speed =( +position.coords.speed*3.6 ) + 'Km/h';
});
});
}
addMarker(){
let marker = new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
position: this.map.getCenter()
});
this.marker.push(marker);
console.log(this.marker);
}
}
}

Use setPosition to move marker. Try this
this.zone.run(() => {
this.lat = position.coords.latitude;
this.lng = position.coords.longitude;
this.marker.setPosition( { lat: this.lat, lng: this.lng });
this.speed =( +position.coords.speed*3.6 ) + 'Km/h';
});

Related

FullCalendar initializing before events load

I have a FullCalendar that takes in an array(selectedEvents) from a function that uses the Location ID that is pulled from the url. The array is built onInit as is the calendar but the calendar has a timeout on it in order to allow the events to populate. When the calendar is initially navigated to from another part of the website, the events for the Default Location are not displayed but they are populated into the selectedEvents array. When I click on another location's calendar, the events are populated and then displayed correctly. The calendar works correctly thereforth. I believe the calendar is taking precedence over the population of events during the first initialization of the calendar even though it is wrapped in a timeout. I've seen this question once before on SO but it was not answered.
I've already tried extending the timeout of the calendar
getLocationEvents(location: PFLocation) {
// if (this.allEvents) {
this.selectedEvents = [];
if (location.events) {
console.log(location.events);
this.eventIdArray = location.events;
for (let event of this.eventIdArray) {
this.eventService.get(event).subscribe(data => {
console.log(data);
this.selectedEvents.push(data);
});
}
} else {
return;
}
console.log(this.selectedEvents);
return this.selectedEvents;
}
getBatchEvents(location: PFLocation) {
var that = this;
if (this.allEvents) {
if (location.batches) {
let batches = location.batches;
for (let batch of batches) {
this.batchService.get(batch).subscribe(data => {
for (let event of data.events) {
this.eventService
.get(event)
.subscribe(eventData => {
console.log(eventData);
this.selectedEvents.push(eventData);
});
}
});
}
console.log(this.selectedEvents);
console.log('out of Batch Events');
return this.selectedEvents;
}
}
if (!this.allEvents) {
this.selectedEvents = [];
if (location.batches) {
let batches = location.batches;
for (let batch of batches) {
this.batchService.get(batch).subscribe(data => {
for (let event of data.events) {
this.eventService
.get(event)
.subscribe(eventData => {
console.log(eventData);
this.selectedEvents.push(eventData);
});
}
});
}
console.log(this.batchEvents);
console.log('out of Batch Events');
return this.selectedEvents;
}
}
}
getAllEvents(location: PFLocation) {
this.allEvents = true;
var that = this;
that.getLocationEvents(location);
that.getBatchEvents(location);
}
ngOnInit() {
let that = this;
this.sub = this.route.params.subscribe(params => {
this.locationId = params['locationid'];
this.userService
.getLocation(this.locationId)
.subscribe(location => {
console.log('Out of on Init');
this.selectedLocation = JSON.parse(
JSON.stringify(location)
);
that.getAllEvents(this.selectedLocation);
console.log(this.selectedLocation);
});`enter code here`
console.log(this.selectedLocation);
if (this.locationId) {
const today = new Date();
const y = today.getFullYear();
const m = today.getMonth();
const d = today.getDate();
$('#fullCalendar').fullCalendar('removeEvents');
$('#fullCalendar').fullCalendar(
'addEventSource',
that.selectedEvents
);
setTimeout(function() {
$('#fullCalendar').fullCalendar({
viewRender: function(view: any, element: any){
// We make sure that we activate the
perfect scrollbar when the view isn't on Month
if (view.name != 'month') {
var elem = $(element).find('.fc-
scroller')[0];
let ps = new PerfectScrollbar(elem);
}
},
header: {
left: 'title',
center: 'month, agendaWeek, agendaDay',
right: 'prev, next, today'
},
defaultDate: today,
selectable: true,
selectHelper: true,
views: {
month: {
// name of view
titleFormat: 'MMMM YYYY'
// other view-specific options here
},
week: {
titleFormat: ' MMMM D YYYY'
},
day: {
titleFormat: 'D MMM, YYYY'
}
},
eventLimit: true, // allow "more" link when
too many events
select: function(start: any, end: any) {
that.openEventForm();
},
eventClick: function(event, jsEvent) {
that.completeEventForm(event);
}
});
}, 500);
}
});
}
I expect the calendar to be populated the first time I navigate to the page.
Aside from refactoring the backend and eliminating the spaghetti code it wasn't a difficult issue once someone pointed out how the calendar inits. First the calendar has to grab onto the DOM element then it grabs the event source. If it doesn't grab the #calendar then it won't grab the event source until the next time it's initialized and at that point it is using the old event source data(if set up as my code was). "viewRender" needs to happen first, then "removeEvents" then "addEventSource".
getLocationEvents(location: PFLocation) {
if (location.events) {
return this.eventService
.getFaciltyTasks(location._id)
.subscribe(data => {
console.log(data);
this.facilityEvents = data;
});
}
}
getAllBatchEvents(location: PFLocation) {
return this.eventService
.getAllCultivationTasks(location._id)
.subscribe(data => {
console.log(data);
this.cultivationEvents = data;
});
}
getBatchEvents(batchId: string) {
return this.eventService.getBatchTasks(batchId).subscribe(data => {
console.log(data);
this.batchEvents = data;
});
}
editEventForm() {
this.state = 'editEvent';
}
getAllEvents(location: PFLocation) {
var that = this;
return new Promise(resolve => {
return this.eventService
.getAllLocationTasks(location._id)
.subscribe(data => {
console.log(data);
that.selectedEvents = data;
that.calInit();
resolve(that.selectedEvents);
});
});
}
calInit() {
var that = this;
const $calendar = $('#fullCalendar');
console.log(that.locationId);
if (this.selectedEvents) {
const today = new Date();
const y = today.getFullYear();
const m = today.getMonth();
const d = today.getDate();
$calendar.fullCalendar({
viewRender: function(view: any, element: any) {
// We make sure that we activate the perfect scrollbar when the view isn't on Month
if (view.name != 'month') {
var elem = $(element).find('.fc-scroller')[0];
let ps = new PerfectScrollbar(elem);
}
},
customButtons: {
filter: {
text: 'filter',
click: function() {
that.open();
}
}
},
// events: that.selectedEvents,
header: {
left: 'title',
center: 'filter, month, agendaWeek, agendaDay',
right: 'prev, next, today'
},
defaultDate: today,
selectable: true,
selectHelper: true,
views: {
month: {
// name of view
titleFormat: 'MMMM YYYY'
// other view-specific options here
},
week: {
titleFormat: ' MMMM D YYYY'
},
day: {
titleFormat: 'D MMM, YYYY'
}
},
eventLimit: true, // allow "more" link when too many events
select: function(start: any, end: any) {
that.openEventForm();
},
eventClick: function(event, jsEvent) {
that.eventLocation = new PFLocation({});
that.eventBatch = new Batch();
that.eventRoom = new Room();
that.viewEvent(event);
}
});
$calendar.fullCalendar('removeEvents');
$calendar.fullCalendar('addEventSource', that.selectedEvents);
}
}
ngOnInit() {
// const $calendar = $('#fullCalendar');
let that = this;
// that.filter = false;
this.sub = this.route.params.subscribe(params => {
that.locationId = params['locationid'];
if (that.locationId) {
that.AuthService.getCurrentUser().then(user => {
that.currentUser = user;
var locations = that.currentUser.locations.admin.concat(
that.currentUser.locations.user
);
var location = find(locations, function(location) {
return location._id == that.locationId;
});
console.log(location);
console.log(that.currentUser);
});
}
this.userService
.getLocation(this.locationId)
.subscribe(location => {
console.log('Out of on Init');
this.selectedLocation = JSON.parse(
JSON.stringify(location)
);
that.getAllEvents(this.selectedLocation);
console.log(this.selectedLocation);
});
console.log(this.selectedLocation);
});
}

first time getting undefined props from mapStateToProps

how can i get asynchronous reducers data ,i search but didn't get solution
Booking component
cutPick = () => {
this.props.pickup(false);
}
action creator
export function pickup(latlng) {
return function (dispatch) {
dispatch({type:PICKUP_STATE,payload:latlng});
}
}
reducer
import {PICKUP_STATE} from '../actions/types';
export default function (state={},action) {
switch(action.type) {
case PICKUP_STATE:
return {...state,pickup:action.payload}
}
return state;
}
Map component
import React from 'react';
import scriptLoader from "react-async-script-loader";
import config from '../../../config'
import 'antd/dist/antd.css';
import { Icon,Button,Alert,Row, Col} from 'antd';
import {connect} from "react-redux";
import * as actions from "../actions";
class Map extends React.Component{
constructor(props){
super(props);
this.state = {
pick:false,
drop:false,
mapCenter : { lat: 17.3850, lng: 78.4867 },
pickupConfirmButton:false,
dropoffConfirmButton:false
};
this.map=false;
this.directionsService =false;
this.directionsDisplay = false;
this.mapLoaded = false;
this.pickMarker=false;
this.dropMarker=false;
}
//listen map current location event and set marker and pick state
addYourLocationButton = (map) => {
this.pickMarker = new google.maps.Marker ({
map: this.map,
animation: google.maps.Animation.DROP,
position: this.state.pick ? this.state.pick : this.state.mapCenter,
draggable: true
});
if(!this.mapLoaded) {
return false;
}
var controlDiv = document.createElement('div');
let firstChild = document.createElement('button');
firstChild.style.backgroundColor = '#fff';
firstChild.style.border = 'none';
firstChild.style.outline = 'none';
firstChild.style.width = '28px';
firstChild.style.height = '28px';
firstChild.style.borderRadius = '2px';
firstChild.style.boxShadow = '0 1px 4px rgba(0,0,0,0.3)';
firstChild.style.cursor = 'pointer';
firstChild.style.marginRight = '10px';
firstChild.style.padding = '0px';
firstChild.title = 'Your Location';
controlDiv.appendChild(firstChild);
let secondChild = document.createElement('div');
secondChild.style.margin = '5px';
secondChild.style.width = '18px';
secondChild.style.height = '18px';
secondChild.style.backgroundImage = 'url(https://maps.gstatic.com/tactile/mylocation/mylocation-sprite-1x.png)';
secondChild.style.backgroundSize = '180px 18px';
secondChild.style.backgroundPosition = '0px 0px';
secondChild.style.backgroundRepeat = 'no-repeat';
secondChild.id = 'you_location_img';
firstChild.appendChild(secondChild);
// google.maps.event.addListener(map, 'dragend', () => {
// document.getElementById("you_location_img").style.backgroundPosition='0px 0px';
// });
google.maps.event.addListener(this.pickMarker, 'dragend', () =>{
let lat=this.pickMarker.getPosition().lat();
let lng=this.pickMarker.getPosition().lng();
this.setState({pick:{lat:lat,lng:lng}},function () {
let geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
if (status === 'OK') {
document.getElementById('pick').value = results[0].formatted_address;
}
})
// console.log(this.state.pick);
})
if (this.state.pick && this.state.drop){
this.calculateRoute();
}
});
firstChild.addEventListener('click', () => {
let imgX = '0';
let animationInterval = setInterval( () =>{
if (imgX == '-18') imgX = '0';
else imgX = '-18';
document.getElementById("you_location_img").style.backgroundPosition=imgX + 'px 0px';
}, 500);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition( (position) => {
let latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
let geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === 'OK') {
document.getElementById('pick').value = results[0].formatted_address;
}
})
if(latlng){
this.setState(()=>({
pick:latlng
}))
}
this.pickMarker.setPosition(latlng);
map.setCenter(latlng);
if (this.state.pick && this.state.drop){
this.calculateRoute();
}
clearInterval(animationInterval);
document.getElementById("you_location_img").style.backgroundPosition='-144px 0px';
});
}
else {
clearInterval(animationInterval);
document.getElementById("you_location_img").style.backgroundPosition='0px 0px';
}
});
controlDiv.index = 1;
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(controlDiv);
}
//load gmaps ,load maps and directions and set center as user current location
componentWillReceiveProps({isScriptLoadSucceed}){
if (isScriptLoadSucceed) {
this.mapLoaded= true;
this.directionsService = new google.maps.DirectionsService();
this.directionsDisplay = new google.maps.DirectionsRenderer({ suppressMarkers: true });
this.map = new google.maps.Map(document.getElementById('map'), {
zoom: 11,
center: this.state.mapCenter
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition( (position)=> {
let initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
// console.log(this.state.mapCenter)
this.setState({mapCenter:initialLocation} , ()=> {
// console.log(this.state.mapCenter)
})
this.map.setCenter(initialLocation);
});
}else{
console.log('error in current location')
}
this.directionsDisplay.setMap(this.map);
//icon of current location in map and current loc pickup marker
this.addYourLocationButton(this.map);
//listener for pickup marker when it clicked
this.pickMarker.addListener('click', () =>{
this.pickupMarkerClickListener();
});
}
else{
alert("Something went wrong, plz check internet Connection")
}
}
//for Refs
componentDidMount() {
this.props.onRef(this);
}
//for Refs
componentWillUnmount() {
this.props.onRef(null);
}
// this function pick state false when user click on cut pick address from pickup field and set direction false also
isPickEmpty=(emptyPickState)=>{
console.log(this.props.pickupProps);
this.setState({pick:emptyPickState},function () {
this.pickMarker.setMap(null);
this.directionsDisplay.set('directions', null);
//sending false as distance to BookingDetails
this.props.routeCalc(false);
});
};
//it handle search hint of google place api (getting data from Booking Form)
pickupSearch =(pickupAddress) =>{
let options = {
types: [],
componentRestrictions: {
'country': 'IN'
}
};
let inputPick = document.getElementById('pick');
const autocompletePick = new google.maps.places.Autocomplete(inputPick, options);
autocompletePick.bindTo('bounds', this.map);
google.maps.event.addListener(autocompletePick, 'place_changed', () => {
let place =autocompletePick.getPlace();
let lat = place.geometry.location.lat(),
lng = place.geometry.location.lng();
let geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
if (status === 'OK') {
document.getElementById('pick').value = results[0].formatted_address;
}
});
this.pickUp({lat:lat,lng:lng})
});
}
//this function put pick marker on pickup search
pickUp = (pick) => {
// console.log(pick)
if(this.pickMarker){
this.pickMarker.setMap(null);
}
this.setState({pick:pick}, () => {
// console.log(this.state.pick);
var infoWindow = new google.maps.InfoWindow;
this.pickMarker = new google.maps.Marker({
map:this.map,
animation: google.maps.Animation.DROP,
position: this.state.pick,
draggable: true
});
infoWindow.setPosition(this.state.pick);
// infoWindow.setContent('Location found.');
// infoWindow.open(this.map);
this.map.setCenter(this.state.pick);
this.pickMarker.addListener('click', () =>{
this.pickupMarkerClickListener();
});
google.maps.event.addListener(this.pickMarker, 'dragend', () =>{
this.pickupMarkerDragListener();
});
this.focus.scrollIntoView();
})
if (this.state.pick && this.state.drop){
this.calculateRoute();
}
};
//this function invoke click and drag function of pickup marker
pickupMaker=()=>{
this.setState({pickupConfirmButton:false});
this.map.setZoom(11);
if(this.pickMarker){
this.pickMarker.setMap(null);
}
google.maps.event.clearListeners(this.map, 'center_changed');
this.pickMarker = new google.maps.Marker ({
map: this.map,
animation: google.maps.Animation.DROP,
position: this.state.pick,
draggable:true
});
if(this.dropMarker){
this.dropMarker.setVisible(true);
}
//listening on drag of pick marker
google.maps.event.addListener(this.pickMarker, 'dragend', () => {
this.pickupMarkerDragListener();
console.log('marker')
});
//listening on click of pick marker
this.pickMarker.addListener('click', () =>{
this.pickupMarkerClickListener();
});
//if both state are set the calculate the root
if (this.state.pick && this.state.drop){
this.calculateRoute();
}
};
//this function handle click event of pick Marker
pickupMarkerClickListener = () => {
if(this.dropMarker){
this.dropMarker.setVisible(false);
}
this.directionsDisplay.set('directions', null);
this.setState({pickupConfirmButton:true});
this.map.setCenter(this.pickMarker.getPosition());
this.map.setZoom(16);
this.map.addListener('center_changed', () => {
let lat=this.map.getCenter().lat();
let lng=this.map.getCenter().lng();
this.setState({pick:{lat:lat,lng:lng}},function () {
let geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
if (status === 'OK') {
document.getElementById('pick').value = results[0].formatted_address;
}
})
// console.log(this.state.pick);
});
this.pickMarker.setPosition({lat:lat,lng:lng});
// console.log(this.map.getCenter().lat(),this.map.getCenter().lng(),this.pickMarker.getPosition())
});
};
//This function Handle drage event of pick marker
pickupMarkerDragListener = () => {
console.log('dragged');
let lat=this.pickMarker.getPosition().lat();
let lng=this.pickMarker.getPosition().lng();
this.setState({pick:{lat:lat,lng:lng}}, () => {
let geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': {lat:lat,lng:lng}}, (results, status) => {
if (status === 'OK') {
document.getElementById('pick').value = results[0].formatted_address;
}
})
console.log(this.state.pick);
})
if ((this.state.pick && this.state.drop) && (this.state.pickupConfirmButton === false && this.state.dropoffConfirmButton ===false)){
this.calculateRoute();
}
}
// this function drop state false when user click on cut drop address from dropoff field and set direction false also
isDropEmpty=(emptyDropState)=>{
// console.log(emptyPickState);
// console.log(this.state.pick);
this.setState({drop:emptyDropState},function () {
// this.pickMarker=false;
this.dropMarker.setMap(null);
this.directionsDisplay.set('directions', null);
//sending false as distance to BookingDetails
this.props.routeCalc(false);
});
};
//it handle drop search hint of google place api (getting data from Booking Form)
dropoffSearch = (dropoffSearch) =>{
let options = {
types: [],
componentRestrictions: {
'country': 'IN'
}
};
const autocompleteDrop = new google.maps.places.Autocomplete(document.getElementById('drop'), options);
autocompleteDrop.bindTo('bounds', this.map);
google.maps.event.addListener(autocompleteDrop, 'place_changed', () => {
let place =autocompleteDrop.getPlace();
let lat = place.geometry.location.lat(),
lng = place.geometry.location.lng();
// this.props.dropHandler({lat:lat,lng:lng})
//
// this.setState({drop:place.name});
// let lat = place.geometry.location.lat(),
// lng = place.geometry.location.lng();
//putting place in pick field
let geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
if (status === 'OK') {
// console.log(results[0].formatted_address)
document.getElementById('drop').value = results[0].formatted_address;
}
});
this.dropOff({lat:lat,lng:lng})
});
};
//this function put drop marker on dropoff search(function invoked from Booking Details)
dropOff = (drop) => {
if (this.dropMarker){
this.dropMarker.setMap(null);
}
this.setState({drop:drop}, () => {
// console.log(this.state.drop);
var infoWindow = new google.maps.InfoWindow;
this.dropMarker = new google.maps.Marker({
map:this.map,
animation: google.maps.Animation.DROP,
position: this.state.drop,
draggable: true
});
infoWindow.setPosition(this.state.drop);
// infoWindow.setContent('Location found.');
// infoWindow.open(this.map);
this.map.setCenter(this.state.drop);
// console.log(this.state.drop);
google.maps.event.addListener(this.dropMarker, 'dragend', () =>{
this.dropoffMarkerDragListener();
});
this.dropMarker.addListener('click', () =>{
this.dropoffMarkerClickListener();
});
if (this.state.pick && this.state.drop){
this.calculateRoute();
}
this.focus.scrollIntoView();
})
// if (this.state.pick && this.state.drop){
// this.calculateRoute();
// }
};
//this function invoke click and drag function of drop marker
dropoffMaker= () =>{
this.setState({dropoffConfirmButton:false});
this.map.setZoom(11);
this.dropMarker.setMap(null);
google.maps.event.clearListeners(this.map, 'center_changed');
this.dropMarker = new google.maps.Marker ({
map: this.map,
animation: google.maps.Animation.DROP,
position: this.state.drop,
draggable: true
});
if(this.pickMarker){
this.pickMarker.setVisible(true);
}
google.maps.event.addListener(this.dropMarker, 'dragend', () =>{
this.dropoffMarkerDragListener();
});
this.dropMarker.addListener('click', () =>{
this.dropoffMarkerClickListener();
});
if (this.state.pick && this.state.drop){
this.calculateRoute();
}
}
//this function handle click event of Drop Marker
dropoffMarkerClickListener=()=>{
this.pickMarker.setVisible(false);
this.directionsDisplay.set('directions', null);
this.setState({dropoffConfirmButton:true});
this.map.setCenter(this.dropMarker.getPosition());
this.map.setZoom(16);
this.map.addListener('center_changed', () => {
let lat=this.map.getCenter().lat();
let lng=this.map.getCenter().lng();
this.setState({drop:{lat:lat,lng:lng}},function () {
let geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
if (status === 'OK') {
document.getElementById('drop').value = results[0].formatted_address;
}
});
});
this.dropMarker.setPosition({lat:lat,lng:lng});
console.log(this.map.getCenter().lat(),this.map.getCenter().lng(),this.dropMarker.getPosition())
});
}
//This function Handle drage event of drop marker
dropoffMarkerDragListener= () => {
let lat=this.dropMarker.getPosition().lat();
let lng=this.dropMarker.getPosition().lng();
this.setState({drop:{lat:lat,lng:lng}},function () {
let geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': {lat:lat,lng:lng}}, function(results, status) {
if (status === 'OK') {
document.getElementById('drop').value = results[0].formatted_address;
}
})
console.log(this.state.drop);
})
if ((this.state.pick && this.state.drop) && (this.state.pickupConfirmButton === false && this.state.dropoffConfirmButton ===false)){
this.calculateRoute();
}
};
//this function set direction and calculate the root of pick and drop
calculateRoute = () =>{
var request ={
origin:this.state.pick,
destination:this.state.drop,
travelMode:"DRIVING"
};
this.directionsService.route(request,(result,status) => {
if(status== "OK"){
console.log(result.routes[0].legs[0].distance);
this.props.routeCalc(result.routes[0].legs[0].distance);
this.directionsDisplay.setDirections(result);
}
});
};
render(){
return(
<div className="Map" ref={node => this.focus = node}>
<Alert
message="Tap or Drag Marker[s] to set exact location Then Click on Confirm Location"
type="info"
showIcon
/>
<div id="map" style={{height: "500px"}}></div>
{this.state.pickupConfirmButton && <Button className="cnfrmBtn" size="large" onClick={this.pickupMaker}>Confirm Location</Button> }
{this.state.dropoffConfirmButton && <Button className="cnfrmBtn" size="large" onClick={this.dropoffMaker}>Confirm Location</Button> }
</div>
)
}
}
function mapStateToProps (state) {
return {pickupProps:state.BookingData.pickup}
}
// export default Map;
const ScriptLoadedMap = scriptLoader(
[config.MapApi]
)(Map);
export default connect(mapStateToProps,actions)(ScriptLoadedMap);
i'm sending false value from Booking to action creator then i'm dispatching and storing value in action in reducer
but when i'm calling pickupProps from Map component first time i'm getting undefined after first time getting false value.
so here my problem is how can i get first time (asynchronous) false value when it called from Booking component.

How to show dynamically multiple popup in openlayers 3 map

Can anyone tell me how to show all popup of markers in openlayers 3 map. I searched many sites but couldn't get any answer please anyone know about this then help me
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.TileJSON({
url: 'https://api.tiles.mapbox.com/v3/mapbox.geography-class.json?secure',
crossOrigin: 'anonymous'
})
})
],
overlays: [overlay],
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([0, 50]),
zoom: 2
})
});
var vectorSource = new ol.source.Vector({
features: [
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([16.37, 48.2])),
name: 'London'
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-0.13, 51.51])),
name: 'NY'
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([30.69, 55.21])),
name: 'Paris'
})
]
});
var markers = new ol.layer.Vector({
source: vectorSource,
style: new ol.style.Style({
image: new ol.style.Icon({
src: '//openlayers.org/en/v3.12.1/examples/data/icon.png',
anchor: [0.5, 1]
})
})
});
map.addLayer(markers);
function showpopup(){
// For showing popups on Map
var arrayData = [1];
showInfoOnMap(map,arrayData,1);
function showInfoOnMap(map, arrayData, flag) {
var flag = 'show';
var extent = map.getView().calculateExtent(map.getSize());
var id = 0;
var element = document.getElementById('popup');
var popup = new ol.Overlay({
element: element,
positioning: 'center'
});
map.addOverlay(popup);
if (arrayData != null && arrayData.length > 0) {
arrayData.forEach(function(vectorSource) {
/* logMessage('vectorSource >> ' + vectorSource); */
if (vectorSource != null && markers.getSource().getFeatures() != null && markers.getSource().getFeatures().length > 0) {
markers.getSource().forEachFeatureInExtent(extent, function(feature) {
/* logMessage('vectorSource feature >> ' + feature); */
console.log("vectorSource feature >> " + markers.getSource().getFeatures());
if (flag == 'show') {
var geometry = feature.getGeometry();
var coord = geometry.getCoordinates();
popup.setPosition(coord);
/* var prop;
var vyprop = ""; */
$(element).popover({
'position': 'center',
'placement': 'top',
'template':'<div class="popover"><div class="popover-content"></div></div>',
'html': true,
'content': function() {
var string = [];
var st = feature.U.name;
if (st != null && st.length > 0) {
var arrayLength = 1;
string = "<table>";
string += '<tr><td>' + st + "</table>";
}
return string;
}
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
});
}
});
}
};
}
I used this code in my file but it show only one popup on all markers please someone tell me how to show all markers popup simultaneously.
I'm not sure exactly what you're trying to show in your popups, but I would probably try this approach. This extends the ol.Overlay class, allowing you to get the map object and attach a listener which you can use to grab the feature that was clicked. Is this what you're trying to accomplish?
function PopupOverlay() {
var element = document.createElement('div');
$(element).popover({
template: '<div class="popover"><div class="popover-content"></div></div>',
placement: 'top',
position: 'center',
html: true
});
ol.Overlay.call(this, {
element: element
});
}
ol.inherits(PopupOverlay, ol.Overlay);
PopupOverlay.prototype.setMap = function (map) {
var self = this;
map.on('singleclick', function (e) {
map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
ol.Overlay.prototype.setPosition.call(self, feature.getGeometry().getCoordinates());
var el = self.getElement();
$(el).data('bs.popover').options.content = function () {
// EDIT THE POPOVER CONTENT
return feature.get('name');
};
$(el).popover('show');
});
});
ol.Overlay.prototype.setMap.call(this, map);
};
Check out this example
So after your comment, I see what you're trying to do now. I would say that you want to take the same basic approach, make a class that overrides ol.Overlay, but this time just loop through all the features, creating an overlay for each feature.
This Updated Example
function PopoverOverlay(feature, map) {
this.feature = feature;
var element = document.createElement('div');
$(element).popover({
template: '<div class="popover"><div class="popover-content"></div></div>',
placement: 'top',
position: 'center',
html: true
});
ol.Overlay.call(this, {
element: element,
map: map
});
};
ol.inherits(PopoverOverlay, ol.Overlay);
PopoverOverlay.prototype.togglePopover = function () {
ol.Overlay.prototype.setPosition.call(this, this.feature.getGeometry().getCoordinates());
var self = this;
var el = this.getElement();
$(el).data('bs.popover').options.content = function () {
// EDIT THE POPOVER CONTENT
return self.feature.get('name');
};
$(el).popover('toggle');
};
// create overlays for each feature
var overlays = (function createOverlays () {
var popupOverlays = [];
vectorSource.getFeatures().forEach(function (feature) {
var overlay = new PopoverOverlay(feature, map);
popupOverlays.push(overlay);
map.addOverlay(overlay);
});
return popupOverlays;
})();
// on click, toggle the popovers
map.on('singleclick', function () {
for(var i in overlays) {
overlays[i].togglePopover();
}
});
Now when you click anywhere on the map, it should call the togglePopover method and toggle the popover on the individual element.

Google Maps InfoBubble windows neither closing nor recentering map

I have a successful working GM prototype using InfoBubble here.
I need the map to recenter when I open each new InfoBubble window.
The map recenters on closing each InfoBubble because I call [line 238 etc]:
google.maps.event.addListener(infoBubble, "closeclick", function ()
Secondly, why doesn't the Los Angeles (United States West Coast, LA) InfoBubble also close the most recent InfoBubble window open as all the others do, please?
Thanks so much in advance for any suggestions; I know it must be simple - but have spent hours and hours and searched S/O too!
javascript:
$(document).ready(function () { initialize(); });
var myLatlng = new google.maps.LatLng(51.30, 0.7);
function initialize() {
google.maps.Map.prototype.setCenterWithOffset = function(LatLng, offsetX, offsetY) {
var map = this;
var ov = new google.maps.OverlayView();
ov.onAdd = function() {
var proj = this.getProjection();
var aPoint = proj.fromLatLngToContainerPixel(LatLng);
aPoint.x = aPoint.x+offsetX;
aPoint.y = aPoint.y+offsetY;
map.setCenter(proj.fromContainerPixelToLatLng(aPoint));
};
ov.draw = function() {};
ov.setMap(this);
};
var centerMap = new google.maps.LatLng(51.30, 0.7);
var mapOptions = {
zoom: 2,
disableDefaultUI: true,
scrollwheel: false,
navigationControl: false,
mapTypeControl: false,
scaleControl: false,
draggable: false,
center: centerMap,
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setCenterWithOffset(myLatlng, 50, 225);
setMarkers(map, sites);
google.maps.event.addListener(infoBubble, "closeclick", function () {
map.setCenterWithOffset(myLatlng, 50, 225);
});
google.maps.event.addListener(infoBubbleLA, "closeclick", function () {
map.setCenterWithOffset(myLatlng, 50, 225);
});
};
var infoBubble = new InfoBubble({
maxWidth: 400,
});
var infoBubbleLA = new InfoBubble({
maxWidth: 400,
});
// locationstrings start
var losangeles1 = 'losangeles1';
var losangeles2 = 'losangeles2';
var losangeles3 = 'losangeles3';
var losangeles4 = 'losangeles4';
var losangelescontentString ='losangelescontentString';
var portonovocontentstring ='Porto Novo';
var shackletoncontentstring = 'Shackleton';
var florencecontentstring = 'Florence';
var buenosairescontentstring = 'Buenos Aires';
var jodhpurcontentstring = 'Jodhpur';
var mtsinaicontentstring = 'Mt Sainai';
var neworleanscontentstring = 'New Orleans';
var pariscontentstring='Paris';
// locationstrings end
infoBubbleLA.addTab('Electronic Cataloguing Initiative', losangeles1);
infoBubbleLA.addTab('Getty Leadership Institute at Claremont Graduate University', losangeles2);
infoBubbleLA.addTab('Tab 3', losangeles3);
infoBubbleLA.addTab('Preserve L.A.', losangeles4);
var sites = [
// 'Title', lat, long, contentstring
['Los Angeles', 34.054082,-118.24261, losangelescontentString],
['Porto Novo', 6.501411,2.604275, portonovocontentstring],
['Shackleton', -77.550000, 166.150000, shackletoncontentstring],
['Florence', 43.773046,11.255901, florencecontentstring],
['Buenos Aires', -34.578528,-58.526273, buenosairescontentstring],
['Jodhpur', 27.199507,73.73826, jodhpurcontentstring],
['Mt Sinai', 28.555972,33.975048, mtsinaicontentstring],
['New Orleans', 29.984676,-90.063171, neworleanscontentstring],
['Paris', 48.821799,2.404933, pariscontentstring]
];
var iconBase = 'http://gettylabs.org/visit/FoundationMap/images/';
function setMarkers(map, markers) {
for (var i = 0; i < markers.length; i++) {
var sites = markers[i];
var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
var marker = new google.maps.Marker({
icon: iconBase + 'bullet.png',
title: sites[0],
position: siteLatLng,
html: sites[3],
map: map
});
google.maps.event.addListener(marker, "click", function () {
map.setCenterWithOffset(myLatlng, 50, 25);
if (this.html == losangelescontentString) {
infoBubbleLA.setContent(this.html);
infoBubbleLA.open(map,this);
} else {
infoBubble.setContent(this.html);
infoBubble.open(map,this);
}
});
};
};
You have 2 different InfoBubbles in you code infoBubbleLA and infoBubble. Opening one won't close the the other.
var infoBubble = new InfoBubble({
maxWidth: 400,
});
var infoBubbleLA = new InfoBubble({
maxWidth: 400,
});
This should do that:
google.maps.event.addListener(marker, "click", function () {
map.setCenterWithOffset(myLatlng, 50, 25);
if (this.html == losangelescontentString) {
infoBubbleLA.setContent(this.html);
infoBubbleLA.open(map,this);
infoBubble.close();
} else {
infoBubble.setContent(this.html);
infoBubble.open(map,this);
infoBubbleLA.close();
}
});
working fiddle

Initializing Google Maps as an AMD module

To initialize google.maps as an AMD module, compliant with twitter/flight and requirejs, use:
define([
'components/flight/lib/component',
'async!http://maps.google.com/maps/api/js?key=AIzaSyDp9D9Db1CWfeGUJ1bin45s2WKZN5sapuM&sensor=false'
], function(defineComponent){
return defineComponent(newMap);
function newMap () {
this.defaultAttrs({
// Selector
mapDiv: '#map',
// Map Canvas
mapCanvas: {},
// Initialized?
initializedMap: false
});
this.initializeMap = function () {
var mapCenter = new google.maps.LatLng(39.960664,-75.605488);
var mapOptions = {
zoom: 15,
center: mapCenter,
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.ROADMAP,
};
this.attr.mapCanvas = new google.maps.Map(document.getElementById("map"), mapOptions);
if (this.attr.mapCanvas != {} ) {
this.attr.initializedMap = true;
this.trigger(document, 'mapInitialized', {
status: this.attr.initializedMap
});
};
// ### Map events
//-----------
// Mouse Up
google.maps.event.addListener(this.attr.mapCanvas, 'mouseup', function() {
this.trigger('mouseup');
});
// Zoom Changed
google.maps.event.addListener(this.attr.mapCanvas, 'zoom_changed', function() {
this.trigger('zoomChanged');
});
};
this.mouseup = function () {
console.log("what");
}
this.zoomChanged = function () {
console.log("is up");
}
this.after('initialize', function () {
this.on('mouseup', this.mouseup);
this.on('zoomChanged', this.zoomChanged);
this.on('initializeMap', this.initializeMap);
this.trigger('initializeMap');
});
}
});
I put together a Google Maps AMD loader plugin, which adds some functionality on top of the async! loader.
require.config({
googlemaps: {
params: {
key: 'abcd1234', // sets api key
libraries: 'geometry' // set google libraries
}
}
});
require(['googlemaps!'], function(gmaps) {
// google.maps available as gmaps
var map = new gmaps.Map('map-canvas');
});

Resources