The Route line is not showing in android by using FeatureCollection - react-native

I need your help in little bit query,
i'm trying to render the multiple polyline on a single map,it look like as it (IOS),
it perfectly fine work fine in IOS but not work in android, so my code Snippet it,
import MapboxGL from '#react-native-mapbox-gl/maps';
const MapbBoxDirection = ({shape}: any) => {
const sp = returnOption(shape);
const Poliline = React.useMemo(() => {
return (
<MapboxGL.Animated.ShapeSource
id="routeSource"
buffer={512}
tolerance={1}
lineMetrics={false}
clusterRadius={10}
shape={sp}>
<MapboxGL.Animated.LineLayer
id="routeFill"
style={{
lineColor: '#ff8109',
lineWidth: 10,
lineRoundLimit: 12,
lineCap: 'round',
lineOpacity: 1.84,
}}
/>
</MapboxGL.Animated.ShapeSource>
);
}, [shape, sp]);
return Poliline;
};
import {featureCollection, lineString as makeLineString} from '#turf/helpers';
///// Make Json
export const returnOption = (res): any => {
const feature = res.map((item: any, index: any) => {
if (item[`Route${index}`]?.length > 2) {
return makeLineString(item[`Route${index}`]);
}
});
const featureCollectiondata = featureCollection(feature);
return featureCollectiondata;
};
it's work fine in IOS but not work in android,
i'm also trying to make a json manually without truf helper, i'm facing same problem.
So would you please help me How i can resolve it for android,
one more thing is SINGLE route work fine for both platform so when i'm trying to use featurecollection json it create problem,
Please I'm very Thankful to you,

After a lot a effort i got the Solution Sometime undefined and null is generate default Therefor route line not render on android, but ios it will handle it by default So
export const returnOption = async (res: any, setShape: any) => {
const feature = await Promise.all(
res.map(async (item: any, index: any): Promise<any> => {
if (item[`Route${index}`]?.length > 1) {
// return makeLineString(item[`Route${index}`]);
return {
type: 'Feature',
properties: {
prop0: 'value0',
prop1: 0.0,
},
geometry: {
type: 'LineString',
coordinates: item[`Route${index}`],
},
};
}
}),
);
const RemoveUndefined = feature?.filter(item => item !== undefined);
setShape({
type: 'FeatureCollection',
features: RemoveUndefined,
});
};
finally I have achieve the solution.

Related

Creating a Heatmap for Rooms - No Structureinfo

