React Native (Track user on following direction (Google Map)) - react-native

React Native;
How we can Monitor The google map Tracking So Actually User drive on line or not, E.g.
if i got the direction from Location A to Location B , So how we can check that User Drive on Line or not.
Basically i can't Monitor it,
E.g
Actually i want it in react native,
So anyOne Help me How we can achieve it or any 3rd party Library,
Thanks in Advance.

This Method isPointNearLine is Solve my problem.
Code Snippet.
import * as geolib from 'geolib';
const returnObj=(lat,lon)=>{
return {
latitude: lat, longitude:lon
}
}
const IsLies = geolib.isPointNearLine(
returnObj(25.976424, -80.238400), ////point
returnObj(25.97641, -80.24045), ////start
returnObj(25.97647,-80.23818), ///end
20 ////distance in meter
);
it will return true and false.
There is another approach is we can user #turf/boolean-point-on-line
Code Snippet
var pt = turf.point([74.276089,31.478847]); //// NearPoint
///Note [[Start Point],[NearPoint],[EndPoint]]
var line = turf.lineString([[74.277908,31.479470],[74.276089,31.478847],[74.274402,31.478452]]);
var isPointOnLine = turf.booleanPointOnLine(pt, line);
it will also return True and false if Points lies on line.

Related

Here map integration in react-native mobile app

