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

Projection conversion (WGS84 -> Mercator) question #1331

Closed
BirukTes opened this issue Nov 2, 2021 · 15 comments
Closed

Projection conversion (WGS84 -> Mercator) question #1331

BirukTes opened this issue Nov 2, 2021 · 15 comments
Labels

Comments

@BirukTes
Copy link

BirukTes commented Nov 2, 2021

Hello,

We are new to Map Controls and Mapsui, and having issues understanding the projection conversions, the results as are follows. The Contour lines data comes from NOAA, and is calculated using the OxyPlot library, seems correct even according to the small rectangle below but when it came to the Global data, which covers 0, 360 and -90, 90 degrees. According to our tests with polygons, Mapsui seems to be limited to ±180 and ±85, as it would not draw with higher than these numbers? (unless we were doing something wrong, as converted using SphericalMercator.FromLonLat(0, 0)).

Any advice would be great, thank you!

Contour lines/LineString code (Click to expand)

Half way off-site (on the tilelayer?) renders:

SvocYoEOXd
AWcAgNwbX8
H3CsLmV5jB

Correct rectangle area conversion

cLCCjHsayT

converted to SM unit, LineString

{LINESTRING (14144305.9249581 222684.208505545, 14146086.8725675 231201.139468704, 14138573.2146273 333111.922170972, 14139014.8069197 334111.17140196, 14144344.7592397 340890.079699847, 14183240.9229634 399874.071311757, 14212686.062437 409349.940218685, 14248894.821539 428930.540922845, 14258248.7509737 436263.816288412, 14271048.864937 445640.109656027, 14261007.8236847 457783.504164248, 14248894.821539 461716.003920748, 14203106.0836212 511355.647743129, 14200090.7277095 557305.257274575, 14209889.6003497 596470.194430118, 14248894.821539 611612.843446787, 14303478.6697952 614280.545399771, 14306024.4545782 614676.365759493, 14360214.3123323 617921.31476913, 14390449.9107648 638746.37006298, 14410508.1672413 669141.057044245, 14422262.4453932 718704.432078043, 14471533.8031256 742533.281849441, 14507935.0596179 705754.002862049, 14565846.1494921 669141.057044245, 14573232.1093574 659467.63946003, 14582853.2939188 652213.569299688, 14592053.880248 659890.489349537, 14633874.7271989 669141.057044245, 14682257.5996945 681123.057562906, 14694172.7847121 693847.31021879, 14722737.9995752 752410.293557938, 14723698.1748647 781182.214188248, 14718155.866133 805351.04106474, 14694172.7847121 849302.943469934, 14673722.5187068 872817.124675088, 14647742.3338327 893463.751012645, 14647978.0214007 940136.662873366, 14644626.4867606 955887.494592196, 14644788.402767 1006021.06275513, 14605881.4145841 1029342.95138802, 14582853.2939188 1044725.91807055, 14527275.1610521 1062331.56399593, 14527109.9753309 1062329.57607567, 14471533.8031256 1111429.03390323, 14427933.6692314 1074643.55495423, 14459642.8575181 1118889.97485796, 14379038.9938649 1138010.06086225, 14360214.3123323 1151377.75797288, 14326549.1437456 1197828.95469926, 14314379.6402362 1232106.80189676, 14294077.8199874 1278167.5822248, 14272678.507072 1321402.9559831, 14261133.8713936 1345708.40840911, 14258615.110409 1355647.46806127, 14248894.821539 1369039.90540607, 14209349.3337382 1419175.3356418, 14193998.3426932 1459732.2718805, 14175891.2443032 1499083.58287907, 14137575.3307457 1567159.06843006, 14134966.2801803 1571527.76212701, 14134229.3727686 1574216.54816146, 14134346.4504879 1577544.48633595, 14123599.2746176 1674735.29607252, 14123977.543943 1689200.13960789, 14122326.694427 1704991.76324687, 14128247.7360501 1795021.30529091, 14126739.4441419 1804722.76625729, 14125786.2874499 1816990.15951934, 14120125.551695 1902585.5545829, 14118677.7534331 1920825.04037747, 14115937.6047228 1943463.21757854, 14126681.4003145 2026097.16013533, 14124112.9126518 2037548.5447506, 14061296.3638012 2074425.44101845, 14026255.8399525 2094125.97584981, 14003919.6564102 2131326.88859717, 13989610.5388284 2154935.91508589, 13969583.5731999 2212818.08108193, 13967454.0121544 2217225.74780375, 13943599.1581883 2273030.92698769, 13928413.5640007 2287378.60810893, 13914936.3491592 2302519.15197322, 13879886.1816197 2354374.13119094, 13844282.0602828 2391878.58794431, 13823312.7390438 2412988.27950425, 13803616.8583659 2433801.93893676, 13768019.6284135 2473175.40835845, 13721396.2124537 2511525.23484571, 13705611.6591873 2525891.23035681, 13692297.3675727 2536431.64834832, 13658088.7440156 2548460.63430405, 13629750.3480424 2564209.98059515, 13580977.8767794 2573884.33139244, 13539422.4381231 2586936.44730294, 13475247.4878438 2632018.63758642)}

