s3dgraphy 1.6.0.dev5__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.dev5/src/s3dgraphy.egg-info → s3dgraphy-1.6.0.dev7}/PKG-INFO +7 -3
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/pyproject.toml +17 -3
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_visual_rules.json +7 -6
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/__init__.py +1 -1
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/canvas_generator.py +22 -1
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/graphml_exporter.py +38 -1
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/node_generator.py +33 -3
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/node_registry.py +26 -39
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/rdf_exporter.py +86 -18
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/import_graphml.py +184 -9
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/pyarchinit_importer.py +143 -17
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/__init__.py +142 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/_db_handle.py +172 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/_legacy_paradata_svgs.py +264 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/_workspace.py +100 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/conflict_resolver.py +27 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/edge_registry.py +219 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/graph_ingestor.py +1322 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/graph_projector.py +1332 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/graphml_writer.py +2169 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/group_projector.py +214 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/group_store.py +436 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/ingest_result.py +64 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/paradata_store.py +952 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/pyarchinit_pg_importer.py +152 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/rapporti.py +551 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/uuid7.py +85 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/vocab_provider_core.py +219 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/vocab_types.py +75 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/yed_classifier.py +222 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/yed_detector.py +69 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/yed_group_walker.py +194 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/yed_import_pipeline.py +1519 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/yed_rapporti_policy.py +443 -0
- s3dgraphy-1.6.0.dev7/src/s3dgraphy/sync/yed_table_parser.py +187 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/templates/em_palette_template.graphml +11 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7/src/s3dgraphy.egg-info}/PKG-INFO +7 -3
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy.egg-info/SOURCES.txt +26 -1
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy.egg-info/requires.txt +8 -2
- s3dgraphy-1.6.0.dev7/tests/test_pg_importer.py +307 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/LICENSE +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/MANIFEST.in +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/README.md +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/setup.cfg +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em.ttl +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_document_types.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_extractor_types.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_palette_icons.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_qualia_types.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_qualia_types_additions.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/hdto_extension.ttl +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/new_qualia_template.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/outdated_s3dgraphy.ttl +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/outdated_s3dgraphy_nomapping.ttl +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json.v155.bak +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/s3Dgraphy_node_datamodel.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/RSF.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/RSF.svg +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/SF.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/TSU.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/US.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/USD.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/USVn.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/USVs.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/VSF.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/combiner.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/continuity.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/document.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/extractor.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/property.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/serSU.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/serUSD.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/2D/serUSV.png +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/RSF.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/SF.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/TSU.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/US.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/USD.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/USVn.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/USVs.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/VSF.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/combiner.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/continuity.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/document.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/extractor.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/property.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/serSU.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/serUSD.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/src/3D/serUSV.glb +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/classification.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/data/StratiMiner_Extraction_Prompt.md +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/diagnostics.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/edges/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/edges/connections_loader.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/edges/edge.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/edge_generator.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/epoch_generator.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/graphml_patcher.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/group_node_generator.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/palette_resources.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/paradata_generator.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/paradata_image_generator.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/paradata_node_generators.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/table_node_generator.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/utils.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/json_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/unified_xlsx_exporter.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/graph.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/base_importer.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/mapped_xlsx_importer.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/qualia_importer.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/unified_xlsx_importer.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/importer/xlsx_importer.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/indices.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/emdb/generic_specialfind_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/emdb/site_properties_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/emdb/usm_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/generic/excel_to_graphml_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/pyarchinit/pyarchinit_us_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/registry.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/template_emdb_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/mappings/template_pyarchinit_mapping.json +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/merge/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/merge/graph_merger.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/multigraph/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/multigraph/multigraph.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/author_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/base_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/combiner_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/document_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/embargo_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/epoch_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/extractor_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/geo_position_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/graph_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/group_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/hdt_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/license_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/link_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/paradata_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/property_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/representation_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/semantic_shape_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/nodes/stratigraphic_node.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/resolvers/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/resolvers/builtin_rules.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/resolvers/property_resolver.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/templates/em_data_template.xlsx +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/temporal/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/temporal/inference_engine.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/transforms/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/transforms/aux_tracking.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/transforms/compact.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/transforms/materialize_continuity.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/utils/__init__.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/utils/utils.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/utils/visual_layout.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy.egg-info/dependency_links.txt +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy.egg-info/top_level.txt +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/tests/test_composite_node_name.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/tests/test_filtered_import.py +0 -0
- {s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/tests/test_lossless_roundtrip.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>
|
|
@@ -43,6 +43,10 @@ Requires-Dist: pyoxigraph>=0.4; extra == "rdf-embedded"
|
|
|
43
43
|
Provides-Extra: visualization
|
|
44
44
|
Requires-Dist: matplotlib>=3.0; extra == "visualization"
|
|
45
45
|
Requires-Dist: plotly>=5.0; extra == "visualization"
|
|
46
|
+
Provides-Extra: sync
|
|
47
|
+
Requires-Dist: sqlalchemy>=2.0; extra == "sync"
|
|
48
|
+
Provides-Extra: postgres
|
|
49
|
+
Requires-Dist: psycopg2-binary>=2.9; extra == "postgres"
|
|
46
50
|
Provides-Extra: dev
|
|
47
51
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
48
52
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -57,9 +61,9 @@ Requires-Dist: sphinx>=5.0; extra == "docs"
|
|
|
57
61
|
Requires-Dist: sphinx-rtd-theme; extra == "docs"
|
|
58
62
|
Requires-Dist: myst-parser; extra == "docs"
|
|
59
63
|
Provides-Extra: full
|
|
60
|
-
Requires-Dist: s3dgraphy[rdf-embedded,visualization]; extra == "full"
|
|
64
|
+
Requires-Dist: s3dgraphy[rdf-embedded,sync,visualization]; extra == "full"
|
|
61
65
|
Provides-Extra: all
|
|
62
|
-
Requires-Dist: s3dgraphy[dev,docs,full]; extra == "all"
|
|
66
|
+
Requires-Dist: s3dgraphy[dev,docs,full,postgres]; extra == "all"
|
|
63
67
|
Dynamic: license-file
|
|
64
68
|
|
|
65
69
|
# s3dgraphy
|
|
@@ -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"
|
|
@@ -92,6 +92,20 @@ visualization = [
|
|
|
92
92
|
"matplotlib>=3.0",
|
|
93
93
|
"plotly>=5.0",
|
|
94
94
|
]
|
|
95
|
+
sync = [
|
|
96
|
+
# Backend-agnostic SQL bridge (s3dgraphy.sync) — bidirectional
|
|
97
|
+
# ingestion + projection between a Graph and the host application's
|
|
98
|
+
# SQL tables. SQLite works out of the box; add the [postgres] extra
|
|
99
|
+
# for the PostgreSQL backend. Moved from pyArchInit in 1.6.0
|
|
100
|
+
# (zalmoxes-laran/s3Dgraphy#10).
|
|
101
|
+
"sqlalchemy>=2.0",
|
|
102
|
+
]
|
|
103
|
+
postgres = [
|
|
104
|
+
# PostgreSQL backend driver. Combine with [sync] for the SQL bridge
|
|
105
|
+
# (zalmoxes-laran/s3Dgraphy#9 + #10). Standalone, it also enables
|
|
106
|
+
# the PG path of PyArchInitImporter when that lands.
|
|
107
|
+
"psycopg2-binary>=2.9",
|
|
108
|
+
]
|
|
95
109
|
dev = [
|
|
96
110
|
"pytest>=7.0",
|
|
97
111
|
"pytest-cov",
|
|
@@ -111,10 +125,10 @@ docs = [
|
|
|
111
125
|
# without the dev/docs tooling. The dev/docs/test stacks stay separate
|
|
112
126
|
# so CI-style installs don't pull editor/QA deps.
|
|
113
127
|
full = [
|
|
114
|
-
"s3dgraphy[rdf-embedded,visualization]",
|
|
128
|
+
"s3dgraphy[rdf-embedded,visualization,sync]",
|
|
115
129
|
]
|
|
116
130
|
all = [
|
|
117
|
-
"s3dgraphy[full,dev,docs]",
|
|
131
|
+
"s3dgraphy[full,dev,docs,postgres]",
|
|
118
132
|
]
|
|
119
133
|
|
|
120
134
|
[tool.setuptools.packages.find]
|
{s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/JSON_config/em_visual_rules.json
RENAMED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"formal_language": "EM",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"_changelog": {
|
|
5
|
+
"1.5.3": "Fix USD / serUSD material colour: RGB was (0.549, 0.103, 0.0) = #8C1A00 (red), should be #D86400 (orange) to match the canonical USD documentary colour used in the GraphML palette template, node_registry defaults and document_variant_styles.observable. USD border_color also corrected from #8C1A00 to #D86400 (serUSD border was already correct).",
|
|
5
6
|
"1.5.2": "Added RSF (Reused Special Find / spolia) node style — octagon, red border (#9B3333), white fill. Sibling of SF/VSF, distinguished by border colour. Originating DP: DP-26.",
|
|
6
7
|
"1.5.1": "Added LocationNodeGroup node style (dashed roundrectangle, kind-based border colour) and is_in_location edge style with primary_modifier override.",
|
|
7
8
|
"1.5.0": "Initial EM 1.5 visual rules."
|
|
@@ -133,13 +134,13 @@
|
|
|
133
134
|
"style": {
|
|
134
135
|
"material": {
|
|
135
136
|
"color": {
|
|
136
|
-
"r": 0.
|
|
137
|
-
"g": 0.
|
|
137
|
+
"r": 0.847,
|
|
138
|
+
"g": 0.392,
|
|
138
139
|
"b": 0.0,
|
|
139
140
|
"a": 1.0
|
|
140
141
|
}
|
|
141
142
|
},
|
|
142
|
-
"border_color": "#
|
|
143
|
+
"border_color": "#D86400",
|
|
143
144
|
"fill_color": "#F5F5F5",
|
|
144
145
|
"border_style": "solid",
|
|
145
146
|
"shape": "rounded_rectangle"
|
|
@@ -173,8 +174,8 @@
|
|
|
173
174
|
"style": {
|
|
174
175
|
"material": {
|
|
175
176
|
"color": {
|
|
176
|
-
"r": 0.
|
|
177
|
-
"g": 0.
|
|
177
|
+
"r": 0.847,
|
|
178
|
+
"g": 0.392,
|
|
178
179
|
"b": 0.0,
|
|
179
180
|
"a": 1.0
|
|
180
181
|
}
|
{s3dgraphy-1.6.0.dev5 → 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.dev5 → 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.dev5 → 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')
|
{s3dgraphy-1.6.0.dev5 → s3dgraphy-1.6.0.dev7}/src/s3dgraphy/exporter/graphml/node_registry.py
RENAMED
|
@@ -236,33 +236,42 @@ class NodeRegistry:
|
|
|
236
236
|
)
|
|
237
237
|
|
|
238
238
|
# Sanity-check the canonical stratigraphic types are all present.
|
|
239
|
+
# Caller paths (NodeGenerator, GraphmlPatcher) already fall back to
|
|
240
|
+
# the 'US' stencil — or to inline defaults — when a single type is
|
|
241
|
+
# missing, so we only emit a diagnostic here.
|
|
239
242
|
missing = sorted(_REQUIRED_PALETTE_TYPES - set(self.visual_properties))
|
|
240
243
|
for em_type in missing:
|
|
241
244
|
warnings.warn(
|
|
242
245
|
f"s3dgraphy: palette template did not yield a stencil "
|
|
243
|
-
f"for stratigraphic type {em_type!r}.
|
|
244
|
-
"
|
|
245
|
-
"
|
|
246
|
-
"
|
|
247
|
-
"
|
|
248
|
-
"
|
|
246
|
+
f"for stratigraphic type {em_type!r}. Callers will fall "
|
|
247
|
+
"back to the 'US' stencil. Verify that the palette "
|
|
248
|
+
"template still contains the expected NodeLabel (USM01, "
|
|
249
|
+
"USM02, USD10, USDxx ellipse for serUSD, USV100, USV102, "
|
|
250
|
+
"USV106, SF01, VSF01, RSF01, TSU) or extend "
|
|
251
|
+
"node_registry._PALETTE_DISPATCH_RULES.",
|
|
249
252
|
S3DgraphyPaletteWarning,
|
|
250
253
|
stacklevel=2,
|
|
251
254
|
)
|
|
252
|
-
if missing:
|
|
253
|
-
# Backfill the missing ones from the hardcoded defaults so
|
|
254
|
-
# callers never get None for a known stratigraphic type.
|
|
255
|
-
defaults = self._default_visual_properties_dict()
|
|
256
|
-
for em_type in missing:
|
|
257
|
-
if em_type in defaults:
|
|
258
|
-
self.visual_properties[em_type] = defaults[em_type]
|
|
259
255
|
|
|
260
256
|
except (FileNotFoundError, ModuleNotFoundError) as e:
|
|
261
|
-
|
|
262
|
-
|
|
257
|
+
# The palette template is bundled with the package — its absence
|
|
258
|
+
# is a packaging/install bug, not a runtime condition we should
|
|
259
|
+
# paper over with hardcoded constants that can silently drift
|
|
260
|
+
# from the canonical palette. Fail loud.
|
|
261
|
+
raise RuntimeError(
|
|
262
|
+
"s3dgraphy: palette template "
|
|
263
|
+
"'templates/em_palette_template.graphml' is missing from "
|
|
264
|
+
f"the installed package ({type(e).__name__}: {e}). "
|
|
265
|
+
"GraphML export cannot proceed without it — reinstall "
|
|
266
|
+
"s3dgraphy or check the package data."
|
|
267
|
+
) from e
|
|
263
268
|
except Exception as e:
|
|
264
|
-
|
|
265
|
-
|
|
269
|
+
# Same rationale: a corrupt template is a packaging issue, not
|
|
270
|
+
# something to silently swallow.
|
|
271
|
+
raise RuntimeError(
|
|
272
|
+
"s3dgraphy: failed to parse palette template "
|
|
273
|
+
f"'templates/em_palette_template.graphml': {e}"
|
|
274
|
+
) from e
|
|
266
275
|
|
|
267
276
|
def _extract_visual_properties(self, node_elem: ET.Element, ns: Dict) -> Optional[NodeVisualProperties]:
|
|
268
277
|
"""Extract visual properties from a palette node element."""
|
|
@@ -308,28 +317,6 @@ class NodeRegistry:
|
|
|
308
317
|
print(f"Warning: Error extracting visual properties: {e}")
|
|
309
318
|
return None
|
|
310
319
|
|
|
311
|
-
@staticmethod
|
|
312
|
-
def _default_visual_properties_dict() -> Dict[str, NodeVisualProperties]:
|
|
313
|
-
"""Hardcoded default visual properties (used as fallback)."""
|
|
314
|
-
return {
|
|
315
|
-
'US': NodeVisualProperties('rectangle', '#FFFFFF', '#9B3333', 'line', 4.0, '#000000'),
|
|
316
|
-
'USVs': NodeVisualProperties('parallelogram', '#000000', '#248FE7', 'line', 4.0, '#FFFFFF'),
|
|
317
|
-
'USVn': NodeVisualProperties('hexagon', '#000000', '#31792D', 'line', 4.0, '#FFFFFF'),
|
|
318
|
-
'SF': NodeVisualProperties('octagon', '#FFFFFF', '#D8BD30', 'line', 4.0, '#000000'),
|
|
319
|
-
'VSF': NodeVisualProperties('octagon', '#000000', '#B19F61', 'line', 4.0, '#FFFFFF'),
|
|
320
|
-
'RSF': NodeVisualProperties('octagon', '#FFFFFF', '#9B3333', 'line', 4.0, '#000000'),
|
|
321
|
-
'USD': NodeVisualProperties('roundrectangle', '#FFFFFF', '#D86400', 'line', 4.0, '#000000'),
|
|
322
|
-
'serSU': NodeVisualProperties('ellipse', '#FFFFFF', '#9B3333', 'line', 4.0, '#000000'),
|
|
323
|
-
'serUSD': NodeVisualProperties('ellipse', '#FFFFFF', '#D86400', 'line', 4.0, '#000000'),
|
|
324
|
-
'serUSVn': NodeVisualProperties('ellipse', '#000000', '#31792D', 'line', 4.0, '#FFFFFF'),
|
|
325
|
-
'serUSVs': NodeVisualProperties('ellipse', '#000000', '#248FE7', 'line', 4.0, '#FFFFFF'),
|
|
326
|
-
'TSU': NodeVisualProperties('roundrectangle', '#FFFFFF', '#9B3333', 'dashed', 4.0, '#000000'),
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
def _load_default_visual_properties(self):
|
|
330
|
-
"""Load hardcoded default visual properties as fallback."""
|
|
331
|
-
self.visual_properties = self._default_visual_properties_dict()
|
|
332
|
-
|
|
333
320
|
def get_visual_properties(self, node_type: str) -> Optional[NodeVisualProperties]:
|
|
334
321
|
"""
|
|
335
322
|
Get visual properties for a node type.
|
|
@@ -259,10 +259,45 @@ class _Datamodel:
|
|
|
259
259
|
return _resolve_prefixed(cidoc), None, deprecated
|
|
260
260
|
|
|
261
261
|
def get_qualia_crm_iri(self, property_type: Optional[str]) -> Optional[URIRef]:
|
|
262
|
+
"""Resolve a property_type string to its CIDOC class IRI.
|
|
263
|
+
|
|
264
|
+
Lookup strategy (graceful, three steps):
|
|
265
|
+
1. Exact match against em_qualia_types.json `id` (e.g.
|
|
266
|
+
"absolute_time_start", "height", "color").
|
|
267
|
+
2. Last segment after dot — handles EM yEd convention where
|
|
268
|
+
properties are labelled with a category prefix
|
|
269
|
+
(e.g. "Dimension.height" → "height", "Spatial.elevation" →
|
|
270
|
+
"elevation").
|
|
271
|
+
3. Lowercase match — handles minor case mismatches between
|
|
272
|
+
graphml labels and qualia ids (e.g. "Height" → "height").
|
|
273
|
+
|
|
274
|
+
Returns None if no strategy matches; the caller (typically
|
|
275
|
+
``_compute_primary_iri``) falls back to the generic PropertyNode
|
|
276
|
+
default mapping.
|
|
277
|
+
"""
|
|
262
278
|
if not property_type:
|
|
263
279
|
return None
|
|
280
|
+
# 1) Exact match
|
|
264
281
|
crm = self._qualia_class_index.get(property_type)
|
|
265
|
-
|
|
282
|
+
if crm:
|
|
283
|
+
return _resolve_prefixed(crm)
|
|
284
|
+
# 2) Last segment after dot (yEd category prefix convention)
|
|
285
|
+
if "." in property_type:
|
|
286
|
+
tail = property_type.rsplit(".", 1)[-1]
|
|
287
|
+
crm = self._qualia_class_index.get(tail)
|
|
288
|
+
if crm:
|
|
289
|
+
return _resolve_prefixed(crm)
|
|
290
|
+
# 3) Lowercase fallback
|
|
291
|
+
crm = self._qualia_class_index.get(property_type.lower())
|
|
292
|
+
if crm:
|
|
293
|
+
return _resolve_prefixed(crm)
|
|
294
|
+
# 4) Combined: lowercase last segment
|
|
295
|
+
if "." in property_type:
|
|
296
|
+
tail_lower = property_type.rsplit(".", 1)[-1].lower()
|
|
297
|
+
crm = self._qualia_class_index.get(tail_lower)
|
|
298
|
+
if crm:
|
|
299
|
+
return _resolve_prefixed(crm)
|
|
300
|
+
return None
|
|
266
301
|
|
|
267
302
|
|
|
268
303
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -521,23 +556,44 @@ class RDFExporter:
|
|
|
521
556
|
Resolve the rdf:type primary IRI for a node, applying conditional rules.
|
|
522
557
|
|
|
523
558
|
Conditional rule for PropertyNode:
|
|
524
|
-
The qualia-type-specific class (looked up in em_qualia_types.json
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
559
|
+
The qualia-type-specific class (looked up in em_qualia_types.json)
|
|
560
|
+
takes precedence over the generic PropertyNode default class
|
|
561
|
+
(typically crm:E54_Dimension). Without this, an aesthetic_value
|
|
562
|
+
property would be typed as BOTH crm:E54_Dimension (PropertyNode
|
|
563
|
+
default) and crminf:I4_Proposition_Set (qualia-specific), which is
|
|
564
|
+
semantically misleading: aesthetic value is NOT a dimension.
|
|
565
|
+
|
|
566
|
+
Lookup key resolution (PropertyNode):
|
|
567
|
+
The s3dgraphy graphml importer preserves raw graphml data
|
|
568
|
+
(``node.name`` carries the NodeLabel, ``node.property_type`` is
|
|
569
|
+
the default "string" unless populated by the
|
|
570
|
+
``_s3d_property_metadata`` side channel). To enrich at export
|
|
571
|
+
time without burdening the importer with vocabulary knowledge,
|
|
572
|
+
we try the lookup key in this order:
|
|
573
|
+
1. ``node.property_type`` if explicitly set (not "string")
|
|
574
|
+
2. ``node.name`` if available (the yEd NodeLabel — qualia
|
|
575
|
+
identifier in EM convention)
|
|
576
|
+
Either string is resolved through the multi-step graceful
|
|
577
|
+
matcher in ``_Datamodel.get_qualia_crm_iri`` (exact / dot-split
|
|
578
|
+
/ lowercase). Falls back to the generic node datamodel mapping
|
|
579
|
+
when no qualia term matches (e.g. custom labels like
|
|
580
|
+
"lenght_pipe" stay as em:Qualia + crm:E1_CRM_Entity).
|
|
535
581
|
"""
|
|
536
582
|
if node_type == "property":
|
|
537
583
|
ptype = getattr(node, "property_type", None)
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
584
|
+
# Treat the default "string" sentinel as "unset" — the importer
|
|
585
|
+
# leaves it on the PropertyNode constructor default when no
|
|
586
|
+
# side-channel metadata is present.
|
|
587
|
+
if ptype and ptype.lower() != "string":
|
|
588
|
+
qualia_iri = self.datamodel.get_qualia_crm_iri(ptype)
|
|
589
|
+
if qualia_iri is not None:
|
|
590
|
+
return qualia_iri
|
|
591
|
+
# Fall back to NodeLabel (em yEd convention: label IS the qualia id)
|
|
592
|
+
name = getattr(node, "name", None)
|
|
593
|
+
if name:
|
|
594
|
+
qualia_iri = self.datamodel.get_qualia_crm_iri(name)
|
|
595
|
+
if qualia_iri is not None:
|
|
596
|
+
return qualia_iri
|
|
541
597
|
return self.datamodel.get_node_primary_iri(cls_name)
|
|
542
598
|
|
|
543
599
|
def _serialize_type_specific(self, node: Any, node_type: Optional[str],
|
|
@@ -547,10 +603,22 @@ class RDFExporter:
|
|
|
547
603
|
if node_type == "property":
|
|
548
604
|
# rdf:type already emitted by _compute_primary_iri (qualia-specific
|
|
549
605
|
# class takes precedence over PropertyNode default).
|
|
606
|
+
#
|
|
607
|
+
# Value resolution: prefer node.value when set & non-empty;
|
|
608
|
+
# fall back to node.description for legacy graphml where the
|
|
609
|
+
# description data field encodes the value (yEd has no separate
|
|
610
|
+
# "value" socket on annotation-style PropertyNodes).
|
|
611
|
+
raw_value = getattr(node, "value", None)
|
|
612
|
+
if raw_value is None or (isinstance(raw_value, str) and not raw_value.strip()):
|
|
613
|
+
raw_value = getattr(node, "description", None)
|
|
614
|
+
if raw_value is not None and (not isinstance(raw_value, str) or raw_value.strip()):
|
|
615
|
+
ctx.add((node_iri, CRM.P90_has_value, Literal(raw_value)))
|
|
616
|
+
|
|
617
|
+
# Qualia type identifier — same key resolution as _compute_primary_iri:
|
|
618
|
+
# property_type if non-default, otherwise the NodeLabel (name).
|
|
550
619
|
ptype = getattr(node, "property_type", None)
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
ctx.add((node_iri, CRM.P90_has_value, Literal(value)))
|
|
620
|
+
if not ptype or ptype.lower() == "string":
|
|
621
|
+
ptype = getattr(node, "name", None)
|
|
554
622
|
if ptype:
|
|
555
623
|
ctx.add((node_iri, EM.hasQualiaType, Literal(ptype)))
|
|
556
624
|
|