smart-spatial-system 0.2.4__tar.gz → 0.2.5__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.
Files changed (436) hide show
  1. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/PKG-INFO +48 -1
  2. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/README.md +47 -0
  3. smart_spatial_system-0.2.5/config/plugins/ring_buffer_analysis.example.yaml +16 -0
  4. smart_spatial_system-0.2.5/config/plugins/ring_buffer_analysis.yaml +16 -0
  5. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/llm_spec_generator.py +9 -0
  6. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/op_catalog.py +35 -0
  7. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/plugin_modules.py +1 -0
  8. smart_spatial_system-0.2.5/plugins/ring_buffer_analysis.py +409 -0
  9. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/pyproject.toml +1 -1
  10. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system.egg-info/PKG-INFO +48 -1
  11. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system.egg-info/SOURCES.txt +4 -0
  12. smart_spatial_system-0.2.5/tests/test_ring_buffer_analysis.py +191 -0
  13. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/LICENSE +0 -0
  14. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/__init__.py +0 -0
  15. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/auth.py +0 -0
  16. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/main.py +0 -0
  17. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/routers/__init__.py +0 -0
  18. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/routers/data_source_connectors.py +0 -0
  19. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/routers/data_sources.py +0 -0
  20. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/routers/plugins_settings.py +0 -0
  21. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/routers/projects.py +0 -0
  22. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/routers/query_planner.py +0 -0
  23. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/routers/requests_outputs.py +0 -0
  24. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/routers/system.py +0 -0
  25. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/routers/uploads.py +0 -0
  26. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/routers/weights.py +0 -0
  27. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/api/support.py +0 -0
  28. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/__init__.py +0 -0
  29. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/__init__.py +0 -0
  30. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/area_perimeter_calc.example.yaml +0 -0
  31. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/area_perimeter_calc.yaml +0 -0
  32. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/attribute_statistics.example.yaml +0 -0
  33. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/attribute_statistics.yaml +0 -0
  34. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/band_math.example.yaml +0 -0
  35. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/band_math.yaml +0 -0
  36. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/buffer_analysis.example.yaml +0 -0
  37. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/buffer_analysis.yaml +0 -0
  38. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/centroid_extractor.example.yaml +0 -0
  39. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/centroid_extractor.yaml +0 -0
  40. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/core_vector.example.yaml +0 -0
  41. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/core_vector.yaml +0 -0
  42. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/crs_transformer.example.yaml +0 -0
  43. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/crs_transformer.yaml +0 -0
  44. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/data_writer_exporter.example.yaml +0 -0
  45. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/data_writer_exporter.yaml +0 -0
  46. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/dissolve_aggregator.example.yaml +0 -0
  47. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/dissolve_aggregator.yaml +0 -0
  48. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/distance_calculator.example.yaml +0 -0
  49. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/distance_calculator.yaml +0 -0
  50. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/feature_enrichment.example.yaml +0 -0
  51. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/feature_enrichment.yaml +0 -0
  52. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/feature_scoring.example.yaml +0 -0
  53. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/feature_scoring.yaml +0 -0
  54. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/geocoding_resolver.example.yaml +0 -0
  55. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/geocoding_resolver.yaml +0 -0
  56. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/geometry_validator.example.yaml +0 -0
  57. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/geometry_validator.yaml +0 -0
  58. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/local_raster_loader.example.yaml +0 -0
  59. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/local_raster_loader.yaml +0 -0
  60. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/local_vector_loader.example.yaml +0 -0
  61. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/local_vector_loader.yaml +0 -0
  62. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/ndvi_calculator.example.yaml +0 -0
  63. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/ndvi_calculator.yaml +0 -0
  64. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/nearest_neighbor.example.yaml +0 -0
  65. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/nearest_neighbor.yaml +0 -0
  66. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/postgis_connector.example.yaml +0 -0
  67. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/postgis_connector.yaml +0 -0
  68. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/raster_clip_mask.example.yaml +0 -0
  69. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/raster_clip_mask.yaml +0 -0
  70. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/raster_reclassify.example.yaml +0 -0
  71. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/raster_reclassify.yaml +0 -0
  72. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/raster_statistics.example.yaml +0 -0
  73. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/raster_statistics.yaml +0 -0
  74. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/raster_threshold.example.yaml +0 -0
  75. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/raster_threshold.yaml +0 -0
  76. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/raster_to_vector.example.yaml +0 -0
  77. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/raster_to_vector.yaml +0 -0
  78. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/risk_enrichment.example.yaml +0 -0
  79. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/risk_enrichment.yaml +0 -0
  80. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/slope_aspect.yaml +0 -0
  81. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/spatial_intersection.example.yaml +0 -0
  82. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/spatial_intersection.yaml +0 -0
  83. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/spatial_join.example.yaml +0 -0
  84. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/spatial_join.yaml +0 -0
  85. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/spatial_predicate.example.yaml +0 -0
  86. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/spatial_predicate.yaml +0 -0
  87. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/spatial_query_filter.example.yaml +0 -0
  88. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/spatial_query_filter.yaml +0 -0
  89. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/spectral_indices.example.yaml +0 -0
  90. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/spectral_indices.yaml +0 -0
  91. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/wms_wfs_fetcher.example.yaml +0 -0
  92. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/wms_wfs_fetcher.yaml +0 -0
  93. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/zonal_statistics.example.yaml +0 -0
  94. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/config/plugins/zonal_statistics.yaml +0 -0
  95. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/__init__.py +0 -0
  96. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/audit.py +0 -0
  97. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/capability_registry.py +0 -0
  98. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/capability_router.py +0 -0
  99. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/capability_scoring.py +0 -0
  100. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/data_source_service.py +0 -0
  101. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/error_contract.py +0 -0
  102. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/feedback.py +0 -0
  103. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/feedback_proposal_service.py +0 -0
  104. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/input_error_mapping.py +0 -0
  105. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/input_reference_resolver.py +0 -0
  106. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/kernel_artifacts.py +0 -0
  107. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/learning_signals.py +0 -0
  108. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/llm_client.py +0 -0
  109. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/llm_gate.py +0 -0
  110. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/llm_intent_planner.py +0 -0
  111. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/loader_plugin_contract.py +0 -0
  112. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/map_layer_service.py +0 -0
  113. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/map_layers.py +0 -0
  114. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/models.py +0 -0
  115. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/natural_query_runner.py +0 -0
  116. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/output_service.py +0 -0
  117. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/output_storage.py +0 -0
  118. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/pipeline_executor.py +0 -0
  119. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/plan_builder.py +0 -0
  120. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/__init__.py +0 -0
  121. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/capability_resolver.py +0 -0
  122. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/dag.py +0 -0
  123. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/dag_executor.py +0 -0
  124. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/error_mapping.py +0 -0
  125. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/kernel_execution_bridge.py +0 -0
  126. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/kernel_plan_adapter.py +0 -0
  127. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/llm_query_spec.py +0 -0
  128. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/output_parity.py +0 -0
  129. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/planner.py +0 -0
  130. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/postgis_semantic_resolver.py +0 -0
  131. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/query_spec_contract.py +0 -0
  132. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/report_spec.py +0 -0
  133. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/runner.py +0 -0
  134. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/semantic_planning_context.py +0 -0
  135. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/planning/spec.py +0 -0
  136. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/plugin_config_store.py +0 -0
  137. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/plugin_error_mapping.py +0 -0
  138. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/plugin_runtime_service.py +0 -0
  139. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/plugin_state.py +0 -0
  140. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/production_response.py +0 -0
  141. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/project_service.py +0 -0
  142. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/project_store.py +0 -0
  143. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/provider_error_mapping.py +0 -0
  144. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/query_execution_service.py +0 -0
  145. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/query_parser.py +0 -0
  146. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/request_history_service.py +0 -0
  147. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/response_assembler.py +0 -0
  148. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/response_builder.py +0 -0
  149. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/router_decision.py +0 -0
  150. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/routing_aware_natural_query_runner.py +0 -0
  151. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/routing_aware_plan_builder.py +0 -0
  152. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/runtime_paths.py +0 -0
  153. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/service.py +0 -0
  154. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/statistics.py +0 -0
  155. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/upload_service.py +0 -0
  156. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/upload_storage.py +0 -0
  157. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/weight_proposals.py +0 -0
  158. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/weight_store_persistence.py +0 -0
  159. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/orchestrator/weighted_router.py +0 -0
  160. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/__init__.py +0 -0
  161. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/_shared/__init__.py +0 -0
  162. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/_shared/local_path_validation.py +0 -0
  163. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/_shared/numeric_validation.py +0 -0
  164. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/_shared/plugin_config.py +0 -0
  165. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/area_perimeter_calc.py +0 -0
  166. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/attribute_statistics.py +0 -0
  167. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/band_math.py +0 -0
  168. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/buffer_analysis.py +0 -0
  169. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/centroid_extractor.py +0 -0
  170. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/core_vector.py +0 -0
  171. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/crs_transformer.py +0 -0
  172. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/data_writer_exporter.py +0 -0
  173. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/dissolve_aggregator.py +0 -0
  174. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/distance_calculator.py +0 -0
  175. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/feature_enrichment.py +0 -0
  176. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/feature_scoring.py +0 -0
  177. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/geocoding_resolver.py +0 -0
  178. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/geometry_validator.py +0 -0
  179. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/local_raster_loader.py +0 -0
  180. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/local_vector_loader.py +0 -0
  181. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/ndvi_analysis.py +0 -0
  182. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/ndvi_calculator.py +0 -0
  183. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/nearest_neighbor.py +0 -0
  184. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/pdf_renderer.py +0 -0
  185. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/postgis_connector.py +0 -0
  186. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/raster_clip_mask.py +0 -0
  187. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/raster_reclassify.py +0 -0
  188. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/raster_statistics.py +0 -0
  189. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/raster_threshold.py +0 -0
  190. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/raster_to_vector.py +0 -0
  191. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/real_estate_scoring.py +0 -0
  192. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/real_estate_spatial_enrichment.py +0 -0
  193. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/report_builder.py +0 -0
  194. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/risk_enrichment.py +0 -0
  195. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/slope_aspect.py +0 -0
  196. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/spatial_intersection.py +0 -0
  197. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/spatial_join.py +0 -0
  198. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/spatial_predicate.py +0 -0
  199. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/spatial_query_filter.py +0 -0
  200. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/spectral_indices.py +0 -0
  201. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/wms_wfs_fetcher.py +0 -0
  202. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/plugins/zonal_statistics.py +0 -0
  203. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/setup.cfg +0 -0
  204. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/__init__.py +0 -0
  205. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/__main__.py +0 -0
  206. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/__init__.py +0 -0
  207. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/__init__.py +0 -0
  208. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/data_source_service.py +0 -0
  209. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/feedback_proposal_service.py +0 -0
  210. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/llm_intent_adapter.py +0 -0
  211. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/map_layer_service.py +0 -0
  212. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/output_service.py +0 -0
  213. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/planning_execution_policy.py +0 -0
  214. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/planning_response_adapter.py +0 -0
  215. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/plugin_runtime_service.py +0 -0
  216. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/project_service.py +0 -0
  217. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/__init__.py +0 -0
  218. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/accessibility_query_spec.py +0 -0
  219. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/direct_query_dispatch.py +0 -0
  220. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/natural_query_context.py +0 -0
  221. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/natural_query_dispatch.py +0 -0
  222. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/natural_query_execution.py +0 -0
  223. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/natural_query_failure.py +0 -0
  224. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/natural_query_persistence.py +0 -0
  225. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/planning_context.py +0 -0
  226. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/planning_execution.py +0 -0
  227. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/planning_persistence.py +0 -0
  228. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/planning_response.py +0 -0
  229. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/postgis_planning_context.py +0 -0
  230. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_analysis_inspector.py +0 -0
  231. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_classifier.py +0 -0
  232. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_context.py +0 -0
  233. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_document_renderer.py +0 -0
  234. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_missing_inputs.py +0 -0
  235. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_ranking_artifacts.py +0 -0
  236. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_ranking_direct_handler.py +0 -0
  237. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_ranking_execution.py +0 -0
  238. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_ranking_query_spec.py +0 -0
  239. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_ranking_response.py +0 -0
  240. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_report_payload.py +0 -0
  241. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution/real_estate_scoring.py +0 -0
  242. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_execution_service.py +0 -0
  243. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/query_spec_enrichment.py +0 -0
  244. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/real_estate_spatial_helpers.py +0 -0
  245. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/request_history_service.py +0 -0
  246. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/system_status_query_handler.py +0 -0
  247. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/upload_service.py +0 -0
  248. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/vector_display_handler.py +0 -0
  249. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/vector_geojson_helpers.py +0 -0
  250. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/application/services/vector_query_classifier.py +0 -0
  251. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/cli.py +0 -0
  252. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/domain/__init__.py +0 -0
  253. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/domain/contracts/__init__.py +0 -0
  254. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/domain/models/__init__.py +0 -0
  255. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/infrastructure/__init__.py +0 -0
  256. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/infrastructure/stores/__init__.py +0 -0
  257. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/interfaces/__init__.py +0 -0
  258. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/interfaces/api/__init__.py +0 -0
  259. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/interfaces/api/routers/__init__.py +0 -0
  260. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/plugins/__init__.py +0 -0
  261. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/runtime/__init__.py +0 -0
  262. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/shared/__init__.py +0 -0
  263. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/workflows/__init__.py +0 -0
  264. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/workflows/ndvi/__init__.py +0 -0
  265. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system/workflows/real_estate/__init__.py +0 -0
  266. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system.egg-info/dependency_links.txt +0 -0
  267. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system.egg-info/entry_points.txt +0 -0
  268. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system.egg-info/requires.txt +0 -0
  269. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/smart_spatial_system.egg-info/top_level.txt +0 -0
  270. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/templates/__init__.py +0 -0
  271. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/templates/reports/__init__.py +0 -0
  272. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/templates/reports/real_estate_report.html +0 -0
  273. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_accessibility_query_spec.py +0 -0
  274. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_api_auth.py +0 -0
  275. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_api_contract_smoke.py +0 -0
  276. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_api_data_source_connectors_e2e.py +0 -0
  277. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_api_map_layers.py +0 -0
  278. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_api_mvp.py +0 -0
  279. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_api_outputs.py +0 -0
  280. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_api_projects.py +0 -0
  281. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_api_structured_error_normalization.py +0 -0
  282. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_api_upload_plugin_resolver.py +0 -0
  283. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_api_uploads.py +0 -0
  284. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_area_perimeter_calc.py +0 -0
  285. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_attribute_statistics.py +0 -0
  286. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_band_math.py +0 -0
  287. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_buffer_analysis.py +0 -0
  288. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_centroid_extractor.py +0 -0
  289. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_cli.py +0 -0
  290. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_crs_transformer.py +0 -0
  291. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_data_source_service.py +0 -0
  292. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_data_writer_exporter.py +0 -0
  293. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_deterministic_planner.py +0 -0
  294. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_dissolve_aggregator.py +0 -0
  295. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_distance_calculator.py +0 -0
  296. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_document_file_report_contract.py +0 -0
  297. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_end_to_end_natural_query_pipeline.py +0 -0
  298. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_error_contract.py +0 -0
  299. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_feature_enrichment.py +0 -0
  300. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_feature_scoring.py +0 -0
  301. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_frontend_api_surface_contract.py +0 -0
  302. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_geocoding_resolver.py +0 -0
  303. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_geocoding_resolver_error_redaction.py +0 -0
  304. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_geometry_validator.py +0 -0
  305. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_input_error_mapping.py +0 -0
  306. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_input_reference_resolver.py +0 -0
  307. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_input_reference_resolver_contract.py +0 -0
  308. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_kernel_artifacts.py +0 -0
  309. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_kernel_execution_bridge.py +0 -0
  310. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_kernel_plan_adapter.py +0 -0
  311. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_llm_intent_adapter.py +0 -0
  312. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_llm_raster_queryspec_normalization.py +0 -0
  313. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_llm_spec_generator.py +0 -0
  314. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_llm_spec_generator_prenormalize.py +0 -0
  315. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_llm_spec_generator_semantic_context.py +0 -0
  316. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_llm_spec_generator_semantic_query_database_enrich.py +0 -0
  317. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_llm_spec_generator_semantic_queryspec_repair.py +0 -0
  318. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_loader_plugin_contract.py +0 -0
  319. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_local_path_validation.py +0 -0
  320. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_local_raster_loader.py +0 -0
  321. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_local_raster_loader_contract.py +0 -0
  322. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_local_vector_loader.py +0 -0
  323. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_local_vector_loader_contract.py +0 -0
  324. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_map_layer_contract.py +0 -0
  325. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_map_layer_service.py +0 -0
  326. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_ndvi_calculator.py +0 -0
  327. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_nearest_neighbor.py +0 -0
  328. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_numeric_validation.py +0 -0
  329. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_op_catalog_semantic_aliases.py +0 -0
  330. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_audit.py +0 -0
  331. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_audit_integration.py +0 -0
  332. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_data_source_service_integration.py +0 -0
  333. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_feedback.py +0 -0
  334. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_feedback_integration.py +0 -0
  335. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_keyword_scoring_router.py +0 -0
  336. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_learning_signals.py +0 -0
  337. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_learning_signals_integration.py +0 -0
  338. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_llm_gate.py +0 -0
  339. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_llm_gate_integration.py +0 -0
  340. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_map_layer_service_integration.py +0 -0
  341. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_natural_query_pipeline.py +0 -0
  342. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_output_service_integration.py +0 -0
  343. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_production_response.py +0 -0
  344. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_production_response_integration.py +0 -0
  345. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_project_service_integration.py +0 -0
  346. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_query_execution_service_integration.py +0 -0
  347. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_registry_router.py +0 -0
  348. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_router_decision.py +0 -0
  349. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_router_decision_integration.py +0 -0
  350. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_routing_aware_plan_builder.py +0 -0
  351. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_runtime_paths.py +0 -0
  352. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_service.py +0 -0
  353. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_service_domain_boundary_contract.py +0 -0
  354. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_service_integration.py +0 -0
  355. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_service_postgis_dedup_contract.py +0 -0
  356. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_statistics.py +0 -0
  357. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_statistics_integration.py +0 -0
  358. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_upload_service_integration.py +0 -0
  359. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_weight_proposals.py +0 -0
  360. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_weight_proposals_integration.py +0 -0
  361. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_weight_store_persistence.py +0 -0
  362. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_weight_store_persistence_integration.py +0 -0
  363. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_weighted_router.py +0 -0
  364. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_orchestrator_weighted_router_integration.py +0 -0
  365. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_output_service.py +0 -0
  366. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_output_storage.py +0 -0
  367. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_pdf_renderer.py +0 -0
  368. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_phase3_kernel_registry_coverage.py +0 -0
  369. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_phase3_output_parity.py +0 -0
  370. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_phase3_postgis_provider_kernel_execution.py +0 -0
  371. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_planning_dag_executor.py +0 -0
  372. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_planning_dag_executor_async_capability.py +0 -0
  373. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_planning_error_mapping.py +0 -0
  374. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_planning_execution_policy.py +0 -0
  375. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_planning_raster_op_catalog_mapping.py +0 -0
  376. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_planning_raster_queryspec_execution.py +0 -0
  377. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_planning_registry_backed_raster_execution.py +0 -0
  378. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_planning_registry_backed_real_estate_execution.py +0 -0
  379. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_planning_runner.py +0 -0
  380. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_plugin_boundary_contract.py +0 -0
  381. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_plugin_config.py +0 -0
  382. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_plugin_config_store.py +0 -0
  383. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_plugin_error_mapping.py +0 -0
  384. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_plugin_modules.py +0 -0
  385. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_postgis_connector.py +0 -0
  386. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_postgis_connector_percent_escape.py +0 -0
  387. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_postgis_semantic_resolver.py +0 -0
  388. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_project_service.py +0 -0
  389. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_project_store.py +0 -0
  390. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_provider_error_mapping.py +0 -0
  391. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_query_dispatch_domain_boundary_contract.py +0 -0
  392. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_query_execution_postgis_planning_context.py +0 -0
  393. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_query_execution_service.py +0 -0
  394. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_query_execution_service_domain_import_boundary_contract.py +0 -0
  395. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_query_response_shape_golden.py +0 -0
  396. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_query_spec_enrichment.py +0 -0
  397. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_raster_capability_registry_contract.py +0 -0
  398. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_raster_clip_mask.py +0 -0
  399. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_raster_reclassify.py +0 -0
  400. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_raster_statistics.py +0 -0
  401. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_raster_threshold.py +0 -0
  402. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_raster_to_vector.py +0 -0
  403. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_real_estate_ranking_bridge.py +0 -0
  404. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_real_estate_ranking_golden.py +0 -0
  405. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_real_estate_ranking_query_spec_planning.py +0 -0
  406. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_real_estate_scoring_plugin.py +0 -0
  407. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_real_estate_spatial_enrichment_plugin.py +0 -0
  408. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_real_estate_spatial_helpers.py +0 -0
  409. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_report_builder.py +0 -0
  410. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_report_spec.py +0 -0
  411. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_request_document_download_contract.py +0 -0
  412. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_response_assembler.py +0 -0
  413. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_response_output_contract.py +0 -0
  414. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_risk_enrichment.py +0 -0
  415. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_runtime_paths.py +0 -0
  416. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_semantic_planning_context.py +0 -0
  417. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_service_auto_postgis_semantic_context.py +0 -0
  418. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_service_planning_artifacts.py +0 -0
  419. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_service_postgis_runtime_connection_injection.py +0 -0
  420. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_service_semantic_planning_context.py +0 -0
  421. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_service_strict_loader_contract.py +0 -0
  422. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_service_structured_error_normalization.py +0 -0
  423. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_slope_aspect.py +0 -0
  424. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_spatial_intersection.py +0 -0
  425. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_spatial_join.py +0 -0
  426. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_spatial_query_filter.py +0 -0
  427. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_spectral_indices.py +0 -0
  428. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_system_status_query_handler.py +0 -0
  429. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_upload_service.py +0 -0
  430. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_upload_storage.py +0 -0
  431. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_vector_display_handler.py +0 -0
  432. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_vector_geojson_helpers.py +0 -0
  433. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_vector_query_classifier.py +0 -0
  434. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_wms_wfs_fetcher.py +0 -0
  435. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_wms_wfs_fetcher_error_redaction.py +0 -0
  436. {smart_spatial_system-0.2.4 → smart_spatial_system-0.2.5}/tests/test_zonal_statistics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: smart_spatial_system
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: Plugin-based GeoAI backend: natural-language questions become QuerySpecs, DAG plans, and map/table/report outputs.
5
5
  Author: Araz Shah
6
6
  License-Expression: MIT
@@ -49,14 +49,48 @@ Dynamic: license-file
49
49
 
50
50
  # Smart Spatial System
51
51
 
52
+ [![PyPI](https://img.shields.io/pypi/v/smart-spatial-system)](https://pypi.org/project/smart-spatial-system/)
53
+ [![CI](https://github.com/arazshah/smart_spatial_system/actions/workflows/ci.yml/badge.svg)](https://github.com/arazshah/smart_spatial_system/actions/workflows/ci.yml)
54
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
55
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue)](pyproject.toml)
56
+
52
57
  **Ask a geospatial question in plain language and get map layers, tables, reports and files back.**
53
58
 
59
+ **[s3geo.com](https://s3geo.com)** — project site, plugin catalog and case-study index.
60
+
54
61
  Smart Spatial System is a plugin-based GeoAI backend with a React workbench. A question such as *"rank these candidate properties by distance to metro stations, malls and main roads"* is turned into a structured `QuerySpec`, planned as a DAG of spatial operations, executed by plugins against uploaded files or PostGIS, and returned as map-ready outputs with a full execution trace.
55
62
 
63
+ ![Running the rule-based accessibility example end to end: the planned DAG, then the ranked output](docs/assets/demo.gif)
64
+
65
+ Real, unedited terminal output from [`examples/accessibility_analysis.py`](examples/accessibility_analysis.py) — no server, no LLM, deterministic by construction. Run it yourself after installing below.
66
+
56
67
  It is the application built on top of [geochat-platform](https://github.com/arazshah/geochat-platform): plugins are written with `geochat_sdk` and executed through `geochat_kernel`.
57
68
 
58
69
  > **Status:** published and usable, still refactoring internally. Logic is moving out of `orchestrator/` into the layered `smart_spatial_system/` package (see [docs/ARCHITECTURE_TARGET.md](docs/ARCHITECTURE_TARGET.md)); the `orchestrator/*_service.py` modules are compatibility shims during that move. The public surface - the CLI, the HTTP API and the documented entry points below - is stable.
59
70
 
71
+ ## Why this, not a general-purpose LLM agent with a GIS tool belt
72
+
73
+ The natural alternative is: give an LLM function-calling access to some GIS
74
+ functions and let it decide what to call. This project deliberately doesn't
75
+ stop there, for reasons that turned out to matter in practice, not just in
76
+ theory - see [`smart-spatial-vienna-accessibility`](https://github.com/arazshah/smart-spatial-vienna-accessibility)'s
77
+ case study and [`CHANGELOG.md`](CHANGELOG.md)'s `0.2.1`-`0.2.4` entries for
78
+ five real bugs this surfaced and fixed:
79
+
80
+ - **A deterministic path exists alongside the LLM path**, built from the same
81
+ operation catalog (`OP_CATALOG`). The same analysis can be run by rule and
82
+ by LLM, so "is the LLM's plan reliable" is a measurable question (Plan
83
+ Agreement Rate, Rank Stability - see [docs/CASE_STUDIES.md](docs/CASE_STUDIES.md)), not
84
+ a leap of faith.
85
+ - **Every LLM-generated plan is validated before execution**, not just before
86
+ syntax errors: missing input roles, an unchained multi-factor scoring step,
87
+ an asymmetric CRS reprojection, an untyped scoring factor - each is a
88
+ distinct, previously-silent failure mode this system now catches and raises
89
+ a specific error for, before spending a single second executing.
90
+ - **Every plugin carries a full execution trace** - which operations ran, in
91
+ what order, with what parameters - so a wrong answer is debuggable, not a
92
+ black box.
93
+
60
94
  ---
61
95
 
62
96
  ## How a query runs
@@ -265,6 +299,15 @@ Full deployment guide - environment variables, authentication, CORS, PostGIS:
265
299
 
266
300
  Full request and response contracts are in [docs/phase5_query_api_contract.md](docs/phase5_query_api_contract.md) and the other `docs/phase5_*` files.
267
301
 
302
+ ## Research and case studies
303
+
304
+ Looking for a study to build on this system, or to see one already done?
305
+ [docs/CASE_STUDIES.md](docs/CASE_STUDIES.md) has a catalog of suggested
306
+ studies (accessibility, risk-aware siting, vegetation change, zoning
307
+ compliance, and a reproducibility-methodology replication) plus what's
308
+ *not* a good fit yet. If you use this software in published work, see
309
+ [CITATION.cff](CITATION.cff).
310
+
268
311
  ## Development
269
312
 
270
313
  ```bash
@@ -272,6 +315,10 @@ pytest # full suite
272
315
  ruff check . # lint
273
316
  ```
274
317
 
318
+ Contributions are welcome - see [CONTRIBUTING.md](CONTRIBUTING.md). Found a
319
+ security issue? See [SECURITY.md](SECURITY.md) rather than opening a public
320
+ issue.
321
+
275
322
  ## Author
276
323
 
277
324
  [Araz Shahkarami](https://github.com/arazshah) · [araz.me](https://araz.me)
@@ -1,13 +1,47 @@
1
1
  # Smart Spatial System
2
2
 
3
+ [![PyPI](https://img.shields.io/pypi/v/smart-spatial-system)](https://pypi.org/project/smart-spatial-system/)
4
+ [![CI](https://github.com/arazshah/smart_spatial_system/actions/workflows/ci.yml/badge.svg)](https://github.com/arazshah/smart_spatial_system/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue)](pyproject.toml)
7
+
3
8
  **Ask a geospatial question in plain language and get map layers, tables, reports and files back.**
4
9
 
10
+ **[s3geo.com](https://s3geo.com)** — project site, plugin catalog and case-study index.
11
+
5
12
  Smart Spatial System is a plugin-based GeoAI backend with a React workbench. A question such as *"rank these candidate properties by distance to metro stations, malls and main roads"* is turned into a structured `QuerySpec`, planned as a DAG of spatial operations, executed by plugins against uploaded files or PostGIS, and returned as map-ready outputs with a full execution trace.
6
13
 
14
+ ![Running the rule-based accessibility example end to end: the planned DAG, then the ranked output](docs/assets/demo.gif)
15
+
16
+ Real, unedited terminal output from [`examples/accessibility_analysis.py`](examples/accessibility_analysis.py) — no server, no LLM, deterministic by construction. Run it yourself after installing below.
17
+
7
18
  It is the application built on top of [geochat-platform](https://github.com/arazshah/geochat-platform): plugins are written with `geochat_sdk` and executed through `geochat_kernel`.
8
19
 
9
20
  > **Status:** published and usable, still refactoring internally. Logic is moving out of `orchestrator/` into the layered `smart_spatial_system/` package (see [docs/ARCHITECTURE_TARGET.md](docs/ARCHITECTURE_TARGET.md)); the `orchestrator/*_service.py` modules are compatibility shims during that move. The public surface - the CLI, the HTTP API and the documented entry points below - is stable.
10
21
 
22
+ ## Why this, not a general-purpose LLM agent with a GIS tool belt
23
+
24
+ The natural alternative is: give an LLM function-calling access to some GIS
25
+ functions and let it decide what to call. This project deliberately doesn't
26
+ stop there, for reasons that turned out to matter in practice, not just in
27
+ theory - see [`smart-spatial-vienna-accessibility`](https://github.com/arazshah/smart-spatial-vienna-accessibility)'s
28
+ case study and [`CHANGELOG.md`](CHANGELOG.md)'s `0.2.1`-`0.2.4` entries for
29
+ five real bugs this surfaced and fixed:
30
+
31
+ - **A deterministic path exists alongside the LLM path**, built from the same
32
+ operation catalog (`OP_CATALOG`). The same analysis can be run by rule and
33
+ by LLM, so "is the LLM's plan reliable" is a measurable question (Plan
34
+ Agreement Rate, Rank Stability - see [docs/CASE_STUDIES.md](docs/CASE_STUDIES.md)), not
35
+ a leap of faith.
36
+ - **Every LLM-generated plan is validated before execution**, not just before
37
+ syntax errors: missing input roles, an unchained multi-factor scoring step,
38
+ an asymmetric CRS reprojection, an untyped scoring factor - each is a
39
+ distinct, previously-silent failure mode this system now catches and raises
40
+ a specific error for, before spending a single second executing.
41
+ - **Every plugin carries a full execution trace** - which operations ran, in
42
+ what order, with what parameters - so a wrong answer is debuggable, not a
43
+ black box.
44
+
11
45
  ---
12
46
 
13
47
  ## How a query runs
@@ -216,6 +250,15 @@ Full deployment guide - environment variables, authentication, CORS, PostGIS:
216
250
 
217
251
  Full request and response contracts are in [docs/phase5_query_api_contract.md](docs/phase5_query_api_contract.md) and the other `docs/phase5_*` files.
218
252
 
253
+ ## Research and case studies
254
+
255
+ Looking for a study to build on this system, or to see one already done?
256
+ [docs/CASE_STUDIES.md](docs/CASE_STUDIES.md) has a catalog of suggested
257
+ studies (accessibility, risk-aware siting, vegetation change, zoning
258
+ compliance, and a reproducibility-methodology replication) plus what's
259
+ *not* a good fit yet. If you use this software in published work, see
260
+ [CITATION.cff](CITATION.cff).
261
+
219
262
  ## Development
220
263
 
221
264
  ```bash
@@ -223,6 +266,10 @@ pytest # full suite
223
266
  ruff check . # lint
224
267
  ```
225
268
 
269
+ Contributions are welcome - see [CONTRIBUTING.md](CONTRIBUTING.md). Found a
270
+ security issue? See [SECURITY.md](SECURITY.md) rather than opening a public
271
+ issue.
272
+
226
273
  ## Author
227
274
 
228
275
  [Araz Shahkarami](https://github.com/arazshah) · [araz.me](https://araz.me)
@@ -0,0 +1,16 @@
1
+ default_distances: null
2
+ default_units: m
3
+ default_quad_segs: 8
4
+ default_engine: auto
5
+
6
+ preserve_properties: true
7
+
8
+ allowed_geometry_types:
9
+ - Point
10
+ - MultiPoint
11
+ - LineString
12
+ - MultiLineString
13
+ - Polygon
14
+ - MultiPolygon
15
+
16
+ metadata: {}
@@ -0,0 +1,16 @@
1
+ default_distances: null
2
+ default_units: m
3
+ default_quad_segs: 8
4
+ default_engine: auto
5
+
6
+ preserve_properties: true
7
+
8
+ allowed_geometry_types:
9
+ - Point
10
+ - MultiPoint
11
+ - LineString
12
+ - MultiLineString
13
+ - Polygon
14
+ - MultiPolygon
15
+
16
+ metadata: {}
@@ -1047,6 +1047,15 @@ Important mappings:
1047
1047
  inputs={{"vector": "<source>", "reference": "<poi>"}}
1048
1048
  params={{"max_distance_m": X, "k": 1, "drop_unmatched": true}}
1049
1049
 
1050
+ - "multiple rings/distance bands around a point/line/polygon" (e.g.
1051
+ "200m, 500m and 800m rings around each station", concentric zones, a
1052
+ gradient outward from a feature):
1053
+ use op="ring_buffer" with params={{"distances": [200, 500, 800]}} - do
1054
+ NOT chain op="buffer" multiple times for this. Chaining buffer only ever
1055
+ produces nested full-circle disks (each one containing all the smaller
1056
+ ones), never the annulus/gap BETWEEN two radii, which is what "ring" or
1057
+ "band" means here.
1058
+
1050
1059
  - "inside permitted/buildable polygon":
1051
1060
  op="filter_points_in_polygon"
1052
1061
  inputs={{"vector": "<points>", "polygon": "<polygon_layer>"}}
@@ -129,6 +129,17 @@ _BUFFER_PARAM_MAP = {
129
129
  "metadata": "metadata",
130
130
  }
131
131
 
132
+ _RING_BUFFER_PARAM_MAP = {
133
+ "distances": "distances",
134
+ "units": "units",
135
+ "quad_segs": "quad_segs",
136
+ "engine": "engine",
137
+ "cap_style": "cap_style",
138
+ "join_style": "join_style",
139
+ "mitre_limit": "mitre_limit",
140
+ "metadata": "metadata",
141
+ }
142
+
132
143
 
133
144
  OP_CATALOG: dict[str, OpDescriptor] = {
134
145
  # ---------------------------------------------------------------------
@@ -474,6 +485,30 @@ OP_CATALOG: dict[str, OpDescriptor] = {
474
485
  ),
475
486
  ),
476
487
 
488
+ "ring_buffer": OpDescriptor(
489
+ op_name="ring_buffer",
490
+ capability_name="generate_ring_buffers",
491
+ input_map={
492
+ "vector": "features",
493
+ },
494
+ input_types={
495
+ "vector": "vector",
496
+ },
497
+ param_map=_RING_BUFFER_PARAM_MAP,
498
+ output_type="vector",
499
+ notes=(
500
+ "Create concentric ring (annulus) polygons around input features at "
501
+ "multiple distances, e.g. params.distances=[200, 500, 800, 1200]. "
502
+ "Returns the area BETWEEN consecutive radii (a true ring/annulus), "
503
+ "not cumulative full-circle disks. Use this instead of chaining "
504
+ "buffer multiple times whenever the user asks for distance bands, "
505
+ "zonal rings, or a gradient outward from a point/line/polygon - "
506
+ "chaining buffer only ever produces nested full disks, never the "
507
+ "gap between two radii. Use metric CRS when distances are in "
508
+ "meters."
509
+ ),
510
+ ),
511
+
477
512
  # ---------------------------------------------------------------------
478
513
  # Raster operations
479
514
  # ---------------------------------------------------------------------
@@ -30,6 +30,7 @@ DEFAULT_SAFE_PLUGIN_MODULES = [
30
30
  "plugins.slope_aspect",
31
31
  "plugins.zonal_statistics",
32
32
  "plugins.buffer_analysis",
33
+ "plugins.ring_buffer_analysis",
33
34
  "plugins.centroid_extractor",
34
35
  "plugins.geometry_validator",
35
36
  "plugins.spatial_query_filter",
@@ -0,0 +1,409 @@
1
+ """
2
+ ring_buffer_analysis.py
3
+
4
+ GeoChat SDK Plugin
5
+ ==================
6
+
7
+ Plugin ID:
8
+ ring_buffer_analysis
9
+
10
+ Purpose:
11
+ Perform vector ring (annulus) buffer analysis on GeoJSON-like features.
12
+
13
+ Capability:
14
+ - generate_ring_buffers:
15
+ Create concentric ring polygons around vector features at multiple
16
+ distances and return VectorOut. Unlike chaining buffer_vector_features
17
+ multiple times - which only ever produces nested full-circle disks -
18
+ this capability returns the actual annulus area BETWEEN consecutive
19
+ radii, e.g. the ring between 200m and 500m, not the full 500m disk.
20
+
21
+ Config-aware behavior:
22
+ Reads config/plugins/ring_buffer_analysis.yaml.
23
+
24
+ Engines:
25
+ - shapely (or auto, when shapely is installed):
26
+ Requires shapely. Builds a real buffer() at each sorted radius and
27
+ subtracts consecutive buffers to produce true annulus geometry.
28
+ - python:
29
+ Not supported. There is no pure-python way to compute the difference
30
+ between two polygons, so this engine always raises SDKDependencyError.
31
+
32
+ Important:
33
+ GeoJSON coordinates are treated as planar coordinates. If coordinates are
34
+ longitude/latitude degrees, distance is interpreted in coordinate units unless
35
+ data has already been projected. Metadata stores the requested units, but no
36
+ CRS transformation is performed in this plugin.
37
+ """
38
+
39
+ from __future__ import annotations
40
+
41
+ from datetime import datetime, timezone
42
+ from typing import Any
43
+
44
+ from geochat_sdk.decorators import capability
45
+ from geochat_sdk.exceptions import SDKDependencyError
46
+ from geochat_sdk.plugin import auto_collect
47
+ from geochat_sdk.types.vector import VectorOut
48
+
49
+ from plugins._shared.plugin_config import (
50
+ load_plugin_config,
51
+ pick_first,
52
+ resolve_env_refs,
53
+ )
54
+ from plugins.buffer_analysis import (
55
+ _build_vector_metadata,
56
+ _configured_allowed_geometry_types,
57
+ _extract_features,
58
+ _get_shapely_tools,
59
+ _to_float,
60
+ _to_int,
61
+ _validate_geometry_type,
62
+ )
63
+
64
+ PLUGIN_ID = "ring_buffer_analysis"
65
+
66
+ VALID_ENGINES = {"auto", "shapely", "python"}
67
+
68
+ _NO_SHAPELY_MESSAGE = "ring buffers require shapely - install shapely or use engine=shapely"
69
+
70
+
71
+ def _load_ring_buffer_config() -> dict[str, Any]:
72
+ """
73
+ Load config/plugins/ring_buffer_analysis.yaml if available.
74
+ """
75
+ config = load_plugin_config(PLUGIN_ID, required=False)
76
+ if not config:
77
+ return {}
78
+ return resolve_env_refs(config)
79
+
80
+
81
+ def _utc_now_iso() -> str:
82
+ """
83
+ Return current UTC timestamp as ISO string.
84
+ """
85
+ return datetime.now(timezone.utc).isoformat()
86
+
87
+
88
+ def _validate_engine(engine: str) -> str:
89
+ """
90
+ Validate ring buffer engine.
91
+ """
92
+ if not isinstance(engine, str) or not engine.strip():
93
+ raise ValueError("engine must be a non-empty string.")
94
+
95
+ engine = engine.strip().lower()
96
+
97
+ if engine not in VALID_ENGINES:
98
+ raise ValueError(f"Unsupported engine '{engine}'. Valid engines: {sorted(VALID_ENGINES)}")
99
+
100
+ return engine
101
+
102
+
103
+ def _validate_quad_segs(value: Any) -> int:
104
+ """
105
+ Validate quad_segs.
106
+ """
107
+ quad_segs = _to_int(value, "quad_segs")
108
+
109
+ if quad_segs < 1:
110
+ raise ValueError("quad_segs must be greater than or equal to 1.")
111
+
112
+ if quad_segs > 128:
113
+ raise ValueError("quad_segs is too large. Maximum allowed value is 128.")
114
+
115
+ return quad_segs
116
+
117
+
118
+ def _validate_distances(distances: Any) -> list[float]:
119
+ """
120
+ Validate ring distances: must be a non-empty list of positive numbers,
121
+ with no duplicates. Automatically sorted ascending.
122
+ """
123
+ if not isinstance(distances, (list, tuple)) or len(distances) == 0:
124
+ raise ValueError("distances must be a non-empty list of positive numbers.")
125
+
126
+ values: list[float] = []
127
+ for item in distances:
128
+ value = _to_float(item, "distances")
129
+ if value <= 0:
130
+ raise ValueError("distances must contain only positive numbers.")
131
+ values.append(value)
132
+
133
+ if len(set(values)) != len(values):
134
+ raise ValueError("distances must not contain duplicate values.")
135
+
136
+ return sorted(values)
137
+
138
+
139
+ def _format_ring_label(inner: float, outer: float, units: str) -> str:
140
+ """
141
+ Format a ring label, e.g. "0-200m".
142
+ """
143
+
144
+ def _fmt(value: float) -> str:
145
+ if value == int(value):
146
+ return str(int(value))
147
+ return str(value)
148
+
149
+ return f"{_fmt(inner)}-{_fmt(outer)}{units}"
150
+
151
+
152
+ def _ring_geometry_shapely(
153
+ geometry: dict[str, Any] | None,
154
+ inner_distance: float,
155
+ outer_distance: float,
156
+ quad_segs: int,
157
+ cap_style: str,
158
+ join_style: str,
159
+ mitre_limit: float,
160
+ ) -> dict[str, Any] | None:
161
+ """
162
+ Build a single annulus ring geometry between inner_distance and
163
+ outer_distance using shapely. When inner_distance is 0, the ring is just
164
+ the outer buffer itself (no subtraction needed).
165
+ """
166
+ if geometry is None:
167
+ return None
168
+
169
+ shape, mapping, _ = _get_shapely_tools()
170
+
171
+ geom = shape(geometry)
172
+
173
+ def _buffer_at(distance: float):
174
+ try:
175
+ return geom.buffer(
176
+ distance,
177
+ quad_segs=quad_segs,
178
+ cap_style=cap_style,
179
+ join_style=join_style,
180
+ mitre_limit=mitre_limit,
181
+ )
182
+ except TypeError:
183
+ # Compatibility with older shapely versions.
184
+ return geom.buffer(
185
+ distance,
186
+ resolution=quad_segs,
187
+ cap_style=cap_style,
188
+ join_style=join_style,
189
+ mitre_limit=mitre_limit,
190
+ )
191
+
192
+ outer_buffer = _buffer_at(outer_distance)
193
+
194
+ if inner_distance <= 0:
195
+ ring_geom = outer_buffer
196
+ else:
197
+ inner_buffer = _buffer_at(inner_distance)
198
+ ring_geom = outer_buffer.difference(inner_buffer)
199
+
200
+ return dict(mapping(ring_geom))
201
+
202
+
203
+ @capability(
204
+ name="generate_ring_buffers",
205
+ keywords=[
206
+ "ring buffer",
207
+ "annulus",
208
+ "concentric buffer",
209
+ "multi-ring buffer",
210
+ "distance band",
211
+ "buffer zones",
212
+ "zonal buffer",
213
+ "حلقه بافر",
214
+ "بافر هم‌مرکز",
215
+ "حریم چندگانه",
216
+ "منطقه فاصله‌ای",
217
+ ],
218
+ description=(
219
+ "Create concentric ring (annulus) polygons around vector features "
220
+ "at multiple distances - the area between consecutive radii, not "
221
+ "cumulative full-circle buffers."
222
+ ),
223
+ required_inputs=["features", "distances"],
224
+ optional_inputs=[
225
+ "units",
226
+ "engine",
227
+ "quad_segs",
228
+ "cap_style",
229
+ "join_style",
230
+ "mitre_limit",
231
+ "metadata",
232
+ ],
233
+ output_kind="vector",
234
+ permissions=[],
235
+ metadata={
236
+ "category": "analysis",
237
+ "data_type": "vector",
238
+ "operation": "ring_buffer",
239
+ "returns": "VectorOut",
240
+ "artifact_kind": "features",
241
+ "access_scope": "spatial_analysis",
242
+ "config_aware": True,
243
+ "routable": True,
244
+ },
245
+ )
246
+ def generate_ring_buffers(
247
+ features: Any,
248
+ distances: list[float] | None = None,
249
+ units: str | None = None,
250
+ quad_segs: int | None = None,
251
+ engine: str | None = None,
252
+ cap_style: str | None = None,
253
+ join_style: str | None = None,
254
+ mitre_limit: float | None = None,
255
+ metadata: dict[str, Any] | None = None,
256
+ ) -> VectorOut:
257
+ """
258
+ Create concentric ring (annulus) polygons around vector features.
259
+
260
+ Args:
261
+ features:
262
+ VectorOut, list[Feature], FeatureCollection dict or single Feature dict.
263
+ distances:
264
+ List of positive ring boundary distances. Automatically sorted
265
+ ascending, so callers do not need to pre-sort. Consecutive values
266
+ define one ring each: [200, 500, 800, 1200] produces rings
267
+ 0-200, 200-500, 500-800 and 800-1200.
268
+ units:
269
+ Distance units label used in metadata and ring_label. If None,
270
+ config default_units is used.
271
+ quad_segs:
272
+ Number of segments per quarter circle.
273
+ engine:
274
+ auto | shapely | python. Only shapely (or auto when shapely is
275
+ installed) can build real annulus geometry - python always
276
+ raises SDKDependencyError.
277
+ cap_style:
278
+ Shapely cap style. Usually: round, flat, square.
279
+ join_style:
280
+ Shapely join style. Usually: round, mitre, bevel.
281
+ mitre_limit:
282
+ Shapely mitre limit.
283
+ metadata:
284
+ Optional metadata to merge into output metadata.
285
+
286
+ Returns:
287
+ VectorOut with one feature per (input feature x ring).
288
+ """
289
+ config = _load_ring_buffer_config()
290
+
291
+ final_distances = _validate_distances(
292
+ pick_first(distances, config.get("default_distances"), default=None)
293
+ )
294
+
295
+ final_units = str(pick_first(units, config.get("default_units"), default="m"))
296
+
297
+ final_quad_segs = _validate_quad_segs(
298
+ pick_first(quad_segs, config.get("default_quad_segs"), default=8)
299
+ )
300
+
301
+ final_engine = _validate_engine(
302
+ str(pick_first(engine, config.get("default_engine"), default="auto"))
303
+ )
304
+
305
+ final_cap_style = str(pick_first(cap_style, config.get("default_cap_style"), default="round"))
306
+ final_join_style = str(pick_first(join_style, config.get("default_join_style"), default="round"))
307
+ final_mitre_limit = _to_float(
308
+ pick_first(mitre_limit, config.get("default_mitre_limit"), default=5.0),
309
+ "mitre_limit",
310
+ )
311
+
312
+ if final_engine == "python":
313
+ raise SDKDependencyError(_NO_SHAPELY_MESSAGE)
314
+
315
+ try:
316
+ _get_shapely_tools()
317
+ except SDKDependencyError as exc:
318
+ raise SDKDependencyError(_NO_SHAPELY_MESSAGE) from exc
319
+
320
+ allowed_geometry_types = _configured_allowed_geometry_types(config)
321
+ preserve_properties = bool(config.get("preserve_properties", True))
322
+
323
+ input_features, source_info = _extract_features(features)
324
+
325
+ ring_boundaries = [0.0, *final_distances]
326
+
327
+ ring_features: list[dict[str, Any]] = []
328
+
329
+ for feature_index, feature in enumerate(input_features):
330
+ geometry = feature.get("geometry")
331
+ _validate_geometry_type(geometry, allowed_geometry_types)
332
+
333
+ source_properties = dict(feature.get("properties") or {}) if preserve_properties else {}
334
+
335
+ for ring_index in range(len(final_distances)):
336
+ inner = ring_boundaries[ring_index]
337
+ outer = ring_boundaries[ring_index + 1]
338
+
339
+ ring_geometry = _ring_geometry_shapely(
340
+ geometry=geometry,
341
+ inner_distance=inner,
342
+ outer_distance=outer,
343
+ quad_segs=final_quad_segs,
344
+ cap_style=final_cap_style,
345
+ join_style=final_join_style,
346
+ mitre_limit=final_mitre_limit,
347
+ )
348
+
349
+ properties = dict(source_properties)
350
+ properties["ring_index"] = ring_index
351
+ properties["ring_inner"] = inner
352
+ properties["ring_outer"] = outer
353
+ properties["ring_label"] = _format_ring_label(inner, outer, final_units)
354
+ properties["source_feature_index"] = feature_index
355
+
356
+ ring_features.append({
357
+ "type": "Feature",
358
+ "geometry": ring_geometry,
359
+ "properties": properties,
360
+ })
361
+
362
+ stats = _build_vector_metadata(ring_features)
363
+
364
+ user_metadata = metadata or {}
365
+ if not isinstance(user_metadata, dict):
366
+ raise ValueError("metadata must be a dict or None.")
367
+
368
+ output_metadata = {
369
+ "source": "ring_buffer_analysis",
370
+ "loader": PLUGIN_ID,
371
+ "operation": "ring_buffer",
372
+ "distances": final_distances,
373
+ "units": final_units,
374
+ "quad_segs": final_quad_segs,
375
+ "engine_requested": final_engine,
376
+ "cap_style": final_cap_style,
377
+ "join_style": final_join_style,
378
+ "mitre_limit": final_mitre_limit,
379
+ "input_feature_count": len(input_features),
380
+ "ring_count": len(final_distances),
381
+ "output_feature_count": len(ring_features),
382
+ "created_at": _utc_now_iso(),
383
+ "note": (
384
+ "Coordinates are treated as planar coordinates. "
385
+ "No CRS transformation is performed by this plugin."
386
+ ),
387
+ **source_info,
388
+ **stats,
389
+ **user_metadata,
390
+ }
391
+
392
+ return VectorOut(
393
+ features=ring_features,
394
+ metadata=output_metadata,
395
+ )
396
+
397
+
398
+ PLUGIN = auto_collect(
399
+ id=PLUGIN_ID,
400
+ version="1.0.0",
401
+ name="Ring Buffer Analysis",
402
+ description=(
403
+ "Creates concentric ring (annulus) polygons around vector features at "
404
+ "multiple distances - the area between consecutive radii, computed with "
405
+ "shapely difference()."
406
+ ),
407
+ author="GeoChat Platform Team",
408
+ permissions=[],
409
+ )
@@ -12,7 +12,7 @@ build-backend = "setuptools.build_meta"
12
12
  # "Open design questions" for why a namespace migration was deliberately
13
13
  # not done here.
14
14
  name = "smart_spatial_system"
15
- version = "0.2.4"
15
+ version = "0.2.5"
16
16
  description = "Plugin-based GeoAI backend: natural-language questions become QuerySpecs, DAG plans, and map/table/report outputs."
17
17
  readme = "README.md"
18
18
  requires-python = ">=3.11"