Skip to content

Instantly share code, notes, and snippets.

@Pisi-Deff
Last active January 12, 2025 00:38
Show Gist options
  • Save Pisi-Deff/92e00008f809383c82d926f843b6dd0f to your computer and use it in GitHub Desktop.
Save Pisi-Deff/92e00008f809383c82d926f843b6dd0f to your computer and use it in GitHub Desktop.
Dynmap RegionGrid component
componentconstructors['regiongrid'] = function(dynmap, configuration) {
// var cfg = $.extend({}, configuration);
var me = this;
this.chunkGroup = new L.LayerGroup();
this.regionGroup = new L.LayerGroup();
this.chunkMarkers = [];
this.regionMarkers = [];
this.chunkStyle = {
color: '#800000',
weight: '1',
opacity: 0.6,
clickable: false,
fill: false
};
this.regionStyle = {
color: '#000080',
weight: '3',
opacity: 0.6,
clickable: false,
fill: false
};
dynmap.addToLayerSelector(this.chunkGroup, 'Chunks', -1);
dynmap.addToLayerSelector(this.regionGroup, 'Regions', -1);
dynmap.map.on('moveend', function () {
setTimeout(function () {updateGrid();}, 0);
});
dynmap.map.on('layeradd layerremove', function (event) {
if (event.layer === me.chunkGroup || event.layer === me.regionGroup)
{
updateGrid();
}
});
function updateGrid() {
removeMarkers(me.chunkMarkers, me.chunkGroup);
removeMarkers(me.regionMarkers, me.regionGroup);
if (!dynmap.map.hasLayer(me.chunkGroup) && !dynmap.map.hasLayer(me.regionGroup))
{
return;
}
var minMax = getMinMaxData();
addAreas(me.chunkGroup, me.chunkMarkers, me.chunkStyle, 16, minMax.minChunk, minMax.maxChunk);
addAreas(me.regionGroup, me.regionMarkers, me.regionStyle, 16*32, minMax.minRegion, minMax.maxRegion);
}
function removeMarkers(markers, group) {
while (markers.length) {
group.removeLayer(markers.pop());
}
}
function addAreas(group, markers, style, multiplier, min, max) {
if (!dynmap.map.hasLayer(group)) return;
if ((max.x - min.x) * (max.z - min.z) > 1500) return; // for performance reasons
for (var x = min.x; x < max.x; x++) {
for (var z = min.z; z < max.z; z++) {
var pointList = [
latlng(x * multiplier, 64, (z + 1) * multiplier),
latlng((x + 1) * multiplier, 64, (z + 1) * multiplier),
latlng((x + 1) * multiplier, 64, z * multiplier)
];
var marker = new L.Polyline(pointList, style);
markers.push(marker);
group.addLayer(marker);
}
}
}
function getMinMaxData() {
// 0,0 => chunk 0 0 => region 0 0
// 15, 15 => chunk 0 0 => region 0 0
// 16, 16 => chunk 1 1 => region 0 0
// 12228, 8898 => chunk 764 556 => region 23 17
var bounds = dynmap.map.getBounds(),
projection = dynmap.maptype.getProjection();
var ne = projection.fromLatLngToLocation(bounds.getNorthEast(), 64),
se = projection.fromLatLngToLocation(bounds.getSouthEast(), 64),
sw = projection.fromLatLngToLocation(bounds.getSouthWest(), 64),
nw = projection.fromLatLngToLocation(bounds.getNorthWest(), 64);
var minX = Math.min(ne.x, se.x, sw.x, nw.x),
maxX = Math.max(ne.x, se.x, sw.x, nw.x),
minZ = Math.min(ne.z, se.z, sw.z, nw.z),
maxZ = Math.max(ne.z, se.z, sw.z, nw.z),
minChunk = {
x: Math.floor(minX / 16) - 1,
z: Math.floor(minZ / 16) - 1
},
maxChunk = {
x: Math.ceil(maxX / 16) + 1,
z: Math.ceil(maxZ / 16) + 1
},
minRegion = {
x: Math.floor(minChunk.x / 32),
z: Math.floor(minChunk.z / 32)
},
maxRegion = {
x: Math.ceil(maxChunk.x / 32),
z: Math.ceil(maxChunk.z / 32)
};
return {
minChunk: minChunk,
maxChunk: maxChunk,
minRegion: minRegion,
maxRegion: maxRegion
};
}
};
@Pisi-Deff
Copy link
Author

Pisi-Deff commented Jan 1, 2025

Heya @dvdmandt :)

Can I include a modified version of this

That's totally fine ๐Ÿ‘

@dvdmandt
Copy link

dvdmandt commented Jan 11, 2025

Hi again @Pisi-Deff! Sorry for the delay, I got a really nasty cold and got pretty knocked out. This is my modified version, which supports configuring the grids in configuration.txt. It also draws the lines from edge to edge instead of around every chunk/region for improved performance.

Is this credit section good with you?

/* Original by Eerik Mรคgi (Pisi-Deff @ GitHub)
 * https://gist.github.com/Pisi-Deff/92e00008f809383c82d926f843b6dd0f
*/