Polygon code (Click to expand)

Complete fill of the tilelayer

ProjectWeather_ln28k1sURk

        polygon.ExteriorRing.Vertices.Add(SphericalMercator.FromLonLat(-180, 85.05));
        polygon.ExteriorRing.Vertices.Add(SphericalMercator.FromLonLat(-180, -85.05));
        polygon.ExteriorRing.Vertices.Add(SphericalMercator.FromLonLat(180, -85.05));
        polygon.ExteriorRing.Vertices.Add(SphericalMercator.FromLonLat(180, -85.05));
        polygon.ExteriorRing.Vertices.Add(SphericalMercator.FromLonLat(180, 85.05));

Results from below code

testname

        var result = new List<Polygon>();
        var polygon = new Polygon();
        var t = SphericalMercator.ToLonLat(0, 10000000); // 0, 66.4460277131412

        // From converted values: uncomment
        //polygon.ExteriorRing.Vertices.Add(SphericalMercator.FromLonLat(0, 0));
        //polygon.ExteriorRing.Vertices.Add(SphericalMercator.FromLonLat(0, 66.4460277131412));
        //polygon.ExteriorRing.Vertices.Add(SphericalMercator.FromLonLat(66.4460277131412, 66.4460277131412));
        //polygon.ExteriorRing.Vertices.Add(SphericalMercator.FromLonLat(66.4460277131412, 0));
        //polygon.ExteriorRing.Vertices.Add(SphericalMercator.FromLonLat(0, 0));
        // Result: POLYGON((0 -7.08115455161362E-10, 0 10000000, 7396737.97026262 10000000, 7396737.97026262 -7.08115455161362E-10, 0 -7.08115455161362E-10))

        // From Sample
        polygon.ExteriorRing.Vertices.Add(new Mapsui.Geometries.Point(0, 0));
        polygon.ExteriorRing.Vertices.Add(new Mapsui.Geometries.Point(0, 10000000));
        polygon.ExteriorRing.Vertices.Add(new Mapsui.Geometries.Point(10000000, 10000000));
        polygon.ExteriorRing.Vertices.Add(new Mapsui.Geometries.Point(10000000, 0));
        polygon.ExteriorRing.Vertices.Add(new Mapsui.Geometries.Point(0, 0));
        // Result: POLYGON((0 0, 0 10000000, 10000000 10000000, 10000000 0, 0 0))

        result.Add(polygon);

        var l = new MemoryLayer("Polygons")
        {
            DataSource = new MemoryProvider(result),
            Style = new VectorStyle
            {
                Fill = new Brush(new Color(150, 150, 30, 128)),
                Outline = new Pen
                {
                    Color = new Color(150, 150, 30, 1),
                    Width = 0
                }
            }
        };

        MyMapControl.Map.Layers.Add(l);
@pauldendulk
Copy link
Member

pauldendulk commented Nov 3, 2021

I don't fully understand your problem yet. As a start I added a point projection sample of cities around the world to make sure it is not impossible to cover the whole area of spherical mercator.

image

I think your problem is related to wrap around. The cities have longitudes between -180 and 180. You mention your data is between 0 and 360. I think you data needs a small conversion to work with Mapsui. Something like this::

lon = lon > 180 ? lon - 360 : lon

