| 522 | } |
| 523 | |
| 524 | void GltfSerializer::setFile(IfcParse::IfcFile* f) { |
| 525 | if (!settings_.get<ifcopenshell::geometry::settings::WriteGltfEcef>().get()) { |
| 526 | return; |
| 527 | } |
| 528 | |
| 529 | boost::optional<std::string> crs_epsg; |
| 530 | boost::optional<std::array<double, 3>> crs_x_axis; |
| 531 | boost::optional<std::array<double, 3>> eastings_northings_elevation; |
| 532 | |
| 533 | aggregate_of_instance::ptr coordops; |
| 534 | try { |
| 535 | coordops = f->instances_by_type("IfcCoordinateOperation"); |
| 536 | } catch (IfcParse::IfcException&) { |
| 537 | // Ignored. Schema likely doesn't support IfcCoordinateOperation. |
| 538 | } |
| 539 | if (coordops) { |
| 540 | for (auto& coordop : *coordops) { |
| 541 | IfcUtil::IfcBaseClass* source_crs = coordop->as<IfcUtil::IfcBaseEntity>()->get("SourceCRS"); |
| 542 | if (source_crs->declaration().is("IfcGeometricRepresentationContext")) { |
| 543 | IfcUtil::IfcBaseClass* target_crs = coordop->as<IfcUtil::IfcBaseEntity>()->get("TargetCRS"); |
| 544 | auto name_attr = target_crs->as<IfcUtil::IfcBaseEntity>()->get("Name"); |
| 545 | if (coordop->declaration().is("IfcMapConversion")) { |
| 546 | |
| 547 | if (!name_attr.isNull()) { |
| 548 | std::string epsg_code = name_attr; |
| 549 | crs_epsg = epsg_code; |
| 550 | |
| 551 | // @todo in which unit are these? |
| 552 | double eastings = coordop->as<IfcUtil::IfcBaseEntity>()->get("Eastings"); |
| 553 | double northings = coordop->as<IfcUtil::IfcBaseEntity>()->get("Northings"); |
| 554 | double height = coordop->as<IfcUtil::IfcBaseEntity>()->get("OrthogonalHeight"); |
| 555 | height = 0.; |
| 556 | |
| 557 | eastings_northings_elevation = { { eastings, northings, height} }; |
| 558 | |
| 559 | auto xaxis_attr = coordop->as<IfcUtil::IfcBaseEntity>()->get("XAxisAbscissa"); |
| 560 | auto yaxis_attr = coordop->as<IfcUtil::IfcBaseEntity>()->get("XAxisOrdinate"); |
| 561 | if (!xaxis_attr.isNull() && !yaxis_attr.isNull()) { |
| 562 | double xaxis = xaxis_attr; |
| 563 | double yaxis = yaxis_attr; |
| 564 | |
| 565 | crs_x_axis = { { xaxis, yaxis, 0. } }; |
| 566 | } |
| 567 | } |
| 568 | } |
| 569 | } |
| 570 | } |
| 571 | } |
| 572 | |
| 573 | if (!crs_epsg) { |
| 574 | auto sites = f->instances_by_type("IfcSite"); |
| 575 | |
| 576 | if (sites && sites->size() == 1) { |
| 577 | auto lat_attr = (*sites->begin())->as<IfcUtil::IfcBaseEntity>()->get("RefLatitude"); |
| 578 | auto lon_attr = (*sites->begin())->as<IfcUtil::IfcBaseEntity>()->get("RefLongitude"); |
| 579 | |
| 580 | if (!lat_attr.isNull() && !lon_attr.isNull()) { |
| 581 | std::vector<int> lat_dms = lat_attr; |
nothing calls this directly
no test coverage detected