s3dgraphy 1.6.0.dev6__tar.gz → 1.6.0.dev7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {s3dgraphy-1.6.0.dev6/src/s3dgraphy.egg-info → s3dgraphy-1.6.0.dev7}/PKG-INFO +1 -1
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/pyproject.toml +1 -1
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/__init__.py +1 -1
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/canvas_generator.py +22 -1
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/graphml_exporter.py +38 -1
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/node_generator.py +33 -3
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/import_graphml.py +184 -9
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/graph_ingestor.py +39 -245
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/graph_projector.py +31 -44
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/graphml_writer.py +10 -57
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/rapporti.py +551 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/templates/em_palette_template.graphml +11 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7/src/s3dgraphy.egg-info}/PKG-INFO +1 -1
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy.egg-info/SOURCES.txt +1 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/LICENSE +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/MANIFEST.in +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/README.md +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/setup.cfg +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em.ttl +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_document_types.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_extractor_types.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_palette_icons.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_qualia_types.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_qualia_types_additions.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_visual_rules.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/hdto_extension.ttl +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/new_qualia_template.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/outdated_s3dgraphy.ttl +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/outdated_s3dgraphy_nomapping.ttl +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json.v155.bak +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/s3Dgraphy_node_datamodel.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/RSF.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/RSF.svg +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/SF.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/TSU.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/US.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/USD.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/USVn.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/USVs.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/VSF.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/combiner.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/continuity.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/document.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/extractor.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/property.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/serSU.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/serUSD.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/serUSV.png +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/RSF.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/SF.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/TSU.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/US.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/USD.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/USVn.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/USVs.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/VSF.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/combiner.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/continuity.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/document.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/extractor.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/property.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/serSU.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/serUSD.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/serUSV.glb +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/classification.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/data/StratiMiner_Extraction_Prompt.md +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/diagnostics.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/edges/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/edges/connections_loader.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/edges/edge.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/edge_generator.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/epoch_generator.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/graphml_patcher.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/group_node_generator.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/node_registry.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/palette_resources.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/paradata_generator.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/paradata_image_generator.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/paradata_node_generators.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/table_node_generator.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/utils.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/json_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/rdf_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/unified_xlsx_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/graph.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/base_importer.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/mapped_xlsx_importer.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/pyarchinit_importer.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/qualia_importer.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/unified_xlsx_importer.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/xlsx_importer.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/indices.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/emdb/generic_specialfind_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/emdb/site_properties_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/emdb/usm_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/generic/excel_to_graphml_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/pyarchinit/pyarchinit_us_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/registry.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/template_emdb_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/template_pyarchinit_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/merge/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/merge/graph_merger.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/multigraph/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/multigraph/multigraph.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/author_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/base_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/combiner_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/document_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/embargo_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/epoch_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/extractor_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/geo_position_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/graph_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/group_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/hdt_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/license_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/link_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/paradata_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/property_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/representation_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/semantic_shape_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/stratigraphic_node.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/resolvers/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/resolvers/builtin_rules.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/resolvers/property_resolver.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/_db_handle.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/_legacy_paradata_svgs.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/_workspace.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/conflict_resolver.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/edge_registry.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/group_projector.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/group_store.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/ingest_result.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/paradata_store.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/pyarchinit_pg_importer.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/uuid7.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/vocab_provider_core.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/vocab_types.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/yed_classifier.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/yed_detector.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/yed_group_walker.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/yed_import_pipeline.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/yed_rapporti_policy.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/sync/yed_table_parser.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/templates/em_data_template.xlsx +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/temporal/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/temporal/inference_engine.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/transforms/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/transforms/aux_tracking.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/transforms/compact.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/transforms/materialize_continuity.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/utils/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/utils/utils.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/utils/visual_layout.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy.egg-info/dependency_links.txt +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy.egg-info/requires.txt +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy.egg-info/top_level.txt +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/tests/test_composite_node_name.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/tests/test_filtered_import.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/tests/test_lossless_roundtrip.py +0 -0
- {s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/tests/test_pg_importer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: s3dgraphy
|
|
3
|
-
Version: 1.6.0.
|
|
3
|
+
Version: 1.6.0.dev7
|
|
4
4
|
Summary: 3D Stratigraphic Graph Management Library for archaeological and heritage applications
|
|
5
5
|
Author-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
|
|
6
6
|
Maintainer-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "s3dgraphy"
|
|
7
|
-
version = "1.6.0.
|
|
7
|
+
version = "1.6.0.dev7"
|
|
8
8
|
description = "3D Stratigraphic Graph Management Library for archaeological and heritage applications"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
{s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/canvas_generator.py
RENAMED
|
@@ -68,7 +68,7 @@ class CanvasGenerator:
|
|
|
68
68
|
return root
|
|
69
69
|
|
|
70
70
|
def _add_node_keys(self, root: ET.Element):
|
|
71
|
-
"""Add key definitions for nodes (d4-d8)."""
|
|
71
|
+
"""Add key definitions for nodes (d4-d8, d13)."""
|
|
72
72
|
# d4: url
|
|
73
73
|
key = ET.SubElement(root, '{http://graphml.graphdrawing.org/xmlns}key')
|
|
74
74
|
key.set('attr.name', 'url')
|
|
@@ -104,6 +104,27 @@ class CanvasGenerator:
|
|
|
104
104
|
key.set('for', 'node')
|
|
105
105
|
key.set('id', 'd8')
|
|
106
106
|
|
|
107
|
+
# d13: physical_relationships (EM 1.6 per-node packed string)
|
|
108
|
+
#
|
|
109
|
+
# Per-node serialisation of the canonical physical stratigraphic
|
|
110
|
+
# edges, in the same list-of-lists Python-literal format used by
|
|
111
|
+
# the pyArchInit ``us_table.rapporti`` column. yEd reserves edges
|
|
112
|
+
# for the temporal Matrix layer, so the EM 1.6 palette surfaces
|
|
113
|
+
# these relationships as a per-node attribute instead — visible
|
|
114
|
+
# to humans editing the file in yEd, and byte-identical with the
|
|
115
|
+
# pyArchInit column when the graph between them is unmutated.
|
|
116
|
+
#
|
|
117
|
+
# The exporter writes this attribute on every stratigraphic node
|
|
118
|
+
# whose canonical edges include physical-stratigraphic types;
|
|
119
|
+
# the importer reads it only when the richer graph-level JSON
|
|
120
|
+
# side channel (``_s3d_physical_relations``) is absent. See
|
|
121
|
+
# ``s3dgraphy.sync.rapporti`` for the canonical vocabulary.
|
|
122
|
+
key = ET.SubElement(root, '{http://graphml.graphdrawing.org/xmlns}key')
|
|
123
|
+
key.set('attr.name', 'physical_relationships')
|
|
124
|
+
key.set('attr.type', 'string')
|
|
125
|
+
key.set('for', 'node')
|
|
126
|
+
key.set('id', 'd13')
|
|
127
|
+
|
|
107
128
|
def _add_edge_keys(self, root: ET.Element):
|
|
108
129
|
"""Add key definitions for edges (d10-d12)."""
|
|
109
130
|
# d10: edgegraphics (yfiles)
|
{s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/graphml_exporter.py
RENAMED
|
@@ -142,6 +142,40 @@ class GraphMLExporter:
|
|
|
142
142
|
# side channel restores all three on import.
|
|
143
143
|
self._write_property_metadata_data(graph_elem, canvas)
|
|
144
144
|
|
|
145
|
+
# 1d. Snapshot per-US-node physical_relationships (the EM 1.6
|
|
146
|
+
# palette per-node packed string format, byte-identical with the
|
|
147
|
+
# pyArchInit ``us_table.rapporti`` column). Computed BEFORE the
|
|
148
|
+
# transitive reduction below so the canonical edges are still
|
|
149
|
+
# present; stashed for NodeGenerator to attach as ``<data
|
|
150
|
+
# key="d13">`` on each stratigraphic node. See
|
|
151
|
+
# ``s3dgraphy.sync.rapporti.serialize_rapporti_from_edges`` for
|
|
152
|
+
# the format and ``canvas_generator._add_node_keys`` (d13) for
|
|
153
|
+
# the key declaration.
|
|
154
|
+
try:
|
|
155
|
+
from ...sync.rapporti import serialize_rapporti_from_edges
|
|
156
|
+
# Pick the site name to stamp into the 4th column of each
|
|
157
|
+
# rapporto entry. Graph.__init__ stores the caller-supplied
|
|
158
|
+
# identifier on ``graph_id`` and leaves ``name`` empty by
|
|
159
|
+
# default, so ``graph_id`` is the most reliable signal in
|
|
160
|
+
# practice — but we still consult ``name`` / ``sito`` for
|
|
161
|
+
# consumers that populate them explicitly.
|
|
162
|
+
default_sito = (
|
|
163
|
+
getattr(self.graph, "graph_id", None)
|
|
164
|
+
or getattr(self.graph, "name", None)
|
|
165
|
+
or getattr(self.graph, "sito", None)
|
|
166
|
+
or ""
|
|
167
|
+
)
|
|
168
|
+
# ``name`` may be a dict in the s3dgraphy Graph schema; only
|
|
169
|
+
# str values are valid for the pyArchInit column.
|
|
170
|
+
if not isinstance(default_sito, str):
|
|
171
|
+
default_sito = ""
|
|
172
|
+
self._physical_relationships_by_node: Dict[str, list] = (
|
|
173
|
+
serialize_rapporti_from_edges(self.graph, default_sito))
|
|
174
|
+
except Exception as exc: # pragma: no cover - defensive
|
|
175
|
+
print(f" [physical_relationships] skipped serialization: "
|
|
176
|
+
f"{exc}")
|
|
177
|
+
self._physical_relationships_by_node = {}
|
|
178
|
+
|
|
145
179
|
# Allocate palette refids starting from 4 (1-3 are reserved for
|
|
146
180
|
# SVG extractor/combiner/continuity emitted by CanvasGenerator).
|
|
147
181
|
# Populated as AuthorNode / LicenseNode / EmbargoNode instances
|
|
@@ -150,7 +184,10 @@ class GraphMLExporter:
|
|
|
150
184
|
self._next_palette_refid: int = 4
|
|
151
185
|
|
|
152
186
|
# 2. Initialize generators
|
|
153
|
-
node_gen = NodeGenerator(
|
|
187
|
+
node_gen = NodeGenerator(
|
|
188
|
+
self.node_registry, self.id_manager,
|
|
189
|
+
physical_relationships_by_node=self._physical_relationships_by_node,
|
|
190
|
+
)
|
|
154
191
|
group_gen = GroupNodeGenerator(self.node_registry, self.id_manager)
|
|
155
192
|
edge_gen = EdgeGenerator(self.id_manager)
|
|
156
193
|
|
{s3dgraphy-1.6.0.dev6 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/node_generator.py
RENAMED
|
@@ -15,17 +15,30 @@ from .utils import IDManager, calculate_node_width, generate_uuid
|
|
|
15
15
|
class NodeGenerator:
|
|
16
16
|
"""Generates GraphML XML for various node types."""
|
|
17
17
|
|
|
18
|
-
def __init__(self, registry: NodeRegistry, id_manager: IDManager
|
|
18
|
+
def __init__(self, registry: NodeRegistry, id_manager: IDManager,
|
|
19
|
+
physical_relationships_by_node: Optional[dict] = None):
|
|
19
20
|
"""
|
|
20
21
|
Initialize node generator.
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
Args:
|
|
23
24
|
registry: Node registry with visual properties
|
|
24
25
|
id_manager: ID manager for nested IDs
|
|
26
|
+
physical_relationships_by_node: Optional pre-computed dict
|
|
27
|
+
mapping ``node_id`` → list of
|
|
28
|
+
``[label, target_us, area, sito]`` entries (the
|
|
29
|
+
pyArchInit list-of-lists serialisation produced by
|
|
30
|
+
:func:`s3dgraphy.sync.rapporti.serialize_rapporti_from_edges`).
|
|
31
|
+
When provided, ``generate_stratigraphic_node`` emits a
|
|
32
|
+
``<data key="d13">`` element with the Python-literal
|
|
33
|
+
``repr`` of the entry list — the EM 1.6 palette format
|
|
34
|
+
for per-node physical relationships. Unknown / missing
|
|
35
|
+
node ids are silently ignored.
|
|
25
36
|
"""
|
|
26
37
|
self.registry = registry
|
|
27
38
|
self.id_manager = id_manager
|
|
28
39
|
self.ns_y = 'http://www.yworks.com/xml/graphml'
|
|
40
|
+
self._physical_relationships_by_node = (
|
|
41
|
+
physical_relationships_by_node or {})
|
|
29
42
|
|
|
30
43
|
def generate_stratigraphic_node(self, node, x: float = 100.0, y: float = 100.0,
|
|
31
44
|
parent_id: Optional[str] = None) -> ET.Element:
|
|
@@ -72,7 +85,24 @@ class NodeGenerator:
|
|
|
72
85
|
data_d7 = ET.SubElement(node_elem, '{http://graphml.graphdrawing.org/xmlns}data')
|
|
73
86
|
data_d7.set('key', 'd7')
|
|
74
87
|
data_d7.text = node_uuid
|
|
75
|
-
|
|
88
|
+
|
|
89
|
+
# Add physical_relationships (d13) — EM 1.6 per-node packed
|
|
90
|
+
# string. The exporter pre-computes a dict ``node_id → list``
|
|
91
|
+
# using :func:`s3dgraphy.sync.rapporti.serialize_rapporti_from_edges`
|
|
92
|
+
# before the transitive reduction collapses canonical edges, and
|
|
93
|
+
# passes it in via ``__init__``. The on-disk format is the
|
|
94
|
+
# Python literal ``repr`` of the list-of-lists, byte-identical
|
|
95
|
+
# with the pyArchInit ``us_table.rapporti`` column when the
|
|
96
|
+
# graph between them is unmutated.
|
|
97
|
+
rapporti_entries = self._physical_relationships_by_node.get(
|
|
98
|
+
node_uuid)
|
|
99
|
+
if rapporti_entries:
|
|
100
|
+
data_d13 = ET.SubElement(
|
|
101
|
+
node_elem,
|
|
102
|
+
'{http://graphml.graphdrawing.org/xmlns}data')
|
|
103
|
+
data_d13.set('key', 'd13')
|
|
104
|
+
data_d13.text = repr(rapporti_entries)
|
|
105
|
+
|
|
76
106
|
# Add nodegraphics (d6) - ShapeNode
|
|
77
107
|
data_d6 = ET.SubElement(node_elem, '{http://graphml.graphdrawing.org/xmlns}data')
|
|
78
108
|
data_d6.set('key', 'd6')
|
|
@@ -362,7 +362,17 @@ class GraphMLImporter:
|
|
|
362
362
|
# exporter. Legacy files without the key are left untouched (the
|
|
363
363
|
# reduced is_after / has_same_time set from parse_edges remains
|
|
364
364
|
# in place). See module-level docstring for the rationale.
|
|
365
|
-
|
|
365
|
+
json_channel_applied = (
|
|
366
|
+
self._restore_physical_relations_from_side_channel(tree))
|
|
367
|
+
|
|
368
|
+
# Fallback for files NOT produced by the lossless exporter: read
|
|
369
|
+
# per-node ``physical_relationships`` (d13) packed strings — the
|
|
370
|
+
# EM 1.6 palette / pyArchInit-native list-of-lists format — and
|
|
371
|
+
# rebuild canonical edges from them. Skipped when the
|
|
372
|
+
# graph-level JSON side channel was present, since that's
|
|
373
|
+
# strictly richer (carries per-edge attributes and edge_ids).
|
|
374
|
+
if not json_channel_applied:
|
|
375
|
+
self._restore_physical_relations_from_node_attribute(tree)
|
|
366
376
|
|
|
367
377
|
# Re-apply structured PropertyNode metadata (value /
|
|
368
378
|
# property_type / units / attributes) from the
|
|
@@ -759,7 +769,7 @@ class GraphMLImporter:
|
|
|
759
769
|
|
|
760
770
|
# print(f"Warning: Could not create edge {original_edge_id} - Source: {original_source_id} -> Target: {original_target_id}")
|
|
761
771
|
|
|
762
|
-
def _restore_physical_relations_from_side_channel(self, tree):
|
|
772
|
+
def _restore_physical_relations_from_side_channel(self, tree) -> bool:
|
|
763
773
|
"""Restore the original physical stratigraphic edges from the
|
|
764
774
|
``_s3d_physical_relations`` graph-level GraphML key, if present.
|
|
765
775
|
|
|
@@ -787,6 +797,13 @@ class GraphMLImporter:
|
|
|
787
797
|
``parse_edges`` / ``process_node_element``), the UUIDs round-trip
|
|
788
798
|
directly. Unknown UUIDs are skipped with a warning so a partial
|
|
789
799
|
graph still imports cleanly.
|
|
800
|
+
|
|
801
|
+
Returns:
|
|
802
|
+
``True`` if the graph-level key was *declared* on the file
|
|
803
|
+
(regardless of payload size), ``False`` otherwise. Callers
|
|
804
|
+
use this to gate the per-node ``physical_relationships``
|
|
805
|
+
(d13) fallback: an authoritative JSON channel should not be
|
|
806
|
+
shadowed by the strictly poorer per-node packed string.
|
|
790
807
|
"""
|
|
791
808
|
root = tree.getroot()
|
|
792
809
|
ns = 'http://graphml.graphdrawing.org/xmlns'
|
|
@@ -803,8 +820,10 @@ class GraphMLImporter:
|
|
|
803
820
|
break
|
|
804
821
|
|
|
805
822
|
if not side_channel_key_id:
|
|
806
|
-
# Legacy file: no key declared, nothing to restore.
|
|
807
|
-
|
|
823
|
+
# Legacy file: no key declared, nothing to restore. The
|
|
824
|
+
# per-node ``physical_relationships`` (d13) fallback may
|
|
825
|
+
# still apply — callers gate on the return value.
|
|
826
|
+
return False
|
|
808
827
|
|
|
809
828
|
# 2) Find the graph-level <data> element carrying the payload.
|
|
810
829
|
# We expect it directly under <graph id="G">. Scan all top-level
|
|
@@ -818,28 +837,34 @@ class GraphMLImporter:
|
|
|
818
837
|
side_channel_data = candidate
|
|
819
838
|
break
|
|
820
839
|
|
|
840
|
+
# From here on, the key was declared — the file was authored by
|
|
841
|
+
# the lossless exporter (or a tool that knows about it). Return
|
|
842
|
+
# True at every exit point so the per-node fallback stays out of
|
|
843
|
+
# the way; the JSON channel is authoritative.
|
|
821
844
|
if side_channel_data is None or not (side_channel_data.text or "").strip():
|
|
822
|
-
# Key declared but no payload — treat as
|
|
823
|
-
|
|
845
|
+
# Key declared but no payload — treat as "no relations" but
|
|
846
|
+
# don't fall back to d13 (that would re-introduce stale data
|
|
847
|
+
# if the producer intentionally cleared the channel).
|
|
848
|
+
return True
|
|
824
849
|
|
|
825
850
|
try:
|
|
826
851
|
relations = json.loads(side_channel_data.text)
|
|
827
852
|
except (ValueError, TypeError) as exc:
|
|
828
853
|
print(f"[GraphML Parser] WARNING: could not parse "
|
|
829
854
|
f"{_S3D_PHYSICAL_RELATIONS_ATTR_NAME} payload: {exc}")
|
|
830
|
-
return
|
|
855
|
+
return True
|
|
831
856
|
|
|
832
857
|
if not isinstance(relations, list):
|
|
833
858
|
print(f"[GraphML Parser] WARNING: "
|
|
834
859
|
f"{_S3D_PHYSICAL_RELATIONS_ATTR_NAME} payload is not a "
|
|
835
860
|
f"list (got {type(relations).__name__}); ignoring")
|
|
836
|
-
return
|
|
861
|
+
return True
|
|
837
862
|
|
|
838
863
|
if not relations:
|
|
839
864
|
# Genuinely empty: drop reduced edges anyway, since the
|
|
840
865
|
# exporter would not have written them either if the graph
|
|
841
866
|
# had no physical relations. But to be safe, leave them.
|
|
842
|
-
return
|
|
867
|
+
return True
|
|
843
868
|
|
|
844
869
|
# 3) Drop the reduced-physical edges produced by the export-side
|
|
845
870
|
# transitive reduction. They are stale once we re-add the
|
|
@@ -913,6 +938,156 @@ class GraphMLImporter:
|
|
|
913
938
|
if skipped_missing else "")
|
|
914
939
|
+ (f", skipped {skipped_invalid} (invalid payload)"
|
|
915
940
|
if skipped_invalid else ""))
|
|
941
|
+
return True
|
|
942
|
+
|
|
943
|
+
def _restore_physical_relations_from_node_attribute(self, tree):
|
|
944
|
+
"""Rebuild canonical physical-stratigraphic edges from per-node
|
|
945
|
+
``physical_relationships`` (d13) packed strings.
|
|
946
|
+
|
|
947
|
+
This is the fallback for GraphML files NOT produced by the
|
|
948
|
+
s3dgraphy lossless exporter — e.g. files hand-authored in yEd
|
|
949
|
+
with the EM 1.6 palette, or files emitted by a pyArchInit-side
|
|
950
|
+
bridge that only fills the per-node attribute. The packed
|
|
951
|
+
string is the same list-of-lists Python-literal format used by
|
|
952
|
+
the pyArchInit ``us_table.rapporti`` column, so the GraphML ↔
|
|
953
|
+
pyArchInit transit is byte-identical when the graph between
|
|
954
|
+
them is unmutated.
|
|
955
|
+
|
|
956
|
+
Behaviour:
|
|
957
|
+
- For each ``<node>`` in the GraphML tree, look for a
|
|
958
|
+
``<data>`` child whose key id resolves to the
|
|
959
|
+
``physical_relationships`` (d13) declaration.
|
|
960
|
+
- Parse the string with
|
|
961
|
+
:func:`s3dgraphy.sync.rapporti.parse_rapporti`, which yields
|
|
962
|
+
canonical 5-tuples ``(edge_type, target_us, area, sito,
|
|
963
|
+
swap)``.
|
|
964
|
+
- Resolve target nodes by walking the imported graph's
|
|
965
|
+
nodes-by-name index; drop the reduced-physical edges (same
|
|
966
|
+
way the JSON channel does) before re-adding the canonical
|
|
967
|
+
ones so the in-memory graph isn't doubled up.
|
|
968
|
+
|
|
969
|
+
Called only when
|
|
970
|
+
:meth:`_restore_physical_relations_from_side_channel` reports
|
|
971
|
+
no graph-level JSON channel was present.
|
|
972
|
+
"""
|
|
973
|
+
from ..sync.rapporti import parse_rapporti
|
|
974
|
+
|
|
975
|
+
root = tree.getroot()
|
|
976
|
+
ns = 'http://graphml.graphdrawing.org/xmlns'
|
|
977
|
+
|
|
978
|
+
# 1) Resolve the d13 key id from the file (don't assume "d13",
|
|
979
|
+
# since downstream tools may renumber keys on patch).
|
|
980
|
+
d13_key_id = None
|
|
981
|
+
for key_elem in root.findall(f'.//{{{ns}}}key'):
|
|
982
|
+
if (key_elem.attrib.get('attr.name')
|
|
983
|
+
== 'physical_relationships'
|
|
984
|
+
and key_elem.attrib.get('for') == 'node'):
|
|
985
|
+
d13_key_id = key_elem.attrib.get('id')
|
|
986
|
+
break
|
|
987
|
+
|
|
988
|
+
if not d13_key_id:
|
|
989
|
+
# Legacy file with no per-node packed string declaration —
|
|
990
|
+
# the reduced ``is_after`` edges from parse_edges stand.
|
|
991
|
+
return
|
|
992
|
+
|
|
993
|
+
# 2) Gather (source_node_id, raw_string) pairs by EMID. The
|
|
994
|
+
# GraphML node element's ``id`` is the nested layout id; the
|
|
995
|
+
# ``EMID`` (d7) data carries the s3dgraphy UUID, which is what
|
|
996
|
+
# the imported graph indexes by. parse_nodes has already
|
|
997
|
+
# populated the EMID slipback; reuse the same lookup pattern.
|
|
998
|
+
emid_key_id = None
|
|
999
|
+
for key_elem in root.findall(f'.//{{{ns}}}key'):
|
|
1000
|
+
if (key_elem.attrib.get('attr.name') == 'EMID'
|
|
1001
|
+
and key_elem.attrib.get('for') == 'node'):
|
|
1002
|
+
emid_key_id = key_elem.attrib.get('id')
|
|
1003
|
+
break
|
|
1004
|
+
|
|
1005
|
+
per_node_raw: list[tuple[str, str]] = []
|
|
1006
|
+
for node_elem in root.findall(f'.//{{{ns}}}node'):
|
|
1007
|
+
d13 = node_elem.find(f'./{{{ns}}}data[@key="{d13_key_id}"]')
|
|
1008
|
+
if d13 is None or not (d13.text or "").strip():
|
|
1009
|
+
continue
|
|
1010
|
+
emid = None
|
|
1011
|
+
if emid_key_id:
|
|
1012
|
+
emid_data = node_elem.find(
|
|
1013
|
+
f'./{{{ns}}}data[@key="{emid_key_id}"]')
|
|
1014
|
+
if emid_data is not None and emid_data.text:
|
|
1015
|
+
emid = emid_data.text.strip()
|
|
1016
|
+
if not emid:
|
|
1017
|
+
# Fall back to the layout id — process_node_element
|
|
1018
|
+
# uses it as the UUID when EMID is missing.
|
|
1019
|
+
emid = node_elem.attrib.get('id')
|
|
1020
|
+
if emid:
|
|
1021
|
+
per_node_raw.append((emid, d13.text))
|
|
1022
|
+
|
|
1023
|
+
if not per_node_raw:
|
|
1024
|
+
return
|
|
1025
|
+
|
|
1026
|
+
# 3) Build a name → list-of-nodes index for target resolution.
|
|
1027
|
+
# parse_rapporti yields ``target_us`` as the bare unit number
|
|
1028
|
+
# (no "US " prefix); match against the imported nodes' .name
|
|
1029
|
+
# after applying the same strip the writer used.
|
|
1030
|
+
from ..sync.rapporti import strip_us_prefix
|
|
1031
|
+
nodes_by_name: dict = {}
|
|
1032
|
+
for n in self.graph.nodes:
|
|
1033
|
+
key = strip_us_prefix(getattr(n, "name", "") or "")
|
|
1034
|
+
nodes_by_name.setdefault(key, []).append(n)
|
|
1035
|
+
|
|
1036
|
+
# 4) Drop the reduced physical edges (parse_edges produced
|
|
1037
|
+
# them); the per-node packed strings carry the canonical set.
|
|
1038
|
+
before = len(self.graph.edges)
|
|
1039
|
+
self.graph.edges = [
|
|
1040
|
+
e for e in self.graph.edges
|
|
1041
|
+
if e.edge_type not in PHYSICAL_STRATIGRAPHIC_TYPES
|
|
1042
|
+
]
|
|
1043
|
+
dropped = before - len(self.graph.edges)
|
|
1044
|
+
if hasattr(self.graph, "_indices_dirty"):
|
|
1045
|
+
self.graph._indices_dirty = True
|
|
1046
|
+
|
|
1047
|
+
restored = 0
|
|
1048
|
+
skipped_missing = 0
|
|
1049
|
+
skipped_invalid = 0
|
|
1050
|
+
seen_edge_ids = {e.edge_id for e in self.graph.edges}
|
|
1051
|
+
for source_uuid, raw in per_node_raw:
|
|
1052
|
+
src_node = self.graph.find_node_by_id(source_uuid)
|
|
1053
|
+
if src_node is None:
|
|
1054
|
+
skipped_invalid += 1
|
|
1055
|
+
continue
|
|
1056
|
+
for (edge_type, target_us, _area, _sito, swap) in \
|
|
1057
|
+
parse_rapporti(raw):
|
|
1058
|
+
candidates = nodes_by_name.get(target_us)
|
|
1059
|
+
if not candidates:
|
|
1060
|
+
skipped_missing += 1
|
|
1061
|
+
continue
|
|
1062
|
+
# No family-preference disambiguation here — the
|
|
1063
|
+
# per-node fallback is by definition shallow (no
|
|
1064
|
+
# PD/property targets); first match is fine.
|
|
1065
|
+
tgt_node = candidates[0]
|
|
1066
|
+
src, dst = ((tgt_node, src_node) if swap
|
|
1067
|
+
else (src_node, tgt_node))
|
|
1068
|
+
edge_id = (f"rap_{src.node_id}_{dst.node_id}_"
|
|
1069
|
+
f"{edge_type}")
|
|
1070
|
+
if edge_id in seen_edge_ids:
|
|
1071
|
+
continue
|
|
1072
|
+
try:
|
|
1073
|
+
self.graph.add_edge(edge_id, src.node_id,
|
|
1074
|
+
dst.node_id, edge_type)
|
|
1075
|
+
except ValueError as exc:
|
|
1076
|
+
print(f"[GraphML Parser] WARNING: failed to restore "
|
|
1077
|
+
f"physical edge {src.node_id} "
|
|
1078
|
+
f"-[{edge_type}]-> {dst.node_id}: {exc}")
|
|
1079
|
+
skipped_invalid += 1
|
|
1080
|
+
continue
|
|
1081
|
+
seen_edge_ids.add(edge_id)
|
|
1082
|
+
restored += 1
|
|
1083
|
+
|
|
1084
|
+
print(f"[GraphML Parser] physical_relationships (d13): "
|
|
1085
|
+
f"dropped {dropped} reduced edges, restored {restored} "
|
|
1086
|
+
f"physical edges"
|
|
1087
|
+
+ (f", skipped {skipped_missing} (target unresolved)"
|
|
1088
|
+
if skipped_missing else "")
|
|
1089
|
+
+ (f", skipped {skipped_invalid} (invalid)"
|
|
1090
|
+
if skipped_invalid else ""))
|
|
916
1091
|
|
|
917
1092
|
def _restore_property_metadata_from_side_channel(self, tree):
|
|
918
1093
|
"""Reapply structured PropertyNode metadata from the
|