Creating a Heatmap for Rooms - No Structureinfo - data-visualization

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);

Related

Prevstate in reactJs

This might be a silly question, but how do I get data if I saved the state using prevState.
I am trying to retrieve data from database and send that data through navigation.
const [dataFromDatabase, setDataFromDatabase] = useState('');
const retrieveFromDatabase = () => {
db.transaction(
tx => {
tx.executeSql("SELECT * FROM PreLoveeedTable",
[],
(_, { rows }) => {
console.log("ROWS RETRIEVED");
// clear data currently stored
setDataFromDatabase('');
let entries = rows._array;
entries.forEach((entry) => {
setDataFromDatabase(prev => prev + `${entry.id}, ${entry.image}, ${entry.title}, ${entry.price}, ${entry.description}\n
});
},
(_, result) => {
console.log('SELECT failed!');
console.log(result);
}
)
}
);
}
{dataFromDatabase} will give me the whole entire data in the database.
But wanted to have each entry in the Database. For example entry for title.
I have been stuck on this for a while now and would be appreciated it if i can get a hint.

Shopify Storage Redis Issue with Node React App

I have added session storage in serve.js as follows :-
import SessionHandler from "./SessionHandler";
const sessionStorage = new SessionHandler();
Shopify.Context.initialize({
API_KEY: process.env.SHOPIFY_API_KEY,
API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
SCOPES: process.env.SCOPES.split(","),
HOST_NAME: process.env.HOST.replace(/https:\/\//, ""),
API_VERSION: ApiVersion.October21,
IS_EMBEDDED_APP: false,
// This should be replaced with your preferred storage strategy
//SESSION_STORAGE: new Shopify.Session.MemorySessionStorage(),
SESSION_STORAGE: new Shopify.Session.CustomSessionStorage(
sessionStorage.storeCallback,
sessionStorage.loadCallback,
sessionStorage.deleteCallback
),
});
My router get function is
router.get("(.*)", async (ctx) => {
const shop = ctx.query.shop;
let documentQuery = { shop: shop };
let data = await SessionStorage.findOne(documentQuery); //this finds the store in the session table
if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
if (data == null) {
ctx.redirect(`/auth?shop=${shop}`);
} else {
await handleRequest(ctx);
}
} else {
await handleRequest(ctx);
}
});
and than in the SessionHandler file added code as attached in file ,
but when I run install the app it goes to the storeCallback , loadcallback and deletecallback function multiple times
StoreCallback Function Code
Load and delete callback function code
sorry I have edited my answer as I think its incorrect . all I can say for now is to look at this example:https://github.com/Shopify/shopify-api-node/blob/main/docs/usage/customsessions.md
if you havent already..

Infinite loop with a graphql and mongoose backend

I have a backend made in express and mongoose:
all my mutations and queries work perfectly except one mutation sends me an infinite loader
updateVehicleVerification: async (_, { id, updateVehicleVerification }) => {
const vehicleVeri = await VehicleVerification.findById(id);
if (!vehicleVeri) {
throw new Error(ErrorMessage + ' : Verification de Vehicule');
}
await VehicleVerification.findByIdAndUpdate(
id,
updateVehicleVerification
);
const veri = await VehicleVerification.findById(id);
return veri;
},
and the query I use here:
export const UPDATE_CONTROL_VEHICLE = gqlmutation updateVehicleVerification( $id: String! $updateVehicleVerification: VerificationVehicleInput ) { updateVehicleVerification( id: $id updateVehicleVerification: $updateVehicleVerification ) { honk { state image comment } mileage dateVerification stateVehicle { damaged good missing } } };
enter code here
I I solved the problem !
I did not manage the case where the data reached me by the request which keyed an infinite loop.

The Route line is not showing in android by using FeatureCollection

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.

When state changes for graphql variable, result stays the same on react-native

I'm trying to create an app using shopify graphql api to create an ecommerce app on react native expo.
I have an onPress that calls a setState to change the state of the graphQL variable but the results don't change from the initial state of 'currentSubCategories'
const [currentSubCategories, setSubCategories] = useState(Categories[0].subCategory[0].handle);
let {
collection,
loading,
hasMore,
refetch,
isFetchingMore,
} = useCollectionQuery(currentSubCategories, first, priceRange);
const [currentCategory, setCategory] = useState({categories: Categories[0]});
const onSubCategorySelect = (subCategory) => { setSubCategories(subCategory.handle) }
onPress={() => onSubCategorySelect(item)}
function useCollectionQuery(
collectionHandle: string,
first: number,
priceRange: [number, number],
) {
let [isInitFetching, setInitFetching] = useState<boolean>(true);
let [isReloading, setIsReloading] = useState<boolean>(true);
let [collection, setCollection] = useState<Array<Product>>([]);
let isFetchingMore = useRef<boolean>(false);
let hasMore = useRef<boolean>(true);
let defaultCurrency = useDefaultCurrency().data;
let { data, loading, refetch: refetchQuery } = useQuery<
GetCollection,
GetCollectionVariables
>(GET_COLLECTION, {
variables: {
collectionHandle,
first,
sortKey: ProductCollectionSortKeys.BEST_SELLING,
presentmentCurrencies: [defaultCurrency],
},
notifyOnNetworkStatusChange: true,
fetchPolicy: 'no-cache',
});
let getMoreUntilTarget = async (
targetAmount: number,
cursor: string | null,
handle: string,
filter: [number, number],
) => {
let result: Array<Product> = [];
let moreData: Array<Product> = [];
let { data } = await refetchQuery({
first,
collectionHandle: handle,
after: cursor,
});
...
useEffect(() => {
if (!loading) {
isFetchingMore.current = false;
}
if (isInitFetching && !!data && !!data.collectionByHandle) {
let newCollection = mapToProducts(data.collectionByHandle.products);
hasMore.current = !!data.collectionByHandle?.products.pageInfo
.hasNextPage;
setCollection(newCollection);
setIsReloading(false);
setInitFetching(false);
}
}, [loading, isInitFetching]); // eslint-disable-line react-hooks/exhaustive-deps
return {
collection,
loading: isReloading,
hasMore: hasMore.current,
isFetchingMore: isFetchingMore.current,
refetch,
};
}
I'm using flatList to show the result
<FlatList
data={collection}
renderItem={({ item }) => (
<Text>{item.title}</Text>
)}
/>
According to docs you have to pass new variables to refetch otherwise refetch will use initial values.
In this case (custom hook) you have 2 ways to solvethis problem:
return variables from your custom hook (taken from useQuery),
return some own refetch function.
1st option needs 'manual' variables updating like:
refetch( { ...variablesFromHook, collectionHandle: currentSubCategories } );
In 2nd case you can create myRefetch (and return as refetch) taking collectionHandle parameter to call refetch with updated variables - hiding 'complexity' inside your hook.
Both cases needs refetch call after updating state (setSubCategories) so you should use this refetch inside useEffect with [currentSubCategories] dependency ... or simply don't use state, call refetch directly from event handler (in onSubCategorySelect).