# map **Repository Path**: mirrors-gis/map ## Basic Information - **Project Name**: map - **Description**: https://github.com/boytchev/map threejs map - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-07-23 - **Last Updated**: 2025-07-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # map.js A minimalistic library for generating outlines and flat 3D shapes of maps and map regions. The library is implemented as a single `map.js` file. ### Table of contents * [**Quick reference**](#quick-reference): [examples](#preview-of-examples) and [API](#preview-of-the-api) * [**API**](#api): [constructor](#constructor), [names](#region-names), [shapes](#region-shapes), [labels](#region-label) and [centers](#region-center) * [**Data**](#map-data): [XML](#xml-data) and [object](#object-data) * [**Examples**](#examples) * Simple: [country](#outline-of-country), [provinces](#outlines-of-provinces) and [3D map](#3d-map) * Intermediate: [colors](#colored-provinces), [elevation](#elevated-provinces) and [labels](#labels-of-provinces) * Advanced: [water supply](#water-supply), [overlays](#overlaying-maps) and [procedural maps](#procedural-maps) ## Quick reference ### Preview of examples Click on an image to run the example online. [](https://boytchev.github.io/map/examples/example-1.html) [](https://boytchev.github.io/map/examples/example-2.html) [](https://boytchev.github.io/map/examples/example-3-ex.html) [](https://boytchev.github.io/map/examples/example-4.html) [](https://boytchev.github.io/map/examples/example-5.html) [](https://boytchev.github.io/map/examples/example-7.html) [](https://boytchev.github.io/map/examples/example-6.html) [](https://boytchev.github.io/map/examples/example-8.html) [](https://boytchev.github.io/map/examples/example-9.html) ### Preview of the API ```javascript new Map( xmlFilename, callback, options ) // Map new Map( object, callback, options ) // Map map.regions // [string, string, ...] map.region2D( regionName, height, color ) // THREE.Line map.region3D( regionName, height, color ) // THREE.Mesh map.geometry2D( regionName ) // THREE.BufferGeometry map.geometry3D( regionName ) // THREE.BufferGeometry map.label2D( regionName, label, height, color, scale, offset ) // THREE.Mesh map.center( regionName, height ) // THREE.Vector3 ``` ## API The library `map.js` defines the class `Map` that encapsulates all the functions. You need to create an instance of `Map` in order to use it. ### Constructor A map instance is created either on map date from external XML file, or on a custom created map. ```javascript new Map( xmlFilename, callback, options ) new Map( object, callback, options ) ``` * `xmlFilename` is a name of an XML file defining the map and its regions. The library provides a low-poly map of Bulgaria in `map.xml` and a more detailed map in `map-ex.xml`. * `object` is a Javascript object defining the map and its regions. It could be used to provide procedural maps. * `callback` is an optional name of a user-defined callback function, that receives the map instance as parameter, when the instance is ready. This is useful for XML maps, that are loaded asynchronously. * `options` is an optional set of configuration parameters. Its default structure is `{width: 45, height: 28, roundness: 25}`, where `width` and `height` define the size of the map, and `roundness` sets the rounding radius of some vertices in the map. There are three typical patterns for making instances of `Map`. The first one uses a callback function to process the map, once it is ready: ```javascript new Map( 'map.xml', drawMap ); function drawMap( map ) { // map is ready to be used } ``` The second pattern uses the `=>` syntax: ```javascript new Map( 'map.xml', map => {/*map is ready to be used*/} ); ``` The third pattern is applicable only to procedural maps, when the map data is not load asynchronously from external file. In such case the map instance can be immediately used. ```javascript var map = new Map( proceduralMap ); // map is ready to be used ``` ### Region names ```javascript map.regions ``` This property contain an array of the names of all regions. It can be used to traverse through all regions in the map: ```javascript for( regionName in map.regions ) { // regionName contains the name of a region } ``` The provided maps `map.xml` and `map-ex.xml` define the shapes of Buigaria and its provinces. These shapes are all treated as regions. To traverse only the provinces the code can filter out the country by its region name: ```javascript for( regionName in map.regions ) if( regionName != 'BG' ) { // regionName contains only the name of a province } ``` ### Region shapes ```javascript map.region2D( regionName, height, color ) // THREE.Line map.region3D( regionName, height, color ) // THREE.Mesh ``` These methods generate a 2D shape (outline) or a 3D shape (flat bar) of the region called `regionName`. Optional parameters `height` and `color` define the heigh and the color of the shape. By default `height` is 1 and `color` is `'black'` for 2D shapes and `'white'` for 3D shapes. The raw geometry of a region is generated by these two methods: ```javascript map.geometry2D( regionName ) // THREE.BufferGeometry map.geometry2D( regionName ) // THREE.BufferGeometry ``` ### Region label ```javascript map.label2D( regionName, labelText, height, color, scale, offset ) // THREE.Mesh ``` The method `label2D` generates a 2D rectangular shape containing a given `labelText`. The shape is positioned at the center of region called `regionName`. The vertical location of the label is set by `height`, its colour is `color` and scale is a number `scale`. The last parameter `offset` is a number used to shift the label as of it is on another line in a multiline text. By default, `height=1`, `color='black'`, `scale=1` and `offset=0`. ### Region center ```javascript map.center( regionName, height ) // THREE.Vector3 ``` This method returns the virtual center of a region. It is used internally by `map.label2D` to position labels and by the user program to place other objects over regions. ## Map data The library builds 2D and 3D shapes of regions based on map data. There are two ways to provide these data: as XML file and as Javascript object. ### XML Data #### Regions The XML files included in the libabry are exported from file `map.drawio` which can be be edited in [Diagrams.net](https://www.diagrams.net/) (previously known as Draw.io). The `Map` class has minimal parser of XML files, i.e. its looks only for specific nodes, ignoring all the rest. The structure of the XMl file must be like this: ```xml : : : : ``` Each region is defined as `` with the name of the region in attribute `value`. The geographical shape of the region is defined by a starting point `` and a list of next consequitive points `` from ``. In the example above the first region is called `BG` and its shapes is defined by points `(370,-620), (540,-550), (540,-510), ... (220,330)`. The position of the label (this is the virtual center) is calculated from the data in `` and ``. #### Locations The map in file `examples\example-8.xml` contains locations of cities. Such locations are not encoded as shapes of points. The XML parser extract the coordinates and generates a small circle as a shape. ```xml : : ``` ### Object Data When the map data is provided as a Javascript object it must have the following structure: ```js { name: {shape:[x1, y1, x2, y2, ...], label: [x,y]}, name: {shape:[x1, y1, x2, y2, ...], label: [x,y]}, : } ``` where `name` is the name of a region, `shape` is an array of 3 or more pairs of 2D coordinates (x1,y1), (x2,y2), ... defining the outline of the region, and `label` is an array of one pair of 2D coordinates (x,y) of the location of the region label. ## Examples The following examples show code sniplets. Click on the image to run the example in real-rime in your browser. Use your default pointing device to change the viewpoint. ### Simple examples These examples show the basic functionality of `maps.js` – using 2D and 3D shapes of regions. #### Outline of country This example draws the outline of Bulgaria as a 2D shape. ```javascript new Map( '../map.xml', drawMap ); function drawMap( map ) { scene.add( map.region2D( 'BG' ) ); } ``` [](https://boytchev.github.io/map/examples/example-1.html) The following two versions of the example show the role of the `roundness` parameter in the map options. Sharp outline with `roundness=0`: ```javascript new Map( '../map.xml', drawMap, {roundness: 0} ); ``` [](https://boytchev.github.io/map/examples/example-1-sharp.html) Smooth outline with `roundness=100`: ```javascript new Map( '../map.xml', drawMap, {roundness: 100} ); ``` [](https://boytchev.github.io/map/examples/example-1-smooth.html) #### Outlines of provinces This example draws the outlines of Bulgarian provinces. The outline of the contry is excluded. ```javascript new Map( '../map.xml', drawMap ); function drawMap( map ) { for( var regionName in map.regions ) if( regionName != 'BG' ) scene.add( map.region2D( regionName ) ); } ``` [](https://boytchev.github.io/map/examples/example-2.html) #### 3D map ```javascript new Map( '../map.xml', drawMap ); function drawMap( map ) { // draw Bulgaria as 3D plate scene.add( map.region3D( 'BG', 1, 'crimson' ) ); // draw provinces outlines for( var regionName in map.regions ) if( regionName!='BG' ) scene.add( map.region2D( regionName ) ); } ``` [](https://boytchev.github.io/map/examples/example-3.html) The same example using the extended map `map-ex.xml` instead of `map.xml`: [](https://boytchev.github.io/map/examples/example-3-ex.html) ### Intermediate examples These examples show modification of regions – different colors, heights and labels. #### Colored provinces This example paints every province in a random color. ```javascript new Map( '../map.xml', drawMap ); function drawMap( map ) { for( var regionName in map.regions ) if( regionName!='BG' ) { var color = new THREE.Color( 0xFFFFFF*Math.random() ); scene.add( map.region3D( regionName, 1, color ) ); scene.add( map.region2D( regionName, 1 ) ); } } ``` [](https://boytchev.github.io/map/examples/example-4.html) #### Elevated provinces This example generates random value for a province and then uses this value to determin the height (elevation) and the color. ```javascript new Map( '../map.xml', drawMap ); function drawMap( map ) { for( var regionName in map.regions ) if( regionName!='BG' ) { var value = Math.random(); var color = new THREE.Color( value, 0.6, 1-value ); var height = 1+3*value; scene.add( map.region3D( regionName, height, color ) ); scene.add( map.region2D( regionName, height ) ); } } ``` [](https://boytchev.github.io/map/examples/example-5.html) #### Labels of provinces This example shows how labels are done. Because provinces' names are encoded in the map as `BG`, `BL`, `BU` and so on, there is an array of the full names of the provinces. ```javascript new Map( '../map.xml', drawMap ); var fullNames = {BG: 'България', BL: 'Благоевград', ... YA: 'Ямбол' }; function drawMap( map ) { : for( var regionName in map.regions ) if( regionName!='BG' ) { : scene.add( // province name map.label2D( regionName, fullNames[regionName], value, 'black', 0.8 ), // province percentage map.label2D( regionName, Math.round(100*value/3.1)+'%', value, 'navy', 0.7, 1.2 ) ); } } ``` [](https://boytchev.github.io/map/examples/example-7.html) ### Advanced examples These examples shows advanced usage of `map.js` by combining different objects and composing more complex maps. #### Water supply Imaginary map of water supply per province. ```javascript new Map( '../map.xml', drawMap ); function drawMap( map ) { for( var regionName in map.regions ) if( regionName!='BG' ) { : scene.add( map.region3D( regionName, 1, color ) ); scene.add( map.region2D( regionName, 1 ) ); var water = new THREE.Mesh( new THREE.IcosahedronGeometry( radius, 4 ), new THREE.MeshPhysicalMaterial( {...} ) ); water.position.copy( map.center( regionName, 1+radius ) ); water.castShadow = true; scene.add( water ); } } ``` [](https://boytchev.github.io/map/examples/example-6.html) #### Overlaying maps Map `map-ex.xml` provides outlines of provinces, map `example-8.xml` provides locations of towns. To have both maps with equal sizes and positions, they have the same region for the whole country. As the maps are loaded asynchronously, they are chained: ```javascript new Map( '../map-ex.xml', loadCityMap ); function loadCityMap( map ) { countryMap = map; new Map( 'example-8.xml', drawMap ); } function drawMap( cityMap ) { // using countryMap for provinces and cityMap for cities : } ``` [](https://boytchev.github.io/map/examples/example-8.html) #### Procedural maps Example of number of undergraduate programs in the 16 faculties of Sofia University. The map of the faculties is generated procedurally. The example also rotates the labels according to the viewer position. ```javascript // generate a procedural map var proceduralMap = {}; { // functions to calculate coordinates function x( ... ) { ... } function y( ... ) { ... } // the university as shapeless object proceduralMap[names[0]] = {shape: [], label: [0,0]}; // the faculties for( var i=1; i](https://boytchev.github.io/map/examples/example-9.html) October, 2021