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

Equal sized grids/squares or chunk systems on a map with mercator projection ? #413

Closed
genaray opened this issue Nov 29, 2017 · 30 comments
Closed
Assignees
Labels

Comments

@genaray
Copy link

genaray commented Nov 29, 2017

Hey community !

Im currently working on an little game using Mapbox and of course Unity. Because i want to manage some sort of resources, buildings or players i need a chunk system. I already created one but i just noticed that it only works good in certain areas, those who arent really affected by the mecator projection.

https://imgur.com/a/jcKDD

Take a look at the pictures, the little grey squares (not the map) in the scene view represent the exact middle of my chunks. In the first one the distances between each are pretty much the same, because they were created near Lat / Lng = 0; The other ones were created in other parts of this world, for example brazil, russia, greenland. And i guess the distances are larger now due to the mecator projection.

Is there some way to disable or switch this type of projection ? Does Mapbox even supports other projections ? Or how can i transform my chunk system to not make it effected by the projection type ?

Thanks for your attention and help :)

@david-rhodes
Copy link

First of all, cool visuals! I love the retro style for this type of project.

As latitude diverges from the equator (0), each tile will begin to represent more physical area.
image
https://wiki.openstreetmap.org/wiki/Zoom_levels

You must use a formula to determine the distance that each pixel (of a tile at 256 * 256) represents. This is available in Conversions.cs

There are likely some other conversions that would be useful for you. That said, I'm not sure what exactly the problem is because I don't understand what the chunking is used for or what I'm looking at in the screenshots. Do you need to stretch the Mapbox tiles, or change the size/position of your chunks accordingly? I suspect that mercator is easiest to work with, given that each tile is a constant size. Perhaps you could set chunks based on geo bounds? If the requirement is to make sure each chunk represents the same physical area?

@wilhelmberg
Copy link
Contributor

As latitude diverges from the equator (0), each tile will begin to represent more physical area.

Feeling nit-picky today 😏:
As latitude diverges from the equator (0), each tile will begin to represent more less physical area.

The red circles in the map above represent the same real world area., but they cover a lot more screen pixels the further away from the equator.

@david-rhodes
Copy link

Right! Thanks for the correction.

@genaray
Copy link
Author

genaray commented Nov 30, 2017

@david-rhodes Thanks for your answer ! im gonna Change my Post later to make it more understandable as soon as im Home :)

So all in all i have the Problem that the distances between my squares increases. For example at lat long 0;0 the distances between my squares ist exactly the amount i want . When trying it near lat Long -70;-70 its effected by the mecator stretching and the distances are longer between each other . And i need a way to prevent this >.<

@david-rhodes
Copy link

How are you placing the squares? Is the goal to have equal distance between each square?

@genaray
Copy link
Author

genaray commented Nov 30, 2017

@david-rhodes Exactly. And somehow even if my chunk calculation are right the mecator projection stretches them and now i want to know how to avoid that :D.
Heres a new example i made : https://imgur.com/a/VoI6K

There two pictures, the first one contains 9 chunks. In this picture everything is fine, i created those 9 chunks near Lat = 0 and Long = 0. And this is exactly how i want my chunks on every lat long location in the world.

The second picture contains 4 chunks created near Lat = -75 and Long = -75, as you can see those chunks got different heights and lenghts due to the mecator projection stretching. And i need a way to avoid this ^^.

@david-rhodes
Copy link

Thanks. I still don't know how you are placing the chunks, though. What's formula are you using? How is mercator affecting your own internal system? Why not just make a grid for your own chunking system (that doesn't care about mercator)?

@genaray
Copy link
Author

genaray commented Nov 30, 2017

@david-rhodes Ouh, right. So i need a lat/lng based chunk system because when i would use a pixel chunk system instead, it would be effected by the different zoom levels.
So first i should tell you what my game is about. Its a mobile mmorpg. Players can farm resources on the map, build buildings and meet with other players. Thats why i need a chunk system, to load the resources from the database, if the player enters a new chunk.

The calculation is pretty easy.

First we need the player lat/lng coordinates : 3.0146683, 5.3046076

One latitude is about : 110.57 km -> 110570 meters
One longitude is about : 111.32 km ->111320 meters

One chunk should be about 750 meters on the map.

Because Latitude and Longitude got different ranges we need to adjust the chunk size.

One latitude factor = 110570 / 750 = 147,43
One longitude factor = 111320 / 750 = 148,42

One latitude chunk size = 110570 / 147 = 750 meters
One longitude chunk size = 111320 / 148,42 = 750 meters

(Maybe this step is unnecessary)

Now we convert the Lat/Lng to meters.

Latitude in Meter = 3.0146683 * 110570 meters = 333 331.873931 Meters
Longitude in Meter = 5.3046076* 111320 meters = 590 508.918032 Meters

Now we need to calculate the meters till the last chunk by using modulo.

Latitude Modulo => 333 331.873931 modulo 750 = 331 meter
Longitude Modulo => 590 508.918032 modulo 750 = 258 meter

After that we are able to calculate the Latitude and Longitude chunks.

Latitude chunk position = 333 331.873931 - 331 = 333 000.873931
Longitude chunk position = 590 508.918032 -258 = 590 250.918032

When we didive that now through the chunk size we get the actual chunk position.

Chunk X = 333 000.873931 / 750 = 444,0011
Chunk Y = 590 250.918032 / 750 = 787,001

Rounded : Chunk X = 444 ; Chunk Y = 787

Now we know that the player stands right in this chunk [444;787]

In the next step i just calculate the Chunk X and Y back to latitude and longitude and convert them via transform.AsUnityPosition to 3D coordinates, where i place those grey objects then. I can also show you the stuff in code when you want, maybe its clearer then :)