Admitted Mapsui could have dealt with it itself. Something to improve.

@BirukTes
Copy link
Author

BirukTes commented Nov 5, 2021

Thank you, actually shifting every longitude (it was probably the latitude) by minus 180 worked as below:
ls.Vertices.Add(SphericalMercator.FromLonLat(point.Y - 180, point.X)); (The Y is the latitude data ±90, but it seems to work taking away 180).

This code did not work, the contours were distorted:
ls.Vertices.Add(SphericalMercator.FromLonLat((point.Y > 180 ? point.Y - 360 : point.Y), point.X));

ogKeNnd5Ja

  • I am not sure, if we will use the SphericalMercator.ToLonLat but it seems to give different result when converting back, like the example posted 'Polygon code (Click to expand)'.

@pauldendulk
Copy link
Member

pauldendulk commented Nov 5, 2021

A little bit about lon and lat.

The order of lon and lat always causes a lot of confusion. The official notation is lat, lon, but in a map like above the lat corresponds to the y-axis and the lon to the x-axis. This is confusing because x, y are ordered the other way around. There is no way that this problem can be properly solved, there will always be confusion. In the code of Mapsui we try to stick to an x, y ordering. The name of the method FromLonLat tries to indicate this order. I see you pass in the y as first argument. If the result is correct the y is probably the lon, this does not have to be a problem but it is easier to stick to x, y.

I still don't know what is going on. If you could provide me with the source data I could take a look? Could I use this data in a sample?

@pauldendulk
Copy link
Member

btw, which geometry types are you using? What kind of provider and layer?

@BirukTes
Copy link
Author

BirukTes commented Nov 5, 2021

We tried switching the order in the SphericalMercator functions, as the result would become not correct or very strangely and mostly vertically centred with distorted visuals, and someone was saying to switch them in one of the Mapsui issues to Y, X, and not to give what the function was asking for, like: X, Y.

  • The Polygon code (Click to expand) above was just tests we ran to test the SphericalMercator functions and our question was that, the converting back process was not correct, unless we did something wrong...
  • We will be able to make the project available (as a zip), it needs some cleaning of the OxyPlot library, there are somethings that we do not need from the library.
  • We are thinking of adding a Heat Map, we know Mapsui does not have this, but it has basic objects. It would be great if you have any ideas about the best way to implement this feature, similar to ThinkGeo's or Bing Maps' one:
    - https://thinkgeo.com/features/data-visualization
    - https://www.bing.com/api/maps/sdkrelease/mapcontrol/isdk/customizedheatmap

@BirukTes
Copy link
Author

BirukTes commented Nov 5, 2021

btw, which geometry types are you using? What kind of provider and layer?

  • These are LineString Geometry in a MemoryLayer and List<IFeature> for adding the labels

@pauldendulk
Copy link
Member

If you have some data on this I can give it priority.

@BirukTes
Copy link
Author

BirukTes commented Nov 8, 2021

Great, thank you very much. I have just imported it to GitHub, you will receive an invitation to the project. It needs several time consuming clean ups which is not done yet, but you should able to restore to the packages and run it.

@pauldendulk
Copy link
Member

I saw that. Hope to have time this Friday.

@BirukTes
Copy link
Author

Hello @pauldendulk, did you manage to check the project?, I am working in Azure DevOps, that is why I couldn't update it in GitHub...

@pauldendulk
Copy link
Member

Not yet, and it will not before next Friday. I have been working on projections last weeks so it is something I really should look into soon.

@pauldendulk
Copy link
Member

@BirukTes When I do a clone the project does not build because it is looking for a beta of Grib.Api. I tried to fix this by removing all references toGrib.Api and adding it from nuget, but now I have another error:

Severity	Code	Description	Project	File	Line	Suppression State
Error		This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is ..\packages\SQLitePCLRaw.lib.e_sqlite3.2.0.7\build\net461\SQLitePCLRaw.lib.e_sqlite3.targets.	ProjectWeather	C:\code\github\ProjectWeather\ProjectWeather\ProjectWeather\ProjectWeather.csproj	345	

If you could get this to build from a clean checkout I could take a look later today.

@BirukTes
Copy link
Author