I am trying to implement heremap api in react-native project.While searching got https://www.npmjs.com/package/react-native-heremaps .But there is no proper documents to use this library. I am new to react-native. Please give me some suggestions to implement this.
! if you don't use expo please comment and I'll change the answer a bit !
First of all, as you probably know you need to make an account at HERE Developer webiste.
After you have made an account, you have to create a project(you can get a Freemium plan for free and it has plenty of requests available for free, upgrade if you need more). After that you need to "Generate App" for REST & XYZ HUB API/CLI at your project page. With that, you will recieve APP ID and APP CODE. With all this, HERE Developer Account setup is complete.
Lets jump to React Native now.
First of all you need to install a npm package called react-native-maps which we will use to display data that HERE provides. You can see installation instructions here.
After this, lets assume you have already created a component that will show the map. You need to import this:
import { Marker, Polyline } from 'react-native-maps'
import { MapView } from 'expo'
With that we have our map almost ready.
I will use axios in this example but you can use fetch to make requests to HERE if you want.
So we import axios(if you never worked with it you can learn more about it here):
import axios from 'axios'
Now, you should have coordinates of those two locations ready in a state or somewhere, and it should look something like this:
constructor(props){
super(props)
this.state = {
startingLocation: {
latitude: "xx.x",
longitude: "yy.y",
},
finishLocation: {
latitude: "xx.x",
longitude: "yy.y",
}
}
}
With "xx.x" and "yy.y" being actual coordinates you want.
So now when you have coordinates of start and finish location you can make a request to you HERE API project. It's as easy as this(I got this api from here):
// I will create a function which will call this, you can call it whenever you want
_getRoute = () => {
// we are using parseFloat() because HERE API expects a float
let from_lat = parseFloat(this.state.startingLocation.latitude)
let from_long = parseFloat(this.state.startingLocation.longitude)
let to_lat = parseFloat(this.state.finishLocation.latitude)
let to_long = parseFloat(this.state.finishLocation.longitude)
// we will save all Polyline coordinates in this array
let route_coordinates = []
axios.get(`https://route.api.here.com/routing/7.2/calculateroute.json?app_id=PUT_YOUR_APP_ID_HERE&app_code=PUT_YOUR_APP_CODE_HERE&waypoint0=geo!${from_lat},${from_long}&waypoint1=geo!${to_lat},${to_long}&mode=fastest;bicycle;traffic:disabled&legAttributes=shape`).then(res => {
// here we are getting all route coordinates from API response
res.data.response.route[0].leg[0].shape.map(m => {
// here we are getting latitude and longitude in seperate variables because HERE sends it together, but we
// need it seperate for <Polyline/>
let latlong = m.split(',');
let latitude = parseFloat(latlong[0]);
let longitude = parseFloat(latlong[1]);
routeCoordinates.push({latitude: latitude, longitude: longitude});
}
this.setState({
routeForMap: routeCoordinates,
// here we can access route summary which will show us how long does it take to pass the route, distance etc.
summary: res.data.response.route[0].summary,
// NOTE just add this 'isLoading' field now, I'll explain it later
isLoading: false,
})
}).catch(err => {
console.log(err)
})
}
NOTE There are few things to note here. First is that you have to replace APP ID and APP CODE with acutal APP ID and APP CODE from your HERE project.
Second note that I added &legAttributes=shape at the end of the request URL but it is not in the documentation. I put it there so Polyline coordinates acutally have a correct shape, if you don't put it, it will just respond with coordinates of road turns and that polyline will go over buildings and stuff, it will just look bad.
OK. So now we have coordinates to make a Polyline, let's do that.
<MapView>
<Polyline coordinates={this.state.routeForMap} strokeWidth={7} strokeColor="red" geodesic={true}/>
<Marker coordinate={{latitude: this.state.startingLocation.latitude, longitude: this.state.startingLocation.longitude}} title="Starting location"/>
<Marker coordinate={{latitude: this.state.finishLocation.latitude, longitude: this.state.finishLocation.longitude}} title="Finishlocation"/>
</MapView>
Explanation:
Polyline.coordinates will map through all of the coordinates that we have provided and draw a Polyline. strokeWidth is just how thick you want your line to be, and strokeColor is obviously color of a line.
Now, you should add a region to your MapView component to let it know what is the initial region you want to show on the map. So I suggest you to do something like this:
In state, define a region field and make it the same coordinates as starting location, and then set delta to make a bit larger view.
// so in state just add this
region: {
latitude: parseFloat("xx.x"),
longitude: parseFloat("yy.y"),
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}
And now, add region={this.state.region} to MapView.
You would be done now, but let's make sure this works every time. You need to make sure that HERE API request is complete before the map renders. I would do it like this:
// in your state define field to control if loading is finished
isLoading: true,
Now, you would call the function _getRoute() we made before in componendDidMount() lifecycle function provided by React Native. Like this:
componentDidMount() {
// when this function is finished, we will set isLoading state to false to let program know that API request has finished and now we can render the map
this._getRoute()
}
So finally a final step is to control isLoading in your render() function:
render() {
if(this.state.isLoading) {
return (
<Text>Loading...(you could also use <ActivityIndicator/> or what ever you want to show while loading the request)</Text>
)
} else {
// just put everything we already did here + stuff you already have
}
}
So here it is. I tried to make it as detailed as possible to make it easy for you and other people that will need help with this.
Don't ever hesitate to ask me anything if something is unclear or it's not working or you need more help! I'm always happy to help :D

How to handle deep linking in react native / expo

I have posted about this previously but still struggling to get a working version.
I want to create a sharable link from my app to a screen within my app and be able to pass through an ID of sorts.
I have a link on my home screen opening a link to my expo app with 2 parameters passed through as a query string
const linkingUrl = 'exp://192.168.0.21:19000';
...
_handleNewGroup = async () => {
try {
const group_id = await this.createGroupId()
Linking.openURL(`${linkingUrl}?screen=camera&group_id=${group_id}`);
}catch(err){
console.log(`Unable to create group ${err}`)
}
};
Also in my home screen I have a handler that gets the current URL and extracts the query string from it and navigates to the camera screen with a group_id set
async handleLinkToCameraGroup(){
Linking.getInitialURL().then((url) => {
let queryString = url.replace(linkingUrl, '');
if (queryString) {
const data = qs.parse(queryString);
if(data.group_id) {
this.props.navigation.navigate('Camera', {group_id: data.group_id});
}
}
}).catch(err => console.error('An error occurred', err));
}
Several issues with this:
Once linked to the app with the query string set, the values don't get reset so they are always set and therefore handleLinkToCameraGroup keeps running and redirecting.
Because the URL is not an http formatted URL, it is hard to extract the query string. Parsing the query string returns this:
{
"?screen": "camera",
"group_id": "test",
}
It doesn't seem right having this logic in the home screen. Surely this should go in the app.js file. But this causes complications not being able to use Linking because the RootStackNavigator is a child of app.js so I do not believe I can navigate from this file?
Any help clarifying the best approach to deep linking would be greatly appreciated.

How to check if a user device is using fingerprint/face as unlock method. [ReactNative] [Expo]

I'm using ReactNative based on Expo Toolkit to develop a App and I want know how I can check if the user is using the fingerprint (TouchID on iPhone) or face detection (FaceID on iPhone X>) to unlock the device.
I already know how to check if device has the required hardware using Expo SDK, as follow:
let hasFPSupport = await Expo.Fingerprint.hasHardwareAsync();
But I need check if the user choose the fingerprint/face as unlock method on your device, instead pattern or pin.
Thanks
Here's an update to Donald's answer that takes into account Expo's empty string for the model name of the new iPhone XS. It also takes into account the Simulator.
const hasHardwareSupport =
(await Expo.LocalAuthentication.hasHardwareAsync()) &&
(await Expo.LocalAuthentication.isEnrolledAsync());
let hasTouchIDSupport
let hasFaceIDSupport
if (hasHardwareSupport) {
if (Constants.platform.ios) {
if (
Constants.platform.ios.model === '' ||
Constants.platform.ios.model.includes('X')
) {
hasFaceIDSupport = true;
} else {
if (
Constants.platform.ios.model === 'Simulator' &&
Constants.deviceName.includes('X')
) {
hasFaceIDSupport = true;
}
}
}
hasTouchIDSupport = !hasFaceIDSupport;
}
EDIT: Expo released an update that fixes the blank model string. However you might want to keep a check for that just in case the next iPhone release cycle causes the same issue.
Currently, you could determine that a user has Face ID by checking Expo.Fingerprint.hasHardwareAsync() and Expo.Fingerprint.isEnrolledAsync(), and then also checking that they have an iPhone X using Expo.Constants.platform (docs here).
So:
const hasHardwareSupport = await Expo.Fingerprint.hasHardwareAsync() && await Expo.Fingerprint.isEnrolledAsync();`
if (hasHardwareSupport) {
const hasFaceIDSupport = Expo.Constants.platform.ios && Expo.Constants.platform.ios.model === 'iPhone X';
const hasTouchIDSupport = !hasFaceIDSupport;
}
Incase you tried the above answer and it's not working please note as at the time of my post expo's documentation has changed
- import * as LocalAuthentication from 'expo-local-authentication';
- let compatible = await LocalAuthentication.hasHardwareAsync()
We can check if device has scanned fingerprints:
await Expo.Fingerprint.isEnrolledAsync()
So, this can be used to reach the objective as follow:
let hasFPSupport = await Expo.Fingerprint.hasHardwareAsync() && await Expo.Fingerprint.isEnrolledAsync();

how to reach to a variable in another js file in appcelerator alloy

I have a small problem.
I have index.js
var loc = require('location');
function doClick (){
loc.doIt();
}
in location.js I have these
var dee = 12;
exports.doIt = function() {
alert(dee);
};
Which means that when I click on the button I can get the alert, however, I want to reach these information without a need of click - onLoad - besides I want to return two values not only one.
How I can fix this maybe it has really an easy solution but because I have been working for a while my mind stopped working :)
regards
you should move your location.js to inside app/lib (as module). for example :
// app/lib/helper.js
exports.callAlert = function(text) {
alert('hello'+ text);
}
and then call it in your controller like this :
var helper = require("helper"); // call helper without path and .js extension
helper.callAlert('Titanium');
and your problem should be solved :)

Blackberry.location API not working correctly

I am experimenting with making Blackberry widgets but having a little trouble.
My first trial involves displaying a button which, when clicked, calls a JavaScript function that should alert the phones latitude and longitude.
The function looks:
function whereAmI() {
var latitude = blackberry.location.latitude;
var longitude = blackberry.location.longitude;
alert("Lat: "+latitude+", Long: "+longitude);
}
But it only ever alerts "Lat: 0, Long: 0". I've checked and my GPS seems to be working ok.
I'm running OS 5.* on a Curve 8900.
Any help would be appreciated :)
I discovered that I wasn't signing my files properly - now that I have, everything works fine.
For kaban:
// called when location object changes
function locationCB()
{
alert("Latitude " + blackberry.location.latitude);
alert("Longitude " + blackberry.location.longitude);
return true;
}
// test to see if the blackberry location API is supported
if( window.blackberry && blackberry.location.GPSSupported)
{
document.write("GPS Supported");
// Set our call back function
blackberry.location.onLocationUpdate("locationCB()");
// set to Autonomous mode
blackberry.location.setAidMode(2);
//refresh the location
blackberry.location.refreshLocation();
}
else
{
document.write("This Device doesn't support the Blackberry Location API");
}
Does your widget have permission to use GPS? Go to Options->Applications, select your app, then "Edit Permissions". Make sure "Location Data" (in Connections) is set to Allow.