And by the way... i found some methods in Conversions.cs which require a map center and a scale that represents the meters of one Unity unit ... do you have an idea where i can find those values ? Or where to set them ?

Thanks again for your time and attention ;)

@genaray genaray changed the title Is it possible to switch mecator projection ? [Trying to create a chunk system] Selfmade game chunk system problem with the mecator projection. Nov 30, 2017
@david-rhodes
Copy link

Maybe this naive on my behalf, but can't you use the formula posted above to resize your chunking grid, based on the zoom level?

@abhishektrip
Copy link
Contributor

@genaray If I understand you correctly, each chunk is representing a location at a different Latitude Longitude ?
If that is the case I would suggest the following :

  1. Web Mercator tiles are already scaled to be exact same dimensions(256x256) at each lat/long so you can avoid scaling your chunks.
  2. If calculating accurate distances is what you are looking for, then I would suggest using the GetTileScaleInMeters method in Conversions.cs to factor in the WebMercator stretching.

Let us know if we are completely misunderstanding your issue.

@genaray
Copy link
Author

genaray commented Nov 30, 2017

@david-rhodes But thats not the problem, the problem is that the chunks are getting larger ( more distance between each other ) the more they are near the mecator stretching zones. Thats the problem i need to solve. And for my type of game those chunks need all to have exactly the same sizes. Also the way i calculate the chunk positions should work on all zoom levels.
Its the same way like nearly all games do their chunk systems, i just use Lat/Long positions instead of x/y coordinates.
So again my iusse is that the calculated positions are stretched (distances are bigger between each other) at some point of the world map. And what i want is that the distances between each of those positions are the same.
When using X and Y pixel coordinates in an normal non based mapbox game it works fine. But as soon as i use lat lng the mecator projection starts to stretch them at some point. THATS the problem. So i just want to know how to avoid that. And the zoom level isnt a problem in this case.

@atripathi-mb Exactly, but a chunk is more a area than a position. But lets just talk about the middle of the chunk which is a position.
But im not scaling my chunks at any point. This system is working without scaling.
Number two is possible what im looking for... Im gonna take a look at it ! Thanks :)
When it works im gonna tell you about it, otherwise i hope for some more help ^^

@genaray
Copy link
Author

genaray commented Nov 30, 2017

Maybe this is one more good example. My "algorithm" for chunk creation does use a constant value : the size of the chunks. This value doesnt change, it just stays the same. It is 750.
So when i calculate the position of the chunks, they are 750 meters away from their neighbour chunks. The space between them is the chunk area.
It works great in all kind of games ( in case i use X and Y pixel positions ) . When i try the same using Mapbox and with Lat/Lng positions my chunks are looking like the squares from the picture previous posted
33406066-5b554cbc-d528-11e7-9506-1cfaf93cb998

The squares in the middle of the picture got the same width and height. When you take a look at the bottom / top squares they are much heigher than the ones in the middle. Thats exactly how my chunks are looking.
But they shouldnt look like this, they should more look like that
equirectangular_projection_sw

As you can see there are no stretched squares. All got the same width and height. Thats what i want to achieve with my chunks. Same width/height and distance between each other no matter where in the mecator projection map.

@david-rhodes
Copy link

http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/

This is mercator ^. Those are all square. Where are you converting your chunks such that their positions get scaled?

@genaray
Copy link
Author

genaray commented Nov 30, 2017

@david-rhodes Sure they are all squares. But the mecator projection is "stretched" isn't it ? Just compare those two Pictures I posted before. In the First one Greenland is nearly as big as Africa. In the second one it isn't. So the First one is stretched because Greenland is much longer. And that's Happens due the mecator projection. The Same Happens with my Position calculation. Im gonna post some of my Code tommorow.

