Spaces:
Sleeping
Sleeping
| 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": []} | |