Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect overlay Problem #23

Closed
tech4GT opened this issue Jul 10, 2019 · 111 comments
Closed

Incorrect overlay Problem #23

tech4GT opened this issue Jul 10, 2019 · 111 comments

Comments

@tech4GT
Copy link
Member

tech4GT commented Jul 10, 2019

The issue:

The distorted images are not being overlaid correctly with respect to each other on the final canvas.

The logic to calculate the distortion and overlay coordinates happens inside the converter util.
https://github.com/publiclab/image-sequencer-app/blob/dev/src/api/v2/util/converter-multiSequencer.js

Steps to reproduce the issue locally:

  1. Please clone the dev branch.
  2. run npm i
  3. run npm run start

The images are getting distorted correctly, to test that we can use this url:
http://localhost:4000/api/v2/export/?url=http://mapknitter.org/maps/pvdtest/warpables.json

Since the upload query param is not set, this should return the correctly distorted image as a response to the browser. I have added Logs on each step so it should be easy to see the status of the request.

download

Now, moving on to multi-image maps, we can use the ceres map to see the relative positioning of the images.

Using this endpoint http://localhost:4000/api/v2/export/?url=https://mapknitter.org/maps/ceres--2/warpables.json
This should return the 3 images distorted and overlaid on a canvas but they won't quite match up.
Screenshot 2019-07-10 at 11 21 05 AM

Please Do not run this with larger image maps since the browser will make repeated requests to the server and you will not see any response.

@tech4GT
Copy link
Member Author

tech4GT commented Jul 10, 2019

cc @jywarren

@jywarren
Copy link
Member

Can you show with a screenshot what it's supposed to look like?

@jywarren
Copy link
Member

Thanks!

@jywarren
Copy link
Member

Ah here, i can!

image

Like this?

@jywarren
Copy link
Member

Hey, it looks like perhaps you're just overlaying them in reverse order?

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

I'm sorry, how's that? I mean the order of overlay won't change their relative positions right?

@jywarren
Copy link
Member

Ah, i'm sorry, i didn't look close enough. Here they are overlaid:

image

It looks like there may be a couple possible issues, because it doesn't look like you've simply got the x-axis scale wrong, it seems the rightmost image is actually taller than it should be as well.

But we should remember that on MapKnitter it's shown in spherical mercator, whereas you're working in unprojected lat/lon, so maybe that part is OK. Most importantly it looks like the overlaps aren't right. Let me look closer...

@jywarren
Copy link
Member

Hmm. the Ruby code relies on gdalwarp to figure this all out, though it does it in pure lat/lon as well: https://github.com/publiclab/mapknitter-exporter/blob/main/lib/mapknitterExporter.rb#L278

@jywarren
Copy link
Member

Sorry, what's going on here? Maybe we should add a comment?

while (width * height * 4 > Math.pow(2, 26)) {
width /= 2;
height /= 2;
}

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

Oh, I added that temporarily, it brings the final canvas size in range of the max allowed array size. We should be able to remove this once we use scale to determine the final size.

@jywarren
Copy link
Member

Hmm, actually, how is width determined? If it's just the pixel width of the image, then we're mixing latitudes/longitudes with pixel dimensions...

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

Oh, OK! So the width field in the json represents the actual image width then?

@jywarren
Copy link
Member

Can you write a simple test for convert? That might help us debug that section. Right now I can't see what's being passed into it -- hmm.

Actually I don't think you need to be using the width parameter here... let me think about webgl-distort for a sec...

@jywarren
Copy link
Member

Hmm. OK, so https://github.com/publiclab/image-sequencer/blob/main/src/modules/WebglDistort/info.json can already determine the height and width of the image, so it doesn't need width or height passed in, i think.

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

Oh okay! This makes sense then!
What I did was make the final width and height of the canvas as the sum of the individual heights of all images! Then I just scaled from latitude and longitude to this final width and height!

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

