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