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

Ensure addGrid.js code is drawing a grid to a decimal precision #18

Closed
jywarren opened this issue Jun 16, 2017 · 46 comments
Closed

Ensure addGrid.js code is drawing a grid to a decimal precision #18

jywarren opened this issue Jun 16, 2017 · 46 comments
Milestone

Comments

@jywarren
Copy link
Member

jywarren commented Jun 16, 2017

The grid seems to have a statically set size of 64 -- https://github.com/publiclab/leaflet-blurred-location/blob/master/src/core/addGrid.js#L24

But it should be drawing a grid that's based on a precision of latitude/longitude, so, for example grid lines on:

44.001, 44.002, 44.003, 44.004

Am i misunderstanding the code, and this is actually the case?

__________________________________________
|72.0,44.3           |72.0,44.4           |
|                    |                    |
|                    |                    |
|                    |                    |
-------------------------------------------
|72.1,44.3           |72.1,44.4           |
|                    |                    |
|                    |                    |
|                    |                    |
-------------------------------------------
@jywarren
Copy link
Member Author

Mridul, I think this may actually be he next place to work -- if we can get this grid to be on a specific scale, the other work on precision makes more sense.

Think about it this way: for a given zoom level, what's the smallest decimal place grid (lines every 0.1, 0.01, or 0.001) you can draw where the grid squares will still be larger than 100px across? That's the grid we should draw.

@jywarren
Copy link
Member Author

You can work from the setupSize method and the origin in addGrid.js -- for example, truncate the origin to the precision you're going for, and set the cellSize to 0.01 or 0.001 or whatever you calculate your precision to.

@jywarren
Copy link
Member Author

jywarren commented Jun 17, 2017

To calculate the precision, you could iterate --

  • Start with gridsize = 1 degree
  • Calculate the pixel width of 1 degree (use leaflet conversion tools for this)
  • If the pixel width is larger than 100 then divide gridsize by 10
  • Recalculate the pixel width
  • Repeat until the pixel width is < 100
  • Gridsize is now your desired precision
  • getPrecision should now return the number of times you had to divide by 10

How's that?

@mridulnagpal
Copy link
Member

@jywarren I didn't get it. Do you want me to locate top corners of the middle box and set precision accordingly?

@jywarren
Copy link
Member Author

No -- the grid itself should be drawn to a given precision, not the other way around. Think -- on the globe, there are set lines on each degree of latitude and longitude. If we drew a grid for each degree, we'd have 360 vertical lines and 180 horizontal ones for the whole globe. That would be a precision of zero -- that is, 0 decimals after the 1..

If we just wanted to look within one degree box of that, say, 71-72 and 33-34, we'd then be able to subdivide that box into 10x10 -- where each line would then fall on 71.0, 71.1, 71.2, 71.3... 71.9. That would be a precision of 1 -- that is, 1 decimal after the . -- and so on.

Take a look at this page: http://leafletjs.com/examples/zoom-levels/

But the zoom levels don't scale the same as the longitude/latitude subdivisions, because zoom is based on (from the article above):

At each zoom level, each tile is divided in four, and its size doubles (in other words, the width and height of the world is 256·2^zoomlevel pixels):

We decide to draw the grid that's most appropriate for the current zoom level. So if you're at zoom level 6, we need to know what's the highest precision that results in something near 100 pixel wide grid squares. That's what the iteration above is designed to determine.

@mridulnagpal
Copy link
Member

Okay so I looked for the documentation and for 0 zoom it shows the whole map. And zooms by 2*2 for each lat and lon. Thus if we want 6 boxes for 360 degrees(i.e 1 box per 60 degrees), we set zoom = 0 else increase zoom by 1 and reduce lat/lon by 2 i.e 1 for 180 and so on. Thus for one degree we need to set the zoom to approx 6 as 2^6 = 64. Is it something like this?

@jywarren
Copy link
Member Author

Ah, not quite -- i still think you're approaching it backwards -- it's not that we want to make 6 boxes for a given # of degrees, it's that we want to make one box for each degree, or each tenth of a degree, or each hundredth of a degree, or thousandth of a degree. We don't want to set the zoom at all -- let the user change the zoom, and we just want to figure out what's the smallest grid we should show them -- degrees (0), tenths (1), hundredths (2), and so on.

@jywarren
Copy link
Member Author

So we're trying to figure out how far to subdivide!

@mridulnagpal
Copy link
Member

If we set zoom = 6 we have 1 box per pixel, don't we?

@mridulnagpal
Copy link
Member

If we zoom out of the map does the size of grid change or remain the same?

@jywarren
Copy link
Member Author

the grid would recalculate each time we zoom in or out. hang on, i'm trying to write another note to help...

@jywarren
Copy link
Member Author

But we can break this down into parts and tackle them one by one. Let's say, the first is:

  • What's the current zoom level?
  • How many pixels is 1 degree of latitude?
  • Is that larger than 100px?

We could write functions for these:

  • gridWidthInPixels(degrees) -- returns how many pixels wide a grid with degrees line spacing would be -- for example degrees values of 1, 0.1, 0.01
  • findPrecisionForMinimumGridWidth(width) could iterate starting with degrees = 1, to 0.1, 0.01, 0.001 (dividing by 10 each time, and maybe doing precision += 1) and checking with (gridWidthInPixels(degrees) < width) to see if it's gotten too small. Once that evaluates to true, we return precision.

@mridulnagpal
Copy link
Member