Hmm. OK, so https://github.com/publiclab/image-sequencer/blob/main/src/modules/WebglDistort/info.json can already determine the height and width of the image, so it doesn't need width or height passed in, i think.

Yeah it just needs the four corner points.

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

Do you think If we do not scale at all, it will work??

@jywarren
Copy link
Member

So maybe this should be:

coords.push({
  x: Math.round((node.lon - minX) / (maxX - minX)),
  y: Math.round((node.lat - minY) / (maxY - minY))
});

But there's another problem - and this might be our issue -- we can't round lat/lon because even 0.000 is a matter of meters!

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

Oh wait!! Another issue!! I just checked the json and the lat, lon values are strings! They need to be parsed first!

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

So maybe this should be:

coords.push({
  x: Math.round((node.lon - minX) / (maxX - minX)),
  y: Math.round((node.lat - minY) / (maxY - minY))
});

But there's another problem - and this might be our issue -- we can't round lat/lon because even 0.000 is a matter of meters!

Actually this is why I decided to scale it in the first place!

@jywarren
Copy link
Member

For now, let's not scale. Once we convert to true projected x,y and not lat,lon, that'll involve a projection function that will require a scale, like in this example:

    scale = 20037508.34    
    y1 = pxperm.to_f * Cartagen.spherical_mercator_lat_to_y(northmost,scale)

Here actually pxperm is the scale value we want -- pixels per meter. scale in this example is just like the diameter of the earth or something :-)

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

Okay so pxperm is consumed via the query parameter then, correct?

@jywarren
Copy link
Member

the passed scale query parameter is in pixels per meter, yeah.

So if we must convert to pixels here, let's use a projection:

#10 (comment)

@jywarren
Copy link
Member

instead of an arbitrary scale factor.

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

Okay, this makes sense! So we ditch the current way of calculating height and width and then using px_per_m we can compute the final height and width of the image, correct?

@jywarren
Copy link
Member

well, the values we pass into the webgl-distort module can be used to calculate the final height and width, so yeah, the values passed in originally are actually pre-distortion values. Maybe that's one thing that was broken!

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

Okay, So I am finally starting to understand this! Yay!
Let me make some changes like you suggested and add a test like you asked and we can pick this up from there! 😃

@tech4GT
Copy link
Member Author

tech4GT commented Jul 11, 2019

One more thing, what do we do if according to the given scale the size of the final canvas is too big for javascript array? Should we just reject the request then? Or modify the scale in some way?

@jywarren
Copy link
Member

jywarren commented Jul 11, 2019 via email

@jywarren
Copy link
Member

Made the change in #24!

@tech4GT
Copy link
Member Author

tech4GT commented Aug 22, 2019

@jywarren Moving over from #24
Working on a module which would resize the image to the desired width and height. After that we should be able to debug the overlay issue more clearly!

@jywarren
Copy link
Member

jywarren commented Aug 22, 2019 via email

@tech4GT
Copy link
Member Author

tech4GT commented Aug 24, 2019

Okay I think this should work https://www.npmjs.com/package/image-sequencer-app-resize

@tech4GT
Copy link
Member Author

tech4GT commented Aug 24, 2019

Hmm, still not quite right! Let me make sure it does resize correctly.
Screen Shot 2019-08-24 at 9 03 21 PM

@jywarren
Copy link
Member

jywarren commented Aug 26, 2019 via email

@tech4GT
Copy link
Member Author

tech4GT commented Sep 13, 2019

Hi @jywarren
I think I got the problems with overlay resolved. This is the result currently!
Screen Shot 2019-09-13 at 8 18 50 PM
It does not line up because the resize module which I adapted from the native resize module in image-sequencer isn't working properly on the width so the images are coming out to be narrower than they should be. I'll write a module for resizing from scratch using something like bilinear interpolation now!
Sorry this took so long, I got caught up in some other stuff 😅

@jywarren
Copy link
Member

jywarren commented Sep 13, 2019 via email

@tech4GT
Copy link
Member Author

tech4GT commented Sep 13, 2019

Yeah! I tried this out with a bunch of different scale values and it gives the same result for all of them! So I am sure that all we need now is to fix the resize! yay!
About that, the module seems to be working if I hardcode it into image-sequencer! Trying to figure it out.

@tech4GT
Copy link
Member Author

tech4GT commented Sep 15, 2019

Okay, a lot of debugging later, I finally figured this out! So what is happening is that after the distortion the image has some extra space which is not cropped out for some reason! Due to this the final size of the usable area of the image is coming out to be incorrect!
Screen Shot 2019-09-15 at 2 48 39 PM

@jywarren Any ideas how we can fix this?? Or is this expected behavior out of the webgl-distort module??

@tech4GT
Copy link
Member Author

tech4GT commented Sep 15, 2019

The inner rectangle is the whole area of the image but that has some extra space on the right side which was causing the image to come out narrower than we were expecting!

@tech4GT
Copy link
Member Author

tech4GT commented Sep 16, 2019

One solution that comes to my mind is a trim module which would trim the image down from the edges up until it finds a row or column with a non zero pixel!

@tech4GT
Copy link
Member Author

tech4GT commented Sep 16, 2019

I tried this! It works!!! 🎉
Screen Shot 2019-09-16 at 1 06 16 PM

@tech4GT
Copy link
Member Author

tech4GT commented Sep 16, 2019

We might wanna make changes to the wegl-distort module in the long term though!

@jywarren
Copy link
Member

OK, cool! I see the latest output generated:

image

@jywarren
Copy link
Member

Compare to original:

@jywarren
Copy link
Member

Wow, Varun, this looks perfect. Amazing work.

So is this the initiating URL? I just opened this and it said This site can’t be reached / 34.74.118.242 refused to connect.

http://34.74.118.242/api/v2/export/?url=https://mapknitter.org/maps/ceres--2/warpables.json

@jywarren
Copy link
Member

Link to #28

@tech4GT
Copy link
Member Author

tech4GT commented Sep 19, 2019

@jywarren I think that's because we are missing the scale, try this:
http://34.74.118.242/api/v2/export/?url=https://mapknitter.org/maps/ceres--2/warpables.json&scale=3

@jywarren
Copy link
Member

Or is it this? http://34.74.118.242/api/v2/export/?url=https://mapknitter.org/maps/ceres--2/warpables.json&upload=false&scale=50

The previous one had finally redirected to the full longer URL, but then also showed an error. Let's get the README updated so we know how to initiate this? Thanks, Varun! Again, fantastic work!

@jywarren
Copy link
Member

Let's add that to the README, thanks! But also why am I getting intermittent refused to connect messages?

@tech4GT
Copy link
Member Author

tech4GT commented Sep 19, 2019

Actually 50 I think would be too big for it to handle! We could start with something like 5.

@jywarren
Copy link
Member

oh ok. maybe the scale is implemented differently that in mapknitter-exporter. 50 is a reasonable value there. But we can set up a conversion function and disambiguate later. Great, i'll try!

@jywarren
Copy link
Member

http://34.74.118.242/api/v2/export/?url=https://mapknitter.org/maps/ceres--2/warpables.json&scale=5

@tech4GT
Copy link
Member Author

tech4GT commented Sep 19, 2019

@tech4GT
Copy link
Member Author

tech4GT commented Sep 19, 2019

@jywarren I think the warpable needs to use http too!

@tech4GT
Copy link
Member Author

tech4GT commented Sep 19, 2019

oh ok. maybe the scale is implemented differently that in mapknitter-exporter. 50 is a reasonable value there. But we can set up a conversion function and disambiguate later. Great, i'll try!

Yeah, I think we gotta scale the scale lol.

@jywarren
Copy link
Member

OK perfect, that worked!

Can you make a quick edit to the README and actually add this test URL that people can use?

Let's close this and open a new one for scale.

@jywarren
Copy link
Member

#29

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants