i tried to show the poligons that came from the KML file and i need to view the polygons on gps map.........
thanks a lot for help.
#################################################################################################
const res = await Picker.pickSingle({
type: [Picker.types.allFiles],
//There can me more options as well
// DocumentPicker.types.allFiles
// DocumentPicker.types.images
// DocumentPicker.types.plainText
// DocumentPicker.types.audio
// DocumentPicker.types.pdf
});
//Printing the log realted to the file
console.log('res : ' + JSON.stringify(res));
console.log('URI : ' + res.uri);
console.log('Type : ' + res.type);
console.log('File Name : ' + res.name);
console.log('File Size : ' + res.size);
//Setting the state to show single file attributes
setKmlFile(res)
return (
<>
<Button
onPress={onPressLoadFile}
title="Import KML File"
color="#841584"
accessibilityLabel="purple button"
/>
<View style={styles.container}>
<MapView style={styles.map} region={region} showsUserLocation={true}>
<Polyline
coordinates={COORDINATES}
strokeColor='red'
strokeWidth={4}></Polyline>
</MapView>
</View>
</>
);}
Related
I am working on a project that uses Google autocomplete to set locations. The project allows users to set pickup and destination location, and then they can also enter stop-by places up to additional 3, making it a total of 5.
Here's my sample code:
const placesRef = useRef([]);
const [stopspots, setStopSpots] = useState([]);
const [state, setState] = useState({
defaultPlacesInput: 'flex',
//and others
});
useEffect(() => {
placesRef.current = placesRef.current.slice(0, 5);
}, []);
const placesComponent = (i, placeholder) => {
return (<PlacesFrame key={i}>
...
<GooglePlacesAutocomplete
placeholder={placeholder}
minLength={2}
ref={el => placesRef.current[i] = el}
onPress={(data, details = null) => {
placesRef.current[i]?.setAddressText(data?.structured_formatting?.main_text);
setState({...state, defaultPlacesInput: 'flex'})
}}
enablePoweredByContainer={false}
fetchDetails
styles={{
textInput: [styles.input1,{paddingLeft:30}],
container: [styles.autocompleteContainer,{display:placesRef.current[i]?.isFocused() ? 'flex' : state.defaultPlacesInput}],
listView: styles.listView,
listView: styles.listView,
row: styles.row,
predefinedPlacesDescription: {
color: '#1faadb',
},
}}
query={{
key: GOOGLE_PLACES_API_KEY,
language: profile.language,
components: 'country:' + profile.iso,
}}
textInputProps={{
//value: '',
onChangeText: alterOtherFields
}}
renderRow={(data) => <PlaceRow data={data} />}
/>
...
</PlacesFrame>)
}
const stopByLocation = () => {
var counter = stopspots.length, obj = placesComponent(counter + 2, 'Drop off location');
setStopSpots([...stopspots, {
id: counter,
place: obj
}
])
}
And here is how the autocomplete component is rendered
return(
...
<View>
{placesComponent(0, 'Pick up location')}
{placesComponent(1, 'Drop off location')}
</View>
...
)
The output look like this
Everything works perfect when I call the placesComponent() function directly. But like I mentioned earlier, I want the users to be able to add up to 3 additional stop by locations, and because it is optional, additional fields is added by appending to hook, and then rendered. the code looks like this.
return(
...
<View>
{placesComponent(0, 'Pick up location')}
{placesComponent(1, 'Drop off location')}
//This will append more placed fields
{stopspots != '' ?
stopspots.map((item : {}) => ((item.place)))
: null}
<ClickableButton>
<TouchableOpacity activeOpacity={0.6} onPress={() => stopByLocation()}><AddPlaces><AntDesign name="plus" size={10} color="#444" /> Add</AddPlaces></TouchableOpacity>
</ClickableButton>
</View>
...
)
The outcome looks like this
I observed that each component binded to the hooks takes the early properties, and does not effect additional changes. While the first two fields rendered by calling the function directly does.
When I make changes to state.defaultPlacesInput (observe this in styles property of GooglePlacesAutocomplete), the changes only effect on the two components called directly.
Is there a module, or a systematic way to append the renderer function call, without using useState hooks to append the 3 additional fields?
Is it possible to expose stored properties in useState hooks to respond as the other two which observe the state changes? If yes, how?
Any contribution, suggestion will be accepted
I am trying to download a video from an S3 bucket and pass it to Expo's Video component. I am using s3.getObject() and the callback function to get the object as an ArrayBuffer. But I don't know how to use this data from this point. I tried concatenating "data:video/mp4;base64," + videoData.body and passing that as an object. I also tried converting it to Base64String, which also didn't work.
let videoData = {}
const downloadIntro = async () => {
s3.getObject(bucketParams, function (err, data) {
if (err) {
console.log("Error:" + err)
} else {
console.log(data.ContentLength) // 1210362
console.log(data.ContentType) // video/mp4
console.log(data.Metadata) // Object {}
console.log(data.Body.buffer) // ArrayBuffer []
videoData.body = data.Body.buffer
}
})
}
export default function App() {
let [vidData, setVidData] = useState(null)
const playVideo = () => {
console.log("Trying to play")
setVidData({video: "data:video/mp4;base64," + videoData.body})
}
return (
<SafeAreaView style={styles.container}>
<Button title={"Load Video"} onPress={downloadIntro}/>
<Button title={"Start"} onPress={playVideo}/>
<Video
source={vidData}
rate={1.0}
volume={1.0}
isMuted={false}
resizeMode={"contain"}
shouldPlay={paused}
isLooping={false}
style={{
width: 300,
height: 300
}}
/>
</SafeAreaView>
);
}
It looks like you are trying to put the raw video data in the source. Try just setting the attribute to the url of the video :
<video controls width="250">
<source src="/media/cc0-videos/flower.mp4"
type="video/mp4">
</video>
How to display "text is copied" to the user after the text has been copied?
const dataArray = [ { title: "Invoice Reference Number", content:QRCODE_SAMPLE.Irn } ];
<TouchableOpacity activeOpacity={1}
onPress={() => Clipboard.setString(QRCODE_SAMPLE.Irn)}>
<Accordion style={{paddingTop:10,paddingBottom:50,backgroundColor:'#E0DDDD'}}dataArray={dataArray} expanded={1}>
</Accordion>
</TouchableOpacity>
You can do it like this :
import {ToastAndroid} from 'react-native';
Create this function :
onCopyPressed(){
Clipboard.setString(QRCODE_SAMPLE.Irn);
ToastAndroid.show('A pikachu appeared nearby !', ToastAndroid.SHORT);
}
And call that function like this :
const dataArray = [ { title: "Invoice Reference Number", content:QRCODE_SAMPLE.Irn } ];
<TouchableOpacity activeOpacity={1}
onPress={this.onCopyPressed.bind(this)}>
<Accordion style={{paddingTop:10,paddingBottom:50,backgroundColor:'#E0DDDD'}}dataArray={dataArray} expanded={1}>
</Accordion>
</TouchableOpacity>
I have never used the clipboard before but I assume your code is working, then:
const [clipboardString, setClipboardString] = useState('');
handleClipboardAction = (str) => () => {
Clipboard.setString(str);
setClipboardString(setClipboardString)
}
<TouchableOpacity activeOpacity={1}
onPress={handleClipboardAction(str)}>
<Accordion style={{paddingTop:10,paddingBottom:50,backgroundColor:'#E0DDDD'}}dataArray={dataArray} expanded={1}>
</Accordion>
</TouchableOpacity>
Then you can observe the state to see if there's anything copied and conditional render the "Text is copied" message:
{clipboardString.length > 0 && <Text>Text is copied</Text>}
The most simple way is using a package that mixes between them:
https://www.npmjs.com/package/react-native-clipboard-toast
React Native Clipboard API with Animated toast message component
Support both Android and iOS | Used react native Clipboard | Toast by
calling api
Im using react-native-video in my react-native application. I want to be able to dynamically change videosource but found out it wasnt that easy. My approach is simply by changing the clip name with a hook, changing video1 to video2. But I was not able to update the videoinstance:
I did try something like this:
const [clipSelected, setClipSelected] = useState('video1');
const onButton = (name) => {
console.log("videoname", name)
setClipSelected(name);
}
return (
<Fragment>
<View style={styles.container}>
<Video
source={require('./' + clipSelected + '.mp4')}
ref={(ref) => {
bgVideo = ref
}}
onBuffer={this.onBuffer}
onError={this.videoError}
rate={1}
repeat={true}
/>
<Button onPress={(e) => onButton('video2')}></Button>
</View>
</Fragment >
);
Are there any other library, approach or method anyone are aware of where I can solve this? Basically a way to update the source instance of the video. Im going to run this on an Android TV ...
Use the status values to make changes.
const [clipSelected, setClipSelected] = useState(false);
const onButton = () => {
setClipSelected(true);
}
...
<Video
source={clipSelected === false ? require('./video1.mp4') : require('./video2.mp4')}
...
<Button onPress={(e) => onButton()}></Button>
I use react-native-fs to download a Lottie file (json) from a remote server. After saving it to the filesystem I get a path like /Users/marlon/Library/Developer/CoreSimulator/Devices/8E0A092D0E86/data/Containers/Data/Application/AADD60D8DFAD/Documents/animation.json.
Is there now any way to use that filepath as a source for LottieView? I tried various approaches, but neither of them succeeded:
var path = '/Users/marlon/Library/Developer/CoreSimulator/Devices/8E0A092D0E86/data/Containers/Data/Application/AADD60D8DFAD/Documents/animation.json'
<LottieView source={{ uri: path }} />
<LottieView source={{ uri: 'file:/' + path }} />
<LottieView source={{ uri: 'file://' + path }} />
<LottieView source={{ uri: 'file://' + path, isStatic: true }} />
ANSWER
Its ok to just pass the animation file as a javascript object to the LottieView. So what I did now, was opening the file with react-native-fs and parsing it with JSON.parse. The final result looks like:
RNFS.readFile(animations.congratsAnimation).then(res => {
this.setState({ animation: JSON.parse(res) });
}
...
<LottieView source={this.state.animation} />
You should not hardcode the downloaded json file path, but rather keep it on a device's storage, e.g. Picture folder:
npm install --save react-native-fetch-blob
const { config, fs } = RNFetchBlob
RNFetchBlob.config({ path : RNFetchBlob.fs.dirs.DocumentDir + '/animation.png' + })
.fetch('GET', 'http://example.com/file/whichever', {
'Cache-Control' : 'no-store'
})
.then((res) => {
// where the file is, keep it as state.animationPath
this.setState(animationPath: res.path())
})
//render()
<LottieView source={{require(this.state.animationPath)}, isStatic: true }} />
I think you should use require() function while referencing the path for the resources.
For example you can do something like:
var path = require('/Users/marlon/Library/Developer/CoreSimulator/Devices/8E0A092D0E86/data/Containers/Data/Application/AADD60D8DFAD/Documents/animation.json');
or
<LottieView source = {require('/Users/marlon/Library/Developer/CoreSimulator/Devices/8E0A092D0E86/data/Containers/Data/Application/AADD60D8DFAD/Documents/animation.json')} />