Can I add rotation to a generated Forma GeoJson?

Can I add rotation to a generated Forma GeoJson?

iklimis
Advocate Advocate
1,083 Views
16 Replies
Message 1 of 17

Can I add rotation to a generated Forma GeoJson?

iklimis
Advocate
Advocate

Hey forma Team 
I was wondering if it would be possible to add rotation of the contained image inside the geoJson 

iklimis_0-1725621198067.png

 

0 Likes
Accepted solutions (1)
1,084 Views
16 Replies
Replies (16)
Message 2 of 17

samarvir_singh_bhayana
Autodesk
Autodesk

Hey,

 

 

can you please add some example screenshot to explain what you mean?

0 Likes
Message 3 of 17

iklimis
Advocate
Advocate

@samarvir_singh_bhayana 
Yes let me explain in more details,

The goal is when the user downloads a terrain image from inside our extension (which we render as a texture inside Forma Canvas) they will ideally have an option to download said image as a Library Item (terrain image) and use it independently from our extension.

As we render the Image from inside the extension however we slightly rotate the image to place it correctly to the area bounds.

But as we create the geoJson so we can create the Library Item we need a way to also add the rotation we need - otherwise the image will be placed slightly of

Could I somehow add a rotation to the geoJson before adding it as Library Item


0 Likes
Message 4 of 17

syed_ammar_abbas_naqvi
Autodesk
Autodesk

Hey @iklimis 

 

You can apply the rotation by multiplying your positions/coordinates matrix by a transformation matrix, there's a library called gl-matrix that can help with that.

Let me know if you have any further questions. 

0 Likes
Message 5 of 17

iklimis
Advocate
Advocate

yes @syed_ammar_abbas_naqvi 

Can you please elaborate?

my problem is that i need to rotate the image contained inside a geojson 
although I can rotate the geojson itself the image that fills the geojson always has the same orientation resulting something in this picture 
You see the problem 
Thank you

Screenshot 2024-09-17 153115.png












0 Likes
Message 6 of 17

syed_ammar_abbas_naqvi
Autodesk
Autodesk

Hey @iklimis 

I see the problem now 🙂
To rotate the image and the geojson together you can provide a transform matrix when adding your element to the proposal.

Link to docs 

Here is an example where the rotated image result ends up something like this. 

syed_ammar_abbas_naqvi_0-1726741086899.png

 

          Forma.proposal.addElement({
            urn,
            transform: [
              0.9339075179317857, -0.35751468214674925, 0, 0,
              0.35751468214674925, 0.9339075179317857, 0, 0, 0, 0, 1, 0,
              96.5774229255095, -95.94896547481207, -0.04881836450415927, 1,
            ],
          })

 

Hope this helps, let me know if you have any further questions.

0 Likes
Message 7 of 17

iklimis
Advocate
Advocate

@syed_ammar_abbas_naqvi 
Hello again  and thanks for your answer
The problem is that I do not intent to use the addElement() method because I would like to let the user import the Library element and import it when they choose 

Meaning I just use thecreateItem() to create the GeoJson and add it the Library 
when the user imports the geojson however the geojson must appear with rotation 











0 Likes
Message 8 of 17

iklimis
Advocate
Advocate
0 Likes
Message 9 of 17

syed_ammar_abbas_naqvi
Autodesk
Autodesk

hey @iklimis 

That makes sense, let me share a solution that would work for having the rotated image in the library.
I have this example here:

          const geojson = {
            type: "FeatureCollection",
            features: [
              {
                type: "Feature",
                properties: {
                  fill: {
                    imgUrl:
                      "https://letsenhance.io/static/73136da51c245e80edc6ccfe44888a99/1015f/MainBefore.jpg",
                    opacity: 1,
                    color: "#ffffff",
                  },
                },
                geometry: {
                  coordinates: [
                    [
                      [-294.9588054623455, -288.804088331759],
                      [331.04119453777093, -288.804088331759],
                      [331.04119453777093, 370.1959116663784],
                      [-294.9588054623455, 370.1959116663784],
                      [-294.9588054623455, -288.804088331759],
                    ],
                  ],
                  type: "Polygon",
                },
                id: "2a8e72e6-5a5d-47bc-9b0c-da69e8d7b299",
              },
            ],
          }

          const { blobId } = await Forma.integrateElements.uploadFile({
            authcontext: "authcontext",
            data: JSON.stringify(geojson),
          })

          const { urn } = await Forma.integrateElements.createElementV2({
            properties: {
              category: "referenceImage",
              noiseIgnore: false,
              treatAsVegetationInWindAnalysis: false,
              virtual: true,
              referenceImageLink: null,
              color: "#755252",
              opacity: 0.6,
            },
            representations: {
              terrainShape: {
                blobId,
                type: "linked",
              },
              footprint: {
                blobId,
                type: "linked",
              },
            },
          })

          const { urn: urn2 } = await Forma.integrateElements.createElementV2({
            children: [
              {
                urn: urn,
                transform: [
                  0.9339075179317857, -0.35751468214674925, 0, 0,
                  0.35751468214674925, 0.9339075179317857, 0, 0, 0, 0, 1, 0,
                  96.5774229255095, -95.94896547481207, -0.04881836450415927, 1,
                ],
              },
            ],
          })

          const item = await Forma.library.createItem({
            data: { name: "My new item", status: "success", urn: urn2 },
          })


