ThinkGeo.com    |     Documentation    |     Premium Support

OpenStreetMap does not line up with Shapefile

Hi, 


I'm trying to open OpenStreetMap as background of my map, but it seems it does not line up properly with my ShapeFile.


I attached a small project which shows my code to load layers(OpenStreetMap, ShapeFile) and a small image which shows the problem.


 


Regards


 



OSM.PNG (58.7 KB)
SampleTG.zip (58.1 KB)

Hi Ben, 
  
 The shape file that you attached, its coordinate system is OSGB 1936 British National Grid (epsg:27700). 
 And open street map is using Google Maps Global Mercator (epsg:900013 alias:3785). 
 When we use the Proj4Projection to convert between those two projections, accuracy is lost. 
 And the reason of losing accuracy is rooted in the Proj4 library which we have no control over. 
 I’ll inform the dev team of this issue, but I won’t keep my hope up for this issue to be solved any time soon, since we aren’t really able to fix bugs in the Proj4 lib. 
  
 Regards, 
 Tsui

 Hi Tsui,


Many thanks for your answer.
 
I created another sample for you, in Silverlight. all the things are same but the problem become worse, what's the problem you thing?
what's your suggestion to solve this accuracy problem?
 
 
Best Regards,
Ben

SilverlightOSM.PNG (54.8 KB)
SilverlightOpenStreetMap.zip (153 KB)

Hi Ben, 
  
 The problem you encountered in Silverlight edition is caused mainly by two reasons: 
 1. The Proj4 system has accuracy losing issues, which we already know. 
 2. The open street map overlay in Silverlight edition has some tiling location issues too, and Bing overlay has the same issue. 
  
 We’d suggest you to use the Google overlay instead. That will reduce the accuracy lost, but won’t eliminate it, because the Proj4 bug will still be there. 
  
 The first reason of the problem is kind of out of our hands, we aren’t really able to fix bugs in the Proj4 lib. But we have an issue for it: MS3-6754. 
 The second reason is a known issue; its issue id is MS3-6400.But I’d not expect it to be fixed very soon, because we are launching the next release. We won’t be able to work on this issue until May 15th, at least. 
  
 Regards, 
 Tsui

Many thanks for you answer, 
 We can wait until you lunch your new release. 
  
 but we can not use GoogleMap, and first problem (MS3-6754) is really important for us too, so any suggestion which help us to solve or reduce the problem, will be really useful for us. 
  
 Best Regards,

Ben,


 I think that your issue is similar to the one described in the Proj4 website in FAQ: "Changing Ellipsoid / Why can't I convert from WGS84 to Google Earth / Virtual Globe Mercator?"


trac.osgeo.org/proj/wiki/FAQ#HowdoI...withPROJ.4


 So, with that in mind, I used the code as below and you can see the result in the screen shot. (the code is for the Desktop edition but the projection issue is the same for all the editions).  It matches pretty well with Open Street Map. I updated the internal issue MS3-6754 so that the development team is aware of my findings and do the appropriate change to fix the bug.


 



  winformsMap1.MapUnit = GeographyUnit.Meter;

    OpenStreetMapOverlay openStreetMapOverlay = new OpenStreetMapOverlay();
    winformsMap1.Overlays.Add(openStreetMapOverlay);

    Proj4Projection proj4 = new Proj4Projection();
    proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(27700);
    //For the Spherical Mercator projection, we need to apply no null grid shift:
    proj4.ExternalProjectionParametersString = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"; 
                                               
    ShapeFileFeatureLayer shapeFileFeatureLayer = new ShapeFileFeatureLayer(@"..\..\data\sample.shp");
    shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Red,
                                                                      3, true);
    shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
    shapeFileFeatureLayer.FeatureSource.Projection = proj4;

    LayerOverlay layerOverlay = new LayerOverlay();
    layerOverlay.Layers.Add(shapeFileFeatureLayer);
    winformsMap1.Overlays.Add(layerOverlay);

    shapeFileFeatureLayer.Open();
    winformsMap1.CurrentExtent = shapeFileFeatureLayer.GetBoundingBox(); 
    shapeFileFeatureLayer.Close();

    winformsMap1.Refresh();


See screen shot:




Hi Val, 
  
 Many thanks for your great answer. 
 the answer completely solved the problem of OSM on WPF. 
  
 do you have idea about problem OSM and silverlight? 
  
 Best Regards, 
 Ben

Ben, 
  
  I am glad this solves the problem for the WPF edition. Regarding the problem the SilverLight problem, I passed this to the SilverLight development team because I think this is SilverLight specific issue. You should hear from them as soon as monday morning. Thank you.

Thank you very much for your very prompt reply. 


Ben,


This issue is caused by projection mismatch. You can adjust your ExternalPorjectionParametersString to meet your requirement. The code snippet below is for your reference.


Proj4Projection proj4 = new Proj4Projection();
proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(27700);
proj4.ExternalProjectionParametersString = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=-35490 +y_0=24070 +k=1.0 +units=m +nadgrids=@null +no_defs";
shapeFileFeatureLayer.FeatureSource.Projection = proj4;


Please let me know if you have further questions.


Regards,


Ivan



Ivan, 
  
  The external projection I provided is adequate as you can see in the screen shot. The issue seemed to be specific to SilverLight. You did not address that in your response. How did you come up with that external projection string with those false easting and false northing parameters? Thank you.

Val, 
  
 In SilverlightEdition, I examined the bounding box of “Sample.shp”, although the source file and projection are identical, the bounding box is different from that of Desktop edition. Currently I didn’t find the root cause of this issue, so I adjust the projection parameter as a workaround. 
  
 Regards, 
  
 Ivan

Ben,


Another solution for your silverlight issue is using different scales while using OpenStreetMapOverlay.


--Client Side


zoomLevelSet.ZoomLevel20.Scale = 1128.50;
zoomLevelSet.ZoomLevel19.Scale = 2257.00;
zoomLevelSet.ZoomLevel18.Scale = 4514.00;
zoomLevelSet.ZoomLevel17.Scale = 9028.00;
zoomLevelSet.ZoomLevel16.Scale = 18055.99;
zoomLevelSet.ZoomLevel15.Scale = 36111.98;
zoomLevelSet.ZoomLevel14.Scale = 72223.96;
zoomLevelSet.ZoomLevel13.Scale = 144447.93;
zoomLevelSet.ZoomLevel12.Scale = 288895.85;
zoomLevelSet.ZoomLevel11.Scale = 577791.71;
zoomLevelSet.ZoomLevel10.Scale = 1155583.42;
zoomLevelSet.ZoomLevel09.Scale = 2311166.84;
zoomLevelSet.ZoomLevel08.Scale = 4622333.68;
zoomLevelSet.ZoomLevel07.Scale = 9244667.36;
zoomLevelSet.ZoomLevel06.Scale = 18489334.72;
zoomLevelSet.ZoomLevel05.Scale = 36978669.43;
zoomLevelSet.ZoomLevel04.Scale = 73957338.86;
zoomLevelSet.ZoomLevel03.Scale = 147914677.73;
zoomLevelSet.ZoomLevel02.Scale = 295829355.45;
zoomLevelSet.ZoomLevel01.Scale = 591658710.9;
Map.SyncClientZoomLevels(zoomLevelSet);


--Sever Side


Proj4Projection managedProj4 = new Proj4Projection();
managedProj4.InternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(27700);
managedProj4.ExternalProjectionParametersString = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs";
shapeFileFeatureLayer.FeatureSource.Projection = managedProj4;


The output is below.



Regards,


Ivan