# -----------------------------------------------------------------------------
# Python Script to use Geo-Data in C4D for maps
# Also creates a network from the lacation points.
# Andreas Pirchner 2020
# -----------------------------------------------------------------------------
import c4d
import json
import random
import math
# Needed C4D Objects:
# "CityPin", "MuseumPin", "SplineNet"
class museum:
def __init__(self, name, lat, lon):
self.name = name
self.lat = lat
self.lon = lon
self.altitude = 0
self.connections = 0
museumsList = []
connectionLimit = 1
scaling = 850
offsetLat = -47.8
offsetLong = -13.2
minDist = 0.1 * scaling
maxDist = 6 * scaling
def main():
def tool():
return c4d.plugins.FindPlugin(doc.GetAction(), c4d.PLUGINTYPE_TOOL)
# Load JSON Data
# -----------------------------------------------------------------------------
with open ("./museumsDataAustria.json") as museumjson: # load JSON for museums
museumsData = json.load(museumjson)
with open ("./citiesGPS.json") as cityjson: # load JSON for cities
citiesData = json.load(cityjson)
# Make Point-Object-Array for Museums
# -----------------------------------------------------------------------------
for m in museumsData:
#if m["Latitude"] > 42 and m["Latitude"] < 48 and m["Longitude"] > 11 and m["Longitude"] < 16:
museumsList.append(museum(m["Institution"], (m["Latitude"]+offsetLat) *1.5 * scaling, (m["Longitude"]+offsetLong) * scaling))
# Make Nulls as Containers for Museums and Cities
# -----------------------------------------------------------------------------
museumsContainer = c4d.BaseObject(c4d.Onull) #make Null to contain all Museums
museumsContainer.SetName("AllMuseums")
doc.InsertObject(museumsContainer)
citiesContainer = c4d.BaseObject(c4d.Onull) #make Null to contain all Cities
citiesContainer.SetName("AllCities")
doc.InsertObject(citiesContainer)
c4d.EventAdd()
# Make Spline of all GPS Points
# -----------------------------------------------------------------------------
# 1 Make Spline of all GPS Points
projectionSpline = c4d.SplineObject(len(museumsList), c4d.SPLINETYPE_LINEAR)
t=0
for p in museumsList:
projectionSpline.SetPoint(t, c4d.Vector(p.lon, p.altitude, p.lat)) # altitude is increased to make sure that spline sits above terrain
t = t+1
projectionSpline.SetName("tempSpline")
doc.InsertObject(projectionSpline)
# 2 Project Spline to underlying Topography
tmpSplineObject = doc.SearchObject("tempSpline")
tmpSplineObject.SetBit(c4d.BIT_ACTIVE)
c4d.CallCommand(450000046) # C4D Command: Spline/Move/Project
tool()[c4d.MDATA_SPLINE_PROJECT_MODE] = 3 # Select Mode: XZ-Plane in Projection-Tool
c4d.CallButton(tool(), c4d.MDATA_APPLY) # Press Apply-Button in Tool
# 3 Upate Point-Object-Array with Y-Values of Spline-Points
ps = tmpSplineObject.GetAllPoints()
print len(ps)
i = 0
for mu in museumsList: #
mu.altitude = 0 # ps[i][1] # set altitude of museums point to Y of spline point
i = i +1
# 4 Delete Spline
# Make City Pins
# -----------------------------------------------------------------------------
for c in citiesData:
cityX = (c["long"]+offsetLong) * scaling
cityZ = (c["lat"]+offsetLat)* scaling * 1.5
cityY = 0
#cityY = c["altitude"]/100
cityName = c["City"]
originalCity = doc.SearchObject("CityPin")
city = originalCity.GetClone()
city.SetAbsPos(c4d.Vector(cityX,cityY,cityZ)) # set the position
#city.SetAbsScale(c4d.Vector(0.3,0.3,0.3))
doc.InsertObject(city)
city.InsertUnder(citiesContainer) # add it in the Null c4d.EventAdd()
# Make Network Connections
# -----------------------------------------------------------------------------
splineContainer = doc.SearchObject("SplineNet")
for mus in museumsList: # loop through all museums
p1 = c4d.Vector(mus.lon, mus.altitude, mus.lat) # get first point
if mus.connections < connectionLimit: # check the connection limit for the first point
for k in museumsList: # loop through all points
if k.connections < connectionLimit and mus.connections < connectionLimit: # check limit for second point
p3 = c4d.Vector(k.lon, mus.altitude,k.lat) # get second point
dist = c4d.Vector.GetDistance(p1,p3) # get distance of the 2 points
if dist < maxDist and dist > minDist: # check if distance is withon limits
mP = p1+(p3-p1)/2 # calculate middle vector between 2 vectors
mP[1] = mP[1]+dist/1.5 # set height (y) of the arc as a fourth of the distance
#print(p1)
#print(p3)
spline = c4d.SplineObject(3, c4d.SPLINETYPE_CUBIC) # make the spline of the 3 points
spline.SetPoint(0, p1)
spline.SetPoint(1, mP)
spline.SetPoint(2, p3)
spline.InsertUnder(splineContainer)
k.connections = k.connections + 1 #update connections number for point 2
mus.connections = mus.connections + 1 # ... and for point 1
print(dist)
# Make Museums Pins
# -----------------------------------------------------------------------------
original = doc.SearchObject("MuseumPin")
obj = original.GetClone()
obj.SetAbsPos(p1) # set the position
obj.SetAbsScale(c4d.Vector(70,70,70))
rotation = random.randint(0,359);
obj.SetAbsRot(c4d.Vector(rotation,0,0))
doc.InsertObject(obj)
obj.InsertUnder(museumsContainer) # add it in the Null c4d.EventAdd()
c4d.EventAdd()
print("done")
# Execute main()
if __name__=='__main__':
main()