Can't change location of object

Ok guys, I’m entirely stuck here. It’s the second day and I really don’t know what I should try to achieve the simple task:

Move an object to a certain location.

Here’s the deal:

I’m working with a GeoJSON file, where I’ve got provided with x and y coordinates (which should represent the coordinates in the file).

I’m storing this data in a “points” list. Everything is fine.

Now for the tricky part:

I’m importing / appending a Tree from another blend file as a new Collection (“Tree”). Nothing special here.

BUT:
I get the length of the list which represents the amount of trees and duplicate the tree. And I think this is where the trouble begins.

Duplicating the trees is not really the big issue. But I want to set the new copy to the desired position from the “points” List. And I’m totally not able to do this. I think it’s a kind of context issue.
I tried duplicate_move (which doesn’t work, because the values are adde)
I tried location[0] = points… (which doesn’t work because of NoneTypes.)

I’m frustrated, beause I don’t find anything. So this is basically my last approach here.

I added the entire script (to demonstrate my frustration and my failed attempts -.-)
I’m happy for any help.

import bpy

import os

import json

class my_vector3():

    x = 0.0

    y = 0.0

    z = 0.0

class Utils():

   

    #def __init__():

    #    self.points = []

    points = []

    # STEP 1 (Der Pfad ist bekannt)

    def setup_environment():

        global path                         # path to blend file directory

        global asset_path                   # path to asset folder

        path = bpy.path.abspath('//')

        asset_path = path + "assets"

       

        Utils.import_tree() # Wir erstellen einen Baum. Der wird einfach importiert.

        return {'FINISHED'}

    # STEP 2 (Wir haben einen Beispielbaum (mit eigener 0,0,0 Pos))

    def import_tree():

        print("Importing Tree from Blend file")

        file_path = asset_path + "\Vegetation.blend"

        inner_path = 'Collection'

        object_name = 'Tree'

 

        bpy.ops.wm.append(

            filepath=os.path.join(file_path, inner_path, object_name),

            directory=os.path.join(file_path, inner_path),

            filename=object_name

            )

           

        return {'FINISHED'}

    # STEP 3 Lese die JSON Um herauszufinden wie oft wir den Baum brauchen. Jetzt wäre es vielleicht gut den Baum zu kopieren

    def open_json(dir, filename):

       

        global v_file    

        global pointLength

        with open(dir + "\\" + filename + ".geojson",'r') as f:

            v_file = json.load(f)

            l = len(v_file['features'])

            print("Point Length: ",l)

            pointLength = l

            # ggf nicht der richtige Platz dafür

            for i in range(l):

                Utils.add_zeroes_to_points(i)

            Utils.copy_tree()

    def copy_tree():

       

        for obj in bpy.data.collections['Tree'].all_objects:

            obj.select_set(True)

            #bpy.context.scene.objects.active = obj

       

        #obj = bpy.ops.object.select_all(action='SELECT')

           

        for i in range(pointLength - 1):

            obj = bpy.context.selected_objects

            for o in bpy.context.selected_objects:

                if o.type == 'MESH':

                    o.location.x = Utils.points[i].x

                    o.location.y = Utils.points[i].y

                    o.location.z = Utils.points[i].z

                   

        return {'FINISHED'}

       

        #for i in range(pointLength -1):

           

            #bpy.ops.object.duplicate()

            #bpy.context.object.location[0] = Utils.points[i].x

            #bpy.context.object.location[1] = Utils.points[i].y

            #bpy.context.object.location[2] = Utils.points[i].z

            #bpy.ops.transform.translate(value=(0, 0, 0), constraint_axis=(False, False, True))

           

            # klappt nicht...

            #bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)

            #if (i != 0):

            #    bpy.ops.transform.translate(value=(0,0,0))

            #    x = Utils.points[i].x - Utils.points[i].x   #-1?

            #    y = Utils.points[i].y - Utils.points[i].y

            #    bpy.ops.object.duplicate_move(TRANSFORM_OT_translate={"value":(x,y,0), "orient_matrix_type": 'LOCAL'})

    def set_location(n):

            bpy.ops.object.select_all(action='SELECT')

            bpy.context.active_object.location[0] = Utils.points[n].x

            bpy.context.active_object.location[1] = Utils.points[n].y

            bpy.context.active_object.location[2] = Utils.points[n].z

    def add_zeroes_to_points(num):

       

        temp =my_vector3()

        temp.x = v_file['features'][num]['geometry']['coordinates'][0]

        temp.y = v_file['features'][num]['geometry']['coordinates'][1]

        temp.z = 0

        Utils.points.append(temp)

   

        return {'FINISHED'}

The question is a bit involved but here’s how you can duplicate and displace an object with a few lines. This code however makes two objects that share the exact same mesh so I advise you do not apply the location of the object.

import bpy

cube = bpy.data.objects["Cube"]
duplicate = bpy.data.objects.new(name="Duplicated Cube", object_data=cube.data)
duplicate.location = (0, 0, 5)

cube.users_collection[0].objects.link(duplicate)

capture

And if you want to create n cubes

import bpy
import random

cube = bpy.data.objects["Cube"]
for i in range(100):
    duplicate = bpy.data.objects.new(name="Duplicated Cube", object_data=cube.data)
    duplicate.location = (random.random() * 10, random.random() * 10, random.random() * 10)

    cube.users_collection[0].objects.link(duplicate)

capture

Changing one object in edit mode will change all the linked duplicates though

capture