Skip to content

Instantly share code, notes, and snippets.

@denilsonsa
Last active May 1, 2024 11:55
Show Gist options
  • Select an option

  • Save denilsonsa/d0cd6c2c678cb83199df to your computer and use it in GitHub Desktop.

Select an option

Save denilsonsa/d0cd6c2c678cb83199df to your computer and use it in GitHub Desktop.
ets2-mobile-route-advisor - Map demo using Leaflet

ets2-mobile-route-advisor - Map demo using Leaflet

This Gist is outdated. Look at denilsonsa/ets2-stuff for the most recent code.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Leaflet demo for ets2-mobile-route-advisor</title>
<!--
See this for more info: https://github.com/mkoch227/ets2-mobile-route-advisor/issues/2
See this for a bug that currently happens with this code: https://groups.google.com/d/msg/leaflet-js/2EX8Shg_sOc/pOdFxpO1AAAJ
-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<!-- Note: if this demo gets incorporated into ets2-mobile-route-advisor, I'd recommend including a copy of these files. That way, it will work even without Internet connection. -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-beta.1/leaflet.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-beta.1/leaflet.js"></script>
<style>
#mapcanvas {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
</head>
<body>
<div id="mapcanvas"></div>
<script>
// Based on http://forum.scssoft.com/viewtopic.php?f=41&t=186779
function calculatePixelCoordinate(x, y, pointsPerPixel, x0, y0) {
return [
(x / pointsPerPixel + x0) | 0,
(y / pointsPerPixel + y0) | 0
];
}
function calculatePixelCoordinateEu(x, y) {
return calculatePixelCoordinate(x, y, 7.278, 11367, 9962);
}
function calculatePixelCoordinateUk(x, y) {
return calculatePixelCoordinate(x, y, 9.69522, 10226, 9826);
}
function game_coord_to_pixels(x, y) {
// I suppose either x,y are both positive, or they are both negative.
if (x < 0) {
return calculatePixelCoordinateUk(x, y);
} else {
return calculatePixelCoordinateEu(x, y);
}
}
var MAX_X = 19200;
var MAX_Y = 18688;
var CustomProjection = {
project: function (latlng) {
return new L.Point(latlng.lat, latlng.lng);
},
unproject: function (point) {
return new L.LatLng(point.x, point.y);
},
bounds: L.bounds([0, 0], [MAX_X, MAX_Y])
};
var CustomCRS = L.extend({}, L.CRS, {
projection: CustomProjection,
// Why 128? Because 7 is the maximum zoom level (i.e. 1:1 scale), and pow(2, 7) = 128.
transformation: new L.Transformation(1.0/128, 0, 1.0/128, 0),
scale: function (zoom) {
return Math.pow(2, zoom);
},
distance: function (latlng1, latlng2) {
var dx = latlng2.lng - latlng1.lng,
dy = latlng2.lat - latlng1.lat;
return Math.sqrt(dx * dx + dy * dy);
},
infinite: false
});
var map = L.map('mapcanvas', {
//attributionControl: false,
crs: CustomCRS,
maxBounds: [
[0, 0],
[MAX_X, MAX_Y]
]
});
L.tileLayer('tiles/{z}/{y}/{x}.png', {
minZoom: 0,
maxZoom: 7,
tileSize: 256,
continuousWorld: false
}).addTo(map);
map.setView([MAX_X/2, MAX_Y/2], 3);
var Debrecen = L.marker(game_coord_to_pixels(41744.53, 17305.5156)).bindPopup('Debrecen').addTo(map);
var Glasgow = L.marker(game_coord_to_pixels(-49770.64, -48417.68)).bindPopup('Glasgow').addTo(map);
// DEBUGGING CODE BELOW!
/*
var marker1 = L.marker([0, 0]).addTo(map);
var marker2 = L.marker([1, 1]).addTo(map);
var marker3 = L.marker([256, 256]).addTo(map);
var marker4 = L.marker([MAX_X/2, MAX_Y/2]).addTo(map);
var marker5 = L.marker([MAX_X/1, MAX_Y/2]).addTo(map);
var marker6 = L.marker([MAX_X/2, MAX_Y/1]).addTo(map);
var marker7 = L.marker([MAX_X/1, MAX_Y/1]).addTo(map);
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}
map.on('click', onMapClick);
*/
/*
// For version 1.0
// https://github.com/Leaflet/Leaflet/issues/3736
var DebugLayer = L.GridLayer.extend({
createTile: function(coords){
// create a <canvas> element for drawing
var tile = L.DomUtil.create('canvas', 'leaflet-tile');
// setup tile width and height according to the options
var size = this.getTileSize();
tile.width = size.x;
tile.height = size.y;
// get a canvas context and draw something on it using coords.x, coords.y and coords.z
var context = tile.getContext('2d');
context.beginPath();
context.rect(0, 0, 256, 256);
context.lineWidth = 2;
context.strokeStyle = 'white';
context.stroke();
context.font="20px Arial";
context.fillStyle = 'white';
context.fillText(coords.x + " / " + coords.y + " / " + coords.z, 80, 140);
// return the tile so it can be rendered on screen
return tile;
}
});
new DebugLayer().addTo(map);
*/
/*
// For versions earlier than 1.0
// https://github.com/Leaflet/Leaflet/issues/2776
var debugLayer = L.tileLayer.canvas({
minZoom: 0,
maxZoom: 7,
continuousWorld: true,
});
debugLayer.drawTile = function(canvas, point, zoom) {
var context = canvas.getContext('2d');
context.beginPath();
context.rect(0, 0, 256, 256);
context.lineWidth = 2;
context.strokeStyle = 'white';
context.stroke();
context.font="20px Arial";
context.fillStyle = 'white';
context.fillText(point.x + " / " + point.y + " / " + zoom, 80, 140);
}
debugLayer.addTo(map);
*/
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>OpenLayers demo for ets2-mobile-route-advisor</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<!-- Note: if this demo gets incorporated into ets2-mobile-route-advisor, I'd recommend including a copy of these files. That way, it will work even without Internet connection. -->
<link rel="stylesheet" href="http://openlayers.org/en/v3.8.2/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.8.2/build/ol.js" type="text/javascript"></script>
<!--script src="http://openlayers.org/en/v3.8.2/build/ol-debug.js" type="text/javascript"></script-->
<style>
#map {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
// Based on http://forum.scssoft.com/viewtopic.php?f=41&t=186779
function calculatePixelCoordinate(x, y, pointsPerPixel, x0, y0) {
return [
(x / pointsPerPixel + x0) | 0,
(y / pointsPerPixel + y0) | 0
];
}
function calculatePixelCoordinateEu(x, y) {
return calculatePixelCoordinate(x, y, 7.278, 11367, 9962);
}
function calculatePixelCoordinateUk(x, y) {
return calculatePixelCoordinate(x, y, 9.69522, 10226, 9826);
}
function game_coord_to_pixels(x, y) {
// I suppose either x,y are both positive, or they are both negative.
var r = null;
if (x < 0) {
r = calculatePixelCoordinateUk(x, y);
} else {
r = calculatePixelCoordinateEu(x, y);
}
// Inverting Y axis.
r[1] = MAX_Y - r[1];
return r;
}
var MAX_X = 19200;
var MAX_Y = 18688;
// Unused variables:
//var TILE_MAX_X = Math.ceil(MAX_X / Math.pow(2,7) / 256) * Math.pow(2,7) * 256;
//var TILE_MAX_Y = Math.ceil(MAX_Y / Math.pow(2,7) / 256) * Math.pow(2,7) * 256;
var projection = new ol.proj.Projection({
// Any name here. I chose "Funbit" because we are using funbit's image coordinates.
code: 'Funbit',
units: 'pixels',
extent: [0, 0, MAX_X, MAX_Y],
worldExtent: [0, 0, MAX_X, MAX_Y]
});
ol.proj.addProjection(projection);
// Unused code:
//ol.proj.addCoordinateTransforms('EPSG:4326', projection,
// function(coord) {
// return [coord[0], -coord[1]];
// },
// function(coord) {
// return [coord[0], -coord[1]];
// }
//);
//ol.proj.addCoordinateTransforms('EPSG:3857', projection,
// function(coord) {
// return [coord[0], -coord[1]];
// },
// function(coord) {
// return [coord[0], -coord[1]];
// }
//);
// The "name" attribute is unused.
var markers = [
new ol.Feature({
geometry: new ol.geom.Point([0, 0]),
name: 'Origin',
}),
new ol.Feature({
geometry: new ol.geom.Point([256, 256]),
name: 'First Tile',
}),
new ol.Feature({
geometry: new ol.geom.Point([256, MAX_Y - 256]),
name: 'Other First Tile',
}),
new ol.Feature({
geometry: new ol.geom.Point([MAX_X, MAX_Y]),
name: 'End',
}),
new ol.Feature({
geometry: new ol.geom.Point(game_coord_to_pixels(41744.53, 17305.5156)),
name: 'Debrecen',
}),
new ol.Feature({
geometry: new ol.geom.Point(game_coord_to_pixels(-49770.64, -48417.68)),
name: 'Glasgow',
}),
];
var feature_source = new ol.source.Vector({
features: markers,
wrapX: false
});
var custom_tilegrid = new ol.tilegrid.TileGrid({
extent: [0, 0, MAX_X, MAX_Y],
minZoom: 0,
origin: [0, MAX_Y],
tileSize: [256, 256],
resolutions: (function(){
var r = [];
for (var z = 0; z <= 7; ++z) {
r[z] = Math.pow(2, 7 - z);
}
return r;
})()
});
var map = new ol.Map({
target: 'map',
interactions: ol.interaction.defaults().extend([
new ol.interaction.DragRotateAndZoom()
]),
layers: [
new ol.layer.Tile({
extent: [0, 0, MAX_X, MAX_Y],
source: new ol.source.XYZ({
projection: projection,
url: 'tiles/{z}/{y}/{x}.png',
tileSize: [256, 256],
// Using createXYZ() makes the vector layer (with the features) unaligned.
// It also tries loading non-existent tiles.
//
// Using custom_tilegrid causes rescaling of all image tiles before drawing
// (i.e. no image will be rendered at 1:1 pixels), But fixes all other issues.
tileGrid: custom_tilegrid,
// tileGrid: ol.tilegrid.createXYZ({
// extent: [0, 0, MAX_X, MAX_Y],
// minZoom: 0,
// maxZoom: 7,
// tileSize: [256, 256]
// }),
wrapX: false,
maxZoom: 7
})
}),
// Debug layer below.
// new ol.layer.Tile({
// extent: [0, 0, MAX_X, MAX_Y],
// source: new ol.source.TileDebug({
// projection: projection,
// tileGrid: custom_tilegrid,
// // tileGrid: ol.tilegrid.createXYZ({
// // extent: [0, 0, MAX_X, MAX_Y],
// // minZoom: 0,
// // maxZoom: 7,
// // tileSize: [256, 256]
// // }),
// wrapX: false
// })
// }),
new ol.layer.Vector({
source: feature_source
//style: ...
})
],
view: new ol.View({
projection: projection,
extent: [0, 0, MAX_X, MAX_Y],
//center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
center: [MAX_X/2, MAX_Y/2],
minZoom: 0,
maxZoom: 7,
zoom: 2
})
});
map.on('singleclick', function(evt) {
var coordinate = evt.coordinate;
console.log(coordinate);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment