treeextraction-ndvi / utils /geo_processing.py
DynamicPacific
Add essential files for HF deployment
4b38b88
Raw History Blame Contribute Delete
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": []}