So we have the total pixels in map to be 400px*400px and for zoom = 0 we have 360 degrees in 400px thus pixels in 1 degree will be 400/360, right?

@jywarren
Copy link
Member Author

That's right -- but we're never going to show the whole map, so that's not a common view. I think we can come up with a solution for that as well, though -- for example, we could draw lines every 10 degrees, in that case.

@mridulnagpal
Copy link
Member

so pixels per degree will be (400*(2^zoom))/360 right. Thats what we want?

@jywarren
Copy link
Member Author

That would be only for a 400px wide map, and that may change. I think the best way to calculate pixels per degree may be to use the conversion tools in Leaflet, which will also ensure you don't make a mistake with projections -- think about the fact that the grid isn't evenly spaced depending on your latitude. Lines of longitude converge at the poles! So, you can calculate the pixel position of two points, degrees apart, and subtract to find their pixel distance.

@mridulnagpal
Copy link
Member

Can you suggest any conversion methods from leaflet?

@jywarren
Copy link
Member Author

Yes, sorry, i had added this link to an earlier comment but it's way up there now: http://leafletjs.com/reference-1.0.3.html#map-latlngtocontainerpoint

@mridulnagpal
Copy link
Member

Perfect so I just take two points varying with difference of one and get there container points, take there difference, and that will be the number of pixels per degree, each for lat and lon. Am I getting it right?

@jywarren
Copy link
Member Author

Yes, exactly! Two points varying with difference of -- whatever the current fraction of a degree we're wondering about -- 1, 0.1, 0.01, 0.001 --

And you know, i think we can leave this part of it at just measuring latitude, because for regions we're looking at they'll be reasonably close to longitude. As we get to northern Russia, it could be like 2:1, but that's still OK for our drawn grid.

@mridulnagpal
Copy link
Member

So first we try with 1 then 0.1 and so on till we have (gridWidthInPixels(degrees) < width) where gridWidthInPixels is nothing but the difference between the outputs of the latlngtocontainerpoint, right?

@jywarren
Copy link
Member Author

jywarren commented Jun 17, 2017 via email

@mridulnagpal
Copy link
Member

And we'll get width from the getSize() method, right ? I will start with the methods right away.

@jywarren
Copy link
Member Author

Well, for now, just let findPrecisionForMinimumGridWidth(width) accept any arbitrary width -- although we'll probably go for 100px squares, as that's a reasonable size on the screen. Remember, this is just so that we have a readable-sized grid drawn on the screen, so by using a parameter, we can decide exactly what looks right later. It might end up being based on getSize(), if that's the size of the map element, but that's not for sure right now.

@mridulnagpal
Copy link
Member

@jywarren Added the two methods we are talking about. Should I write test specs for them as well?

@jywarren
Copy link
Member Author

Let's move forward for a bit -- first i left some comments, but second, can you get the addGrid grid drawer to use this?

@mridulnagpal
Copy link
Member

mridulnagpal commented Jun 17, 2017

We can call addGrid with an options argument, which will set the block size.Something like blurredLocation.addgrid(options)

@jywarren
Copy link
Member Author

yes, perfect

@mridulnagpal
Copy link
Member

Added the options part, also renamed it to gridSystem. What next?

@jywarren
Copy link
Member Author

i left a request about the latlng of 1,1 -- take a look!

@jywarren
Copy link
Member Author

Great, #32 merged. Copying in my notes from the end of that:

OK, this looks good -- why don't we merge it and then do another one where you create a method called:

options.gridSystem.setCellSizeInDegrees(degrees);

And let's rename findPrecisionForMinimumGridWidth() to getMinimumGridWidth(pixels) and have it return { degrees: ____, precision: _____ } -- that way we can do:

var degrees = getMinimumGridWidth(100).degrees;
options.gridSystem.setCellSizeInDegrees(degrees);

Makes sense? setCellSizeInDegrees() will then adjust the geometry of the grid accordingly, and we can run it each time the zoom changes.

@jywarren
Copy link
Member Author

Take a short break and delete location_tags -- check off #11 -- it'll feel good! :-)

@mridulnagpal
Copy link
Member

Sure, thanks Jeff 😄

@jywarren
Copy link
Member Author

ok! i think you can begin integrating varying cellSize into https://github.com/publiclab/leaflet-blurred-location/blob/master/src/core/gridSystem.js -- give it a try!

A test might be -- zoom the map, then show that the cell size has changed.

@mridulnagpal
Copy link
Member

What would be the cell size for different degrees?

@jywarren
Copy link
Member Author

jywarren commented Jun 19, 2017 via email

@mridulnagpal
Copy link
Member

mridulnagpal commented Jun 19, 2017 via email

@jywarren
Copy link
Member Author

jywarren commented Jun 19, 2017 via email

@mridulnagpal
Copy link
Member

@jywarren So if I enter 0.1 as degrees first I will have to calculate cellSize in pixels using latLngToContainerPoint() method?

@jywarren
Copy link
Member Author

jywarren commented Jun 19, 2017 via email

@mridulnagpal
Copy link
Member

I got it now, what we are trying to do. Please have a look at the PR I have posted. The grid is made according to degrees it that.

@mridulnagpal
Copy link
Member

@jywarren Is there anything left of this issue or are we through?

@jywarren
Copy link
Member Author

jywarren commented Jun 22, 2017 via email

@mridulnagpal
Copy link
Member

Please have a look at #36 posted the snaps there, also pushed changes.

@mridulnagpal
Copy link
Member

Is this done?

@jywarren
Copy link
Member Author

Merging into #36

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