@abhishektrip
Copy link
Contributor

@genaray Are you using the lat/long to compute where in Unity World space your chunk is going to be centered? Have you tried using GeoToWorldPosition from Conversions.cs to do that?

@abhishektrip
Copy link
Contributor

@genaray I went through the calculations that you listed above again and have a few comments:

  1. Latitude/Longtitude to meters is not a constant value, it varies with lat long changes.
  2. I don't quite understand what the calculation with the modulo operator is doing.

And by the way... i found some methods in Conversions.cs which require a map center and a scale that represents the meters of one Unity unit ... do you have an idea where i can find those values ? Or where to set them ?

I think you can avoid doing the math by using GeoToWorldPosition , which essentially does the calculations for you.
Use the map's CenterMercator , WorldRelativeScale as parameters for center & scale.

@genaray
Copy link
Author

genaray commented Dec 1, 2017

@atripathi-mb Im using VectorExtensions.AsUnityPosition(); for converting my lat / lng into a Vector3. I just took a look into the definition and saw that AsUnityPosition(); uses Conversion.GeoToWorld(); to convert it.

The Modulo part is just ... how to explain that ... It just calculates the remaining meters to the last chunk.

For example if the player is at latitude : 50.5 and one chunk is exactly 1 latitude big.
Than modulo calculates 0.5, this is the remaining latitude till the last chunk, in which the player is standing. 50.5 modulo 1 = 0.5 | 50.5 - 0.5 = 50 and this is the chunk in which the player is standing.

So latitude and longitude arent constant values ? Well i didnt knew that. how do they varie with lat long changes ? Is there a formula for this ? Maybe that causes the can solve the weierd distances between my chunks :/

So and there is really no damn way to change the projection of mapbox ? From web mercator to another projection ? That would solve my iusse immediately...

@genaray
Copy link
Author

genaray commented Dec 1, 2017

@david-rhodes @atripathi-mb
Heres another representation of what i want to achieve :

I just want to apply a regular grid to that flat map so that each square is the same size. So my chunk system is supposed to look like this :

b24xz

And thats all i want to achieve... but as you know those squares/grids/chunks are currently stretched which looks like this :

33455422-4b707e9e-d61c-11e7-8727-ceb4cbd350db

And all i need is a way to remove the disortion / stretching from my lat/lng positions of the chunks. Or another way to have an equal sized grid.

@genaray genaray changed the title Selfmade game chunk system problem with the mecator projection. Equal sized grids/squares or chunk systems on a map with mercator projection ? Dec 1, 2017
@abhishektrip
Copy link
Contributor

@genaray

So latitude and longitude arent constant values ? Well i didnt knew that. how do they varie with lat long changes ? Is there a formula for this ? Maybe that causes the can solve the weierd distances between my chunks :/

Apologies if I confused you. To clarify my statement, the distance calculations have to take into account the curvature of the earth, so distance between each latitude is approximately same, but distance between longitudes vary depending on its latitude value. Here is an article explaining the various mathematical formulas for calculating distances.
https://blog.mapbox.com/fast-geodesic-approximations-with-cheap-ruler-106f229ad016

but as you know those squares/grids/chunks are currently stretched which looks like this

Web Mercator tiles are all sqaures (256 x256) , the second image you are referring to is just an illustration to explain the stretching that occurs when projecting earth to Web Mercator ( sphere to flat plane).Actual tiles look like the first image.
The tiles are not physically stretched, it just means the meters per pixel are different based on latitude longitude ( use GetTileScaleInMeters to get that value)

For more information
http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/

Here are some ways that I think might help solve your issue:

  1. The Web Mercator tile service use a QuadTree structure and have an implicit (x,y) tileID system built in. Basically for each (lat,long) pair there is a corresponding (x,y) tileID which you can use for your chunk placement.

  2. Use the AsUnityPosition directly as your chunk placement position.

  3. Use a Euclidian Coordinate space to compute chunk positions ( chunk 1 at (0,0) , chunk 2 at (20,0) and so on..) and then assume 1 unit in X = 1 longitude , 1 unit in y = 1 latitude and request tiles for those lat,long pair.

I think WebMercator is not the problem (as most projections will suffer from similar issues, because there is no globally accurate sphere to plane mapping)

If this still doesn't address your issue. I would suggest sharing a simplified example of your issue to help us understand better and help you out.

@genaray
Copy link
Author

genaray commented Dec 1, 2017

@atripathi-mb
Im very confused right now. You know what, i guess a lat/lng based chunk system isnt the best thing to do and its just to complicated... Did you guys even ever tried to create a visual equal lat/lng based chunk system ?