I'm working on a project in which I have to generate a heatmap for some sensors that are beeing rendered inside of a modell using forgeviewer. For the implementation I'm following this tutorial: https://forge.autodesk.com/en/docs/dataviz/v1/developers_guide/examples/create_heatmap_for_rooms/
The modell I'm using was generated through Revit and translated into .svf using the Model-Derivative-API.
My problem now is, that I cant get any room or level data from my model which are needed for the generation of the heatmap.
These lines always give me no rooms or levels, eventhough there are rooms shown in the viewers modellbrowser as shown in the picture below.
modellbrowser with rooms
const structureInfo = new Autodesk.DataVisualization.Core.ModelStructureInfo(viewer.model);
console.log("STRUCTUREINFO");
console.log(structureInfo);
...
const shadingdata= await structureInfo.generateSurfaceShadingData(devices);
console.log("SHADINGDATA");
console.log(shadingdata);
StructureInfo in console
ShadingData in console
Question now is: Why cant I get any room or level data and how can I fix this?
The only thing that came to my mind so far that I have tried was to convert the revit file into .nwd using navisworks and translating that file into .svf. But the results where the same.
Here is some more Code. Please note that the application is clientside only and wont go into production like this. I'm only creating a prototype for presentations.
export const initializeViewer = async (urn: string) => {
let viewer: Autodesk.Viewing.GuiViewer3D;
fetch("https://developer.api.autodesk.com/authentication/v1/authenticate", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
client_id: "ClinetID",
client_secret: "ClentSecret",
grant_type: "client_credentials",
scope: "viewables:read",
}),
}) .then((res) => res.json())
.then((value) => {
const options = {
document: urn,
env: "AutodeskProduction",
accessToken: value.access_token,
api: "derivativeV2",
};
var container = document.getElementById("viewer-container");
if (container !== null) {
viewer = new Autodesk.Viewing.GuiViewer3D(container, {
extensions: [],
});
}
Autodesk.Viewing.Initializer(options, function onInitialized() {
addEvents();
viewer.start();
Autodesk.Viewing.Document.load(urn, onSuccess, onFailure);
});
});
const addEvents = () => {
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, () => {
loadExtensions();
onModelLoaded(viewer);
});
....
....
async function onModelLoaded(viewer: Autodesk.Viewing.GuiViewer3D) {
const dataVizExtn: any | Autodesk.Extensions.DataVisualization = await viewer.loadExtension("Autodesk.DataVisualization");
...
const aecModelData = await viewerDocument.downloadAecModelData();
if (aecModelData) {
const levelsExt: any | Autodesk.AEC.LevelsExtension = await viewer.loadExtension("Autodesk.AEC.LevelsExtension", {
doNotCreateUI: true,
});
const floorData = levelsExt.floorSelector.floorData;
const floor = floorData[2];
levelsExt.floorSelector.selectFloor(floor.index, true);
}
const structureInfo = new Autodesk.DataVisualization.Core.ModelStructureInfo(viewer.model);
let roomDevices: Autodesk.DataVisualization.Core.RoomDevice[] = [];
devices.forEach((device) => {
let autodeskDevice: Autodesk.DataVisualization.Core.RoomDevice = {
id: device.id, // An ID to identify this device
position: device.position, // World coordinates of this device
sensorTypes: device.sensorTypes, // The types/properties this device exposes
type: "Thermometer",
};
roomDevices.push(autodeskDevice);
});
const heatmap = await structureInfo.generateSurfaceShadingData(roomDevices, undefined, "Rooms");
};
Looks your source model is RVT in Deutschland. If so, please use this code snippet instead.
const shadingdata = await structureInfo.generateSurfaceShadingData(devices, null, 'Räumen')
For RVT -> NWD/DWC, please check my blog post here Add Data Visualization Heatmaps for Rooms of non-Revit model part I - NWC
Querying Revit master views in the viewer:
const root = viewerDocument.getRoot();
const viewables = root.search({'type':'geometry', 'role': '3d'});
console.log('Viewables:', viewables);
const phaseViews = viewables.filter(v => v.data.name === v.data.phaseNames && v.getViewableRootPath().includes('08f99ae5-b8be-4f8d-881b-128675723c10'));
console.log('Master Views:', phaseViews);
// or this one if you just have one master view (phase) inside your model.
// viewerDocument.getRoot().getDefaultGeometry(true);

react-native-reanimated how to use delay between 'Animated.timing' functions

I use react-native-reanimated version: '1.7.1' and I tried to process delay between 4 different timing functions.
I tried to find instructions on the web and didn't find one that was clear:
https://docs.swmansion.com/react-native-reanimated/docs/1.x.x/about#reanimated-overview
https://docs.swmansion.com/react-native-reanimated/docs/1.x.x/declarative
I know that in the original reactNative API there is a delay so I tried to find something comparable with this good library
export const createTimingAnimation = (value: Animated.Node<number>, duration = 500, easing = Easing.inOut(Easing.ease), toValue = 1) => {
return Animated.timing(value, {
toValue,
duration,
easing,
});
};
I didn't find any formal way, so I created one:
export const timingAnimationWithDelay = (delay: number, timingAnimation: Animated.BackwardCompatibleWrapper, finishCallback?: any): void => {
setTimeout(() => {
timingAnimation.start(() => {
finishCallback && finishCallback();
});
}, delay);
};
And then you call it like this:
const greetingNfnTiming = createTimingAnimation(animatedValue, 480, Easing.out(Easing.cubic));
timingAnimationWithDelay(1000, greetingNfnTiming, onGreetingFinish);

(AppsFlyer / ReactNative) How can I get attribution parameter from onAppOpenAttribution?

