Hi guys I need help in how to watch position in google maps with Ionic 3, I would like that upload position in real time in the firebase
In my home.ts I have the following code :
getMyPosition() {
this.geolocation.getCurrentPosition().then((result) => {
this.positionTruck = new google.maps.LatLng(result.coords.latitude, result.coords.longitude);
const mapOptions = {
zoom: 18,
center: this.positionTruck,
disableDefaultUI: true
}
this.map = new google.maps.Map(document.getElementById('map'), mapOptions);
this.truckMarker(this.positionTruck);
let watch = this.geolocation.watchPosition();
watch.subscribe((data) => {
let truck = { latitude: data.coords.latitude, longitude: data.coords.longitude };
this.truckService.updateGeolocation(this.truck.key, truck);
console.log(data.coords)
});
}).catch((error) => {
console.log('Erro ao tentar pegar sua localização ', error);
})
}
And now I have this code in service to update truck.service:
update(key: string, truck: any) {
return new Promise((resolve, reject) => {
this.db.list(this.PATH)
.update(key, (truck))
.then(() => resolve())
.catch((e) => reject())
})
}
this way when I test on the device, the home page giving refresh in page, why ?
Is this form correctly the update position ? help please.
import : import { Geolocation, Geoposition } from '#ionic-native/geolocation';
and declare :
public lat: number = 0;
public lng: number = 0;
and add in your code
let options = {
frequency: 3000,
enableHighAccuracy: true
};
this.watch = this.geolocation.watchPosition(options).filter((p: any) => p.code === undefined).subscribe((position: Geoposition) => {
console.log(position.coords.latitude + ' ++++++++++ ' + position.coords.longitude);
// Run update inside of Angular's zone
this.zone.run(() => {
this.lat = position.coords.latitude;
this.lng = position.coords.longitude;
);
});
});
Related
I've made a custom hook, which can be used to fetch users location and find nearest marker on map based on that information.
Right now it works, but first object it returns is useStates default value. Response looks like this:
{
coordinates: { lat: '', lng: '' },
loaded: false
}
After returning object first time, it starts to work like it should:
{
coordinates: { lat: 45.024335, lng: 19.277089 },
loaded: true
}
So basically I don't want that the hook sends empty objects, with no values. How can I fix this?
const useGeoLocation = (markers) => {
const [location, setLocation] = useState({
loaded: false,
coordinates: { lat: "", lng: "" },
});
const onSuccess = (location) => {
// User location succesfully fetched, converting data format.
const targetPoint = turf.point([
location.coords.latitude,
location.coords.longitude,
]);
// Fetching data from markers parameter and converting data format.
var arr = [];
markers.map((marker) => arr.push(turf.point(marker.location)));
var points2 = turf.featureCollection(arr);
// Calculating which marker is nearest to targetPoint.
var nearest = turf.nearestPoint(targetPoint, points2);
// Setting location of nearest marker to usestate.
setLocation({
loaded: true,
coordinates: {
lat: nearest.geometry.coordinates[0],
lng: nearest.geometry.coordinates[1],
},
});
};
const onError = () => {
setLocation({
loaded: true,
coordinates: {
lat: 65.024335,
lng: 27.277089,
},
});
};
useEffect(() => {
if (markers) {
if (!("geolocation" in navigator)) {
onError();
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
}
}, [markers]);
return location;
};
Instead of just returning the location object as a whole, you could split the return into an object with values for the data, a loading state, an error message if needs be. For example:
const useGeoLocation = (markers) => {
const [location, setLocation] = useState(undefined);
const [error, setError] = useState("");
const onSuccess = (location) => {
// Rest of the success handler...
setLocation({
coordinates: {
lat: nearest.geometry.coordinates[0],
lng: nearest.geometry.coordinates[1],
},
});
};
const onError = () => {
setLocation({
coordinates: {
lat: 65.024335,
lng: 27.277089,
},
});
setError("Some error message");
};
useEffect(() => {
if (markers) {
if (!("geolocation" in navigator)) {
onError();
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
}
}, [markers]);
return {
data: location,
isLoading: !location && !error,
error: error,
};
};
Then when calling the hook you can do:
const {data, isLoading, error} = useGeoLocation();
and check for the value of data, or that isLoading and error are false, before doing anything.
this is the sample search widget in arcGIS, I want to override the search function, that the only thing that can be searched is the data in my query and it will appear just like in the picture
const [searchData, setSearchData] = useState(null);
const fetchSearchLocation = async (name) => {
const { data } = await client.query({
query: SEARCH_LOCATION,
variables: {
name: name
},
})
setSearchData(data);
return data;
};
useEffect(() => {
location();
}, []);
const location = () => {
if (mapDiv.current) {
esriConfig.apiKey = "sample api key";
const map = new Map({
basemap: 'arcgis-light-gray',
});
const view = new MapView({
center: [123.5504, 12.3574], // Longitude, latitude
container: mapDiv.current,
map: map,
zoom: 2, // Zoom level
});
const searchWidget = new Search({
view: view,
sources: [customSearchSource],
includeDefaultSources: false
});
view.ui.add(searchWidget, { position: "top-left", index: 0 });
view
.when((r) => {})
.then(() => {
mapDiv.current = view;
fetchData();
});
}
};
const searchDataLocation = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("searchData: ", searchData)
resolve(searchData); //test_data = Your data.
}, 1000);
});
const customSearchSource = new SearchSource({
placeholder: 'Search',
getSuggestions: (params) => {
fetchSearchLocation(params.suggestTerm)
console.log("searchData2: ", searchData)
return searchDataLocation.then((data) => {
console.log("datas: ", data) // the result is null.
})
....
resource
https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Search.html
How to put queries in ArcGIS esri search?
note: this is edited question
Here i am trying to display the leaflet js maps in ionic 5 tabs below are my issues
i have 2 tabs in ionic app tab1--> map , tab2 --> some other page when i click on tab1 and go to tab 2 and after some time if click on tab1 again i am getting error as
Map container is already initialized
if i am tab1 and going to tab2 and again clicking on the tab1 if pinch n zoom the maps tiles are going back wards and clearing map images and showing grey area.
below is my code :
html
<ion-content id="mapId" style="--offset-top:0px; --offset-bottom:0px;">
</ion-content>
// when ever a marker on map is clicked then the this below ionic content will displayed
<ion-content class="detail-desc" id="detail-desc">
</ion-content>
type script code:
map: L.Map;
center: L.PointTuple;
leafletMap() {
document.getElementById('detail-desc').style.display = 'none';
this.map = L.map('mapId').setView([this.Latitude, this.Longitude], 20);
L.tileLayer('https://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(this.map);
const myFeatureGroup = L.featureGroup().addTo(this.map).on('click', (e) => {
console.log(e);
const event = e;
const that = this;
this.myTest(event, that);
});
let marker: any;
const availableIcon = L.icon({
iconUrl: '../../assets/icon/marker-icon-2x.png',
iconSize: [21, 34],
});
const unAvailableIcon = L.icon({
iconUrl: '../../assets/icon/marker-icon-red.png',
iconSize: [21, 34],
});
const locationIcon = L.icon({
iconUrl: '../../assets/icon/current-location.png',
iconSize: [30, 30],
});
marker = L.marker([this.Latitude, this.Longitude], { icon: locationIcon }).addTo(myFeatureGroup);
for (let i = 0; i < this.mapData.length; i++) {
if (this.mapData[i].status === 'Available') {
marker = L.marker([this.mapData[i].locationLat, this.mapData[i].locationLong],{ icon: availableIcon ,id:this.mapData[i].Id}).addTo(myFeatureGroup);
} else {
marker = L.marker([this.mapData[i].locationLat, this.mapData[i].locationLong],{ icon: unAvailableIcon,id:this.mapData[i].Id }).addTo(myFeatureGroup);
}
marker.selectedData = this.mapData[i];
}
}
to check the gps permission
// Check if application having GPS access permission
checkGPSPermission() {
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.ACCESS_COARSE_LOCATION).then(
result => {
if (result.hasPermission) {
// If having permission show 'Turn On GPS' dialogue
this.askToTurnOnGPS();
} else {
// If not having permission ask for permission
this.requestGPSPermission();
}
},
err => {
alert(err);
}
);
}
requestGPSPermission() {
this.locationAccuracy.canRequest().then((canRequest: boolean) => {
if (canRequest) {
console.log('4');
} else {
// Show 'GPS Permission Request' dialogue
this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.ACCESS_COARSE_LOCATION)
.then(
() => {
// call method to turn on GPS
this.askToTurnOnGPS();
},
error => {
// Show alert if user click on 'No Thanks'
alert('requestPermission Error requesting location permissions ' + error);
}
);
}
});
}
askToTurnOnGPS() {
this.locationAccuracy.request(this.locationAccuracy.REQUEST_PRIORITY_HIGH_ACCURACY).then(
() => {
// When GPS Turned ON call method to get Accurate location coordinates
this.getLocationCoordinates();
},
error => alert('Error requesting location permissions ' + JSON.stringify(error))
);
}
// Methos to get device accurate coordinates using device GPS
getLocationCoordinates() {
this.geolocation.getCurrentPosition().then((resp) => {
// resp.coords.latitude
// resp.coords.longitude
const latLong = {
lat: resp.coords.latitude,
long: resp.coords.longitude
};
// this.LatAndLang.push(latLong);
console.log(this.Latitude, this.Longitude);
this.Latitude = resp.coords.latitude;
this.Longitude = resp.coords.longitude;
console.log(resp);
}).catch((error) => {
console.log('Error getting location', error);
});
}
loading the data on the on ion view did load
getLoadedLocations(){
this.httpClient.get(this.endPointUrl).subscribe(data => {
// tslint:disable-next-line: no-string-literal
this.mapData = data;
// tslint:disable-next-line:prefer-for-of
this.platform.ready().then(() => {
setTimeout(() => {
if (this.Latitude) {
this.leafletMap();
}
}, 5000);
});
// this.products = data;
},error => {
console.log('Unable to get the location');
});
}
ionViewDidEnter(){
console.log('view loaded');
this.getLoadedLocations();
this.checkGPSPermission();
}
I'm fairly new to React and I have run into a problem. I need to gather data from an API and then use the data to create Polygons with Google Maps. However, I'm experiencing problems accessing it.
When I log this.state.coordinates:
Console.log result of this.state.coordinates
However, when I try to log this.state.coordinates[0] it shows undefined. My guess is that the order in which the data binds is wrong, but I can't seem to find the solution. Here is my code:
constructor(props) {
super(props);
this.state = {
coordinates: [{}],
loading: 'initial'
};
}
componentDidMount() {
this.setState({
loading: 'true'
})
this.getData()
}
getData = async () => {
let coordinates = []
let res = await axios.get('https://smartcity-parking-api.herokuapp.com/sectors')
const sectors = await res.data.data
sectors.map(async (sector, i) => {
let res = await axios.get(sector.self_links.detail)
const coordinateArray = await res.data.data.coordinates
coordinates[i] = {
latlng: [],
id: res.data.data.sector_data.sector_id
}
coordinateArray.map(coordinate => {
let latlng = {
lat: coordinate.latitude,
lng: coordinate.longitude
}
coordinates[i].latlng.push(latlng)
})
coordinates[i].latlng.push({
lat: coordinateArray[0].latitude,
lng: coordinateArray[0].longitude
})
})
this.setState({
coordinates: coordinates,
loading: 'false'
})
}
render() {
let { coordinates, loading } = this.state
if (loading === 'initial') {
return <h2>Intializing...</h2>;
}
if (loading === 'true') {
return <h2>Loading...</h2>;
}
if (loading === 'false') {
return (
//Google maps here
);
}
I have tried making a loader, but it doesn't seem to be working. Any help would be very appreciated!
Why not set coordinates to null initially in your constructor and then have your conditional be
(loading === 'false' && coordinates)
That may solve your issue.
Change getData function to this.
getData = async () => {
let coordinates = []
let res = await axios.get('https://smartcity-parking-api.herokuapp.com/sectors')
const sectors = res.data.data
const sectorsLinks = await Promise.all(sectors.map(sector => axios.get(sector.self_links.detail)))
sectorsLinks.map((sector, i) => {
const coordinateArray = sector.data.data.coordinates;
coordinates[i] = {
latlng: [],
id: sector.data.data.sector_data.sector_id
}
coordinateArray.map(coordinate => {
let latlng = {
lat: coordinate.latitude,
lng: coordinate.longitude
}
coordinates[i].latlng.push(latlng)
})
coordinates[i].latlng.push({
lat: coordinateArray[0].latitude,
lng: coordinateArray[0].longitude
})
});
console.log(coordinates);
this.setState({
coordinates: coordinates,
loading: 'false'
})
};
I want to store my geopoints to firestore database but it wont work.
I created an array called acctPosition to store there the geopoints inside,
but in firebase i can't see the data, it looks like that nothing is stored.
How can I store the geopoints correctly?
The output:
The Geoloaction component:
data () {
coords: {
latitude: null,
longitude: null
},
acctPosition: []
},
...
mounted () {
var self = this;
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
console.log(pos)
var acctPos = self.acctPosition.push(pos)
console.log(acctPos)
}
} else {
// Browser doesn't support Geolocation
}
let docId = `${this.currentUser.uid}`
// store geoData to currentUser in firebase firestore
fb.usersCollection.doc(docId).set({
acctPosition: this.acctPos
}).then(ref => {
console.log('work')
}).catch(err => {
console.log(err)
})
}
Javascript is asynchronous, so fb.usersCollection.doc(docId).set() is going to be executed before getCurrentPosition is finished.
You can push to firebase after getCurrentPosition is done:
mounted () {
...
var self = this;
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
console.log(pos)
map.setCenter(pos);
var acctPos = self.acctPosition.push(pos)
console.log(acctPos)
let docId = `${self.currentUser.uid}`
// store geoData to currentUser in firebase firestore
fb.usersCollection.doc(docId).set({
acctPosition: self.acctPosition
}).then(ref => {
console.log('work')
}).catch(err => {
console.log(err)
})
}
} else {
// Browser doesn't support Geolocation
}
}