react-native-maps local tiles/offline on iOS - react-native

I have been trying to get offline leaflet/openStreetMap tiles rendering in the react native maps view with both the <LocalTile/> and <UrlTile/> components.
I can render the map on android and iOS and can see the standard map for each platform with PROVIDER_DEFAULT (Apple's MapKit and Google Maps, respectively).
I download the tiles as a zip file, and unzip them into the appropriate document storage path on each type of device.
I verify that the paths are working and that the map can access these images with the following code:
render() {
const { region } = this.state;
//gets the document directory based on platform(ios/android)
const docDir = BlobService.setDocDir();
const tilesPath = `${docDir}/projects/${this.props.projectId}/pdf/tiles/${
this.props.floorData.id
}/{z}/tile_{x}_{y}.png`;
return (
<View style={styles.container}>
<MapView
provider={PROVIDER_DEFAULT}
mapType={MAP_TYPES.STANDARD}
style={styles.map}
initialRegion={region}
>
<LocalTile pathTemplate={tilesPath} tileSize={512} zIndex={-1} />
</MapView>
<View style={styles.buttonContainer}>
//button code removed for brevity
</View>
</View>
);
}
Referring to my comments within my code snippet above:
1) the tiles path is formatted in (0,1,2,3) folder formats, with the numbers corresponding to the appropriate zoom levels.
2) The path to tiles seems to work, however it only seems to infinitely tile a single tile, and the zoom levels don't seem to match OSM/Leaflet zoom levels appropriately:
I have left a comment on this thread on github, which looked nearly identical to all the steps I have taken, except that I am ejected from expo in the app I am working with.
I tried to follow this article but I can't seem to understand how to map these tiles into the region appropriately. Using the formula he's provided doesn't seem to mimic the same zoom levels as in react-leaflet as it was previously implemented, and I always get an out of range error when trying to set the region parameters.
I've seen the examples provided and am simply at a loss for how to convert this mapping system to work with OSM tiles that work in a leaflet based map view.

Hello are you still working on this?
I read your question as I have issues with new react native, I use webview not the mapview, it worked fine until react 0.44 then latest versions block webview access to file system of app data files.
Do you manage the unzipping and access to tiles within your app? I will probably try react-native-maps for offline times since I am stuck with using webview for the android app.
About your question, you need some geographic systems (GIS) skills. If you georeference the building corners to latitude, longitude then you can relate it to the tiles scheme used in leaflet, I do this with quantumGIS (qGIS) and QmetaTiles plugin.

Related

is there anyway i can implement tradingview widget (chart) in react-native mobile app?

i am building a mobile app and i need to show the user the trading view chart so that they can use.
i have searched and i haven't seen any react-native package for implementing the chart.
i am building a mobile app and i need to show the user the trading view chart so that they can use.
i have searched and i haven't seen any react-native package for implementing the chart.
i am building a mobile app and i need to show the user the trading view chart so that they can use.
i have searched and i haven't seen any react-native package for implementing the chart.
There is no official way to do this right now. As a turnaround, I used react-native-webview library for this purpose. My code implementation is as follows:
<WebView
forceDarkOn
style={{
backgroundColor: THEME.COLORS.primaryBackground,
}}
source={{
uri: `https://www.tradingview.com/chart?symbol=usd`,
}}
useWebKit={true}
originWhitelist={['https://www.tradingview.com']}
allowsInlineMediaPlayback={true}
incognito
/>
Please note that I have used incognito and originWhitelist params. Incognito for disabling cache as trading view will display a non dismiss ad after some time and originWhitelist for disabling popup ads that open new windows.

React Native - Images loading extremely slowly, not at all

I am creating an app using Expo/RN where the first screen has a fair amount (~20) images loaded, as the result of a network call. I am only working in iOS.
My issue is that the images load extremely slowly, most taking around a minute to load, and some never load but stay black. I am using the built in Image component, with a url supplied in the source object. The images load immediately when the mobile website is loaded in Safari.
Furthermore, the built-in caching seems to not work at all. When an image has loaded and should be shown in multiple places, it often doesn't appear in the second place at all. I have tried using "force-cache" with no effect.
I have tried the packages react-native-fast-image, which wouldn't run, and react-native-expo-image-cache, which gave me some results but memory leak issues and UI freezes.
Is there any solution? Should I just create my own caching component?
EDIT: The images are loaded in a FlatList. Each item is rendered by a custom component including an . The image simply takes the url as
<Image
style={[styles.image, smallCell ? { width: smallCellWidth } : {}]}
source={{ uri: project.imageUrl, cache: "force-cache" }}
opacity={0.85}
/>
It turns out the biggest issue was not on the RN side, but the API call used. I was downloading the original sized images from the server, rather than the resized ones, and they were so large that I was getting the above result.
However, using force-cache did have good results for me.

Images from Device storage custom path In React Native

I have an Image that I've downloaded and saved to the path /data/user/0/com.project/files/assets/image.png and I want to use this in my Image component in React-Native. Is there a way to use images stored in this path?
Ways to solve it that I have knowledge of but cannot use :
using require. which basically accepts literal strings that is not what I want for non-static images. names may change as per image for a single image source
using Native bundles, which is again I cannot use as the images are first being downloaded and then is being used.
using http links directly.which as again I cannot use as my feature states that the App cannot rely on network as it needs to render images in offline mode as well
If it's a file on your device, I think the way of displaying it is somewhat like this:
<Image source={{uri:'file:///data/user/0/com.project/files/assets/image.png'}} style={{width: 100, height: 100}}/>
Just make sure the file path is from the root. Hope it works for you.

How to convert current React Native project to ReactXP