What I am doing in this example is creating an element with the image, and then creating a parent element for the image element which has a transform for rotating the image. and then storing the parent element with the transform and image to the library.



0 Likes
Message 10 of 17

iklimis
Advocate
Advocate


Hello again @syed_ammar_abbas_naqvi 

I tried this solution and although the rotation problem might be solved there is an issue when the user imports the image form the Library 

Instead of the image being placed according to the coords of the geojson the image is not being placed it just hovers over the area and the user has to manually place it by clicking somewhere 

That presents a problem because the user cannot center or place the image precisely - the image has to be georeferenced in order for the terrain to be concise with the area 

we do not want the user to place the image - the image must be placed according to the coordinates




Recording2024-09-26105724-ezgif.com-video-to-gif-converter.gif







0 Likes
Message 11 of 17

syed_ammar_abbas_naqvi
Autodesk
Autodesk

Hi again @iklimis 

 

That makes sense. I feel like we are addressing only the symptoms here and not the real underlying problem. Do you mind me asking why do we need the image to be rotated? I have a feeling there's a deeper issue here about conversion from lat/long to UTM and the true North not aligning correctly. 
From the video in your latest reply, it seems like even if we were to manage to successfully rotate and geolocate the image correctly, it will not achieve the purpose of a basemap correctly fitting and covering the whole terrain, which I am assuming you would like to do.

If possible we can schedule a meeting with one of the engineers who worked on making the image ordering pipeline inside Forma and try to discuss a solution that addresses the core problem.

Let me know if I am making any incorrect assumptions or if you have any further questions.
Send me an email at ammar.naqvi@autodesk.com with what call times usually work for you and I will schedule a call to look into this problem.

Regards,
Ammar

0 Likes
Message 12 of 17

hallvard.braatenE6H3T
Autodesk
Autodesk

Hey!

 

You can now try the new terrainTexture representation when creating the element.

 

const imageElement = {
  "properties": {
    "name": "my-image.png",
    "category": "referenceImage",
    "geoReference": {
      "srid": 32631,
      "refPoint": [
        450951.58389586565,
        5418912.06353131
    ]
    }
  },
  "representations": {
    "terrainTexture": {
      "type": "linked",
      "blobId": upload_link["blobId"],
      "properties": {
        "mimeType": "image/png",
        "opacity": 1,
        "color": "#ffffff",
        "boundingBox":
          [
            [
              [
                0,
                -500
              ],
              [
                500,
                0
              ],
              [
                0,
                500
              ],
              [
                -500,
                0
              ],
              [
                0,
                -500
              ]
            ]
          ]
      }
    }
  },
}

const { urn } = await Forma.integrateElements.createElementV2(imageElement)

 

The boundingBox property can be rotated and should work properly.

 

Regards,

Hallvard

0 Likes
Message 13 of 17

iklimis
Advocate
Advocate

Hey @hallvard.braatenE6H3T 
thanks for implementing this 

so, just to make sure: 

I still need to use the uploadFile() method with a geojson or an image of the integrateElements Api correct?

So I can use the blobId that is being returned and I can subsequently use it in this line 

"blobId": upload_link["blobId"],

 

0 Likes
Message 14 of 17

hallvard.braatenE6H3T
Autodesk
Autodesk

That is correct!  Also, this will only work for images. For other data types you still do it the old way.

0 Likes
Message 15 of 17

iklimis
Advocate
Advocate

@hallvard.braatenE6H3T 
would you be so kind as to give me an example of an image File upload?
I tried something like this but with no result 

iklimis_0-1728997403223.png

 

0 Likes
Message 16 of 17

hallvard.braatenE6H3T
Autodesk
Autodesk
Accepted solution

sure! Using ArrayBuffer instead of Base64 string will work.

 

const response = await fetch(imageUrl);
const blob = await response.blob();
const arrayBuffer = await blob.arrayBuffer();
const file = { data: arrayBuffer}
const { blobId } = await Forma.integrateElements.uploadFile(file)

 

0 Likes
Message 17 of 17

iklimis
Advocate
Advocate

Thanks a lot @hallvard.braatenE6H3T

works great!

0 Likes