componentconstructors['regiongrid'] = function(dynmap, configuration) {
	// var cfg = $.extend({}, configuration);

	var me = this;
	
	if(configuration.grids){
		this.grids = [];
		for(var i = 0; i < configuration.grids.length; i++) {
			var cfgGrid = configuration.grids[i];
			var newGrid = makeSet(cfgGrid.sizeInChunks*16, cfgGrid.weight, cfgGrid.color, cfgGrid.title);
			this.grids.push(newGrid);
		}
	}
	else{
		this.grids = [
			makeSet(16, '1', '#800000', 'Grid - Chunks'),
			makeSet(16*32, '3', '#000080', 'Grid - Regions'),
		];
	}
	
	dynmap.map.on('moveend', function () {
		setTimeout(function () {updateGrid();}, 0);
	});

	dynmap.map.on('layeradd layerremove', function (event) {
		for(var i = 0; i < me.grids.length; i++){
			if (event.layer === me.grids[i].group)
			{
				updateGrid();
				break;
			}
		}
	});

	function updateGrid() {
		var atLeastOne = false;
		for(var i = 0; i < me.grids.length; i++){
			removeMarkers(me.grids[i].markers, me.grids[i].group);
			if(dynmap.map.hasLayer(me.grids[i].group))
				atLeastOne = true;
		}


		if (!atLeastOne){
			return;
		}

		var minMax = getMinMaxData();

		for(var i = 0; i < me.grids.length; i++){
			addAreas(me.grids[i].group, me.grids[i].markers, me.grids[i].style, me.grids[i].sizeInBlocks, minMax.minBlock, minMax.maxBlock);
		}
		
	}

	function removeMarkers(markers, group) {
		while (markers.length) {
			group.removeLayer(markers.pop());
		}
	}

	function addAreas(group, markers, style, multiplier, min, max) {
		if (!dynmap.map.hasLayer(group)) return;

		var minx = Math.floor(min.x / multiplier) - 50;
		var maxx = Math.ceil(max.x / multiplier) + 50;
		var minz = Math.floor(min.z / multiplier) - 50;
		var maxz = Math.ceil(max.z / multiplier) + 50;
		
		if (Math.max(maxx - minx, maxz - minz) > 500) return; // for performance reasons, plus it's not useful at this stage
		
		for (var x = minx; x < maxx; x++) {
			var pointList = [
				latlng(x * multiplier, 64, minz * multiplier),
				latlng(x * multiplier, 64, maxz * multiplier)
			];
			var marker = new L.Polyline(pointList, style);
			markers.push(marker);
			group.addLayer(marker);
		}
		for (var z = minz; z < maxz; z++) {
			var pointList = [
				latlng(minx * multiplier, 64, z * multiplier),
				latlng(maxx * multiplier, 64, z * multiplier)
			];
			var marker = new L.Polyline(pointList, style);
			markers.push(marker);
			group.addLayer(marker);
		}
	}

	function getMinMaxData() {
		// 0,0 => chunk 0 0 => region 0 0
		// 15, 15 => chunk 0 0 => region 0 0
		// 16, 16 => chunk 1 1 => region 0 0
		// 12228, 8898 => chunk 764 556 => region 23 17

		var bounds = dynmap.map.getBounds(),
			projection = dynmap.maptype.getProjection();

		var ne = projection.fromLatLngToLocation(bounds.getNorthEast(), 64),
			se = projection.fromLatLngToLocation(bounds.getSouthEast(), 64),
			sw = projection.fromLatLngToLocation(bounds.getSouthWest(), 64),
			nw = projection.fromLatLngToLocation(bounds.getNorthWest(), 64);

		var minX = Math.min(ne.x, se.x, sw.x, nw.x),
			maxX = Math.max(ne.x, se.x, sw.x, nw.x),
			minZ = Math.min(ne.z, se.z, sw.z, nw.z),
			maxZ = Math.max(ne.z, se.z, sw.z, nw.z),

			minBlock = {
				x: minX,
				z: minZ
			},
			maxBlock = {
				x: maxX,
				z: maxZ
			};

		return {
			minBlock: minBlock,
			maxBlock: maxBlock
		};
	}
	function makeSet(sizeInBlocks, weight, color, title){
		var group = new L.LayerGroup();
		var markers = [];
		var style = {
			color: color,
			weight: weight,
			opacity: 0.6,
			clickable: false,
			fill: false
		};
		dynmap.addToLayerSelector(group, title, 1000 + sizeInBlocks);
		
		return {
			group: group,
			markers: markers,
			style: style,
			sizeInBlocks: sizeInBlocks
		};
	}
};

Example configuration:

  - class: org.dynmap.ClientComponent
    type: regiongrid
    grids:
      - title: "Grid - Chunks"
        sizeInChunks: 1
        color: "#FF0000"
        weight: 1
      - title: "Grid - Veins (3x3)"
        sizeInChunks: 3
        color: "#00FFFF"
        weight: 2
      - title: "Grid - Oilfields (8x8)"
        sizeInChunks: 8
        color: "#FFFF00"
        weight: 3
      - title: "Grid - Regions (32x32)"
        sizeInChunks: 32
        color: "#0000FF"
        weight: 4

@Pisi-Deff
Copy link
Author

That looks fantastic! Well done man, especially with the improved performance ๐Ÿ˜ƒ ๐Ÿ‘
I'm totally happy with that credit section.

I'm also glad you survived the cold! ๐Ÿ˜„

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment