Skip to content

Commit

Permalink
geosolutions-it#9830: enhance Support for IFC 3d model in MS (geosolu…
Browse files Browse the repository at this point in the history
  • Loading branch information
mahmoudadel54 authored Feb 26, 2024
1 parent 273103b commit 5261361
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 22 deletions.
37 changes: 32 additions & 5 deletions web/client/api/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
import axios from 'axios';
import proj4 from 'proj4';
import { METERS_PER_UNIT } from '../utils/MapUtils';

/**
* get ifc model main info such as: longitude, latitude, height and scale
Expand Down Expand Up @@ -192,6 +193,30 @@ export const getIFCModel = (url) => {
});
});
};

const getSize = ({ modelID, ifcModule, data }) => {
const { ifcApi, WebIFC } = ifcModule;
const boundingBoxSize = ifcApi.GetLineIDsWithType(modelID, WebIFC.IFCBOUNDINGBOX).size(); // eslint-disable-line
if (boundingBoxSize) {
const sizes = [...Array(boundingBoxSize).keys()].map((index) => {
const ifcBBoxLineID = ifcApi.GetLineIDsWithType(modelID, WebIFC.IFCBOUNDINGBOX).get(index); // eslint-disable-line
const ifcBBoxEntity = ifcApi.GetLine(modelID, ifcBBoxLineID); // eslint-disable-line
const corner = ifcApi.GetLine(modelID, ifcBBoxEntity.Corner.value); // eslint-disable-line
const coordinates = (corner?.Coordinates || []).map((coord) => coord?.value || 0);
// adding the corner because it could not be 0,0,0
return [
ifcBBoxEntity.XDim.value + Math.abs(coordinates[0]),
ifcBBoxEntity.YDim.value + Math.abs(coordinates[1]),
ifcBBoxEntity.ZDim.value + Math.abs(coordinates[2])
];
});
return sizes[0];
}
// if there is not bounding box we could compute the size from the data itself
const { size } = ifcDataToJSON({ data, ifcModule });
return size;
};

/**
* Common requests to IFC
* @module api.IFC
Expand All @@ -215,19 +240,21 @@ export const getCapabilities = (url) => {
let capabilities = extractCapabilities(ifcModule, modelID, url);
// extract model origin info by reading IFCProjectedCRS, IFCMapCONVERSION in case of IFC4
const modelOriginProperties = getModelOriginCoords(ifcModule, capabilities.version, modelID);
const size = getSize({ modelID, ifcModule, data });
capabilities.properties = {
...capabilities.properties,
...modelOriginProperties
...modelOriginProperties,
size
};
ifcApi.CloseModel(modelID); // eslint-disable-line
let properties = capabilities.properties;
// todo: getting bbox needs to enhance to get the accurate bbox of the ifc model
let bbox = {
bounds: {
minx: properties.longitude || 0 - 0.001,
miny: properties.latitude || 0 - 0.001,
maxx: properties.longitude || 0 + 0.001,
maxy: properties.latitude || 0 + 0.001
minx: (properties.longitude || 0) - ((size[0] / 2) / METERS_PER_UNIT.degrees),
miny: (properties.latitude || 0) - ((size[1] / 2) / METERS_PER_UNIT.degrees),
maxx: (properties.longitude || 0) + ((size[0] / 2) / METERS_PER_UNIT.degrees),
maxy: (properties.latitude || 0) + ((size[1] / 2) / METERS_PER_UNIT.degrees)
},
crs: 'EPSG:4326'
};
Expand Down
3 changes: 2 additions & 1 deletion web/client/api/__tests__/Model-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ describe('Test Model API for ifc models', () => {
expect(properties).toEqual({
projectedCrs: 'EPSG:5834',
projectedCrsNotSupported: true,
mapConversion: { northings: 5334600, eastings: 4468005, orthogonalHeight: 515, xAxisOrdinate: 0, xAxisAbscissa: 1, rotation: 0, scale: 1 }
mapConversion: { northings: 5334600, eastings: 4468005, orthogonalHeight: 515, xAxisOrdinate: 0, xAxisAbscissa: 1, rotation: 0, scale: 1 },
size: [ 1000, 1000, 0 ]
});
expect(bbox).toBeTruthy();
expect(bbox.crs).toBe('EPSG:4326');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import PropTypes from 'prop-types';
import { FormGroup, ControlLabel, InputGroup } from 'react-bootstrap';
import DebouncedFormControl from '../../../misc/DebouncedFormControl';
import Message from '../../../I18N/Message';

import { METERS_PER_UNIT } from "../../../../utils/MapUtils";
/**
* ModelTransformation. This component shows the model transformation options available
* @prop {object} layer the layer options
Expand All @@ -32,13 +32,14 @@ function ModelTransformation({
height,
...value
};
const size = feature?.properties?.size || [2, 2];
const newBbox = {
...layer?.bbox,
bounds: {
minx: updatedCenter.longitude - 0.001,
miny: updatedCenter.latitude - 0.001,
maxx: updatedCenter.longitude + 0.001,
maxy: updatedCenter.latitude + 0.001
minx: updatedCenter.longitude - ((size[0] / 2) / METERS_PER_UNIT.degrees),
miny: updatedCenter.latitude - ((size[1] / 2) / METERS_PER_UNIT.degrees),
maxx: updatedCenter.longitude + ((size[0] / 2) / METERS_PER_UNIT.degrees),
maxy: updatedCenter.latitude + ((size[1] / 2) / METERS_PER_UNIT.degrees)
}
};
onChange('features', [
Expand Down
15 changes: 9 additions & 6 deletions web/client/epics/catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,10 @@ import {getCapabilitiesUrl, getLayerId, getLayerUrl, removeWorkspace} from '../u
import {zoomToExtent} from "../actions/map";
import CSW from '../api/CSW';
import { projectionSelector, mapSelector } from '../selectors/map';
import { getResolutions } from "../utils/MapUtils";
import { getResolutions, METERS_PER_UNIT } from "../utils/MapUtils";
import { describeFeatureType } from '../api/WFS';
import { extractGeometryType } from '../utils/WFSLayerUtils';
import { createDefaultStyle } from '../utils/StyleUtils';

const onErrorRecordSearch = (isNewService, errObj) => {
if (isNewService) {
return Rx.Observable.of(
Expand Down Expand Up @@ -297,14 +296,15 @@ export default (API) => ({
const center = CoordinatesUtils.reproject(mapCenter, mapCenter.crs, 'EPSG:4326');
const longitude = center.x;
const latitude = center.y;
const size = properties.size || [2, 2];
const newLayer = {
...layer,
bbox: {
bounds: {
minx: longitude || 0 - 0.001,
miny: latitude || 0 - 0.001,
maxx: longitude || 0 + 0.001,
maxy: latitude || 0 + 0.001
minx: (longitude || 0) - ((size[0] / 2) / METERS_PER_UNIT.degrees),
miny: (latitude || 0) - ((size[1] / 2) / METERS_PER_UNIT.degrees),
maxx: (longitude || 0) + ((size[0] / 2) / METERS_PER_UNIT.degrees),
maxy: (latitude || 0) + ((size[1] / 2) / METERS_PER_UNIT.degrees)
},
crs: 'EPSG:4326'
},
Expand All @@ -324,6 +324,9 @@ export default (API) => ({
title: "notification.warning",
message: properties?.projectedCrsNotSupported ? "layerProperties.modelLayer.warnings.projectedCrsNotSupported" : "layerProperties.modelLayer.warnings.projectedCrsNotProvided",
autoDismiss: 15,
values: {
modelProjection: properties?.projectedCrsNotSupported ? `(${properties?.projectedCrs})` : ""
},
position: "tc"
})]
);
Expand Down
2 changes: 1 addition & 1 deletion web/client/translations/data.de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
"height": "Höhe (m)",
"heading": "Kurswinkel (DD)",
"warnings": {
"projectedCrsNotSupported": "Das Modell wird aus folgenden Gründen in der Mitte der aktuellen Ansicht platziert: Das Modell verfügt über eine CRS-Projektion, diese wird jedoch nicht unterstützt.",
"projectedCrsNotSupported": "Das Modell wird aus folgenden Gründen in der Mitte der aktuellen Ansicht platziert: Das Modell verfügt über eine CRS-Projektion {modelProjection}, diese wird jedoch nicht unterstützt.",
"projectedCrsNotProvided": "Das Modell wird aus folgenden Gründen in der Mitte der aktuellen Ansicht platziert: Das Modell verfügt über keine definierte CRS-Projektion."
}
},
Expand Down
2 changes: 1 addition & 1 deletion web/client/translations/data.en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
"height": "Height (m)",
"heading": "Heading (DD)",
"warnings": {
"projectedCrsNotSupported": "The model is placed on the center of the current view because: the model has a CRS projection but it is not supported.",
"projectedCrsNotSupported": "The model is placed on the center of the current view because: the model has a CRS projection {modelProjection} but it is not supported.",
"projectedCrsNotProvided": "The model is placed on the center of the current view because: the model has no defined CRS projection."
}
},
Expand Down
2 changes: 1 addition & 1 deletion web/client/translations/data.es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@
"height": "Altura (m)",
"heading": "Ángulo de rumbo (DD)",
"warnings": {
"projectedCrsNotSupported": "El modelo se coloca en el centro de la vista actual porque: el modelo tiene una proyección CRS pero no es soportado",
"projectedCrsNotSupported": "El modelo se coloca en el centro de la vista actual porque: el modelo tiene una proyección CRS {modelProjection} pero no es soportado",
"projectedCrsNotProvided": "El modelo se coloca en el centro de la vista actual porque: el modelo no tiene una proyección CRS definida."
}
},
Expand Down
2 changes: 1 addition & 1 deletion web/client/translations/data.fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
"height": "Hauteur (m)",
"heading": "Angle de cap (DD)",
"warnings": {
"projectedCrsNotSupported": "Le modèle est placé au centre de la vue actuelle car: le modèle a une projection CRS, mais elle n'est pas prise en charge.",
"projectedCrsNotSupported": "Le modèle est placé au centre de la vue actuelle car: le modèle a une projection CRS {modelProjection}, mais elle n'est pas prise en charge.",
"projectedCrsNotProvided": "Le modèle est placé au centre de la vue actuelle car: le modèle n'a pas de projection CRS définie."
}
},
Expand Down
2 changes: 1 addition & 1 deletion web/client/translations/data.it-IT.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
"height": "Altezza (m)",
"heading": "Angolo di rotta (DD)",
"warnings": {
"projectedCrsNotSupported": "Il modello è posizionato al centro della vista corrente perché: il modello ha una proiezione CRS, ma non è supportata.",
"projectedCrsNotSupported": "Il modello è posizionato al centro della vista corrente perché: il modello ha una proiezione CRS {modelProjection}, ma non è supportata.",
"projectedCrsNotProvided": "Il modello è posizionato al centro della vista corrente perché: il modello non ha una proiezione CRS definita."
}
},
Expand Down

0 comments on commit 5261361

Please sign in to comment.