We have a developed react native project using JavaScript, now we decided to have it's website too. We found out that Microsoft introduced ReactXP and it is able to release website too. is it possible to convert current react native project to reactXP?
Yes, it's possible. You'll need to replace tags like <View/> with <RX.View/>, <Text/> with <RX.Text/>, etc. Then, when compiling for the browser or native, ReactXP will internally exchange <RX.View/> etc. with the appropriate tag automatically depending on your current target (<div/> for the browser and <View/> for native).
But you don't have to exchange all tags with their <RX.* counterparts right away. Meaning you can still use a few <div/> etc. for the browser target and <View/> etc. for the native target. However, if you really only want one codebase and then cross-compile to any target, then you need to replace them all.
Styling is a bit different too: ReactXP doesn't have percentage values for width, height, etc.

React native Image prefetch

I am having difficulties to understand Image prefetch. In the doc's there is not much explanation about it:
"Prefetches a remote image for later use by downloading it to the disk
cache"
Could you please help me understand the following about Image prefetch:
Suppose a user uploads a profile image, and the image's URL is stored in the AsyncStorage.
Should I run Image.prefetch(UserStore.profileImageUrl) only once after successful upload. And use prefetched image in the components normally like <Imagesource={{uri: UserStore.profileImageUrl}}/>
Or should I always run Image.prefetch(UserStore.profileImageUrl) before using that image in the component, then only run <Imagesource={{uri: UserStore.profileImageUrl}}/>
Suppose, later on, the user changes their profile image by uploading a new image and after successful upload, I will prefetch the new image. Will the previously cached image still exist on the disk?
If yes, won't it occupy a lot of space in the device if there are lots of prefetched images?
Is there any way to manually remove the prefetched image from the disk?
With the above questions in mind, if there are alternate solutions to achieve caching of images when using react native with expo, could you please help me with it.
It was indeed a question that I was dealing with for a while, and I learned a few things about Image.prefetch:
In the current React-Native version (0.48), this method is still in progress. To be more precise:
the ios implementation is still incomplete.
There is no complete guide on it.
There is no way to clear cache (you can check if the url is cached, however as far as I know you cannot clear it now).
As a result, I don't suggest you use it. Regardless, if you want to know how the API works, it is how:
Purpose
The purpose is quite obvious I think, this API:
Prefetches a remote image for later use by downloading it to the disk cache
It means that you can use Image.prefetch(url) in your constructor or componentWillMount. It tries to fetch image asynchronically, then, render your page with some kind of an ActivityIndicator, Finally, when the image is successfully fetched you can re-render your component.
Image.prefetch(url) actually saves the image to disk (not memory), as a result, whenever or wherever you try to use
<Image source={{uri:url}}/>
At firsts it checks the list of caches urls, if you have prefetched that url before (and it is located on the disk), it won't bother to re-fetch (unless you run function `Image.prefetch(url)' again (I am not sure if it works properly).
The implications of this issue are so complicated. It means that if you prefetch an image inside one component (for example <Component1/>), when you try to show this specific image in another component (for example <Component12>), It won't fetch the image and just uses the disk cache.
Therefore, either don't use this Image.prefetch at all (until there is a complete API, with cache control) or use it at your own risk.
on Android
On Android, you have 3 APIs for prefetch, and only one of them is presented in the documentation:
prefetch:
var response = Image.prefetch(imageUrl,callbackFunction)
Image.prefetch can have an optional second argument callbackFunction, which a function that runs Before fetching image. It can be written in the following format:
var response = Image.prefetch(imageUrl,()=>console.log('Image is being fetched'))
It might be worthy to note that, callbackFunction can have an argument called requestId, (indicating the number of prefetch among all other prefetches) which can be then used to abort the fetch.
var response = Image.prefetch(imageUrl,(id)=>console.log(id))
Moreover, response is a promise, you can use .then to do more after the image is pre-fetched.
abortPrefetch
Image.abortPrefetch(requestId) ;
used to abort the pending prefetch. requestId used as argument is the same as the one seen in prefetch.
queryCache
Image.queryCache([url1,url2, ...])
.then((data)=>console.log(data));
Used to check if a certain url is already cached, and if so where is it cached (disk or memory)
on IOS
I think that only Image.prefetch(url) is currently available on IOS, and there is no callback function to be called as the second argument.
if there are alternate solutions to achieve caching of images when
using react native with expo, could you please help me with it.
You may be interested in my higher order component module that adds performance related image caching and "permanent cache" functionality to the native <Image> component.
React Native Image Cache HOC
Tl;DR Code Example:
import imageCacheHoc from 'react-native-image-cache-hoc';
const CacheableImage = imageCacheHoc(Image);
export default class App extends Component<{}> {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<CacheableImage style={styles.image} source={{uri: 'https://i.redd.it/rc29s4bz61uz.png'}} />
<CacheableImage style={styles.image} source={{uri: 'https://i.redd.it/hhhim0kc5swz.jpg'}} permanent={true} />
</View>
);
}
}
The first image will be cached until the total local cache grows past 15 MB (by default) then cached images are deleted oldest first until total cache is below 15 MB again.
The second image will be stored to local disk permanently. People use this as a drop in replacement for shipping static image files with your app.
Personally I would not overcomplicate things by writing over files over and over when the file changes, that's just asking for a massive headache. Instead I would create a unique filename for each upload. So the user's profile pic the first time they upload is "profile-uniqueIdHere.jpg" and when they change their profile pic you just create a new file "profile-anotherUniqueIdHere.jpg" and update their user data to reflect the new file location. For help with creating unique Ids look at react-native-uuid.