ForestAI-TreeExtraction / utils /geo_processing.py
DynamicPacific
Add essential files for HF deployment
4b38b88
raw
history blame
4.45 kB
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": []}