Last active
February 13, 2025 14:39
-
-
Save AncientHello/92607a1c1864f6e21e1c6ac2000411df to your computer and use it in GitHub Desktop.
import GeoJSON data from naturalearthdata.com into Blender as a globe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# import GeoJSON data from naturalearthdata.com into Blender as a globe | |
# run inside Blender from scripts | |
import bpy | |
import geopandas as gpd | |
import numpy as np | |
RADIUS = 10.0 # Modify this value as desired | |
# Load GeoJSON data using geopandas | |
try: | |
geo_data = gpd.read_file('C:/path/to/naturalearthdata/ne_110m_admin_0_countries_lakes.geojson') | |
print("Successfully read the GeoJSON file.") | |
except Exception as e: | |
print("Error while reading the GeoJSON file:", str(e)) | |
geo_data = None | |
def extract_polygon_data(coords): | |
""" | |
Extract vertices and edges from coordinates. | |
""" | |
print(" - Starting extraction of polygon data...") | |
# Convert to radians | |
coords_in_radians = [(np.radians(lon), np.radians(lat)) for lon, lat in coords] | |
verts = [(RADIUS * np.cos(lon) * np.cos(lat), RADIUS * np.sin(lon) * np.cos(lat), RADIUS * np.sin(lat)) for lon, lat in coords_in_radians] | |
edges = [(i, i + 1) for i in range(len(verts) - 1)] | |
edges.append((len(verts) - 1, 0)) | |
print(f" - Extracted data: {len(verts)} vertices, {len(edges)} edges.") | |
return verts, edges | |
def create_mesh_object(verts, edges, name): | |
""" | |
Create a mesh object from vertices and edges and assign a name. | |
""" | |
print(f" - Creating mesh object '{name}' with {len(verts)} vertices and {len(edges)} edges...") | |
mesh = bpy.data.meshes.new(name=name) | |
mesh.from_pydata(verts, edges, []) | |
mesh.update() | |
obj = bpy.data.objects.new(name, mesh) | |
bpy.context.collection.objects.link(obj) | |
print(f" - Mesh object '{name}' created.") | |
# Create base sphere for Earth | |
bpy.ops.mesh.primitive_uv_sphere_add(radius=RADIUS, segments=64, ring_count=32) | |
print("Created the base sphere.") | |
if not geo_data.empty: | |
for index, row in geo_data.iterrows(): | |
polygon_name = row['NAME_LONG'] | |
polygon_geometry = row['geometry'] | |
try: | |
if polygon_geometry.geom_type == 'Polygon': | |
print(f"Processing Polygon {polygon_name}...") | |
verts, edges = extract_polygon_data(polygon_geometry.exterior.coords) | |
print(f" - Extracted {len(verts)} vertices and {len(edges)} edges for {polygon_name}.") | |
create_mesh_object(verts, edges, polygon_name) | |
print(f" - Created mesh object for {polygon_name}.") | |
elif polygon_geometry.geom_type == 'MultiPolygon': | |
print(f"Processing MultiPolygon {polygon_name}...") | |
all_verts = [] | |
all_edges = [] | |
offset = 0 | |
for part in polygon_geometry.geoms: | |
verts, edges = extract_polygon_data(part.exterior.coords) | |
print(f" - Extracted {len(verts)} vertices and {len(edges)} edges for a part of {polygon_name}.") | |
all_verts.extend(verts) | |
all_edges.extend([(i + offset, j + offset) for i, j in edges]) | |
offset += len(verts) | |
print(f" - Combined total of {len(all_verts)} vertices and {len(all_edges)} edges for {polygon_name}.") | |
create_mesh_object(all_verts, all_edges, polygon_name) | |
print(f" - Created mesh object for {polygon_name}.") | |
except Exception as e: | |
print(f"Error while processing geometry {polygon_name}: {str(e)}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment