I decided to paint the geometries on a html canvas with the Mercator projection.
Last active
August 9, 2016 16:40
-
-
Save sebelga/39a79c95f39548b88be4b5f02af4195d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="x-ua-compatible" content="ie=edge"> | |
<title></title> | |
<meta name="description" content=""> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
</head> | |
<body> | |
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> | |
<script src="main.js"></script> | |
<script> | |
$(function() { | |
app.init(); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
'use strict'; | |
var app = function() { | |
this.scale = 1; | |
this.width = 960; | |
this.height = 505; | |
this.options = { | |
bkgColor: '#333', | |
color : '#eee' | |
}; | |
}; | |
app.prototype.init = function() { | |
console.log('Initializing app...'); | |
// Create Canvas | |
this.canvas = createCanvas(this.width, this.height); | |
document.body.appendChild(this.canvas); | |
// Load geo data | |
this.loadGeoJson(); | |
}; | |
app.prototype.loadGeoJson = function() { | |
var _this = this; | |
var sqlStatement = 'select * from public.mnmappluto'; | |
$.getJSON('https://rambo-test.carto.com:443/api/v2/sql/?format=GeoJSON&q=' + sqlStatement, function(data) { | |
_this.geojson = data.features; | |
_this.draw(); | |
}); | |
}; | |
app.prototype.draw = function() { | |
this.context = this.canvas.getContext('2d'); | |
this.bounds = this.getBounds(); | |
// Draw bkg | |
this.context.fillStyle = this.options.bkgColor; | |
this.context.fillRect(0, 0, this.width, this.height); | |
this.context.fillStyle = this.options.color; | |
for (var i = 0, l = this.geojson.length; i < l; i++) { | |
var coords = this.geojson[i].geometry.coordinates[0][0]; | |
for (var j = 0; j < coords.length; j++) { | |
var point = this.coordinateToPoint(coords[j][1], coords[j][0]); | |
if (j === 0) { | |
this.context.beginPath(); | |
this.context.moveTo(point.x, point.y); | |
} else { | |
this.context.lineTo(point.x, point.y); | |
} | |
} | |
this.context.fill(); | |
} | |
}; | |
app.prototype.getBounds = function () { | |
var bounds = {}; | |
var coords; | |
var point; | |
for (var i = 0, l = this.geojson.length; i < l; i++) { | |
coords = this.geojson[i].geometry.coordinates[0][0]; | |
for (var j = 0, l2 = coords.length; j < l2; j++) { | |
point = this.projectCoordinate(coords[j][1], coords[j][0]); | |
bounds.xMin = bounds.xMin < point.x ? bounds.xMin : point.x; | |
bounds.xMax = bounds.xMax > point.x ? bounds.xMax : point.x; | |
bounds.yMin = bounds.yMin < point.y ? bounds.yMin : point.y; | |
bounds.yMax = bounds.yMax > point.y ? bounds.yMax : point.y; | |
} | |
} | |
return bounds; | |
}; | |
app.prototype.projectCoordinate = function (latitude, longitude) { | |
var point = app.Projection.mercator(latitude, longitude); | |
point.x = point.x * this.scale; | |
point.y = point.y * this.scale; | |
return point; | |
}; | |
app.prototype.coordinateToPoint = function (latitude, longitude) { | |
var point = this.projectCoordinate(latitude, longitude); | |
var xScale = this.width / Math.abs(this.bounds.xMax - this.bounds.xMin); | |
var yScale = this.height / Math.abs(this.bounds.yMax - this.bounds.yMin); | |
var scale = xScale < yScale ? xScale : yScale; | |
return { | |
x: (point.x - this.bounds.xMin) * scale, | |
y: (this.bounds.yMax - point.y) * scale | |
}; | |
}; | |
function createCanvas (width, height) { | |
var canvas = document.createElement('canvas'); | |
canvas.width = width; | |
canvas.height = height; | |
return canvas; | |
} | |
app.Projection = { | |
RADIUS: 6378137, | |
MAX: 85.0511287798, | |
RADIANS: Math.PI / 180, | |
mercator: function (latitude, longitude) { | |
var point = {}; | |
point.x = this.RADIUS * longitude * this.RADIANS; | |
point.y = Math.max(Math.min(this.MAX, latitude), -this.MAX) * this.RADIANS; | |
point.y = this.RADIUS * Math.log(Math.tan((Math.PI / 4) + (point.y / 2))); | |
return point; | |
} | |
}; | |
window.app = new app(); | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment