Nika provides seamless integration with PostgreSQL databases, including support for PostGIS spatial extensions, enabling you to leverage the power of spatial databases within your geospatial workflows while using Nika AI for intelligent data querying and analysis.
Nika fully supports PostgreSQL with PostGIS spatial extensions, providing native access to spatial data types, spatial indexing, and advanced spatial functions directly within your workspace.Key Features:
Native PostGIS Support: Full compatibility with spatial data types
Spatial Indexing: Leverage GiST and SP-GiST spatial indexes
Nika seamlessly integrates with Supabase, the open-source Firebase alternative built on PostgreSQL, providing a powerful combination of real-time capabilities and spatial data management.
Nika AI can execute SQL queries and extract data from PostgreSQL databases directly through the GUI, making database operations accessible to users of all technical levels.
# Example: AI-powered SQL generationfrom nika_ai import SQLAssistant# Initialize AI SQL assistantsql_ai = SQLAssistant(database_connection=db)# Natural language querynatural_query = "Find all parcels within 500 meters of flood zones that are larger than 2 hectares"# AI generates SQLgenerated_sql = sql_ai.generate_sql(natural_query)# Execute the queryresults = db.query(generated_sql)# Display results with visualizationspatial.visualize(results, style={'color': 'orange', 'opacity': 0.8})
# Example: AI query optimization# AI analyzes query performance and suggests optimizationsoptimized_query = sql_ai.optimize_query(""" SELECT p.*, f.flood_risk FROM parcels p JOIN flood_zones f ON ST_Intersects(p.geom, f.geom) WHERE p.area_hectares > 2.0""")# AI suggests adding spatial indexsql_ai.suggest_indexes("parcels", ["geom"])sql_ai.suggest_indexes("flood_zones", ["geom"])
# Example: Advanced spatial analysis with PostGISdef advanced_spatial_analysis(): # Multi-criteria analysis analysis_query = """ WITH ranked_parcels AS ( SELECT p.id, p.name, p.geom, p.area_hectares, -- Distance to transportation ST_Distance(p.geom, t.geom) as dist_to_transport, -- Flood risk score CASE WHEN ST_Intersects(p.geom, f.geom) THEN f.risk_level ELSE 0 END as flood_risk, -- Slope analysis AVG(s.slope) as avg_slope FROM parcels p LEFT JOIN transportation t ON ST_DWithin(p.geom, t.geom, 1000) LEFT JOIN flood_zones f ON ST_Intersects(p.geom, f.geom) LEFT JOIN slope_data s ON ST_Intersects(p.geom, s.geom) WHERE p.area_hectares > 1.0 GROUP BY p.id, p.name, p.geom, p.area_hectares, t.geom, f.geom, f.risk_level ) SELECT *, -- Composite suitability score (1.0 / (1.0 + dist_to_transport/1000)) * 0.4 + (1.0 - flood_risk/10) * 0.4 + (1.0 - avg_slope/45) * 0.2 as suitability_score FROM ranked_parcels ORDER BY suitability_score DESC; """ results = db.query(analysis_query) return results
# Example: Urban planning analysisdef urban_planning_analysis(): # Zoning analysis zoning_query = """ SELECT z.zone_type, COUNT(p.id) as parcel_count, SUM(p.area_hectares) as total_area, ST_Union(p.geom) as zone_boundary FROM parcels p JOIN zoning_districts z ON ST_Intersects(p.geom, z.geom) GROUP BY z.zone_type; """ zoning_analysis = db.query(zoning_query) # Infrastructure proximity analysis infrastructure_query = """ SELECT p.id, p.name, MIN(ST_Distance(p.geom, i.geom)) as min_dist_to_infrastructure, COUNT(i.id) as infrastructure_count FROM parcels p CROSS JOIN LATERAL ( SELECT id, geom FROM infrastructure WHERE ST_DWithin(p.geom, geom, 2000) ) i GROUP BY p.id, p.name; """ infrastructure_analysis = db.query(infrastructure_query) return zoning_analysis, infrastructure_analysis
# Example: Environmental monitoringdef environmental_monitoring(): # Habitat fragmentation analysis habitat_query = """ WITH habitat_patches AS ( SELECT ST_Union(geom) as habitat_geom, COUNT(*) as patch_count, SUM(area_hectares) as total_habitat_area FROM parcels WHERE land_use = 'natural_habitat' ) SELECT patch_count, total_habitat_area, ST_Area(habitat_geom) / ST_Area(ST_ConvexHull(habitat_geom)) as fragmentation_index FROM habitat_patches; """ habitat_analysis = db.query(habitat_query) # Water quality monitoring water_query = """ SELECT w.station_id, w.water_quality_score, w.geom, COUNT(p.id) as nearby_parcels, AVG(p.impervious_cover) as avg_impervious_cover FROM water_quality_stations w LEFT JOIN parcels p ON ST_DWithin(w.geom, p.geom, 500) GROUP BY w.station_id, w.water_quality_score, w.geom; """ water_analysis = db.query(water_query) return habitat_analysis, water_analysis