Yes, I guessed you would encounter such errors. We have updated the package config and added some of the missing files such as Grib file...You can re-clone and restore (rebuild solution, from NuGet CLI do restore) the packages and try again (Update the file Paths also, it is a prototype project).

Apparently, there is dependency for SkiaRender that is not included in the dependency, or for some reason it could not work for me without it. It is called: SVG2XAML, at the beginning the SkiaRender was fine until at some point I added a package, I cannot remember but ignored it to using WPFRender (which shows the white lines/gaps in the between the tiles), after discovering the MapsuiLogger which gave me clues that the SVG2XAML was needed and it solved. So, I wonder if it is a dependency that was not included?, what do you think?

@pauldendulk
Copy link
Member

Yes, I guessed you would encounter such errors. We have updated the package config and added some of the missing files such as Grib file...You can re-clone and restore (rebuild solution, from NuGet CLI do restore) the packages and try again (Update the file Paths also, it is a prototype project).

Now it build but I still get a runtime exception during startup

System.TypeInitializationException
  HResult=0x80131534
  Message=The type initializer for 'SQLite.SQLiteConnection' threw an exception.
  Source=SQLite-net
  StackTrace:
   at SQLite.SQLiteConnection..ctor(SQLiteConnectionString connectionString)
   at BruTile.MbTiles.MbTilesTileSource..ctor(SQLiteConnectionString connectionString, ITileSchema schema, MbTilesType type, Boolean determineZoomLevelsFromTilesTable, Boolean determineTileRangeFromTilesTable)
   at ProjectWeather.Views.MainView.CreateMbTilesLayer(String path, String name) in C:\code\github\ProjectWeather\ProjectWeather\ProjectWeather\Views\MainView.xaml.cs:line 204
   at ProjectWeather.Views.MainView..ctor() in C:\code\github\ProjectWeather\ProjectWeather\ProjectWeather\Views\MainView.xaml.cs:line 47

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
Exception: Library e_sqlite3 not found
plat: win
suffix: DLL
possibilities (2):
    1) C:\code\github\ProjectWeather\ProjectWeather\ProjectWeather\bin\Debug\runtimes\win-x64\native\e_sqlite3.dll
    2) C:\code\github\ProjectWeather\ProjectWeather\ProjectWeather\bin\Debug\e_sqlite3.dll
win TryLoad: C:\code\github\ProjectWeather\ProjectWeather\ProjectWeather\bin\Debug\runtimes\win-x64\native\e_sqlite3.dll
thrown: System.ComponentModel.Win32Exception (0x80004005): The specified module could not be found
   at SQLitePCL.NativeLibrary.TryLoad(String name, Loader plat, Action`1 log, IntPtr& h)
win TryLoad: C:\code\github\ProjectWeather\ProjectWeather\ProjectWeather\bin\Debug\e_sqlite3.dll
thrown: System.ComponentModel.Win32Exception (0x80004005): The specified module could not be found
   at SQLitePCL.NativeLibrary.TryLoad(String name, Loader plat, Action`1 log, IntPtr& h)
NOT FOUND

Apparently, there is dependency for SkiaRender that is not included in the dependency, or for some reason it could not work for me without it. It is called: SVG2XAML, at the beginning the SkiaRender was fine until at some point I added a package, I cannot remember but ignored it to using WPFRender (which shows the white lines/gaps in the between the tiles), after discovering the MapsuiLogger which gave me clues that the SVG2XAML was needed and it solved. So, I wonder if it is a dependency that was not included?, what do you think?

I see SVG2XAML is used in the in the WPF renderer and missing in the nuspec. So that is an error in Mapsui, but one that will probably not be fixed, since in 4 we are not supporting the WPF renderer anymore.

So, my advice is to use the Skia renderer, which you are using in your code (MyMapControl.RenderMode = Mapsui.UI.Wpf.RenderMode.Wpf is commented out). What exactly is the problem in that scenario? Do you still see an error in the log? It do the graphics not look like they should?

@BirukTes
Copy link
Author

I am not sure, what the solution to this is, but it is okay, you can stop working on this project. It is unlikely that we will be continuing work on it, maybe in the long future, we had stopped a couple weeks ago. On our real project ThinkGeo's map controls are used. Thank you for your time.

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

2 participants