Google Map Background layer not aligning to my parcel data

Topics: SharpMap Project, SharpMap v0.9 / v1.x
Aug 22 at 10:57 AM
Edited Aug 22 at 12:19 PM
Hi,
I've been at this for quite a while now.
What I'm trying to achieve here is to add a Google map as background layer to my Sharpmap, I'm able to achieve this but the problem I'm facing now is My map always centre's to a point near a Greenland in Google Map , it's like it won't take my centre point coordinates.

I'm using Sharpmap 1.1 with BruTile 0.7.4.4

So far I've done the below.
SharpMap.Map _map = new SharpMap.Map();
SharpMap.Layers.VectorLayer layer = new SharpMap.Layers.VectorLayer("parcel");
SharpMap.Data.Providers.MsSqlSpatial DBlayer = new SharpMap.Data.Providers.MsSqlSpatial(_connectionString, "XXXXXX", "XXXX", "XXX");
 layer.Style.Fill = new SolidBrush(Color.Transparent);
     layer.Style.Outline = new Pen(Color.Black);
     layer.Style.EnableOutline = true;
     layer.MaxVisible = 13000;

    layer.DataSource = DBlayer;

    ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory ctFact = new ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory();
    layer.CoordinateTransformation = ctFact.CreateFromCoordinateSystems(ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84, ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator);
    layer.ReverseCoordinateTransformation = ctFact.CreateFromCoordinateSystems(ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);

    //SharpMap.Layers.TileLayer layerBackground = new TileLayer(new BingTileSource(BingRequest.UrlBing, "", BingMapType.Aerial), "TileLayer");
    SharpMap.Layers.TileLayer layerBackground = new TileLayer(new GoogleTileSource(GoogleMapType.GoogleMap), "googlemaps");   

    _map.Layers.Add(layerBackground);

    _map.Layers.Add(layer);

    _map.BackColor = Color.White;

    //-98.526890,29.411539  
    _map.Center = new GeoAPI.Geometries.Coordinate(0,0);

   return _map;
Even if I manually give Geo Coordinates It just points to the same spot in sea.

Please see the below Google map Geo point, this is the point where my map shows as centre. Every time I generate no matter what I do it shows this point as its centre.
71.946088, -3.956171
Any help is much appreciated. Thanks and Cheers!
Coordinator
Aug 23 at 11:55 AM
Could you post the result of DBLayer.GetExtents().
Aug 24 at 4:44 AM
Edited Aug 24 at 4:46 AM
I'm getting an error when trying to get the extents.
Cannot implicitly convert type 'GeoAPI.Geometries.Envelope' to 'SharpMap.Data.Providers.IProvider'. An explicit conversion exists (are you missing a cast?)
I suspect the problem is with the coordinate transformation but can't figure out what's wrong
Coordinator
Aug 24 at 5:58 AM
The provider does not care about any coordinate transformation.
There should be no casting from Envelope to IProvider. Could you show the code?
Aug 24 at 9:08 AM
Edited Aug 24 at 9:52 AM
I was talking about the pinning of google maps to the sea (the coordinate Transformation thing).

Please see the core code which generates the map.
SharpMap.Map _map = new SharpMap.Map();

           
        //HttpContext.Current.Trace.Write("Initializing map...")
      
        //string _parcelTable = null;

        int _SRID;
        _SRID = 0;
        //_parcelTable = "";
        _connectionString = System.Configuration.ConfigurationManager.AppSettings["XX"];

        _SRID = 0;
       _parcelTable = "XXX";

        _map.Layers.Clear();
        _map.Size = size;
      // _map.PixelAspectRatio = pixel;
        //System.Drawing.Color mapcolor = System.Drawing.ColorTranslator.FromHtml("#020824");

 
        SharpMap.Layers.VectorLayer layer = new SharpMap.Layers.VectorLayer("parcel");

        SharpMap.Data.Providers.MsSqlSpatial DBlayer = new SharpMap.Data.Providers.MsSqlSpatial(_connectionString, "XXX", "XXX", "XX");
      
     //layer.DataSource = new SharpMap.Data.Providers.ShapeFile(@"c:\ConvertedParcel.shp");
    layer.DataSource = DBlayer.GetExtents();
     layer.Style.Fill = new SolidBrush(Color.Transparent);
     layer.Style.Outline = new Pen(Color.Black);
     layer.Style.EnableOutline = true;
     layer.MaxVisible = 13000;
 ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory ctFact = new ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory();
    layer.CoordinateTransformation = ctFact.CreateFromCoordinateSystems(ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84, ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator);
    layer.ReverseCoordinateTransformation = ctFact.CreateFromCoordinateSystems(ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);
    //SharpMap.Layers.TileLayer layerBackground = new TileLayer(new BingTileSource(BingRequest.UrlBing, "", BingMapType.Aerial), "TileLayer");
    SharpMap.Layers.TileLayer layerBackground = new TileLayer(new GoogleTileSource(GoogleMapType.GoogleMap), "googlemaps");

    _map.Layers.Add(layer);
    _map.BackgroundLayer.Add(layerBackground);    

    _map.BackColor = Color.White;

    //-98.526890,29.411539  
    _map.Center = new GeoAPI.Geometries.Coordinate(0,0);//SharpMap.Geometries.Point(0, 0);
  

    return _map;
