/Jorm-Maps

A customizeable 'google maps'-like map for DnD campaigns made using LeafletJS

Primary LanguageJavaScript

Jorm Maps

A project to display the DnD westmarches world of Jorm using the LeafletJS library.

Though made specifically for the world of Jorm, it can easily be reused for any other world by editing the locations.json file. Likewise to add/edit existing locations just edit the locations.json file. (Fork and pull request or ask to become a contributor to directly push changes)

Sharing locations

Locations specified with markers in the Locations.json file can be shared by specifying both a plane= and a location= url parameter. Alternatively any location can be shared by specifying its latitude and longitude with both the lat= and lng= url parameters. Additionally there zoom= url parameter can be specified to share a location at a specific zoom level (LeafletJS zoom levels, meaning 0 is zoomed out and 20 is zoomed in).

Example

http://localhost:8000/?plane=Jorm&location=Dod%27Estrin
http://localhost:8000/?plane=Jorm&location=Dod%27Estrin&zoom=5
http://localhost:8000/?lat=2815360.8285000003&lng=3152704.8960000006
http://localhost:8000/?lat=2815360.8285000003&lng=3152704.8960000006&zoom=5

Running locally

When trying to open the index.html after cloning you'll notice that it won't load correctly, this is due to the fact that you can't use a fetch(), which is used to load locations.json, on local files (Cross-Origin Request Blocked). So in order to test the page and anything on it you'll have to run an http server and open that in your browser instead, for example with python you can run py -m http.server in your working directory and it'll be available on http://localhost:8000 by default.

Locations.json

The JSON file which is used to load all marker and image data.

Structure

The base of Locations.json is made of key-value pairs for Planes.

{
	"Jorm": {...},
	"Shadowfell": {...},
	...
}

Plane

A Plane is made of key-value pairs for Places.

"Plane": {
	"Dod'Estrin": {...},
	"Wizard Tower": {...},
	...
}

Place

A Place has 3 optional objects: image, images, marker. Where images will be ignored if an image object has also been supplied.

"Place 1": {
	"images": {...},
	"marker": {...}
},
"Place 2": {
	"image": {...}
}

Images

An Images object is made of key-value pairs for Image objects where the key is the floor at which the image is located.

"images": {
	"-5": {...},
	"0": {...},
	"3": {...},
	...
}

Image

An Image has a required meta object containing meta data about where the image is located and optionally options that are passed to the leaflet constructor for the image. By default if not set an image will have the option pane set to "tilePane" which adds all generated html elements to the same container div.

"image": {
	"meta": {...},
	"opacity": 1,
	...
}

Image Meta

Image metadata has 3 required objects: position, layers, file. Where file is a string which is the link to the image to be shown, if the image is local then it'll be found relative to the images folder.

"meta": {
	"position": {...},
	"file": "DodEstrin.jpg",
	"layers": {...}
}

Image Position

An image position has an optional rotation which is how many degrees the image will be rotated and a required boundaries representation which can be either bounds, which is a 2 long array of latlng's which define the top-left latlng and bottom-right latlng of the boundaries, or a combination of a width length, a height length, and either a center location or topleft latlng (if both are defined the center will take precedent).

"position": {
	"bounds": [[33, 33], [44, 44]]
}
//
"position": {
	"rotation": 33,
	"width": {...},
	"height": {...},
	"center": {...}
}
//
"position": {
	"width": {...},
	"height": {...},
	"topleft": {...}
}

Marker

A Marker has a required meta object containing meta data about where the marker is located and optionally options that are passed to the leaflet constructor for the marker.

"marker": {
	"meta": {...},
	"attribution": "A brain",
	...
}

Marker Meta

Marker metadata has an optional object click and 2 required objects: location, layers.

"meta": {
	"location": {...},
	"click": {...},
	"layers": {...}
}

Click

A Click object has an optional jump_zoom number which specifies what at zoomlevel will be zoomed to when the marker is clicked. (Currently that's the only click option but it's an object for future possible additional options)

"click": {
	"jump_zoom": 13
}

Layers

Layers has 2 required numbers min, max which define the range from what layer until what layer (inclusive) the marker/image is visible.

"layers": {
	"min": 13,
	"max": 19
}

Location

A Location is an object that resolves to a latlng which can be using one of 3 ways: 1. latlng, 2. origin and offset, 3. origin, distance length, and direction. They have precedence in that order and are all required for their respective ways.

//1
"location": {
	"latlng": [200, 30]
}
//2
"location": {
	"origin": {...},
	"offset": {...}
}
//3
"location": {
	"origin": {...},
	"direction": {...},
	"distance": {...}
}

Latlng

A Latlng is a number array of 2 numbers representing a Latitude and Longitude, in that order.

"latlng": [42, 420]

Length

A Length is a representation of a distance, either by specifying the length itself, via meter, feet, tiles, kilometers, and mile, or by specifying a duration. (Taking precedence in that order)

"length": {
	"meter": 10
}
//...
"length": {
	"duration": {...}
}

Duration

A Duration is a distance as specified by the travel duration in a number days, number hours, or special hour_timestamp. Assuming a travel speed of 3 mile/hour or 24 miles per day (As per the Travel Pace table in the 5e PHB).

//10 and a half days of travel
"duration": {
	"days": 10.5
}
//4 and a half hours of travel
"duration": {
	"hours": 4.5
}
//1 hour and 20 minutes of travel
"duration": {
	"hour_timestamp": "1:20"
}

Origin

An Origin is a relative point of reference which resolves to a latlng using either latlng or a location which is the name of a Place (specifically the place's marker will be used for getting its location, so if it doesn't have a marker it cannot be used as an origin) with optionally a Plane's name to specify what plane that place is on if it's not on the same Plane the currently being assigned to location is.

"origin": {
	"latlng": [60, 90]
}
//
"origin": {
	"location": "Dod'Estrin",
	"plane": "Jorm"
}

Offset

An Offset has a lat Length and a lng Length which specify how far offset from the origin the latitude and longitude will be.

"offset": {
	"lat": {...},
	"lng": {...}
}

Direction

A Direction has an angle in degrees, radians, or a compass string. (Presedence in that order).

"direction": {
	"degrees": 50.41
}
//
"direction": {
	"radians": 2.1
}
//
"direction": {
	"compass": "SSW"
}