import os import logging import uuid import numpy as np from PIL import Image import json # Try to import GDAL, but provide fallback for environments without it try: from osgeo import gdal, ogr, osr HAS_GDAL = True except ImportError: logging.warning("GDAL not available. Using simplified GeoJSON conversion.") HAS_GDAL = False def convert_to_geojson(image_path): """ Convert a processed image to GeoJSON format. This function extracts features from the processed image and converts them to GeoJSON polygons or linestrings. Args: image_path (str): Path to the processed image Returns: dict: GeoJSON object """ try: logging.info(f"Converting image to GeoJSON: {image_path}") # Open the image img = Image.open(image_path) img_array = np.array(img) # Create a simple GeoJSON structure geojson = { "type": "FeatureCollection", "features": [] } # Extract contours from the image # In a real application, we would use OpenCV's findContours here # Since we're simulating it, we'll create a simplified process height, width = img_array.shape # Create a random bounding box as a demo # In a real application, this would be based on actual image analysis feature_id = 0 # Process the image to find contours # (For simplicity, we'll simulate finding features by looking at non-zero pixels) visited = np.zeros_like(img_array, dtype=bool) for y in range(0, height, 10): # Step by 10 for performance for x in range(0, width, 10): # Step by 10 for performance if img_array[y, x] > 0 and not visited[y, x]: # Found a feature, trace its boundary feature_id += 1 # Simplified feature extraction - in a real app this would be more sophisticated # Here we'll just create a small polygon around the point coords = [] size = min(20, min(width-x, height-y)) # Create a simple polygon polygon = [ [x, y], [x + size, y], [x + size, y + size], [x, y + size], [x, y] # Close the polygon ] # Convert pixel coordinates to approximate geo-coordinates # In a real application, this would use proper geo-referencing # Here we'll just normalize to [0,1] range and then to fake lat/long geo_polygon = [] for px, py in polygon: # Convert to fake geographic coordinates (for demo purposes) lon = (px / width) * 0.1 - 74.0 # Fake longitude centered around New York lat = (py / height) * 0.1 + 40.7 # Fake latitude centered around New York geo_polygon.append([lon, lat]) # Add the feature to GeoJSON feature = { "type": "Feature", "id": feature_id, "properties": { "name": f"Feature {feature_id}", "value": int(img_array[y, x]) }, "geometry": { "type": "Polygon", "coordinates": [geo_polygon] } } geojson["features"].append(feature) # Mark this area as visited for cy in range(y, min(y + size, height)): for cx in range(x, min(x + size, width)): visited[cy, cx] = True logging.info(f"Converted image to GeoJSON with {feature_id} features") return geojson except Exception as e: logging.error(f"Error in GeoJSON conversion: {str(e)}") # Return a minimal valid GeoJSON if there's an error return {"type": "FeatureCollection", "features": []}