Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm using Google's Projection class to try to convert my map projection from the default spherical mercator to something like Lambert Conformal Conic. I was previously adapting the code from this example to the v3 API, but am getting some weird drawing errors. Then I remembered Proj4 and decided to try it out.

I'm not sure how to use it with the Projection's two main functions:

  • fromLatLngToPoint()
  • fromPointToLatLng()

I understand how Proj4 returns a meter value when you pass it a lat long and a destination projection, but I'm not sure how that could be used with the Projection class's functions (or if this is even the correct approach to doing custom projections in Google maps anyway).

I think the main thing that I'm not sure about is how to use the Point object in these functions. Am I going to need to take into account my map canvas size + my map bounds to do a calculation on my Point's relative position within the frame?

Here's an image of what it looks like, and my code is below:

// my base layer, currently with no tiles
var lambertBase = new google.maps.ImageMapType({
    getTileUrl: function(coord, zoom) {
        return null;
    },
    tileSize: new google.maps.Size(256,256),
    minZoom:  1,
    maxZoom: 8,
    name: 'Lambert'
});

lambertBase.projection = new ConformalConicLambertProjection();

var myLatlng = new google.maps.LatLng(34, -96);

// map options
var mapOptions = {
    zoom: 4,
    maxZoom: 8,
    center: myLatlng,
    panControl: false,
    streetViewControl: false,
    mapTypeControl: false,
    zoomControlOptions: {
        style: google.maps.ZoomControlStyle.SMALL,
        position: google.maps.ControlPosition.TOP_RIGHT
    }
}

// Draw the map into the div with the above options
var vMap = new google.maps.Map(document.getElementById('mapCanvas'), mapOptions);

vMap.mapTypes.set('lambertTiles', lambertBase);
vMap.setMapTypeId('lambertTiles');

// then I draw the county polygons

// projection utils (modified from link above)
var phi0 = 10*Math.PI/180;
var phi1 = 20*Math.PI/180;
var phi2 = 70*Math.PI/180;
var n = (Math.log(Math.cos(phi1)) - Math.log(Math.cos(phi2)))/
    (-Math.log(Math.tan(phi1/2 + Math.PI/4)) + Math.log(Math.tan(phi2/2 + Math.PI/4)));
var rho0 = (Math.cos(phi1)*Math.pow(Math.tan(phi1/2 + Math.PI/4),n))/
    (n*Math.pow(Math.tan(phi0/2 + Math.PI/4),n));

function ConformalConicLambertProjection() {};
ConformalConicLambertProjection.prototype.fromLatLngToPoint = function(latLng) {
    var z = vMap.getZoom();
    var t = Math.PI/180*(100 + latLng.lng())*n;
    var rho = (Math.cos(phi1)*Math.pow(Math.tan(phi1/2. + Math.PI/4.),n))/
        (n*Math.pow(Math.tan((Math.PI/180*latLng.lat())/2. + Math.PI/4.),n));
    var x1 = rho*Math.sin(t);
    var y1 = rho0 - rho*Math.cos(t);
    x = Math.round(Math.pow(2,z)*(128 + 290.9090909090909*x1));
    y = Math.round(Math.pow(2,-1 + z)*(405.68181818181824 - 579.5454545454546*y1));

    return new google.maps.Point(x, y);
};
ConformalConicLambertProjection.prototype.fromPointToLatLng = function(pixel, noWrap) {
    var z = vMap.getZoom();
    var x1 = (-0.0034375*(Math.pow(2,7 + z) - pixel.x))/Math.pow(2,z);
    var y1 = -0.0017254901960784311*Math.pow(2,1 - z)*
        (pixel.y - 405.68181818181824*Math.pow(2,-1 + z));
    var rho = Math.sqrt(2.143305952697287 + Math.pow(x1,2) - 
        2.9280067982826044*y1 + Math.pow(y1,2));
    var t = Math.asin(x1/rho);
    var lng = 78.17779218926289*t-100;
    var lat = 28.64788975654*(-3.141592653589793 + 
        4*Math.atan(2.004758218840869/Math.pow(rho,1.3644598756425434575)));

    return new google.maps.LatLng(lat, lng, noWrap);
};
share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.