FObermaier does this help you?
Coordinator
Aug 24 at 10:07 AM
This canot work:
layer.DataSource = DBlayer.GetExtents();
I wanted you to add sth like the following line:
System.Console.WriteLine(DBlayer.GetExtents());
layer.DataSource = DBlayer;
Please report what is written to the console/output pane during execution.
Aug 24 at 10:31 AM
Edited Aug 24 at 10:31 AM
The below is what I got
DBlayer.GetExtents()
{Env[-95.9608197152296 : -94.9076037302456, 29.4972965529593 : 30.1705440427555]}
    Area: 0.70907501810369788
    Centre: {(-95.4342117227376, 29.8339202978574, NaN)}
    Height: 0.67324748979619287
    IsNull: false
    MaxExtent: 1.0532159849839928
    MaxX: -94.9076037302456
    MaxY: 30.170544042755541
    MinExtent: 0.67324748979619287
    MinX: -95.96081971522959
    MinY: 29.497296552959348
    Width: 1.0532159849839928
    MinExtent: 0.67324748979619287
Coordinator
Aug 24 at 12:21 PM
// this should work:
_map.ZoomToBox(layer.Envelope);
// Or, if you don't want to change the zoom level
_map.Center = layer.Envelope.Centre
Aug 24 at 1:05 PM
Edited Aug 24 at 1:06 PM
FObermaier,

I tried both but it still points to the same point , however in Bing map layer the point has changed from that of google map layer and now it has moved to a residential area in Greenland.
Coordinator
Aug 24 at 1:51 PM
Is layer.Envelope same as DBlayer.GetExtents()?
Aug 25 at 4:56 AM
Edited Aug 25 at 4:56 AM
This is what I got

layer.Envelope.ToString()
 "Env[-10682309.5868045 : -10565066.1196607, 3439094.29137215 : 3525490.58059818]"
DBlayer.GetExtents()
{Env[-95.9608197152296 : -94.9076037302456, 29.4972965529593 : 30.1705440427555]}
    Area: 0.70907501810369788
    Centre: {(-95.4342117227376, 29.8339202978574, NaN)}
    Height: 0.67324748979619287
    IsNull: false
    MaxExtent: 1.0532159849839928
    MaxX: -94.9076037302456
    MaxY: 30.170544042755541
    MinExtent: 0.67324748979619287
    MinX: -95.96081971522959
    MinY: 29.497296552959348
    Width: 1.0532159849839928
Coordinates Seem to be different.
Coordinator
Aug 25 at 6:50 AM
Edited Aug 25 at 6:56 AM
When I adapt your code by replacing the DBlayer with a geometry representing the envlope you posted, I get a map of the Houston area. You must be changing your viewport someplace else.
public void Discussion657340()
{
    var size = new System.Drawing.Size(640, 480);
    var map = new SharpMap.Map(size);

    // -95.9608197152296 : -94.9076037302456, 29.4972965529593 : 30.1705440427555
    // -10682309.5868045 : -10565066.1196607, 3439094.29137215 : 3525490.58059818

    var factory = GeoAPI.GeometryServiceProvider.Instance.CreateGeometryFactory(4326);
    var parcel =
        new SharpMap.Data.Providers.GeometryFeatureProvider(
            factory.ToGeometry(new Envelope(-95.9608197152296, -94.9076037302456, 29.4972965529593,
                30.1705440427555)));
    var layer = new SharpMap.Layers.VectorLayer("parcel", parcel);
    layer.Style.Fill = new System.Drawing.SolidBrush(System.Drawing.Color.Transparent);
    layer.Style.Outline = new System.Drawing.Pen(System.Drawing.Color.Black, 2f);
    layer.Style.EnableOutline = true;
    //layer.MaxVisible = 13000;
    var ctFact = new ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory();
    layer.CoordinateTransformation =
        ctFact.CreateFromCoordinateSystems(ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84,
            ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator);
    layer.ReverseCoordinateTransformation =
        ctFact.CreateFromCoordinateSystems(ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator,
            ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);
    //SharpMap.Layers.TileLayer layerBackground = new TileLayer(new BingTileSource(BingRequest.UrlBing, "", BingMapType.Aerial), "TileLayer");

    var layerBackground =
        new SharpMap.Layers.TileLayer(new BruTile.Web.GoogleTileSource(BruTile.Web.GoogleMapType.GoogleMap),
            "googlemaps");

    map.Layers.Add(layerBackground);
    map.Layers.Add(layer);

    map.BackColor = System.Drawing.Color.White;

    //-98.526890,29.411539  
    map.ZoomToBox(layer.Envelope.Grow(layer.Envelope.MaxExtent*0.1));
    var img = map.GetMap();
    var name = System.IO.Path.ChangeExtension(System.IO.Path.GetTempFileName(), "png");
    img.Save(name);
    Console.WriteLine("Filename: {0}", new Uri(name).AbsoluteUri);
}
Aug 25 at 8:49 AM
Edited Aug 25 at 8:51 AM
Yes, my map covers all of the Houston area.
What did you mean by changing viewport?
You mean changing the centre of the map?
Coordinator
Aug 25 at 9:21 AM
Lookout for
  • _map.ZoomToExtents()
  • _map.ZoomToBox(...)
  • _map.Zoom = ...
  • _map.Centre = ...
These are the functions that might change the viewport and the centre.
Aug 26 at 5:56 AM
Edited Aug 26 at 5:58 AM
FObermaier,
I found the problem for Google map layer not centring, the reason is that I used QGIS to convert my ESRI shapefile to WGS84 format and it changed the coordinates to UTM format but Google uses Google Maps Global Mercator -- Spherical Mercator. When I used an online converter to test this out. It worked just fine once I gave that coordinates. Now all i have to do is find a way to convert my UTM coordinates to Google Maps Global Mercator -- Spherical Mercator on the fly.

Thanks for your help FObermaier, if it wasn't for you I would've still be stuck without an idea of what's wrong. You rock man!