Skip to content

Instantly share code, notes, and snippets.

@sebelga
Last active August 9, 2016 16:40
Show Gist options
  • Save sebelga/39a79c95f39548b88be4b5f02af4195d to your computer and use it in GitHub Desktop.
Save sebelga/39a79c95f39548b88be4b5f02af4195d to your computer and use it in GitHub Desktop.

Carto Technical test

I decided to paint the geometries on a html canvas with the Mercator projection.

<!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>
(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