This might be a dumb question, but currently I really need a help. Can someone please help me out?
I'm implementing AppsFlyer on my ReactNative Project (Android)
What I want to do is console.log attribution parameter.
But, there are no console.logging happening.
Could someone please read my snippet and how can I access to attribution parameter, please?
or, is there any proper way to console.log attribution parameter or save it to variable?
App.tsx
​import appsFlyer from 'react-native-appsflyer';
var testFunc = appsFlyer.onAppOpenAttribution(
    (data) => {
        console.log(data);
    }
);
appsFlyer.initSdk(
    {
        devKey: '***************************',
        isDebug: false,
    },
    (result) => {
        console.log(result);
    },
    (error) => {
        console.error(error);
    },
);
const Home: React.FC<Props> = props => {
    const [appState, setAppState] = useState(AppState.currentState);
    // ! when I press device's home button (appstate changes to background),
   // ! console.log in testFunc is not working...
  
    useEffect(() => {
        function handleAppStateChange(nextAppState) {
            if (appState.match(/active|foreground/) && nextAppState === 'background') {
                if (testFunc) {
                    testFunc();
                    testFunc = null;
                }
            }
          setAppState(nextAppState);
       }
        AppState.addEventListener('change', handleAppStateChange);
        return () => {
        AppState.removeEventListener('change', handleAppStateChange);
      };
  })
To my understanding, the onAppOpenAttribution event only triggers when you already have the app installed and click on a deep link. Try to use onInstallConversionData instead and see what happens, since it triggers once the SDK is initialized. I'd also remove the "useEffect" section entirely just to test. I hope this helps.
nevermind,
I added appsFlyer.onInstallConversionData
then it worked...
import appsFlyer from 'react-native-appsflyer';
var onInstallConversionDataCanceller = appsFlyer.onInstallConversionData((res) => {
if (JSON.parse(res.data.is_first_launch) == true) {
if (res.data.af_status === 'Non-organic') {
var media_source = res.data.media_source;
var campaign = res.data.campaign;
console.log('This is first launch and a Non-Organic install. Media source: ' + media_source + ' Campaign: ' + campaign);
} else if (res.data.af_status === 'Organic') {
console.log('This is first launch and a Organic Install');
}
} else {
console.log('This is not first launch');
}
});
var onAppOpenAttributionCanceller = appsFlyer.onAppOpenAttribution((res) => {
console.log(res)
});
appsFlyer.initSdk(
{
devKey: '***************************',
isDebug: false,
},
(result) => {
console.log(result);
},
(error) => {
console.error(error);
},
);
const Home: React.FC<Props> = props => {
const [appState, setAppState] = useState(AppState.currentState);
useEffect(() => {
function handleAppStateChange(nextAppState) {
if (appState.match(/active|foreground/) && nextAppState === 'background') {
if (onInstallConversionDataCanceller) {
onInstallConversionDataCanceller();
onInstallConversionDataCanceller = null;
}
if (onAppOpenAttributionCanceller) {
onAppOpenAttributionCanceller();
onAppOpenAttributionCanceller = null;
}
}
AppState.addEventListener('change', handleAppStateChange);
return () => {
AppState.removeEventListener('change', handleAppStateChange);
};
})

React-Native Flatlist's onViewableItemChanged error

I am trying to account for changes when the element in view changes.
I get the following
Invariant Violation: Changing onViewableItemsChanged on the fly is not supported
I have the following
<Animated.FlatList
viewabilityConfig={carouselViewabilityConfig}
onViewableItemsChanged={onViewableItemsChanged}
...//other properties
/>
and my functions are
const onViewableItemsChanged = ({
viewableItems,
}: {
viewableItems: Array<number>;
}) => {
const insightsById = savedInsights.byId;
console.log('byId:!', insightsById);
if (!viewableItems.length) {
return;
}
const visibleInsightId =
insightsById[viewableItems[Math.max(viewableItems.length - 2, 0)].index];
console.log(visibleInsightId);
Analytics.logViewItem({ insight_id: visibleInsightId });
// const visibleInsightIndex = insightsById.indexOf(visibleInsightId);
};
const carouselViewabilityConfig = {
waitForInteraction: false,
minimumViewTime: 100,
viewAreaCoveragePercentThreshold: 50,
};
I saw a method using refs but it didn't work, my function wouldn't run.
Any help would be appreciated. Thanks.

Crash with simple history push

just trying come silly stuff and playing around with Cycle.js. and running into problem. Basically I just have a button. When you click it it's suppose to navigate the location to a random hash and display it. Almost like a stupid router w/o predefined routes. Ie. routes are dynamic. Again this isn't anything practical I am just messing with some stuff and trying to learn Cycle.js. But the code below crashes after I click "Add" button. However the location is updated. If I actually just navigate to "#/asdf" it displays the correct content with "Hash: #/asdf". Not sure why the flow is crashing with error:
render-dom.js:242 TypeError: Cannot read property 'subscribe' of undefined(…)
import Rx from 'rx';
import Cycle from '#cycle/core';
import { div, p, button, makeDOMDriver } from '#cycle/dom';
import { createHashHistory } from 'history';
import ranomdstring from 'randomstring';
const history = createHashHistory({ queryKey: false });
function CreateButton({ DOM }) {
const create$ = DOM.select('.create-button').events('click')
.map(() => {
return ranomdstring.generate(10);
}).startWith(null);
const vtree$ = create$.map(rs => rs ?
history.push(`/${rs}`) :
button('.create-button .btn .btn-default', 'Add')
);
return { DOM: vtree$ };
}
function main(sources) {
const hash = location.hash;
const DOM = sources.DOM;
const vtree$ = hash ?
Rx.Observable.of(
div([
p(`Hash: ${hash}`)
])
) :
CreateButton({ DOM }).DOM;
return {
DOM: vtree$
};
}
Cycle.run(main, {
DOM: makeDOMDriver('#main-container')
});
Thank you for the help
I would further suggest using #cycle/history to do your route changing
(Only showing relevant parts)
import {makeHistoryDriver} from '#cycle/history'
import {createHashHistory} from 'history'
function main(sources) {
...
return {history: Rx.Observable.just('/some/route') } // a stream of urls
}
const history = createHashHistory({ queryKey: false })
Cycle.run(main, {
DOM: makeDOMDriver('#main-container'),
history: makeHistoryDriver(history),
})
On your function CreateButton you are mapping your clicks to history.push() instead of mapping it to a vtree which causes the error:
function CreateButton({ DOM }) {
...
const vtree$ = create$.map(rs => rs
? history.push(`/${rs}`) // <-- not a vtree
: button('.create-button .btn .btn-default', 'Add')
);
...
}
Instead you could use the do operator to perform the hashchange:
function CreateButton({ DOM }) {
const create$ =
...
.do(history.push(`/${rs}`)); // <-- here
const vtree$ = Observable.of(
button('.create-button .btn .btn-default', 'Add')
);
...
}
However in functional programming you should not perform side effects on you app logic, every function must remain pure. Instead, all side effects should be handled by drivers. To learn more take a look at the drivers section on Cycle's documentation
To see a working driver jump at the end of the message.
Moreover on your main function you were not using streams to render your vtree. It would have not been reactive to locationHash changes because vtree$ = hash ? ... : ... is only evaluated once on app bootstrapping (when the main function is evaluated and "wires" every streams together).
An improvement will be to declare your main's vtree$ as following while keeping the same logic:
const vtree$ = hash$.map((hash) => hash ? ... : ...)
Here is a complete solution with a small locationHash driver:
import Rx from 'rx';
import Cycle from '#cycle/core';
import { div, p, button, makeDOMDriver } from '#cycle/dom';
import { createHashHistory } from 'history';
import randomstring from 'randomstring';
function makeLocationHashDriver (params) {
const history = createHashHistory(params);
return (routeChange$) => {
routeChange$
.filter(hash => {
const currentHash = location.hash.replace(/^#?\//g, '')
return hash && hash !== currentHash
})
.subscribe(hash => history.push(`/${hash}`));
return Rx.Observable.fromEvent(window, 'hashchange')
.startWith({})
.map(_ => location.hash);
}
}
function CreateButton({ DOM }) {
const create$ = DOM.select('.create-button').events('click')
.map(() => randomstring.generate(10))
.startWith(null);
const vtree$ = Rx.Observable.of(
button('.create-button .btn .btn-default', 'Add')
);
return { DOM: vtree$, routeChange$: create$ };
}
function main({ DOM, hash }) {
const button = CreateButton({ DOM })
const vtree$ = hash.map(hash => hash
? Rx.Observable.of(
div([
p(`Hash: ${hash}`)
])
)
: button.DOM
)
return {
DOM: vtree$,
hash: button.routeChange$
};
}
Cycle.run(main, {
DOM: makeDOMDriver('#main-container'),
hash: makeLocationHashDriver({ queryKey: false })
});
PS: there is a typo in your randomstring function name, I fixed it in my example.