Booster2ooo
Booster2ooo

Reputation: 21

Place GPS coordinates on a map image without external API

I'm currently working on a "trip tracker". The goal is to place some GPS coordinates (logged by a GPS device) on a static image map downloaded from MapQuest (or OpenStreetMap). In order to achieve this goal, I followed to follwing procedure:

  1. Find my GPS coordinates set's center ((maxLat-minLat)/2, (maxLon-minLon)/2)
  2. Download a 3840x3840 map (fixed zoom 15 for now) centered on my "coordinates set's center" from MapQuest
  3. Using mercator projection (I tries both spherical & eliptical with EPSG:4326 or EPSG:3857), get the (X,Y) of the center in meters
  4. For each point of my set
  5. Get the point's (X,Y) using mercator projection
  6. Substract the point(X,Y) to center(X,y)
  7. Convert meters to pixel according to Zoom level and map (tile?) width (I tried both tile width (256) and map width (3840)

Unfortunatly, in one week of research & tries, I didn't succeed in placing those point.

Does anybody have a complete solution for this kind of problems ?

Thank you

Edit #1

(Removed: inconsistent)

Edit #2

Here is a clean project sample

https://dl.dropboxusercontent.com/u/429726/MapSample.zip

Img: https://dl.dropboxusercontent.com/u/429726/MapSample.jpg

Edit #3

Added multiple formulas

GeographicCoordinates > ToMercator() modification

public System.Windows.Point ToMercator(int test = 0)
{
    System.Windows.Point mercator;
    double x = this.Longitude.ToMercator(test);
    double y = this.Latitude.ToMercator(test);
    mercator = new System.Windows.Point(x, y);
    return mercator;
}

GeographicCoordinate > ToMercator() modification

public double ToMercator(int test = 0)
{
    double result = 0;
    switch (this.Type)
    {
        case(GeographicCoordinateType.Longitude):
            switch (test) { 
                case 0:
                    return this.DecimalDegrees.ToRadians() * Maps.EarthGreatRadius;
                case 1:
                    //http://jackofalltradesdeveloper.blogspot.be/2012/03/how-to-project-point-from-geography-to.html
                    return this.DecimalDegrees * 0.017453292519943 * 6378137;
                case 2:
                    //http://alastaira.wordpress.com/2011/01/23/the-google-maps-bing-maps-spherical-mercator-projection/
                    return this.DecimalDegrees * 20037508.34 / 180;
            }
            break;
        case(GeographicCoordinateType.Latitude):
            switch (test)
            {
                case 0:
                    double latitude = this.DecimalDegrees;
                    if (latitude > 89.5)
                    {
                        latitude = 89.5;
                    }
                    if (latitude < -89.5)
                    {
                        latitude = -89.5;
                    }
                    double temp = Maps.EarthGreatRadius / Maps.EarthGreatRadius;
                    double es = 1.0 - (temp * temp);
                    double eccent = Math.Sqrt(es);
                    double phi = latitude.ToRadians();
                    double sinphi = Math.Sin(phi);
                    double con = eccent * sinphi;
                    double com = 0.5 * eccent;
                    con = Math.Pow((1.0 - con) / (1.0 + con), com);
                    double ts = Math.Tan(0.5 * ((Math.PI * 0.5) - phi)) / con;
                    double y = 0 - Maps.EarthGreatRadius * Math.Log(ts);
                    return y;
                case 1:
                    double FSin = Math.Sin(this.DecimalDegrees.ToRadians());
                    return 6378137 / 2.0 * Math.Log((1.0 + FSin) / (1.0 - FSin));
                case 2:
                    y  = Math.Log(Math.Tan((90 + this.DecimalDegrees) * Math.PI / 360)) / (Math.PI / 180);
                    return y * 20037508.34 / 180;
            }
            break;
        default:
            throw new Exception();
    }
    return result;
}

Edit #4

I've tried multiples formulas & Proj.Net library, I always end up with the same shape (-90° && "flatened")

Upvotes: 1

Views: 8144

Answers (3)

Booster2ooo
Booster2ooo

Reputation: 21

Here is the answer

GeographicCoordinates > ToMercator()

public System.Windows.Point ToMercator(int test = 0)
{
    System.Windows.Point mercator;
    double x = this.Longitude.ToMercator(test);
    double y = this.Latitude.ToMercator(test);
    mercator = new System.Windows.Point(x, y);
    return mercator;
}

Should be

public System.Windows.Point ToMercator(int test = 0)
{
    System.Windows.Point mercator;
    double x = this.Latitude.ToMercator(test);
    double y = this.Longitude.ToMercator(test);
    mercator = new System.Windows.Point(x, y);
    return mercator;
}

And GeographicCoordinate > ToMercator() should swap GeographicCoordinateType.Latitude/Longitude cases.

I also had to fix Y according to the hemisphere

& the job was done.

Upvotes: 0

Martin Milan
Martin Milan

Reputation: 6390

I've used this in the past to build information on a map on a Windows Form client:

http://greatmaps.codeplex.com/

Upvotes: 0

Cybercartel
Cybercartel

Reputation: 12592

The map coordinates need also translate to mercator. You need delta x and delta y of the map and the image properties:Convert lat/lon to pixel coordinate?.

Upvotes: 0

Related Questions