Ok here is my last question to this iusse, when that doesnt work i try an other chunk system.

I know that the distances between my chunks are equal, but the mercator projection does make them look like the distance from each other is increased and you already told me why.

But is it possible to make a grid/chunk system which just VISUAL LOOKS like the distance between every point is the same on the map ?
Until now i always told you that the distance between the chunks need to be equal... no it doesnt need to.

So when i have a grid with EQUAL square sizes (width = 750 meters,height = 750 meters), the mercator projection stretches them and makes them look ... stretched, right ?

So i just thought would it be possible that i create instead a grid with DIFFERENT/ADJUSTED square sizes ( width = 500 meters/height = 500 meters) to just make it VISUAL LOOK like the sizes and distances are the same to each other ?

For example, we have 2 points in europa which are exactly 750 meters away from each other.
Now we want 2 more points in greenland, so we just take the distance of 750 meters as before.

When we take a look at them we will see that the distance between the 2 points in greenland are stretched. Because the mathematical distance between them is equal, but not the VISUAL distance on the map.

So couldnt we just change the distance between the points in greenland to 500 meters ? That would make them VISUAL look like they have the same distance on the map like those 2 points in europe, even if thats not the case mathematicly. The mercator projection would stretch them like the rest to make them look like they have the same distance.

Would that work ? And if yes do you know how it could work and what to do ?

Thanks again for your support and help :)

@david-rhodes
Copy link

@genaray Ok, let's step back and simplify this problem. Each tile is the same size, regardless where you are in the world. Each chunk needs to be the same size. This is good, we can simply make a chunk from each tile.

screen shot 2017-12-01 at 1 39 30 pm

For this screenshot, I literally spawned a cube at the center of each tile (transform.position--no conversions). Isn't this what you need?

@genaray
Copy link
Author

genaray commented Dec 1, 2017

@david-rhodes Yep exactly. I also already thought about that, but the Problem ist that i cant Change the size of the tiles right ? When i want a bigger Chunk i cant do anything about it ... Also the Zoom Level effects the amount of tiles.

When i would increases the unity tile sizes the textures would get blured i guess.

What about my Idea from the Post before ?
Also If theres a formula to calculate the Mercator projection it should be possible to Change this formula a bit to remove the distortion/stretching or am i wrong ?

@david-rhodes
Copy link

Why can't you adjust the size of the tiles? UnityTileSize is the width and height that each tile will be in Unity coordinates.

You can dictate how many tiles you want in your TileProvider, as well.

Maybe you can tell us how you intend to use tile zoom level in your application? Ideally, you would simply create chunks for every tile at the zoom levels you are interested in. Then, you can simply match the chunk ID to the tile ID.

@genaray
Copy link
Author

genaray commented Dec 2, 2017

@david-rhodes That could Work... So I can modify the amount of tiles in the Tileprovider ? Im gonna Test that later :)

@david-rhodes
Copy link

You can make any tile provider implementation that you need for your application. It's all based on an ID system. 😉

@genaray
Copy link
Author

genaray commented Dec 3, 2017

@david-rhodes So i just tried to adjust the unity tile sizes, i noticed that somehow the resolution of the map is blurred...
Now im currently using 100 as unity tile size and a zoom of 18 for my game.
I also noticed that this :

      var leftTopTile = TileCover.CoordinateToTileId(new Vector2d(85, -180), 18);
       var rightBottomTile = TileCover.CoordinateToTileId(new Vector2d(-85, 180), 18);

       Debug.Log("<MapBox : Left Top Tile-ID "+leftTopTile.X+" "+leftTopTile.Y);
       Debug.Log("<MapBox : Right Bottom Tile-ID " + rightBottomTile.X + " " + rightBottomTile.Y);

Returns : 0;429 and 262144;261714
So why does the first mapbox tile got the id of 0;429 instead of 0;0 ?

@genaray
Copy link
Author

genaray commented Dec 3, 2017

@david-rhodes Also, i dont find any option to modify the amount of tiles in the tile provider :/

@abhishektrip
Copy link
Contributor

@genaray If you use the Range*TileProvider , you can specify how many tiles in each direction you want around the center tile.

@genaray
Copy link
Author

genaray commented Dec 5, 2017

@atripathi-mb Thanks ! :) Also i finally got a working chunk system !

@haxpor
Copy link

haxpor commented Apr 7, 2018

Apologize to bring this discussion back, are these similar functionalities available there as well on iOS SDK? I want to achieve the similar thing as I filed it here. It'd be helpful to know whether I need to port above functionality, or use existing functionalities in which I might miss on iOS SDK. Thank you!

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

No branches or pull requests

7 participants